The transfer
and transferFrom
functions from Solmates's ERC20 contract return a bool
value, indicating whether a transfer is successful or not. However the issue with this is that, if the transfer fails and it returns false
, the transaction doesn't revert. If there are some state changes made during the execution of the transaction, this can leave a protocol open for exploits. Checking the return value is a requirement as per EIP-20 standard's documentation:
Neither one of protocol's functions (Airdrop::claim
, Staking::deposit
, Staking::withdraw
, Staking::claimRewards
) that use transfer
or transferFrom
, doesn't handle the returned value. This can lead to a malicious user draining all the funds from the Staking
contract.
I made a LoveTokenMock
contract for this one, which is the same like LoveToken.sol
, just added thеse two functions for simplicity and facilitation of the Proof-Of-Code:
Add the following in StakingTest.t.sol
file, here is a scenario:
Let's say some users already have staked their love tokens to the Staking
contract, so it will start with 10 ether initial balance.
The malicious actor first deposits the transfer fails, but the userStakes
mapping needs to be updated. Because when withdrawing it updates it again, subtracting the specified amount from the mapping. Otherwise if it's with default value it will revert with arithmetic underflow error.
Finally withdraws specifying the Staking
contract's balance as a parameter.
Ends up stealing all the tokens.
Likelihood is Low/Medium to happen, severity is High because funds are at risk -> impact: Medium
Manual Review, Foundry
Consider implementing OpenZeppelin's SafeERC20
library for transfer functions.
Or do a check with custom error for to the returned bool
value.
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.