> ## Documentation Index
> Fetch the complete documentation index at: https://docs.krokoswap.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Permit2

> Token approval contract ABI and usage

# Permit2 Contract

Permit2 is the shared token approval manager. Users approve tokens to Permit2 once, then grant scoped permissions to specific spenders.

For the concept overview, see [Permit2 Concepts](/concepts/permit2).

## Key Functions

### approve

Grants a spender permission to transfer a specific token on behalf of the caller via Permit2.

```solidity theme={null}
function approve(
    address token,
    address spender,
    uint160 amount,
    uint48 expiration
) external;
```

| Parameter    | Type      | Description                                                   |
| ------------ | --------- | ------------------------------------------------------------- |
| `token`      | `address` | The ERC-20 token to approve                                   |
| `spender`    | `address` | The address being granted permission (e.g., Universal Router) |
| `amount`     | `uint160` | Maximum amount the spender can transfer                       |
| `expiration` | `uint48`  | Unix timestamp when the permission expires                    |

**Example:**

```typescript theme={null}
const permit2 = new ethers.Contract(PERMIT2_ADDRESS, PERMIT2_ABI, signer);

await permit2.approve(
  tokenAddress,
  UNIVERSAL_ROUTER,
  ethers.MaxUint160,                           // Max amount
  Math.floor(Date.now() / 1000) + 365 * 86400  // 1 year expiration
);
```

### allowance

Queries the current permission for a given owner-token-spender tuple.

```solidity theme={null}
function allowance(
    address owner,
    address token,
    address spender
) external view returns (
    uint160 amount,
    uint48 expiration,
    uint48 nonce
);
```

| Return       | Type      | Description                       |
| ------------ | --------- | --------------------------------- |
| `amount`     | `uint160` | Remaining allowed amount          |
| `expiration` | `uint48`  | Unix timestamp of expiration      |
| `nonce`      | `uint48`  | Current nonce for this permission |

**Example:**

```typescript theme={null}
const [amount, expiration, nonce] = await permit2.allowance(
  userAddress,
  tokenAddress,
  UNIVERSAL_ROUTER
);

const needsApproval = amount < requiredAmount || expiration < Math.floor(Date.now() / 1000);
```

## ABI

```json theme={null}
[
  "function approve(address token, address spender, uint160 amount, uint48 expiration)",
  "function allowance(address owner, address token, address spender) view returns (uint160 amount, uint48 expiration, uint48 nonce)"
]
```

## Integration Pattern

```typescript theme={null}
async function ensurePermit2Approval(signer, tokenAddress, spender, requiredAmount) {
  const permit2 = new ethers.Contract(PERMIT2_ADDRESS, PERMIT2_ABI, signer);
  const owner = await signer.getAddress();

  // 1. Check existing Permit2 sub-approval
  const [amount, expiration] = await permit2.allowance(owner, tokenAddress, spender);
  const now = Math.floor(Date.now() / 1000);

  if (amount >= requiredAmount && expiration > now) {
    return; // Already approved
  }

  // 2. Check ERC-20 approval to Permit2
  const token = new ethers.Contract(tokenAddress, ERC20_ABI, signer);
  const tokenAllowance = await token.allowance(owner, PERMIT2_ADDRESS);

  if (tokenAllowance < requiredAmount) {
    const tx = await token.approve(PERMIT2_ADDRESS, ethers.MaxUint256);
    await tx.wait();
  }

  // 3. Grant Permit2 sub-approval
  const tx = await permit2.approve(
    tokenAddress,
    spender,
    ethers.MaxUint160,
    now + 365 * 86400
  );
  await tx.wait();
}
```
