The claimCut()
and closePot()
functions use the i_token.transfer()
method to distribute rewards, which may fail silently for some tokens that return false
on failure. This could lead to rewards not being transferred properly to claimants or the manager without any indication of failure.
In the current implementation, the _transferReward()
function is responsible for transferring rewards to claimants and the manager. The function uses i_token.transfer()
to handle token transfers:
However, some ERC20 tokens do not revert on transfer failure and instead return false
, which transfer()
does not handle properly. Additionally, some tokens impose transfer taxes or fees, meaning the recipient might receive less than expected. This could lead to discrepancies between the intended and actual reward distribution, causing the following issues:
Silent Transfer Failures: For tokens that return false
on failure, the transaction will continue without reverting, potentially leaving rewards untransferred without the contract being aware.
Taxed or Funky Tokens: Tokens that deduct transfer fees might cause the reward sent to the recipient to be less than intended, resulting in incorrect reward distribution or a mismatch between the remaining balance and expected rewards.
Initial Setup:
A pot is created with 1000 tokens in total rewards.
Five claimants are eligible to receive rewards.
Scenario:
The claimCut()
function is called to transfer rewards to a claimant.
The token used by the contract has a transfer fee of 2%. When 100 tokens are transferred, only 98 tokens actually reach the claimant.
The contract does not account for this discrepancy, and the remainingRewards
variable becomes inconsistent with the actual token balance, leading to potential further issues during future claims or when closing the pot.
Silent Failures: If a transfer fails (e.g., due to insufficient balance or other reasons), the function will not revert, leaving the rewards unpaid while the contract continues execution as if the transfer was successful.
Incorrect Reward Distribution: If a token imposes transfer fees or taxes, the reward sent to claimants may be less than intended, causing discrepancies in remaining rewards and token balances.
Manual Review
To mitigate these risks, use safeTransfer()
from the OpenZeppelin SafeERC20
library, which ensures the transaction will revert if the transfer fails.
Import the SafeERC20
Library: Import the SafeERC20
utility and apply it to the IERC20
token interface:
Replace transfer()
with safeTransfer()
: Modify the _transferReward()
function as follows:
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.