Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

twin transfer issue - returnbomb attack #768

Closed
zajck opened this issue Aug 11, 2023 · 1 comment · Fixed by #772
Closed

twin transfer issue - returnbomb attack #768

zajck opened this issue Aug 11, 2023 · 1 comment · Fixed by #772
Assignees
Labels
bug Something isn't working

Comments

@zajck
Copy link
Member

zajck commented Aug 11, 2023

Despite the protective measures currently implemented, the seller can still make redeemVoucher to revert and effectively force the buyer to either cancel the voucher or let it expire (in either case, the buyer loses the cancellation penalty).

There are possible attacks:

Returnbomb attack

The twin transfer reverts with insanely long revert data. The return value gets copied into the memory here

(success, result) = twin.tokenAddress.call{ gas: gasleft() - reservedGas }(data);

If the result is of the right size it can consume enough gas to make the transaction fail.

Example:

* @title Foreign20 that returns an absurdly long return data
*
* @notice Mock ERC-(20) for Unit Testing
*/
contract Foreign20ReturnBomb is Foreign20 {
function transferFrom(address, address, uint256) public virtual override returns (bool) {
assembly {
revert(0, 3000000)
// This is carefully chosen. If it's too low, not enough gas is consumed and contract that call it does not run out of gas.
// If it's too high, then this contract runs out of gas before the return data is returned.
}
}
}

Recommendation

Use a solution like this https://github.com/nomad-xyz/ExcessivelySafeCall which limits the amount of return data copied to the memory.

@zajck zajck added the bug Something isn't working label Aug 11, 2023
@zajck zajck self-assigned this Aug 11, 2023
@zajck
Copy link
Member Author

zajck commented Aug 11, 2023

Some references:

OZ is not planning to implement this:
OpenZeppelin/openzeppelin-contracts#3544
OpenZeppelin/openzeppelin-contracts#3168

Solidity compiler handles it if the returndata is not used at all (not the case for use).
There is an open issue that addresses the problem.
ethereum/solidity#14467

So in the future, we might be able to handle it without the need for assembly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant