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.
Consider the following scenario for a vault that uses stETH as collateral, USD is the asset:
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
Bidder B deposits 1 ETH worth of stETH into the vault, which sets s.vaultUser[vault][bidder].ethEscrowed = 1e18
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
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.
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.
Manual review
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.
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.