A good user experience and gas cost optimization are important building blocks when implementing use cases on a public blockchain. The original permission method in Ethereum had weaknesses. Users had to send multiple approval transactions depending on the application, which could lead to confusion. For convenience, some apps even asked users to approve their maximum available token balance, which then gave apps access to the entire token balance of the wallet for an indefinite period, putting all users’ tokens at risk in the event of a potential hack. Later, the permission system in Ethereum was improved by introducing granular permissions that allowed applications to better control access to the token balance. However, older tokens do not support this feature, and not all newer tokens have adopted it.
How do ERC-20 token approvals work by default?
The standard model of ERC-20 tokens in Ethereum requires two transactions, each of which incurs gas charges: An approval and an interaction (see Figure 1).
Figure 1: Approval process in the standard model of ERC-20
- Bob calls the approve() function on an ERC-20 to grant issue approval for a smart contract.
- Bob calls the interaction() function, which in turn calls transferFrom() on the ERC20 token smart contract to transfer the tokens.
- Poor usability: Users have to approve each new protocol with a separate transaction for each token they want to use.
- Poor security: Many applications often require unlimited approvals to address the UX problem from point 1. Consequently, if the protocol were hacked, all tokens would compromise all users who had granted open-ended permission.
Permit (EIP-2612) model as the first improvement
To improve the standard model, “EIP-2612 Permit Extension for EIP-20 Signed Approvals” was introduced. EIP-2612 is an extension of the ERC-20 token standards, which is expected to solve the previously mentioned problems (see Figure 2).
Figure 2: Approval process of EIP-2612
- Bob signs an off-chain approval message giving permission to a smart contract to issue an (EIP-2612) token.
- Bob sends the signed message as part of the interaction with the smart contract.
- The smart contract calls permit() on the token, which consumes the permit message and signature and gives the smart contract a permit.
- The smart contract now has permission, so it calls transferFrom() on the token and can take the tokens held by Bob.
This solves the original problems of the ERC20 approach:
- The user never has to submit a separate approve() transaction.
- Permit signatures are granted and consumed immediately.
- Amount limits and expiry times can be set.
The problem, however, is that this approach is out of the question in most cases, as EIP-2612 is an extension of the ERC20 standard, and this feature is only possible for new tokens. So, there are very few larger tokens that can benefit from this.
The solution is called Permit2
In the research for product improvements for Uniswap, the team at Uniswap Labs has identified a new market standard to solve the problems from both the standard model and EIP-2612: Permit2 (see Figure 3).
Figure 3: Approval process of Permit2
- Bob calls approve() on an ERC-20 to give the Permit2 smart contract unlimited approval.
- Bob signs an off-chain Permit2 message signaling that the protocol smart contract is allowed to transfer tokens.
- Bob calls an interaction function of the protocol smart contract and passes the signed permit2 message as a parameter.
- The protocol smart contract calls permitTransferFrom() on the permit2 smart contract, which in turn uses permission granted from point 1 to call transferFrom() on the ERC-20 smart contract and transfer the tokens held by Bob.