The safePermit
call can be front-run
Description
In the RouteProcessor3, a user can provide a cryptographically signed permit that, when consumed, will allow the contract to send tokens on behalf of the user.
function applyPermit(address tokenIn, uint256 stream) private {
//address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s)
uint256 value = stream.readUint();
uint256 deadline = stream.readUint();
uint8 v = stream.readUint8();
bytes32 r = stream.readBytes32();
bytes32 s = stream.readBytes32();
IERC20Permit(tokenIn).safePermit(msg.sender, address(this), value, deadline, v, r, s);
}
The values of the signature are visible in the mempool until the transaction is executed. An attacker could use the genuine signature to invoke the exact call to IERC20Permit.permit
.
Impact
This does not cause any loss of funds, as the contract will not send funds on behalf of anyone except msg.sender
and itself. However, it will cause a subsequent transaction to fail on IERC20Permit.safePermit
, since the nonce will be incremented and the signature cannot be used again.
Recommendations
Potentially, ignore reverts caused by safePermit
calls. The contract will revert anyway when attempting to transfer tokens that are not authorized. This prevents a frontrun from halting the transaction.
Remediation
This issue has been acknowledged by Sushiswap.