Front-runners can cancel any permit deposit
Description
The depositWithERC20WithPermit
function allows a user to use an ERC-20 permit, instead of an allowance, to deposit tokens:
function depositWithERC20WithPermit(address _token, uint256 _amount, address _referral, PermitInput calldata _permit) external whenNotPaused returns (uint256) {
IERC20Permit(_token).permit(msg.sender, address(this), _permit.value, _permit.deadline, _permit.v, _permit.r, _permit.s);
return depositWithERC20(_token, _amount, _referral);
}
It processes the permit and then calls the public depositWithERC20
, which assumes that the sender has given the Liquifier contract an allowance.
However, per the ERC-20 permit specification, given a signed permit, anyone can submit the permit to the ERC-20. So, if a front-runner notices that a legitimate call to depositWithERC20WithPermit
is in the mempool, they can race to submit that signed permit first.
Impact
If a front-runner successfully submits the signed permit first, the call to IERC20Permit(_token).permit
will revert due to the reused nonce, cancelling the deposit transaction.
Recommendations
Use a try-catch to allow for the failure of the permit
call.
If a failure is ignored rather than reverted upon, in the event that someone front-runs it and submits the permit first, the call to permit
in this function will revert, but the approval will still be there in either case, so the next call to depositWithERC20
should succeed anyways.
Remediation
This issue has been acknowledged by Gadze Finance SEZC, and a fix was implemented in commit e4119fa0↗.