DittoETH

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

rETH can be stuck in the BridgeReth contract

Summary

rETH can be stuck in the BridgeReth contract because of rocketETH token becoming more valuable as more ETH liquidity is deposited in the rocket pool.

Vulnerability Details

Let's consider the following example:
Let's imagine that in the rocketDeposit pool we have 1000 minted rETH which is backed up by 2000 ETH. This means that 1rETH = 2ETH. Now the DittoETH protocol becomes live and users start using it.

  1. Alice sends 2 ETH through the depositETH function in BridgeRouterFacet using the BridgeReth contract address. Now the depositETH function calls the depositEth function in BridgeReth and passes the msg.value which is 2 ETH. We then call rocketDepositPool.deposit{value: msg.value}() which does some checks and then calls rocketTokenRETH.mint(depositNet, msg.sender) where depositNet is our msg.value - depositFee and the msg.sender is the BridgeReth contract. Then we go to the mint function of the rETH token contract where we get the rETH value using the ETH we send minus the depositFee. This ETH is converted to rETH by using the formula - _ethAmount.mul(rethSupply).div(totalEthBalance). So in our example this would be: (2ETH - depositFee)*1000e18/2000e18 = 1rETH approximately(we are going to round it up to make it easier). So now our BridgeReth contract gets 1rETH and the rocket supply increases to 1001rETH and the ETH tokens are now 2002ETH. Alice's ethEscrowed becomes 2zETH(or 2ETH since we assume 1zETH = 1ETH).

  2. Now let's say the ETH liquidity increases and this can happen by various ways. For example users can provide ETH without minting rETH and then the rETH supply stays the same while the ETH supply increases which means rETH becomes more valuable. This can happen since according to Etherscan right now 1rETH trades for about 1.09ETH. Now the ETH tokens increase to let's say 2100ETH and the rETH tokens are still 1001rETH.

  3. Alice wants to withdraw her deposit so she calls the withdraw function in the BridgeRouterFacet contract and passes as arguments the BridgeRouter address and the amount she wants to withdraw(2zETH). After some protocol fees are taken now we go to the withdraw function of the bridge. There we get the rETH value from the 2zETH Alice wants to withdraw. But now since rETH has become more valuable Alice would get less rETH transferred. The rethValue would be 2*1001/2100 = 0,95rETH. Then a transfer is called and the rethValue is transferred to Alice. The BridgeReth is left with 0,05rETH that cannot be withdrawn since if Alice tries to call withdraw again the function will revert because the Alice ethEscrow amount will be 0 and when trying to subtract from it, it will revert with arithmetic overflow / underflow.

This leaves the contract with funds that cannot be withdrawn. And the tokens are stuck forever.

Here is a link to the rETH contract where calculations are done described in the above steps:
https://etherscan.io/token/0xae78736cd615f374d3085123a210448e74fc6393#code#F6#L122

Impact

Stuck funds in the bridge contract

Tools Used

Manual review

Recommendations

Add a way to withdraw the stuck funds that can then be transferred to the TAPP/DAO.

Updates

Lead Judging Commences

0xnevi Lead Judge
over 1 year ago
0xnevi Lead Judge over 1 year ago
Submission Judgement Published
Invalidated
Reason: Other
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.