Closed code423n4 closed 1 year ago
0xSorryNotSorry marked the issue as high quality report
0xSorryNotSorry marked the issue as duplicate of #601
Picodes marked the issue as satisfactory
Picodes marked the issue as duplicate of #1125
Picodes marked the issue as duplicate of #1125
Picodes changed the severity to 3 (High Risk)
Lines of code
https://github.com/code-423n4/2023-03-asymmetry/blob/main/contracts/SafEth/SafEth.sol#L63-L101 https://github.com/code-423n4/2023-03-asymmetry/blob/main/contracts/SafEth/derivatives/Reth.sol#L170-L185 https://github.com/code-423n4/2023-03-asymmetry/blob/main/contracts/SafEth/derivatives/Reth.sol#L215 https://github.com/code-423n4/2023-03-asymmetry/blob/main/contracts/SafEth/derivatives/Reth.sol#L228-L242
Vulnerability details
Impact
An attacker can craft a set of transactions so that when they are depositing funds in the
SafEth
contract, using thestake()
function, they can understate the value of existing deposits (preDepositPrice
value), while overstating the value of their deposit (totalStakeValueEth
value). This vulnerability happens because of howethPerDerivative(..)
is calculated for rETH. Specifically, if users cannot deposit directly into the rETH contract, then theReth
logic will revert to pricing rETH using the UniswapV3 pool spot price, and also the call todeposit()
will result in swapping through the same UniswapV3 pool.To take advantage of this, an attacker can first decrease the spot price of rETH in the pool, which will result in a lower
preDepositPrice
value when the attacker calls thestake()
function of theSafEth
contract. Then, later in the same call whendeposit()
is called for the rETH staking derivative, it will get rETH by swapping ETH -> rETH in the UniswapV3 pool. This swapping will increase the value of the rETH that was received by the swap. The subsequentethPerDerivative(..)
function call will then award the attacker an excess amount for their deposit, by overstating the value of the received rETH. This is invalid behavior, as the price of rETH should not be changing atomically in the same transaction.This is medium severity because an attacker is able to drain significant funds from the
SafEth
contract. However, this can only occur in specific scenarios, based on maxSlippage, whether the rETH contract is accepting deposits, the distribution and depth of the UniswapV3 liquidity.Proof of Concept
POC including preliminary state and steps (foundry test). This POC was done using block number 16936327:
Tools Used
Manual review
Recommended Mitigation Steps
The fix for this exploit is very simple, in that you simply need the ensure that the call to
ethPerDerivative(..)
for the Reth contract does not change in a single transaction during the call tostake()
. For example, you can use the chainlink oracle for rETH instead of the UniswapV3 pool spot price.