When fee-on-transfer tokens are used, discrepancies arise between the amount sent by the seller
and the amount received by the Escrow
contract due to the token's transfer taxes. Consequently, the seller
will not receive the intended amount, and an additional fee will be incurred when transferring the funds from the Escrow
contract to the seller
.
In the Proof of Concept, Alice wants to pay $10,000 for an audit, and Bob agrees to perform the audit. They use USDT, a fee-on-transfer token with a 1% fee. When Alice transfers 10,000 USDT to the Escrow
contract, only 9,900 USDT is received due to the fee. After the audit, when Alice calls the confirmReceipt()
function, the contract's balance of 9,900 USDT, along with the fee, results in Bob receiving 9,801 USDT, about $200 less than expected.
The recommended mitigation involves modifying the EscrowFactory
contract to ensure that sufficient tokens are sent to cover the transfer fee. The Escrow
contract should then send the price
number of tokens to the contract, returning any remaining tokens to the buyer
.
In summary, the proposed mitigation aims to address the discrepancies caused by fee-on-transfer tokens, ensuring that the seller
receives the intended amount and accounting for the transfer fee in the EscrowFactory
contract.
The EscrowFactory
contract assumes that all ERC20 contracts send all token amounts to the destination. However, fee-on-transfer tokens (for example those with transfer taxes) behave differently. The amount of tokens sent by the sender is not the same as the amount of tokens received by the destination. If this type of token is used, the seller
will not receive the intended amount because there will be discrepancies between the sent amount by the seller
and the received amount by the Escrow
contract. Also, there would be a fee when the amount is sent from the Escrow
contract to the seller
.
Consider Alice wants to pay $10,000 for an audit, and Bob decides to audit for Alice. Also, consider they are using USDT which is a fee-on-transfer token, and it takes 1% of the transfer amount as the fee.
Alice creates the Escrow
contract and transfers 10,000 USDT to the contract; however, 0.99 * 10,000 = 9,900 USDT will be sent to the contract. Then, after finishing the audit, Alice calls confirmReceipt()
function, and the balance of the Escrow
contract will be transferred to Bob. The balance of the contract is 9,900 and the fee is 1%, so 9,900 * 0.99 = 9,801 USDT will be received by Bob.
In this case, we can see that Bob received about $200 less than the expected income.
Manual Review
In the EscrowFactory
contract, send the amount of tokens more than the price
and make sure that they can cover the fee of the transfer. Then, in the Escrow
contract, send the i_price
number of tokens to the and return the remainings to the buyer
.
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.