The deposit()
function in Staking
contract transfers the specified TKN amount from the msg.sender
to the contract. The problem is the return value of this operation is never checked. Some tokens do not revert on transfer failure, but return false
instead. This creates the possibility for the attacker to steal all of the TKNs from the Staking
contract.
The deposit()
method looks like this:
The return value of the transferFrom
method is never checked, so the following scenario is possible:
Attacker notices a Staking
contract where 1 million TKNs have been deposited. The TKN is a token that does not revert on failure.
The attacker calls the deposit()
function with the _amount
of 1 million. The attacker does not have enough TKNs so the transfer will fail, but since the return value is never checked, the balances[msg.sender]
will be updated to 1 million.
The attacker calls the withdraw()
method, stealing the 1 milltion TKNs from the contract.
The attacker can steal all of the TKNs from the contract. This requires the TKN to be a token that does not revert on failure.
The unsafe ERC20 operations have been reported in the known issues section under low category, however this particular exploitation of them is a separate, high-risk issue.
Manual Review
Replace the transfer
/transferFrom
calls with the OpenZeppelin safeTransfer
/safeTransferFrom
.
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.