Uniswap introduced the Permit2 authorization standard last year to improve the authorization experience for traditional ERC20 tokens. It offers gas efficiency, enhanced security compared to traditional ERC20 approvals, and easier management. This article provides an introduction to the Permit2 authorization standard and analyzes potential security risks associated with it.
Before analyzing the Permit2 authorization standard, let’s first understand Permit authorization.
Permit was introduced in ERC-2612. It allows users to sign authorization details, such as addresses and token amounts, off-chain without the need for an on-chain transaction. Once the authorization address obtains the signed permit, it can call the
Permit function of the token contract to obtain approval, enabling token transfers.
Here is the implementation of the
Permit function in USDC:
Permit function first checks if the signature has expired. Then it packs the parameters, verifies the validity of the signature, and if the verification passes, it calls the
_approve function to grant approval.
The Permit authorization method requires the token contract to implement the
Permit function. However, previous standard ERC20 tokens do not have this function, making it impossible to use off-chain signed permits.
Permit2 requires users to first grant traditional authorization to the Permit2 contract. Once authorized, they can use off-chain signatures by signing Permit2 messages and passing the signed Permit2 signature to the function of the smart contract. The smart contract then calls the Permit2 contract, which verifies the signature and calls the
transferFrom function of the token contract to perform the transfer.
Users only need to grant authorization to the Permit2 contract once. When interacting with other smart contracts and needing to use authorized tokens, they can interact through off-chain signatures and pass them to the corresponding functions, without the need to authorize different smart contracts each time. Of course, this assumes that the interacting smart contract integrates the Permit2 contract.
The Permit2 contract consists of two contracts: the SignatureTransfer contract and the AllowanceTransfer contract. The SignatureTransfer contract handles all signature-based transfers, while the AllowanceTransfer contract handles the setting of token allowances, allowing spenders to use specified amounts within a designated time period.
The main function in the SignatureTransfer contract is the
permitTransferFrom function, which transfers tokens using a signed message. The implementation is as follows:
PermitTransferFrom holds the token address to be transferred, the maximum amount that can be transferred, the nonce, and the deadline:
SignatureTransferDetails holds the recipient's address and the amount to be transferred:
Then the internal function
_permitTransferFrom is called, which performs checks for expiration, amount, nonce, and signature validity. If all checks pass, the tokens are transferred to the specified address:
It also supports transferring multiple types of tokens at once by modifying the two structures passed in:
The internal function called now becomes
_permitTransferFrom with a
for loop to iterate through the transfer details:
While the AllowanceTransfer contract primarily implements token allowance management and transfer functions.
In the AllowanceTransfer contract, the mapping
allowance is a mapping that points from an owner to a token address, which in turn points to a spender and then to a PackedAllowance structure. The structure stores the amount, expiration time, and nonce:
In the AllowanceTransfer contract, users can modify the authorization information directly by calling the
approve function. They can also modify it using a signature-based approach by calling the
permit function (where permitSingle is used for single authorization and permitBatch is used for batch authorization):
In permitSingle and permitBatch, the spender’s address, signature expiration, and PermitDetails structure are stored. The PermitDetails structure contains the token address, amount, authorization expiration, and nonce:
After the authorization process, you can call the
transferFrom function to transfer tokens, which will invoke the internal function
_transfer function first retrieves the information from the corresponding
allowance. It then checks if the authorization has expired and verifies if the transfer amount exceeds the maximum allowed amount. It updates the allowed amount accordingly and finally calls the
transferFrom function of the token contract to transfer the tokens.
The above is a brief overview of the two constituent contracts of Permit2: SignatureTransfer and AllowanceTransfer.
Permit2 Risk Analysis
After introducing the implementation of Permit2, let’s analyze the risks associated with it.
In traditional ERC20 token authorization, transactions need to be confirmed. However, with Permit2, once authorization is granted to the Permit2 contract, subsequent authorizations can be achieved through signatures. Users tend to be less cautious when it comes to signatures compared to confirming transactions, and they rarely verify the information contained in the signatures. This significantly increases the risk of phishing attacks. If the wallet being used does not have…
Furthermore, previously, tokens that did not implement Permit can now be authorized through Permit2 using signatures. While this provides convenience, it also increases the risk of users’ assets being phished.
Traditional ERC20 token authorization does not have an expiration time. In the Permit2 protocol, however, there is a validity period for authorizations. The duration of authorization depends on the various DApps implementing the Permit2 standard.
The Permit2 protocol introduced by Uniswap does indeed make the process of authorization more convenient for users, saving gas costs and allowing centralized management of authorizations within the Permit2 contract. However, it also increases the risk of users falling victim to phishing attacks.
At Eocene Research, we provide the insights of intentions and security behind everything you know or don’t know of blockchain, and empower every individual and organization to answer complex questions we hadn’t even dreamed of back then.