Kelp DAO | rsETH - spark's results

A collective DAO designed to unlock liquidity, DeFi and higher rewards for restaked assets through liquid restaking.

General Information

Platform: Code4rena

Start Date: 10/11/2023

Pot Size: $28,000 USDC

Total HM: 5

Participants: 185

Period: 5 days

Judge: 0xDjango

Id: 305

League: ETH

Kelp DAO

Findings Distribution

Researcher Performance

Rank: 111/185

Findings: 2

Award: $7.42

QA:
grade-b

🌟 Selected for report: 0

🚀 Solo Findings: 0

Lines of code

https://github.com/code-423n4/2023-11-kelp/blob/main/src/LRTOracle.sol#L52

Vulnerability details

Impact

The rsETH price can be manipulated easily when the deposit is low, since the price is relies on the contracts' balance.

Proof of Concept

The rsETH's price is calculated by $\frac{total_asset_value}{total_supply}$, and when supply is zero, the price will be 1 ether.

However, when the first token is minted by Alice and Alice can transfer another 1 ether asset into the deposit pool, the current price will be 2 ether for 1 rsETH.

This will create a larger issue if the price will be used by any other protocol like a lending platform. Also, there could be an inflationary attack since the getRsETHAmountToMint may return 0 when the user mints.

rsethAmountToMint = (amount * lrtOracle.getAssetPrice(asset)) / lrtOracle.getRSETHPrice();
/// @notice Provides RSETH/ETH exchange rate /// @dev calculates based on stakedAsset value received from eigen layer /// @return rsETHPrice exchange rate of RSETH function getRSETHPrice() external view returns (uint256 rsETHPrice) { address rsETHTokenAddress = lrtConfig.rsETH(); uint256 rsEthSupply = IRSETH(rsETHTokenAddress).totalSupply(); if (rsEthSupply == 0) { return 1 ether; } //@audit try reth/steth price uint256 totalETHInPool; address lrtDepositPoolAddr = lrtConfig.getContract(LRTConstants.LRT_DEPOSIT_POOL); address[] memory supportedAssets = lrtConfig.getSupportedAssetList(); uint256 supportedAssetCount = supportedAssets.length; for (uint16 asset_idx; asset_idx < supportedAssetCount;) { address asset = supportedAssets[asset_idx]; uint256 assetER = getAssetPrice(asset); uint256 totalAssetAmt = ILRTDepositPool(lrtDepositPoolAddr).getTotalAssetDeposits(asset); totalETHInPool += totalAssetAmt * assetER; unchecked { ++asset_idx; } } return totalETHInPool / rsEthSupply; }

Tools Used

Manual

Recommend tracking contract balance by creating a variable.

Assessed type

Other

#0 - c4-pre-sort

2023-11-16T23:48:35Z

raymondfam marked the issue as sufficient quality report

#1 - c4-pre-sort

2023-11-16T23:48:42Z

raymondfam marked the issue as duplicate of #42

#2 - c4-judge

2023-12-01T17:02:48Z

fatherGoose1 changed the severity to 3 (High Risk)

#3 - c4-judge

2023-12-01T17:06:43Z

fatherGoose1 marked the issue as satisfactory

Awards

2.7592 USDC - $2.76

Labels

bug
downgraded by judge
grade-b
insufficient quality report
QA (Quality Assurance)
duplicate-70
Q-06

External Links

Lines of code

https://github.com/code-423n4/2023-11-kelp/blob/f751d7594051c0766c7ecd1e68daeb0661e43ee3/src/NodeDelegator.sol#L38

Vulnerability details

Impact

NodeDelegator may approve max to EIGEN_STRATEGY_MANAGER via maxApproveToEigenStrategyManager. Which allows the EIGEN_STRATEGY_MANAGER move all funds.

Proof of Concept

The protocol is highly centralized and in NodeDelegator, it will approve max value to EIGEN_STRATEGY_MANAGER which fully relies on the trust of the LRTConfig

And EIGEN_STRATEGY_MANAGER is out of the scope.

Tools Used

Manual

It's better to approve on demand, instead of approve max.

Assessed type

Rug-Pull

#0 - c4-pre-sort

2023-11-16T23:24:43Z

raymondfam marked the issue as insufficient quality report

#1 - c4-pre-sort

2023-11-16T23:24:53Z

raymondfam marked the issue as duplicate of #70

#2 - c4-judge

2023-11-29T19:28:16Z

fatherGoose1 changed the severity to QA (Quality Assurance)

#3 - c4-judge

2023-11-29T19:29:31Z

fatherGoose1 marked the issue as grade-b

AuditHub

A portfolio for auditors, a security profile for protocols, a hub for web3 security.

Built bymalatrax © 2024

Auditors

Browse

Contests

Browse

Get in touch

ContactTwitter