Skip to main content
Version: 2.0

How to Set a Token Allowance

To enable a third party to move your tokens, you must set an ERC-20 token allowance. This grants permission to either the Permit2 or AllowanceHolder contracts, depending on whether you use swap/permit2 or /swap/allowance-holder.

To do so, we will need approve an allowance to the issues.allowance.spender address returned Swap API /price and /quote endpoints. The issues.allowance.spender.

danger
  • NEVER set an allowance on the Settler contract. Doing so may result in unintended consequences, including potential loss of tokens or exposure to security risks. The Settler contract does not support or require token allowances for its operation. Setting an allowance on the Settler contract will lead to misuse by other parties.

  • ONLY set allowances on Permit2 or AllowanceHolder contracts, as indicated by the API responses.

  • The correct allowance target is returned in issues.allowance.spender. :::

Allowance Target vs. Entry Point

In API v2, the allowance target and the entry point contract serve different roles:

  • The allowance target is either Permit2 or AllowanceHolder, depending on the approval method. This address is returned inissues.allowance.spender.

  • The entry point contract is where you send the data payload. It is returned under transaction.to and dynamically changes based on the latest Settler deployment (API reference).

Example response from /swap/permit2/quote will return back the contract address if an allowance needs to be set:

"issues": {
"allowance": {
"actual": "0",
"spender": "0x000000000022d473030f116ddee9f6b43ac78ba3"
},

No allowance is required for wrapping or unwrapping ETH (e.g., WETH ⇄ ETH). In these cases, allowance will be null. :::

Setting Allowances for 0x API quotes

There are several ways to set a token allowance, both programmatically and through a UI. We will cover options for both methods below.

Using wagmi

wagmi has a number of hooks that can help us read and write to contracts.

  1. First, we need to check if the spender (Permit2) has an allowance already. We can use wagmi's useReadContract hook to read from the sellToken's "allowance" function.
  2. If thre is no allowance, then we can write an approval to the sellToken's smart contract using wagmi's useSimulateContract and useWriteContract
  3. Lastly, use wagmi's useWaitForTransactionReceipt to wait for the approval transaction to complete

Here is an example snippet demonstrating how to approve a USDC token allowance for the Permit2 contract using wagmi. See the full code implementation in the Swap v2 Demo App and accompanying guide.

// Setup wallet client, contract addresses and ABIs
// Fetch price
...
// Once price has been fetched, check and approve allowance
function ApproveOrReviewButton({
taker,
onClick,
sellTokenAddress,
disabled,
}: {
taker: Address;
onClick: () => void;
sellTokenAddress: Address;
disabled?: boolean;
}) {
// 1. Read from erc20, check approval for permit2 to spend sellToken
const { data: allowance, refetch } = useReadContract({
address: sellTokenAddress,
abi: erc20Abi,
functionName: "allowance",
args: [taker, PERMIT2_ADDRESS],
});
console.log("checked permit2 approval");
// 2. (only if no allowance): write to erc20, approve token allowance for permit2
const { data } = useSimulateContract({
address: sellTokenAddress,
abi: erc20Abi,
functionName: "approve",
args: [PERMIT2_ADDRESS, MAX_ALLOWANCE],
});

// Define useWriteContract for the 'approve' operation
const {
data: writeContractResult,
writeContractAsync: writeContract,
error,
} = useWriteContract();

// useWaitForTransactionReceipt to wait for the approval transaction to complete
const { data: approvalReceiptData, isLoading: isApproving } =
useWaitForTransactionReceipt({
hash: writeContractResult,
});
...

Using Etherscan

There are a lot of apps that let you set your allowances such as Metamask, but for this example we will be using Etherscan.

Let's look at an example of how to approve an allowance for WETH from the Etherscan website. Navigate to the WETH ERC20 Contract > Contracts > Write Contract tab > approve method here.

Etherscan approve method

From here, you can call the approve method to approve the Permit2 Address (what's returned in issues.allowance.spender) for the max uint256 amount which is 115792089237316195423570985008687907853269984665640564039457584007913129639935.

You can give a WETH allowance to any smart contract this way. To set your allowance for a different token, you'll have to navigate to the smart contract interface for that token.

Revoking Allowances

To revoke an allowance, you will need to set the allowance to 0. This can be done programmatically or through a UI such as https://revoke.cash/ .

Common Issues

When setting the token allowance, make sure to provide enough allowance for the buy or sell amount as well as the gas; otherwise, you may receive a 'Gas estimation failed' error.