Kelp DAO | rsETH - anarcheuz'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: 14/185

Findings: 3

Award: $594.30

QA:
grade-b

🌟 Selected for report: 0

🚀 Solo Findings: 0

Findings Information

Labels

bug
3 (High Risk)
partial-50
sufficient quality report
duplicate-584

Awards

451.2859 USDC - $451.29

External Links

Lines of code

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

Vulnerability details

Impact

According to the logic of the protocol (https://blog.kelpdao.xyz/exploring-a-new-defi-primitive-liquid-restaked-token-lrt-ed0a8f63a4e2), minted tokens can be swapped on AMMs. This is a serious problem as prices on AMMs follow a bonding curve that are independent from the Chainlink pricing feed. This will create arbitrage opportunities for hackers to profit using the price difference to mint the LRT token on LRTDepositPool (that uses chainlink for pricing) and the price to swap on external AMMs. Furthermore, depending on which AMMs, prices in these AMMs could be manipulated with flashloans.

The end result would be the protocol funds being drained.

Proof of Concept

https://blog.kelpdao.xyz/exploring-a-new-defi-primitive-liquid-restaked-token-lrt-ed0a8f63a4e2:

Restakers can swap their LRT tokens for other tokens on AMMs or choose to redeem underlying assets through LRT contracts.

Tools Used

Manual review.

Do not use external AMMs to redeem as the prices are not the same as those returned by chainlink.

Assessed type

Other

#0 - c4-pre-sort

2023-11-17T00:04:16Z

raymondfam marked the issue as insufficient quality report

#1 - c4-pre-sort

2023-11-17T00:04:34Z

raymondfam marked the issue as duplicate of #284

#2 - c4-pre-sort

2023-11-18T01:30:56Z

raymondfam marked the issue as duplicate of #584

#3 - c4-pre-sort

2023-11-18T01:33:08Z

raymondfam marked the issue as sufficient quality report

#4 - c4-judge

2023-12-01T17:09:01Z

fatherGoose1 marked the issue as unsatisfactory: Invalid

#5 - c4-judge

2023-12-08T17:46:19Z

fatherGoose1 marked the issue as partial-50

#6 - fatherGoose1

2023-12-08T17:46:20Z

The core impact is correct, but very little explanation or recommended mitigation steps are provided.

Findings Information

Awards

140.2525 USDC - $140.25

Labels

bug
2 (Med Risk)
downgraded by judge
satisfactory
sufficient quality report
duplicate-148

External Links

Lines of code

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

Vulnerability details

Impact

Prices are fetched from Chainlink but it is possible that the prices are stale (due to to the fact that it is not checking for the freshness of the price) or chainlink could be experiencing a crash event where it would return prices between a minimum and maximum pre-defined. In these instances, an attacker could make use of this opportunity to delay a user transaction to force the user to incur high slippage.

Proof of Concept

function depositAsset( address asset, uint256 depositAmount ) external whenNotPaused nonReentrant onlySupportedAsset(asset) { // checks if (depositAmount == 0) { revert InvalidAmount(); } if (depositAmount > getAssetCurrentLimit(asset)) { revert MaximumDepositLimitReached(); } if (!IERC20(asset).transferFrom(msg.sender, address(this), depositAmount)) { revert TokenTransferFailed(); } // interactions uint256 rsethAmountMinted = _mintRsETH(asset, depositAmount); emit AssetDeposit(asset, depositAmount, rsethAmountMinted); }

Tools Used

Manual review.

Add a slippage check.

Assessed type

Other

#0 - c4-pre-sort

2023-11-16T23:50:45Z

raymondfam marked the issue as sufficient quality report

#1 - c4-pre-sort

2023-11-16T23:50:53Z

raymondfam marked the issue as duplicate of #39

#2 - c4-pre-sort

2023-11-17T06:43:20Z

raymondfam marked the issue as duplicate of #148

#3 - c4-judge

2023-11-29T19:11:17Z

fatherGoose1 changed the severity to 2 (Med Risk)

#4 - c4-judge

2023-11-29T19:11:22Z

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-69
Q-08

External Links

Lines of code

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

Vulnerability details

Impact

transferBackToLRTDepositPool() does not check if the LRTDepositPool is not paused before sending tokens to it. If the contract was indefinitely paused due to being compromised, the funds would be forever bricked in the LRTDepositPool.

Proof of Concept

function transferBackToLRTDepositPool( address asset, uint256 amount ) external whenNotPaused nonReentrant onlySupportedAsset(asset) onlyLRTManager { address lrtDepositPool = lrtConfig.getContract(LRTConstants.LRT_DEPOSIT_POOL); if (!IERC20(asset).transfer(lrtDepositPool, amount)) { revert TokenTransferFailed(); } }

Tools Used

Manual review.

It is recommended to check if LRTDepositPool is not paused before sending tokens to it.

Assessed type

Token-Transfer

#0 - c4-pre-sort

2023-11-16T23:39:16Z

raymondfam marked the issue as insufficient quality report

#1 - c4-pre-sort

2023-11-16T23:39:25Z

raymondfam marked the issue as duplicate of #69

#2 - c4-judge

2023-11-29T20:58:12Z

fatherGoose1 changed the severity to QA (Quality Assurance)

#3 - c4-judge

2023-11-29T21:03:00Z

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