Open sherlock-admin3 opened 4 months ago
The severity of this finding being medium is due to the fact it requires an externally malicious factor to incur the exploit.
Escalate
This issue should be High instead of Medium.
Anyone can easily execute this attack by injecting malicious withdrawal requests into the withdrawal queue, causing harm to the victim. The attack could lead to the following impacts:
Refer to my report for more details (https://github.com/sherlock-audit/2024-06-leveraged-vaults-judging/issues/62)
The lead judge downgraded this issue from High to Medium based on the following rationale, which is incorrect:
The severity of this finding being medium is due to the fact it requires an externally malicious factor to incur the exploit
Anyone can execute this attack anytime, so no externally malicious factor is required here.
Escalate
This issue should be High instead of Medium.
Anyone can easily execute this attack by injecting malicious withdrawal requests into the withdrawal queue, causing harm to the victim. The attack could lead to the following impacts:
- Loss of assets
- Account's collateral to be undervalued, leading to unexpected liquidation
Refer to my report for more details (https://github.com/sherlock-audit/2024-06-leveraged-vaults-judging/issues/62)
The lead judge downgraded this issue from High to Medium based on the following rationale, which is incorrect:
The severity of this finding being medium is due to the fact it requires an externally malicious factor to incur the exploit
Anyone can execute this attack anytime, so no externally malicious factor is required here.
You've created a valid escalation!
To remove the escalation from consideration: Delete your comment.
You may delete or edit your escalation comment anytime before the 48-hour escalation window closes. After that, the escalation becomes final.
Please see my comment on #62
I agree with the escalation, I don't see any malicious factors that are needed here and the attack is easily repeatable. Even though the attacker doesn't get anything, it's a clear loss of the entire withdrawal without external limitations.
Planning to accept the escalation and leave the issue as it is.
Result: High Has duplicates
As a fix for this issue, we are switching to direct ETH withdraws from Kelp instead of stETH. This was not supported at the time we wrote the code but is now supported.
The protocol team fixed this issue in the following PRs/commits: https://github.com/notional-finance/leveraged-vaults/pull/92
The Lead Senior Watson signed off on the fix.
lemonmon
High
Kelp:_finalizeCooldown
cannot claim the withdrawal if adversary would requestWithdrawals with dust amount for the holderSummary
If an adversary calls
LidoWithdraw.requestWithdrawals
with some dust stETH amount and theKelpCooldownHolder
's address, the withdrawal will be locked. It cannot be rescued viarescueTokens
, since it does not have to logic toclaimWithdrawal
, therefore the withdrawal will be locked permanently.Vulnerability Detail
The
KelpCooldownHolder
is responsible to withdraw from rsETH to stETH viaWithdraManager
, and then withdraw stETH to ETH viaLidoWithdraw
. Since it is two step process, theKelpCooldownHolder
implementstriggerExtraStep
. After the first withdrawal request is finalized, thetriggerExtraStep
should be called to initiate the second withdrawal request. https://github.com/sherlock-audit/2024-06-leveraged-vaults/blob/main/leveraged-vaults-private/contracts/vaults/staking/protocols/Kelp.sol#L83The
KelpCooldownHolder._finalizeCooldown
will be called when theexitVault
is called to finalize the process byLidoWithdraw.claimWithdrawal
and send the claimed ETH back to the vault.https://github.com/sherlock-audit/2024-06-leveraged-vaults/blob/main/leveraged-vaults-private/contracts/vaults/staking/protocols/Kelp.sol#L100
This
KelpCooldownHolder._finalizeCooldown
is, however, hardcoded to claim the 0-th request from theLidoWithdraw.getWithdrawalRequests
, thus if there are more than 1 withdrawal requests for thisKelpCooldownHolder
, all the requests but the 0-th request will be ignored.An adversary can abuse this fact by request withdrawal for the
KelpCooldownHolder
before thetriggerExtraStep
is called. In that case the real withdrawal request will not be the 0-th, and will be ignored.After the finalize on the dust withdrawal is done, the accountWithdrawRequest on the PendlePTKelpVault will be deleted and this
finalizeCooldown
on the holder cannot be called again since it has onlyVault modifier. TherescueTokens
will not help, as the stETH is already transferred to LidoWithdraw.PoC
Here is a proof of concept demonstrating that a third party can call
LidoWithdrawals.requestWithdrawals
. And the requestId is in the order of request:The Result is below: note that the 0-th request only has the dust amount of stETH request (100)
The addresses are taken from the mainnet, so should fork from the mainnet to test.
Impact
A malicious actor can use dust amount of stETH to freeze withdrawal from the
KelpPTKelpVault
. The frozen withdrawal will be locked permanently,Code Snippet
https://github.com/sherlock-audit/2024-06-leveraged-vaults/blob/main/leveraged-vaults-private/contracts/vaults/staking/protocols/Kelp.sol#L83
https://github.com/sherlock-audit/2024-06-leveraged-vaults/blob/main/leveraged-vaults-private/contracts/vaults/staking/protocols/Kelp.sol#L100
Tool used
Manual Review
Recommendation
Consider claiming all the withdrawals from LidoWithdraw. However, an adversary can request withdrawals for the holder multiple times with dust stETH, attempting another DoS factor. Alternatively consider storing the requestId in the triggerExtraStep, and claim only the stored request in the finalize step.