First depositAsset
could ruin the rsETH
price calculation.
#172
Labels
3 (High Risk)
Assets can be stolen/lost/compromised directly
bug
Something isn't working
duplicate-42
edited-by-warden
satisfactory
satisfies C4 submission criteria; eligible for awards
sufficient quality report
This report is of sufficient quality
Lines of code
https://github.com/code-423n4/2023-11-kelp/blob/c5fdc2e62c5e1d78769f44d6e34a6fb9e40c00f0/src/LRTOracle.sol#L52-L79
https://github.com/code-423n4/2023-11-kelp/blob/c5fdc2e62c5e1d78769f44d6e34a6fb9e40c00f0/src/LRTDepositPool.sol#L119-L144
Vulnerability details
Summary
First user deposit followed by direct transfer to any contract that is used to calcualte the price of
rsETH
will ruin the price ofrsETH
.Vulnerability details
After the protocol is deployed first user can call
depositAsset
with1 wei
ofdepositAmount
.In
depositAsset
we will get the amount ofrsETH
to be minted, calcualted fromgetRsETHAmountToMint
in_mintRsETH
.uint256 rsethAmountMinted = _mintRsETH(asset, depositAmount);
.(rsethAmountToMint) = getRsETHAmountToMint(_asset, _amount);
.rsethAmountToMint = (amount * lrtOracle.getAssetPrice(asset)) / lrtOracle.getRSETHPrice();
.Now let's take a look how
rsETH
price is calculated inLRTOracle
at first deposit:We can see that when the
rsETH
total supply is zero (first deposit, norsETH
minted yet).rsETH
price is equal to 1 ether (1e18).This is data from chainlink price feed for
rETH / ETH
at address0x536218f9E9Eb48863970252233c8F271f554C2d0
copied fromlatestAnswer
at 12.11.2023 14:45 GMT +1.1091400000000000000
int256We come back here and we can see the amount of
rsETH
minted from this calculation:rsethAmountToMint = (amount * lrtOracle.getAssetPrice(asset)) / lrtOracle.getRSETHPrice();
amount = 1
lrtOracle.getAssetPrice(asset) = 1_091_400_000_000_000_000
lrtOracle.getRSETHPrice() = 1_000_000_000_000_000_000
Let's calculate the amount of
rsETH
to be minted using solidity. We will use remix for simplicty.Copy and paste is in remix and see that it returns 1.
Calculations return 1 it means that 1 wei of
rsETH
will be minted.Now malcious user can directly transfer as little as
1 gwei
(1000000000) toLRTDepositPool
address.If next user would like to deposit let's say 10 ether to the pool he would receive 0
rsETH
due to calculation ingetRSETHPrice
inLRTOracle
.Direct tranfer does not mint any
rsETH
so the price will be inflated.Now the
rsEthSupply
is equal to 1,totalAssetAmt
= 1000000000 + 1 (1000000000 direct transfer, 1 wei after deposit), sotoalETHInPool
= 1000000001 * assetER (which is in 18 decimals). This inflatedrsETH
price will round down to zero even for VERY big deposits.PoC
I set
LRTDepositPoolZeroMints
as oracle for simplicity and modified thegetRSETHPrice
function to better ilustrate the reality of the calculation in protocol. Also I used only the balance of the pool for simplicty because nodes balances are still zero.Test passed so user received zero
rsETH
tokens for 10 ether deposit ofrETH
.Impact
Loss of funds on deposit.
Tools used
VScode, Manual Review, Foundry
Recommendations
Change the
rsETH
price calculation method to make sure that direct transfers of tokens will not affect the price ofrsETH
.Assessed type
Math
The text was updated successfully, but these errors were encountered: