Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Liquidation will never work with non-zero discounts #66

Open
code423n4 opened this issue Oct 26, 2021 · 0 comments
Open

Liquidation will never work with non-zero discounts #66

code423n4 opened this issue Oct 26, 2021 · 0 comments
Labels
3 (High Risk) Assets can be stolen/lost/compromised directly bug Something isn't working sponsor confirmed Sponsor agrees this is a problem and intends to fix it (OK to use w/ "disagree with severity")

Comments

@code423n4
Copy link
Contributor

Handle

harleythedog

Vulnerability details

Impact

Right now, there is only one discount profile in the github repo: the "NoDiscountProfile" which does not discount the debt at all. This specific discount profile works correctly, but I claim that any other discount profile will result in liquidation never working.

Suppose that we instead have a discount profile where discount() returns any value strictly larger than 0. Now, suppose someone wants to trigger a liquidation on a position. First, triggerLiquidation will be called (within DutchAuctionLiquidator.sol). The variable "debt" is initialized as equal to vault.currentDebt(_nftId). Notice that currentDebt(_ndfId) (within MochiVault.sol) simply scales the current debt of the position using the liveDebtIndex() function, but there is no discounting being done within the function - this will be important. Back within the triggerLiquidation function, the variable "collateral" is simply calculated as the total collateral of the position. Then, the function calls vault.liquidate(_nftId, collateral, debt), and I claim that this will never work due to underflow. Indeed, the liquidate function will first update the debt of the position (due to the updateDebt(_id) modifier). The debt of the position is thus updated using lines 99-107 in MochiVault.sol. We can see that the details[_id].debt is updated in the exact same way as the calculations for currentDebt(_nftId), however, there is the extra subtraction of the discountedDebt on line 107.

Eventually we will reach line 293 in MochiVault.sol. However, since we discounted the debt in the calculation of details[_id].debt, but we did not discount the debt for the passed in parameter _usdm (and thus is strictly larger in value), line 293 will always error due to an underflow. In summary, any discount profile that actually discounts the debt of the position will result in all liquidations erroring out due to this underflow. Since no positions will be liquidatable, this represents a major flaw in the contract as then no collateral can be liquidated so the entire functionality of the contract is compromised.

Proof of Concept

Liquidate function in MochiVault.sol: https://github.com/code-423n4/2021-10-mochi/blob/main/projects/mochi-core/contracts/vault/MochiVault.sol#:~:text=function-,liquidate,-(

triggerLiquidation function in DutchAuctionLiquidator.sol: https://github.com/code-423n4/2021-10-mochi/blob/main/projects/mochi-core/contracts/liquidator/DutchAuctionLiquidator.sol#:~:text=function-,triggerLiquidation,-(address%20_asset%2C%20uint256

Retracing the steps as I have described above, we can see that any call to triggerLiquidation will result in:

details[_id].debt -= _usdm;

throwing an error since _usdm will be larger than details[_id].debt.

Tools Used

Manual inspection.

Recommended Mitigation Steps

An easy fix is to simply change:

details[_id].debt -= _usdm;

to be:

details[_id].debt = 0;

as liquidating a position should probably just be equivalent to repaying all of the debt in the position.

Side Note: If there are no other discount profiles planned to be added other than "NoDiscountProfile", then I would recommend deleting all of the discount logic entirely, since NoDiscountProfile doesn't actually do anything

@code423n4 code423n4 added 3 (High Risk) Assets can be stolen/lost/compromised directly bug Something isn't working labels Oct 26, 2021
code423n4 added a commit that referenced this issue Oct 26, 2021
@r2moon r2moon added the sponsor confirmed Sponsor agrees this is a problem and intends to fix it (OK to use w/ "disagree with severity") label Oct 26, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
3 (High Risk) Assets can be stolen/lost/compromised directly bug Something isn't working sponsor confirmed Sponsor agrees this is a problem and intends to fix it (OK to use w/ "disagree with severity")
Projects
None yet
Development

No branches or pull requests

2 participants