DittoETH

Ditto
DeFiFoundryOracle
55,000 USDC
View results
Submission Details
Severity: medium
Invalid

When there is a negative rebase, bidders can cheat ask/short users out of funds

Summary

The protocol has an implicit assumption that the value of ETH collateral which a bidder deposits as collateral (ethEscrowed) will only increase over time. This is because they never again reference, e.g. when a bidder creates an order, that there is actually enough ETH in the vault to cover the total amount of ethEscrowed across all users. This is a faulty assumption however, because there are certain scenarios where this invariant is broken: (1) a series of down-rebases due to e.g. issues across validators used by LST (2) a full or partial exploit of a liquid staking protocol which leads an extreme down-rebase. It's important to note here that this system is being collateralized by LSTs, rather than ETH, which introduces this risk.

Issues such as those above can then effectively break the protection of the price specified in limitAsk and limitShort orders. As per the documentation, it's clear that the price is in terms of ETH, not zETH. However, if there is a down-rebase where the actual value of ETH is less than ethEscrowed, this price protection will no longer function as intended, because zETH < ETH. Bidders can then exchange their zETH for the asset token at elevated prices, effectively stealing from the ask/short orders. They are also effectively circumventing the down-rebase.

Vulnerability Details

Consider the following scenario for a vault that uses stETH as collateral, USD is the asset:

  1. Asker A creates an ask order with a price of 0.001 ETH/USD (technically 1e15) and ercAmount of 1000e18. This means they are willing to swap 1000e18 of USD for 1e18 of ETH

  2. Bidder B deposits 1 ETH worth of stETH into the vault, which sets s.vaultUser[vault][bidder].ethEscrowed = 1e18

  3. There is a down rebase where the value of stETH is now worth 0.9 ETH. Here, there is no change to the ethEscrowed of bidder B

  4. Bidder B then calls createBid with a price equal to 0.001 ETH/USD, which will allow them to match with Asker A's order. Here, Bidder B will receive 1000e18 USD, while Asker A will receive 1e18 zETH (which is now worth 9e17 ETH). Effectively the price control for Asker A was circumvented, as they only checked the zETH amount, rather than the underlying ETH amount in the swap.

Impact

When there is a negative rebase (meaning the value of zETH < ETH), bidders can circumvent improper price protection of limitAsk and limitShort orders, and effectively sell their zETH to ask/short users at elevated prices. This means limitAsk/limitShort users will lose funds due to improper price protection.

Tools Used

Manual review

Recommendations

Although admittedly this will cost extra gas, I believe that during a call to _createBid, there should be a check as to whether there's enough ETH in the vault to fully cover a user's ethEscrowed. When this is not the case, either revert or adjust the value of the zETH. This will also need to be handled for bid orders already on the book.

Updates

Lead Judging Commences

0xnevi Lead Judge
over 1 year ago
0xnevi Lead Judge over 1 year ago
Submission Judgement Published
Invalidated
Reason: Other

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.