Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Inflation attack can cause early users to lose their deposit #631

Closed
c4-submissions opened this issue Nov 15, 2023 · 3 comments
Closed

Inflation attack can cause early users to lose their deposit #631

c4-submissions opened this issue Nov 15, 2023 · 3 comments
Labels
3 (High Risk) Assets can be stolen/lost/compromised directly bug Something isn't working duplicate-42 satisfactory satisfies C4 submission criteria; eligible for awards sufficient quality report This report is of sufficient quality

Comments

@c4-submissions
Copy link
Contributor

Lines of code

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#L152
https://github.com/code-423n4/2023-11-kelp/blob/f751d7594051c0766c7ecd1e68daeb0661e43ee3/src/LRTDepositPool.sol#L109
https://github.com/code-423n4/2023-11-kelp/blob/f751d7594051c0766c7ecd1e68daeb0661e43ee3/src/LRTOracle.sol#L56-L58
https://github.com/code-423n4/2023-11-kelp/blob/f751d7594051c0766c7ecd1e68daeb0661e43ee3/src/LRTOracle.sol#L52-L79
https://github.com/code-423n4/2023-11-kelp/blob/f751d7594051c0766c7ecd1e68daeb0661e43ee3/src/LRTDepositPool.sol#L79

Vulnerability details

Impact

The first user that deposit can artificially increase the getRSETHPrice and by doing so he manipulates getRsETHAmountToMint. Subsequent depositors will receive much less rsETH shares than expected. On some scenarios users can receive 0 shares.

Proof of Concept

LRTDepositPool.sol::depositAsset helps users to stake LST in exchange for rsETH shares. To get the amount of rsETH to mint, getRsETHAmountToMint is used :

    function getRsETHAmountToMint(
        address asset,
        uint256 amount
    )
        public view override returns (uint256 rsethAmountToMint)
    {
        // setup oracle contract
        address lrtOracleAddress = lrtConfig.getContract(LRTConstants.LRT_ORACLE);
        ILRTOracle lrtOracle = ILRTOracle(lrtOracleAddress);

        // calculate rseth amount to mint based on asset amount and asset exchange rate
        rsethAmountToMint = (amount * lrtOracle.getAssetPrice(asset)) / lrtOracle.getRSETHPrice();
    }
  • lrtOracle.getAssetPrice(asset) returns the asset/ETH exchange rate.
  • lrtOracle.getRSETHPrice uses LST assets amounts distributed among depositPool, NDCs and eigenLayer to calculate the rsETH/ETH exchange rate.

Attack scenario:

  • A first depositor (attacker) deposit 1 wei of rEth;
    a. rsETH totalSupply is 0 => getRSETHPrice returns 1 ether;
        if (rsEthSupply == 0) {
            return 1 ether;
        }

b. rETH/ETH ratio is > 1 (~ 1.09 * 1e18 more precise);
c. attacker mint rsethAmountToMint = 1 * 1.09 * 1e18 / 1e18 = 1 wei of rsETH.

  • Attacker transfer 1 ether of rETH to LRTDepostitPool or directly to any NodeDelegator.

  • Since getAssetDistributionData is using balanceOf ( 1 2) to get the LST amounts from these 2 contracts the rsEth price calculated by getRSETHPrice will be:
    totalAssetAmt * assetER/ rsEthSupply = (1 wei + 1 ether) * (1.09 * 1e18) / 1 wei ~= 1.09 * 1e36

  • The next user deposit 1 ether of LSD and will mint:
    rsethAmountToMint = (amount * lrtOracle.getAssetPrice(asset)) / lrtOracle.getRSETHPrice(); <=>
    1 ether * (1.09 * 1e18) /(1.09 * 1e36) = 1 wei rsEth.
    Instead if the second staker deposit only 0.9 ether of LST, the rsETH minted amount rounds down to 0. The attacker has all rsETH shares and victim none.

Tools Used

Manual review,

Recommended Mitigation Steps

Since one of the LST tokens used by protocol is stETH (rebase token) an internal account solution to get the balances is excluded.
Instead a simple solution is to deposit a small amount of LST when contract is initialized and transfer the minted rsETH to a null address.
Even if protocol doesn't use ERC4626 (but a similar approach) these details can be usefull.

Assessed type

ERC4626

@c4-submissions c4-submissions added 3 (High Risk) Assets can be stolen/lost/compromised directly bug Something isn't working labels Nov 15, 2023
c4-submissions added a commit that referenced this issue Nov 15, 2023
@c4-pre-sort c4-pre-sort added the sufficient quality report This report is of sufficient quality label Nov 16, 2023
@c4-pre-sort
Copy link

raymondfam marked the issue as sufficient quality report

@c4-pre-sort
Copy link

raymondfam marked the issue as duplicate of #42

@c4-judge
Copy link
Contributor

c4-judge commented Dec 1, 2023

fatherGoose1 marked the issue as satisfactory

@c4-judge c4-judge added the satisfactory satisfies C4 submission criteria; eligible for awards label Dec 1, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
3 (High Risk) Assets can be stolen/lost/compromised directly bug Something isn't working duplicate-42 satisfactory satisfies C4 submission criteria; eligible for awards sufficient quality report This report is of sufficient quality
Projects
None yet
Development

No branches or pull requests

3 participants