Open code423n4 opened 1 year ago
vaporkane marked the issue as disagree with severity
vaporkane requested judge review
It is true that the first staker may claim all previous dripped rewards. I consider this a medium severity issue as the likelihood is very low since it only occurs for the first staker and only if the strip was started before any stakers deposited.
kirk-baird changed the severity to 2 (Med Risk)
kirk-baird marked the issue as primary issue
kirk-baird marked the issue as selected for report
vaporkane marked the issue as sponsor confirmed
Lines of code
https://github.com/code-423n4/2023-05-xeth/blob/d86fe0a9959c2b43c62716240d981ae95224e49e/src/wxETH.sol#L222-L256
Vulnerability details
Impact
If wxETH drips when nothing is staked, then the first staker can claim every drop.
Proof of Concept
Suppose drip is enabled when
totalSupply() == 0
. At least one block passes and the first staker stakes, just1
xETH is enough. This mints her1
wxETH. This also calls_accrueDrip()
(by thedrip
modifier) which drips some amount of xETH. Note that_accrueDrip()
is independent oftotalSupply()
, so it doesn't matter how little she stakes.cashMinusLocked
is now1
plus the amount dripped. Naturally, since she owns the entire supply she can immediately unstake the entirecashMinusLocked
. Specifically, theexchangeRate()
is now(cashMinusLocked * BASE_UNIT) / totalSupply()
and she gets(totalSupply() * exchangeRate()) / BASE_UNIT
=cashMinusLocked
.The issue is simply that drip is independent of staked amount, especially that it may drip even when nothing is staked, which enables the above attack.
Recommended Mitigation Steps
Note what happens when
totalSupply() > 0
. Then drops will fall on existing wxETH, and any new staker will trigger a drip before having to pay the new exchange rate which includes the extra drops. So a new staker in this case cannot unstake more than they staked; all drops go to previous holders. Therefore, do not drip whentotalSupply == 0
; in_accrueDrip()
:Assessed type
MEV