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: 43/183
Findings: 1
Award: $283.37
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: shikhar229169
Also found by: 0x486776, 0xSecuri, 0xfox, 3th, Circolors, Honour, KupiaSec, Maroutis, Sancybars, Stormreckson, Strausses, ke1caM, kennedy1030
283.3687 USDC - $283.37
https://github.com/code-423n4/2024-04-dyad/blob/main/src%2Fcore%2FVaultManagerV2.sol#L230-L248
During liquidation the for loop iterated through the normal vault
list only and not the keroseneVault
list
https://github.com/code-423n4/2024-04-dyad/blob/main/src%2Fcore%2FVaultManagerV2.sol#L34-L35
mapping (uint => EnumerableSet.AddressSet) internal vaults; mapping (uint => EnumerableSet.AddressSet) internal vaultsKerosene;
Because of this user's that hold enough kerosene
token won't be liquated even if the users normal vault
is undercollatralized.
Vaults will become undercollatralized.
Users become liquidatable when the value of their asset drops below 150% minimum collateral ratio the liquidator specifies the id
being liquidated and to
the address to recieve the liquidation profits.
https://github.com/code-423n4/2024-04-dyad/blob/main/src%2Fcore%2FVaultManagerV2.sol#L205-L229
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)); uint cappedCr = cr < 1e18 ? 1e18 : cr; uint liquidationEquityShare = (cappedCr - 1e18).mulWadDown(LIQUIDATION_REWARD); uint liquidationAssetShare = (liquidationEquityShare + 1e18).divWadDown(cappedCr); uint numberOfVaults = vaults[id].length(); for (uint i = 0; i < numberOfVaults; i++) { Vault vault = Vault(vaults[id].at(i)); uint collateral = vault.id2asset(id).mulWadUp(liquidationAssetShare); vault.move(id, to, collateral); } emit Liquidate(id, msg.sender, to); }
The collateralRatio
calls getTotalUsdValue
to get the value of the vault being liquidated which is the total of the two distinct vaults vault
and keroseneVault
.
https://github.com/code-423n4/2024-04-dyad/blob/main/src%2Fcore%2FVaultManagerV2.sol#L230-L248
function collatRatio( uint id ) public view returns (uint) { uint _dyad = dyad.mintedDyad(address(this), id); if (_dyad == 0) return type(uint).max; return getTotalUsdValue(id).divWadDown(_dyad); } function getTotalUsdValue( uint id ) public view returns (uint) { return getNonKeroseneValue(id) + getKeroseneValue(id); }
Which is returned as the cr to be compared to the minimum collateral ratio.
uint cr = collatRatio(id); if (cr >= MIN_COLLATERIZATION_RATIO) revert CrTooHigh();
If the user being liquidated holds enough kerosene token of 150% against the minted dyad
liquidation reverts.
While the normal vault
will remain undercollateralized.
Manual Review
Implement a way to liquidate kerosene tokens if the exo-collateral is not enough.
Context
#0 - c4-pre-sort
2024-04-28T10:21:48Z
JustDravee marked the issue as duplicate of #128
#1 - c4-pre-sort
2024-04-29T09:01:34Z
JustDravee marked the issue as sufficient quality report
#2 - c4-judge
2024-05-08T09:57:43Z
koolexcrypto marked the issue as not a duplicate
#3 - c4-judge
2024-05-08T09:57:49Z
koolexcrypto marked the issue as duplicate of #338
#4 - c4-judge
2024-05-11T12:20:31Z
koolexcrypto marked the issue as satisfactory