An attacker could skew the RSETH price by donating LSTs (stETH, rETH, cbETH) to LTRDepositPool. The getRSETHPrice() calls ILRTDepositPool.getTotalAssetDeposits(asset) in a loop for each supported asset as follows.
Inside getTotalAssetDeposits(), the call to getAssetDistributionData(asset) returns the current balance of LST of LTRDepositPool inside the assetLyingInDepositPool variable.
function getAssetDistributionData(address asset)
public
view
override
onlySupportedAsset(asset)
returns (uint256 assetLyingInDepositPool, uint256 assetLyingInNDCs, uint256 assetStakedInEigenLayer)
{
// Question: is here the right place to have this? Could it be in LRTConfig?
assetLyingInDepositPool = IERC20(asset).balanceOf(address(this));
...
}
Therefore, the RSETH price returned from getRSETHPrice() could be dramatically increased by a donation attack.
And an attacker, as a first depositor, can block further deposits to LTRDepositPool by forcing subsequent depositors to mint 0 RSETH tokens.
The attack scenario is the following:
The attacker, as the first depositor, calls depositAsset() with 1 wei of stETH as depositAmount and mints 1 wei of RSETH.
The attacker donates 1 stETH to LTRDepositPool.
So the price returned from getRSETHPrice() will be 1 ether * 10^18 instead of 1 ether.
A benign depositor will mint 0 RSETH because denominator is huge in the formula (amount * lrtOracle.getAssetPrice(asset)) / lrtOracle.getRSETHPrice().
Lines of code
https://github.com/code-423n4/2023-11-kelp/blob/main/src/LRTOracle.sol#L52 https://github.com/code-423n4/2023-11-kelp/blob/main/src/LRTDepositPool.sol#L109 https://github.com/code-423n4/2023-11-kelp/blob/main/src/LRTDepositPool.sol#L79
Vulnerability details
Impact
An attacker could skew the RSETH price by donating LSTs (stETH, rETH, cbETH) to
LTRDepositPool
. ThegetRSETHPrice()
callsILRTDepositPool.getTotalAssetDeposits(asset)
in a loop for each supported asset as follows.Inside
getTotalAssetDeposits()
, the call togetAssetDistributionData(asset)
returns the current balance of LST ofLTRDepositPool
inside theassetLyingInDepositPool
variable.Therefore, the RSETH price returned from
getRSETHPrice()
could be dramatically increased by a donation attack.And an attacker, as a first depositor, can block further deposits to
LTRDepositPool
by forcing subsequent depositors to mint 0 RSETH tokens.The attack scenario is the following:
depositAsset()
with 1 wei of stETH asdepositAmount
and mints 1 wei of RSETH.LTRDepositPool
.getRSETHPrice()
will be1 ether * 10^18
instead of1 ether
.(amount * lrtOracle.getAssetPrice(asset)) / lrtOracle.getRSETHPrice()
.Proof of Concept
Tools Used
Manual review.
Recommended Mitigation Steps
Use ERC4626.sol as a base contract for the
LTRDepositPool
which has built-in protection.Assessed type
DoS