rsETH
amount to mint calculation when depositing an asset in the LRTDepositPool::depositAsset()
is incorrect, leading to an immediate loss of value
#524
Labels
3 (High Risk)
Assets can be stolen/lost/compromised directly
bug
Something isn't working
duplicate-62
edited-by-warden
satisfactory
satisfies C4 submission criteria; eligible for awards
sufficient quality report
This report is of sufficient quality
upgraded by judge
Original issue severity upgraded from QA/Gas by judge
Lines of code
https://github.com/code-423n4/2023-11-kelp/blob/f751d7594051c0766c7ecd1e68daeb0661e43ee3/src/LRTDepositPool.sol#L136
https://github.com/code-423n4/2023-11-kelp/blob/f751d7594051c0766c7ecd1e68daeb0661e43ee3/src/LRTDepositPool.sol#L141
https://github.com/code-423n4/2023-11-kelp/blob/f751d7594051c0766c7ecd1e68daeb0661e43ee3/src/LRTDepositPool.sol#L151-L152
Vulnerability details
Bug description
In this protocol, users deposit underlying assets and get the corresponding amount of
rsETH
for their deposits. How manyrsETH
will be minted is calculated based on the underlying asset's price and the currentrsETH
price, which are fetched from theLRTOracle
contract.https://github.com/code-423n4/2023-11-kelp/blob/f751d7594051c0766c7ecd1e68daeb0661e43ee3/src/LRTDepositPool.sol#L109
In the LRTOracle contract:
asset price is returned directly from the ChainLink oracle. (Ref)
rsETH
price is calculated based on the total deposited ETH value in the pool and the total supply of the mintedrsETH
. (Ref)Everything is as expected up to this point. Now, let's check the
depositAsset()
function:https://github.com/code-423n4/2023-11-kelp/blob/f751d7594051c0766c7ecd1e68daeb0661e43ee3/src/LRTDepositPool.sol#L119C1-L144C6
As we can see above, the calculation to decide how many
rsETH
to mint is performed after the token transfer is completed. At that point, thersETH
price has already been increased, which causes users to get lessrsETH
.When the transaction is executed completely,
rsETH
supply will increase and the price will fall down. The impact depends on how many tokens are deposited.Down below you can see a coded PoC showing a scenario where
the user deposited 100 ether worth of assets when the
rsETH
price is equal to 1 ether (total asset balance in the pool was 100,rsETH
supply was 100)rsETH
's are minted based on the price of 2 ether during the transaction (total balance increased to 200 but thersETH
supply was still 100 duringgetRsETHAmountToMint()
function)The user got 50 rsETH
Transaction finalized and the last price of
rsETH
is 1.33 ether (total balance in the pool 200,rsETH
supply 150)The user immediately lost 1/3 of his/her deposit value (deposited 100 ether worth of tokens, got 66.6666 ether worth of tokens)
Impact
rsETH
price will be calculated higher than its actual value during the transactionrsETH
than expected due to this higher calculated pricersETH
price will decrease after the transaction is completed due to increased supply.Proof of Concept
Coded PoC
Note: This PoC uses a mock
LRTOracle
similar to the protocol's other tests. In this mock contract, thersETH
price calculation is exactly the same as the code in scope. The only difference is that the asset price is fixed at 1 ether.Create a new file in the test folder and copy and paste the snippet to this file. The setup of this file is the same setup in the protocol's other test files.
To run it:
forge test --match-test test_MintAmount_WhenDepositing_Is_Incorrect -vvvv
After running the tests, the result is like below:
Tools Used
Manual review, foundry
Recommended Mitigation Steps
rsETH
amount to mint calculation should be done before transferring these tokens to the pool.It might be implemented in different ways. For an example:
Assessed type
Math
The text was updated successfully, but these errors were encountered: