Kelp DAO | rsETH - twcctop'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: 98/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/ee1154fcb6f6619cdc9aeda27503d9a2cbf6d8eb/src/LRTDepositPool.sol#L95-L110 https://github.com/code-423n4/2023-11-kelp/blob/ee1154fcb6f6619cdc9aeda27503d9a2cbf6d8eb/src/LRTDepositPool.sol#L119

Vulnerability details

Impact

LRTDepositPool is vunerable to inflation attack. Malicious can send asset token directly to dos the contract.

Proof of Concept

This issue is very similar to the well-known ERC4626 inflation attack.

Take a look at function getRSETHPrice,the price calculation formula is: totalETHInPool / rsEthSupply. Attack steps:

  1. Malicious user deposit a very tiny value for example 1 wei stEth after protocol initialized. The totalETHInPool = 1wei * 1e18 ,and rsEthSupply will be 1wei, so getRSETHPrice will return to 1e18, it's a normal return value.
  2. Malicious user direct transfer 1 stEth or other asset to this LRTDepositPool, now totalETHInPool increase to 1 ether,but rsEthSupply still is 1wei, so the getRSETHPrice will return 1e18 * 1e18 =1e36, notice the annotation of this function rsETHPrice exchange rate of RSETH, for the exchange rate, 1e36 is an extremely large value.
  3. Another user wants to deposit 1 ether asset, in the function getRsETHAmountToMint calculate the rsETH he will get. In rsethAmountToMint = (amount * lrtOracle.getAssetPrice(asset)) / lrtOracle.getRSETHPrice(); rsethAmountToMint = 1ether * 1ether / 1e36 = 1wei , this user deposit 1 ether but gets 1 wei. So do the later depositors.

Tools Used

manual

Add a variable to record the deposit asset to identify the direct transfer asset and deposit assset.

Assessed type

Oracle

#0 - c4-pre-sort

2023-11-16T19:18:35Z

raymondfam marked the issue as sufficient quality report

#1 - c4-pre-sort

2023-11-16T19:18:44Z

raymondfam marked the issue as duplicate of #42

#2 - c4-judge

2023-12-01T17:05:03Z

fatherGoose1 marked the issue as satisfactory

Awards

2.7592 USDC - $2.76

Labels

bug
grade-b
insufficient quality report
QA (Quality Assurance)
Q-41

External Links

[L-1] addNodeDelegatorContractToQueue doesn't check nodeDelegatorContracts duplicate

https://github.com/code-423n4/2023-11-kelp/blob/ee1154fcb6f6619cdc9aeda27503d9a2cbf6d8eb/src/LRTDepositPool.sol#L168-L175

It's possible to add duplicate nodes to queue, and there is no function to delete from nodeDelegatorQueue. Once duplicate node is added, duplicate node data will sum twice,this will affect the deposit logic and price calculation.

[L-2] getAssetBalance should check asset is valid

https://github.com/code-423n4/2023-11-kelp/blob/ee1154fcb6f6619cdc9aeda27503d9a2cbf6d8eb/src/NodeDelegator.sol#L121 should check the input asset is valid or not

[L-3] pause never gets used in this NodeDelegator

https://github.com/code-423n4/2023-11-kelp/blob/ee1154fcb6f6619cdc9aeda27503d9a2cbf6d8eb/src/NodeDelegator.sol#L127-L134

pause is defined, but never get used.

[L-4] updateMaxNodeDelegatorCount, new maxNodeDelegatorCount_ should higher than current node length

https://github.com/code-423n4/2023-11-kelp/blob/ee1154fcb6f6619cdc9aeda27503d9a2cbf6d8eb/src/LRTDepositPool.sol#L202-L205

but there is no such check

#0 - c4-pre-sort

2023-11-18T00:17:35Z

raymondfam marked the issue as insufficient quality report

#1 - c4-judge

2023-12-01T16:40:43Z

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