Platform: Code4rena
Start Date: 18/04/2024
Pot Size: $36,500 USDC
Total HM: 19
Participants: 183
Period: 7 days
Judge: Koolex
Id: 367
League: ETH
Rank: 59/183
Findings: 1
Award: $200.84
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: MrPotatoMagic
Also found by: 0xtankr, ArmedGoose, Egis_Security, Giorgio, KYP, Maroutis, NentoR, OMEN, Sabit, Shubham, SpicyMeatball, T1MOH, d3e4, dimulski, peanuts
200.8376 USDC - $200.84
https://github.com/code-423n4/2024-04-dyad/blob/main/src/core/VaultManagerV2.sol#L215
According to docs: "If a Note’s collateral value in USD drops below 150% of its DYAD minted balance, it faces liquidation. The liquidator burns a quantity of DYAD equal to the target Note’s DYAD minted balance, ..."
This means that the liquidator must have atleast the same amount or higher token balance than the user they are going to liquidate if the user's collateral ratio drops down. If the liquidator does not hold the equivalent amount of tokens, the function would revert due to underflow. Thus it would be not be possible for liquidators to liquidate if the user has high amount of dyad tokens minted.
The dyad.burn
makes an external call to reduce the minted dyad balance for a particular nft.
File: VaultManagerV2.sol function liquidate( uint id, uint to ) external isValidDNft(id) isValidDNft(to) { uint cr = collatRatio(id); if (cr >= MIN_COLLATERIZATION_RATIO) revert CrTooHigh(); dyad.burn(id, msg.sender, dyad.mintedDyad(address(this), id)); @> issue ...
The burn()
makes an external call to the erc20 contract _burn()
to reduce the balance of the user who called the liquidate()
in this case.
File: Dyad.sol function burn( uint id, address from, uint amount ) external licensedVaultManager { _burn(from, amount); mintedDyad[msg.sender][id] -= amount; }
Here, when deducting the amount from the balance of the liquidator, the function will throw error due to underflow if the liquidator's balance is less than the user it is about to liquidate.
File: ERC20.sol function _burn(address from, uint256 amount) internal virtual { balanceOf[from] -= amount; @> error when reducing the liquidator's balance // Cannot underflow because a user's balance // will never be larger than the total supply. unchecked { totalSupply -= amount; } emit Transfer(from, address(0), amount); }
Thus for a liquidator to liquidate a user, first they must have that particular or higher number of dyad that they are going to liquidate for which they must have initially deposited collateral at the required ratio to be able to mint dyad themselves. Given that the rewards can be transferred to another nft id & there isn't a specific 'liquidator' role assigned by the protocol meaning anyone can be a liquidator, the liquidator must first put in their own funds to be one.
In the case where top users holding high volumes of dyad gets their collateral ratio below 150%, they won't get liquidated because the liquidator does not have enough token balance themselves. Even if the liquidators manage to get the required balance to liquidate at a later time, the user could have added extra collateral & prevent themselves from being liquidated.
Manual Review
Burn the nft owner's token balance instead of burning the liquidator's.
Invalid Validation
#0 - c4-pre-sort
2024-04-29T05:52:15Z
JustDravee marked the issue as duplicate of #1097
#1 - c4-pre-sort
2024-04-29T08:34:39Z
JustDravee marked the issue as sufficient quality report
#2 - c4-judge
2024-05-11T12:21:59Z
koolexcrypto marked the issue as satisfactory