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: 54/183
Findings: 2
Award: $224.23
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: Maroutis
Also found by: 0x486776, 0xShitgem, 0xabhay, 0xleadwizard, 0xlemon, 0xnilay, 0xtankr, 3docSec, AM, Aamir, Abdessamed, Al-Qa-qa, AlexCzm, Circolors, CodeWasp, Daniel526, Egis_Security, Emmanuel, Giorgio, Honour, Hueber, Infect3d, Krace, KupiaSec, LeoGold, Limbooo, PoeAudits, SBSecurity, SpicyMeatball, T1MOH, The-Seraphs, TheSavageTeddy, TheSchnilch, Topmark, VAD37, ZanyBonzy, adam-idarrha, bhilare_, btk, carlitox477, cinderblock, dimulski, falconhoof, grearlake, gumgumzum, iamandreiski, itsabinashb, josephdara, ke1caM, kennedy1030, ljj, n0kto, n4nika, neocrao, oakcobalt, petro_1912, pontifex, poslednaya, shaflow2, shikhar229169, web3km, ych18, zhaojohnson, zigtur
0.2831 USDC - $0.28
https://github.com/code-423n4/2024-04-dyad/blob/cd48c684a58158de444b24854ffd8f07d046c31b/script/deploy/Deploy.V2.s.sol#L64-L65 https://github.com/code-423n4/2024-04-dyad/blob/cd48c684a58158de444b24854ffd8f07d046c31b/script/deploy/Deploy.V2.s.sol#L93-L94 https://github.com/code-423n4/2024-04-dyad/blob/cd48c684a58158de444b24854ffd8f07d046c31b/src/core/VaultManagerV2.sol#L75 https://github.com/code-423n4/2024-04-dyad/blob/cd48c684a58158de444b24854ffd8f07d046c31b/src/core/VaultManagerV2.sol#L88
The idea of Kerosine manager is whitelisting/license vaults that are going to be consider to calculate Kerosine intrinsict value, while the idea of Licenser is whitelisting/licensing vaults that will be able to be considered exogenous collateral to mint DYAD.
However, this is not the way that they are used in VaultManagerV2
. In this contract, considering that WETH and wstETH vaults are licensed by Licenser contract and Kerosine manager, the same balance associated to an NFT in these vault can be used twice to increase collateral ratio avoiding liquidation of undercollateralized vaults.
wstETH and WETH vault can be used twice to increase collateral ratio, avoiding liquidation of undercollateralize vaults
VaultManagerV2.add(BOB_NFT_ID,wstETH_VAULT)
.VaultManagerV2.addKerosene(BOB_NFT_ID,wstETH_VAULT)
. Given it is licensed by keroseneManager
this function does not revertVaultManagerV2.deposit(BOB_NFT_ID, wstETH_VAULT,USD_100_VALUE)
VaultManagerV2.mint(BOB_NFT_ID, wstETH_VAULT,99 * 10e18)
. given that collatRatio
account for watETH balance twice the transaction does not revertIn addition Bob position cannot be liquidated until wstETH deposit value is reduced to 75 USD, which would leave the protocol totally undercollateralized. This become extremely dangerous in case of an abrupt crash of ETH or stETH price.
The idea of using kerosine manager to also add vault make no sense at all, it should be removed. To track Kerosine and non-Kerosine USD value simply iterate through vaults and check its assets to defien where to add it or not. Here a quick fix to current design, however consider it might also include other bugs. Use it as inspiration for a new contract
Other
#0 - c4-pre-sort
2024-04-29T05:19:07Z
JustDravee marked the issue as duplicate of #966
#1 - c4-pre-sort
2024-04-29T08:37:59Z
JustDravee marked the issue as sufficient quality report
#2 - c4-judge
2024-05-04T09:46:27Z
koolexcrypto marked the issue as unsatisfactory: Invalid
#3 - c4-judge
2024-05-28T15:28:38Z
koolexcrypto marked the issue as duplicate of #1133
#4 - c4-judge
2024-05-29T07:07:10Z
koolexcrypto marked the issue as satisfactory
🌟 Selected for report: SBSecurity
Also found by: AlexCzm, Emmanuel, Stefanov, carlitox477, carrotsmuggler, d3e4, grearlake, peanuts
223.9474 USDC - $223.95
According to docs, code walkthrough and sponsor private messages during contest liquidator should receive rewards for
However this is not the case:
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; //@audit max(cr,100%) uint liquidationEquityShare = (cappedCr - 1e18).mulWadDown(LIQUIDATION_REWARD); // @audit (max(cr,100%) - 100%) * 20% --> Excedent 20% uint liquidationAssetShare = (liquidationEquityShare + 1e18).divWadDown(cappedCr); // @audit ((max(cr,100%) - 100%) * 20% + 100%) / max(cr,100%) 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 actual reward for a liquidator is a 20% of the remaining associated to the NFT, not a 20% of the 100% collateral. This means that current rewards correspond to:
Instead of the desired calculation
Modify current codebase to match intended behaviour
// VaultManagerV2.liquidate uint cappedCr = cr < 1e18 ? 1e18 : cr; // max(cr,100%) - uint liquidationEquityShare = (cappedCr - 1e18).mulWadDown(LIQUIDATION_REWARD); // (max(cr,100%) - 100%) * 20% --> Excedent 20% + uint excedentRatio = cappedCr <= 1e18 ? 0 : cappedCr - 1e18; + uint liquidationEquityShare = excedentRatio < LIQUIDATION_REWARD ? excedentRatio : LIQUIDATION_REWARD; uint liquidationAssetShare = (liquidationEquityShare + 1e18).divWadDown(cappedCr);
Math
#0 - c4-pre-sort
2024-04-29T06:34:36Z
JustDravee marked the issue as duplicate of #906
#1 - c4-pre-sort
2024-04-29T08:46:38Z
JustDravee marked the issue as high quality report
#2 - c4-judge
2024-05-05T10:09:12Z
koolexcrypto marked the issue as not a duplicate
#3 - c4-judge
2024-05-05T10:13:57Z
koolexcrypto marked the issue as unsatisfactory: Invalid
#4 - carlitox477
2024-05-16T13:08:07Z
Dup of https://github.com/code-423n4/2024-04-dyad-findings/issues/75
The comment in the POC express (max(cr,100%) - 100%) * 20% --> Excedent 20%
Given that the excedent can be at most 50%, is the same than saying that the rewards are capped to 10% of the total debt.
#5 - carlitox477
2024-05-16T14:54:13Z
On the other hand, I honestly think the impact is not fully considered. Capping rewards to 10% of excess collateral is not a good approach. For instance, if collateral goes down sharply to 120% with current implementation a liquidator is just incentivize with by 2% of rewards, leaving the other 18% to the borrower, if this 2% is not enough to cover gas is nonsense to execute the liquidation. I strongly suggest DYAD team to reconsider their decision of keeping current implementation. The suggested mitigation is easy to implement and cover the protocol of this risk, providing a better experience to liquidator and also provide better protection to lenders funds
#6 - c4-judge
2024-05-24T10:29:50Z
koolexcrypto removed the grade
#7 - c4-judge
2024-05-24T10:30:20Z
koolexcrypto marked the issue as duplicate of #75
#8 - c4-judge
2024-05-24T10:30:43Z
koolexcrypto changed the severity to 2 (Med Risk)
#9 - c4-judge
2024-05-28T19:22:08Z
koolexcrypto marked the issue as duplicate of #982
#10 - c4-judge
2024-05-29T11:23:58Z
koolexcrypto marked the issue as satisfactory