DYAD - 0xfox's results

The first capital efficient overcollateralized stablecoin.

General Information

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

DYAD

Findings Distribution

Researcher Performance

Rank: 38/183

Findings: 3

Award: $319.60

🌟 Selected for report: 0

🚀 Solo Findings: 0

Awards

3.8221 USDC - $3.82

Labels

bug
3 (High Risk)
satisfactory
sufficient quality report
:robot:_28_group
duplicate-830

External Links

Lines of code

https://github.com/code-423n4/2024-04-dyad/blob/cd48c684a58158de444b24854ffd8f07d046c31b/src/core/VaultManagerV2.sol#L146-L149 https://github.com/code-423n4/2024-04-dyad/blob/cd48c684a58158de444b24854ffd8f07d046c31b/src/core/VaultManagerV2.sol#L195-L198

Vulnerability details

Impact

The withdraw and redeemDyad functions will revert when attempting to withdraw from any kerosene vault address. This issue will lead to a scenario where users are unable to withdraw their collateral from kerosene vaults, effectively locking their tokens within the protocol.

Proof of Concept

The vulnerable code can be found in the withdraw and redeemDyad functions of VaultManagerV2

Specifically, the lines that cause the issue are: https://github.com/code-423n4/2024-04-dyad/blob/cd48c684a58158de444b24854ffd8f07d046c31b/src/core/VaultManagerV2.sol#L195-L198 https://github.com/code-423n4/2024-04-dyad/blob/cd48c684a58158de444b24854ffd8f07d046c31b/src/core/VaultManagerV2.sol#L146-L149

uint value = amount * _vault.assetPrice() * 1e18 / 10**_vault.oracle().decimals() / 10**_vault.asset().decimals();

value is the USD value of the token amount _vault is the passed in vault address cast to Vault oracle is the automatic getter function created for the oracle public variable on Vault

The KerosineVault contract does not have an oracle public variable defined: https://github.com/code-423n4/2024-04-dyad/blob/main/src/core/Vault.kerosine.sol

As a result, when the withdraw function is called with a kerosene vault address, the transaction will revert due to the absence of the oracle function.

Tools Used

Manual review

Modify the withdraw and redeemDyad functions to handle kerosene vaults differently. The exogenous collateral check should be skipped if the passed in vault address is of a kerosene vault.

Assessed type

DoS

#0 - c4-pre-sort

2024-04-26T21:32:54Z

JustDravee marked the issue as duplicate of #1048

#1 - c4-pre-sort

2024-04-28T18:39:29Z

JustDravee marked the issue as duplicate of #830

#2 - c4-pre-sort

2024-04-29T08:45:28Z

JustDravee marked the issue as sufficient quality report

#3 - c4-judge

2024-05-11T20:05:36Z

koolexcrypto marked the issue as satisfactory

Awards

32.4128 USDC - $32.41

Labels

bug
3 (High Risk)
satisfactory
sufficient quality report
upgraded by judge
:robot:_28_group
duplicate-397

External Links

Lines of code

https://github.com/code-423n4/2024-04-dyad/blob/cd48c684a58158de444b24854ffd8f07d046c31b/src/core/VaultManagerV2.sol#L150

Vulnerability details

Impact

The withdraw function in the VaultManagerV2 contract has a bug that could prevent users from withdrawing their kerosene collateral even when they are sufficiently overcollateralized. This issue could impact a large amount of the user base.

Proof of Concept

This is the context of the withdraw function:

    function withdraw(uint256 id, address vault, uint256 amount, address to) public isDNftOwner(id) {
        if (idToBlockOfLastDeposit[id] == block.number) revert DepositedInSameBlock();
        uint256 dyadMinted = dyad.mintedDyad(address(this), id); //e18
        Vault _vault = Vault(vault);
        uint256 value =
            amount * _vault.assetPrice() * 1e18 / 10 ** _vault.oracle().decimals() / 10 ** _vault.asset().decimals();
        if (getNonKeroseneValue(id) - value < dyadMinted) revert NotEnoughExoCollat();
        _vault.withdraw(id, to, amount);
        if (collatRatio(id) < MIN_COLLATERIZATION_RATIO) revert CrTooLow();
    }

The specific line causing the issue is: https://github.com/code-423n4/2024-04-dyad/blob/cd48c684a58158de444b24854ffd8f07d046c31b/src/core/VaultManagerV2.sol#L150

if (getNonKeroseneValue(id) - value < dyadMinted) revert NotEnoughExoCollat();

id is the id of the user's nft value is the USD value of the token amount to withdraw dyadMinted is the amount of dyad minted by the user

This line checks the non-kerosene collateral value associated with the user's nft minus the withdrawal amount - against the minted dyad of the user, even when the withdrawal is for kerosene collateral. If the non-kerosene collateral value minus the withdrawal amount exceeds the minted dyad - the function will wrongly revert and prevent the user from withdrawing their kerosene.

Tools Used

Manual review

To mitigate this issue, the withdraw function should be modified to handle endogenous (currently kerosene) and exogenous collateral separately. The function should check if the vault being withdrawn from is a kerosene vault or a non-kerosene vault, and apply the appropriate collateralization check accordingly.

Assessed type

DoS

#0 - c4-pre-sort

2024-04-26T21:11:02Z

JustDravee marked the issue as duplicate of #397

#1 - c4-pre-sort

2024-04-29T08:48:28Z

JustDravee marked the issue as sufficient quality report

#2 - c4-judge

2024-05-11T19:23:04Z

koolexcrypto marked the issue as satisfactory

#3 - c4-judge

2024-05-13T18:33:04Z

koolexcrypto changed the severity to 3 (High Risk)

Findings Information

Labels

bug
3 (High Risk)
satisfactory
sufficient quality report
edited-by-warden
:robot:_11_group
duplicate-338

Awards

283.3687 USDC - $283.37

External Links

Lines of code

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

Vulnerability details

Impact

The inability to liquidate a user whose exogenous collateral falls below the value of their minted DYAD can lead to a scenario where under-collateralized positions are not liquidated promptly putting the protocol in financial risk.

Proof of Concept

The liquidate function will only allow the liquidation to proceed if the user's collateralization ratio as calculated by collatRatio function is below the minimum (MIN_COLLATERIZATION_RATIO of 150%). The collatRatio function takes into account both the endogenous (Kerosine) and exogenous collateral when calculating the CR. This means that by holding a sufficiently large ratio of Kerosine tokens a user could prevent themselves from being liquidated even if the value of their exogenous collateral falls below the value of their minted DYAD. Here is the relevant part of the liquidate function:

uint256 cr = collatRatio(id);
if (cr >= MIN_COLLATERIZATION_RATIO) revert CrTooHigh();

Modify the liquidate function to allow liquidation based on the value of the exogenous collateral compared to the minted DYAD as well as the overall collateralization ratio.

Tools Used

Manual code review.

Assessed type

Other

#0 - c4-pre-sort

2024-04-28T19:58:38Z

JustDravee marked the issue as duplicate of #128

#1 - c4-pre-sort

2024-04-29T09:03:44Z

JustDravee marked the issue as sufficient quality report

#2 - c4-judge

2024-05-08T09:58:56Z

koolexcrypto marked the issue as not a duplicate

#3 - c4-judge

2024-05-08T09:59:04Z

koolexcrypto marked the issue as duplicate of #338

#4 - c4-judge

2024-05-11T12:20:24Z

koolexcrypto marked the issue as satisfactory

AuditHub

A portfolio for auditors, a security profile for protocols, a hub for web3 security.

Built bymalatrax © 2024

Auditors

Browse

Contests

Browse

Get in touch

ContactTwitter