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: 131/183
Findings: 1
Award: $4.87
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: dimulski
Also found by: 0xleadwizard, 0xlemon, Aamir, Al-Qa-qa, AvantGard, Bauchibred, Cryptor, DarkTower, Egis_Security, Giorgio, Maroutis, MrPotatoMagic, OMEN, Ocean_Sky, Ryonen, SBSecurity, Sabit, SpicyMeatball, Stefanov, T1MOH, Tigerfrake, WildSniper, atoko, bhilare_, darksnow, fandonov, grearlake, iamandreiski, igdbase, pontifex, web3km, xiao
4.8719 USDC - $4.87
The absence of a minimum mint position size introduces a vulnerability where the protocol's collateral and stability are at risk. Imagine a scenario where multiple users, with malicious intentions, create dust accounts. This could result in the protocol accumulating bad debt that is not appealing for liquidation, potentially disrupting the redeemability of 1 DYAD
for 1 USD
.
The protocol does not enforce a minimum mint position size, which could potentially allow malicious actors to create numerous small positions, known as dust positions. These positions, if they become underwater, might not be attractive to liquidators due to the low value involved. This scenario poses a significant risk to the protocol's overall collateral and stability, especially when considering multiple users with malicious intentions creating dust accounts. This situation could lead to the accumulation of bad debt that no one is willing to liquidate, potentially compromising the redeemability of 1 DYAD
for 1 USD
.
To dive into more details protocol enforces a collateral ratio (cr) of 150%
for minting. If the cr falls below this threshold, the user becomes liquidatable. However, if the cr drops to less than 100%
, the protocol reimburses the liquidator 100% of the current asset's worth during the liquidation process. This mechanism is designed to protect the protocol from undercollateralized positions.
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); }
However, there is a critical issue with this approach. The collateral ratio is checked in percentages, which means a user could have a $10
position backed by $20
collateral, indicating an overcollateralized position. If the asset's value drops significantly, and the position is now only backed by $9
(i.e., cr = 9%
), liquidators might not be incentivized to liquidate this position on the mainnet due to the high gas fees involved.
Manual review
To mitigate this risk, consider implementing a minimum restriction on the type of position that can be minted. Additionally, it's crucial to factor in the gas fees when making decisions about position sizes and liquidation thresholds.
Other
#0 - c4-pre-sort
2024-04-27T10:11:34Z
JustDravee marked the issue as duplicate of #1258
#1 - c4-pre-sort
2024-04-29T09:20:59Z
JustDravee marked the issue as sufficient quality report
#2 - c4-judge
2024-05-03T14:07:47Z
koolexcrypto changed the severity to QA (Quality Assurance)
#3 - c4-judge
2024-05-12T09:33:20Z
koolexcrypto marked the issue as grade-c
#4 - c4-judge
2024-05-22T14:26:07Z
This previously downgraded issue has been upgraded by koolexcrypto
#5 - c4-judge
2024-05-28T16:52:27Z
koolexcrypto marked the issue as satisfactory
#6 - c4-judge
2024-05-28T20:06:32Z
koolexcrypto marked the issue as duplicate of #175