A selling can go through with the ERC20 token transfer
failing and yet the transaction won't revert.
The ether amount will be paid but the user could still not receive his ERC20 tokens.
The TokenDivider.sol::buyOrder()
function is the one having a flaw:
https://github.com/Cyfrin/2025-01-pieces-protocol/blob/main/src/TokenDivider.sol#L261-L307
https://github.com/Cyfrin/2025-01-pieces-protocol/blob/main/src/TokenDivider.sol#L305
If the transfer()
fails, the transaction won't revert
. Usually for the transaction to revert on a failing transfer
, you need to check for success
or just use the safeTransfer()
function instead of transfer()
.
Checking for success
:
The problem is that you can never know with certainty that the transfer()
function of the ERC20 contract is well implemented and will return 0
for sure if something went wrong.
When using safeTransfer()
instead of transfer()
:
=> If safeTransfer()
fails, the transaction will revert
.
A practical example for a transaction of an ERC20 token not going through could be : the user being blacklisted
by a token contract with
a blacklist
like USDC.
The sell order will be considered done, the transfer of Ethers will go through but not the ERC20 transfer.
Loss of funds, the user spends ethers but never gets his tokens in exchange.
Github, manual review.
Use the safeTransfer()
function from the safeERC20's openzeppelin library
.
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.