code-423n4 / 2024-04-dyad-findings

8 stars 6 forks source link

Big undercollateralized positions may not get liquidated #505

Closed c4-bot-4 closed 6 months ago

c4-bot-4 commented 6 months ago

Lines of code

https://github.com/code-423n4/2024-04-dyad/blob/main/src/core/VaultManagerV2.sol#L205-L228

Vulnerability details

Impact

There are no restrictions on the maximum collateral amount a user can deposit into a single Note, and the amount of DYAD tokens he can mint. The liquidate() function requires all of the DYAD tokens, a Note has minted to be burned in a single transaction as can be seen from this line:

dyad.burn(id, msg.sender, dyad.mintedDyad(address(this), id));

Typically liquidators are bots that monitor protocols and liquidate undercollateralized positions if there is profit to be made. They don't hold the specific funds that will be required to be transferred to the protocol, or burned in order to execute a potentially profitable liquidation. They rely on flash loans, and most protocols providing flash loan functionality, require users to pay back the loan in the same token they received when taking the flash loan + some fee, paid in the same token. There are no DYAD markets on AAVE or Compound, so a liquidator can't take a big enough loan of DYAD tokens in order to liquidate an undercollateralized position. Thus the liquidator will have to acquire the DYAD tokens required to be burned in a different way. At the time of writing this report there are no DYAD pools on Curve. There is a Uniswap V2 ETH/DYAD pool which contains 31714921551045792676107 ≈ 31_714e18 DYAD tokens, as well as Uniswap V3 USDC/DYAD pool which contains ≈ 336_153e18 DYAD tokens. There are around 370_000e18 DYAD tokens supplied as liquidity on DEXes. However the slippage on the Uniswap V2 pool will be extremely big. As for Uniswap v3 pools, tokens are converted to the other token, when the current price, is not in the price range the liquidity was provided for. So we can assume that a liquidator can make a swap of 150_000 - 200_000 DYAD tokens max. To create a position of \$150_000 - \$200_000 DYAD tokens with a collateralization rate of 150%, a user would have to provide \$225_000 - \$300_000 worth of collateral, to satisfy the collateral ratio requirement. The deposti() function allows for anyone to provide collateral for a note, and the mintDyad() function allows the owner of the Note to mint DYAD tokens to an arbitrary address. Many users not wanting to buy a Note NFT, which price starts at 0.1e18 ETH and increase linearly on each new minted NFT with 0.001e18ETH, may opt in for a single Note, and provide collateral in it, thus creating one big position, split between different users. Due to the implementation of the liquidate() function all of the DYAD of the undercollateralized position have to be burned in one transaction. It will take 1 or 2 big positions, in the range of 150_000 - 200_000 DYAD tokens, to go below the collateralization ratio, and at the time of writing this report there isn't a way to get this positions liquidated. The whole protocol can go underwater very quickly.

Tools Used

Manual review

Recommended Mitigation Steps

Either provide a maximum amount of DYAD tokens that a single Note can mint, or allow undercollateralized positions to be liquidated on parts.

Assessed type

Context

c4-pre-sort commented 6 months ago

JustDravee marked the issue as duplicate of #1097

c4-pre-sort commented 6 months ago

JustDravee marked the issue as sufficient quality report

c4-judge commented 5 months ago

koolexcrypto marked the issue as satisfactory

c4-judge commented 5 months ago

koolexcrypto changed the severity to 3 (High Risk)