Beginner FriendlyFoundryDeFi
100 EXP
View results
Submission Details
Severity: high
Valid

Loss of ETH Due to Value Overwrite in Steaking.vy::stake() Function

Summary

The function Steaking.vy::stake() overwrites the previously staked value, leading to a user losing ETH.

Vulnerability Details

The function Steaking.vy::stake() uses the following code to record the staked value of each user:

@external
@payable
def stake(_onBehalfOf: address):
...
self.usersToStakes[_onBehalfOf] = msg.value ---> This will overwrite the previous amount
...

Each time a user stakes their ETH, the function creates a new mapping instead of adding to the previous staked value, resulting in the loss of the earlier staked amount.

PoC

Add the following code to the end of Steaking.t.sol in the test folder:

function testOverwriteStakingAmount() public {
address alice = makeAddr("alice");
uint256 stakeAmount = 1 ether;
// Alice stakes 1 ETH for the first time
_stake(alice, stakeAmount, alice);
uint256 aliceStakedAmountFirst = steaking.usersToStakes(alice);
// Alice stakes an additional 1 ETH
_stake(alice, stakeAmount, alice);
uint256 aliceStakedAmountSecond = steaking.usersToStakes(alice);
// Check if the staked value remains the same, indicating it overwrote the previous value
assertEq(aliceStakedAmountFirst, aliceStakedAmountSecond);
}

Impact

Users will lose their previously staked ETH.

Tools Used

Recommendations

Update the Steaking.vy::stake() function with the following code:

@external
@payable
def stake(_onBehalfOf: address):
.....
- self.usersToStakes[_onBehalfOf] = msg.value ----> This will overwrite the previous amount rather than accumulating it.
+ self.usersToStakes[_onBehalfOf] += msg.value ----> This will accumulate the new value with the previous one.
.....
Updates

Lead Judging Commences

inallhonesty Lead Judge 10 months ago
Submission Judgement Published
Validated
Assigned finding tags:

Steaking::stake overwrites the msg.value into storage

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.