Platform: Code4rena
Start Date: 21/10/2021
Pot Size: $80,000 ETH
Total HM: 28
Participants: 15
Period: 7 days
Judge: ghoulsol
Total Solo HM: 19
Id: 42
League: ETH
Rank: 7/15
Findings: 4
Award: $6,350.90
🌟 Selected for report: 3
🚀 Solo Findings: 2
0.2624 ETH - $1,092.19
gpersoon
Everyone can call the function registerAsset() of MochiProfileV0.sol Assuming the liquidity for the asset is sufficient, registerAsset() will reset the _assetClass of an already registered asset to AssetClass.Sigma.
When the _assetClass is changed to AssetClass.Sigma then liquidationFactor(), riskFactor(), maxCollateralFactor(), liquidationFee() keeperFee() maxFee() will also return a different value. Then the entire vault will behave differently. The threshold for liquidation will also be different, possibly leading to a liquidation that isn't supposed to happen.
Add the following in function registerAsset(): require(_assetClass[_asset] ==0,"Already exists");
🌟 Selected for report: gpersoon
0.9718 ETH - $4,045.16
gpersoon
The value of the global variable debts in the contract MochiVault.sol is calculated in an inconsistent way.
In the function borrow() the variable debts is increased with a value excluding the fee. However in repay() and liquidate() it is decreased with the same value as details[_id].debt is decreased,, which is including the fee.
This would mean that debts will end up in a negative value when all debts are repay-ed. Luckily the function repay() prevents this from happening.
In the mean time the value of debts isn't accurate. This value is used directly or indirectly in:
This means the entire debt and claimable calculations are slightly off.
function borrow(..) details[_id].debt = totalDebt; // includes the fee debts += _amount; // excludes the fee
function repay(..)
debts -= _amount;
details[_id].debt -= _amount;
function liquidate(..) debts -= _usdm; details[_id].debt -= _usdm;
In function borrow(): replace debts += _amount; with debts += totalDebt
🌟 Selected for report: gpersoon
0.2915 ETH - $1,213.55
gpersoon
Every time you deposit some assets in the vault (via deposit() of MochiVault.sol) then "lastDeposit[_id]" is set to block.timestamp. The modifier wait() checks this value and makes sure you cannot withdraw for "delay()" blocks. The default value for delay() is 3 minutes.
Knowing this delay you can do a griefing attack: On chains with low gas fees: every 3 minutes deposit a tiny amount for a specific NFT-id (which has a large amount of assets). On chains with high gas fees: monitor the mempool for a withdraw() transaction and frontrun it with a deposit()
This way the owner of the NFT-id can never withdraw the funds.
Create a mechanism where you only block the withdraw of recently deposited funds
#0 - r2moon
2021-10-27T12:41:56Z
Will update deposit function to allow only NFT owner to deposit