> ## 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

> 代币授权合约 ABI 及使用方法

# Permit2 合约

Permit2 是共享的代币授权管理器。用户只需将代币授权给 Permit2 一次，然后可以向特定的授权对象授予限定范围的权限。

概念概述请参阅 [Permit2 概念](/concepts/permit2)。

## 核心函数

### approve

授予授权对象通过 Permit2 代表调用者转移特定代币的权限。

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

| 参数           | 类型        | 描述                            |
| ------------ | --------- | ----------------------------- |
| `token`      | `address` | 要授权的 ERC-20 代币                |
| `spender`    | `address` | 被授予权限的地址（例如 Universal Router） |
| `amount`     | `uint160` | 授权对象可转移的最大数量                  |
| `expiration` | `uint48`  | 权限过期的 Unix 时间戳                |

**示例：**

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

await permit2.approve(
  tokenAddress,
  UNIVERSAL_ROUTER,
  ethers.MaxUint160,                           // 最大数量
  Math.floor(Date.now() / 1000) + 365 * 86400  // 1 年有效期
);
```

### allowance

查询给定的 owner-token-spender 三元组的当前授权信息。

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

| 返回值          | 类型        | 描述             |
| ------------ | --------- | -------------- |
| `amount`     | `uint160` | 剩余授权数量         |
| `expiration` | `uint48`  | 过期的 Unix 时间戳   |
| `nonce`      | `uint48`  | 此授权的当前 nonce 值 |

**示例：**

```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)"
]
```

## 集成模式

```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. 检查现有的 Permit2 子授权
  const [amount, expiration] = await permit2.allowance(owner, tokenAddress, spender);
  const now = Math.floor(Date.now() / 1000);

  if (amount >= requiredAmount && expiration > now) {
    return; // 已授权
  }

  // 2. 检查对 Permit2 的 ERC-20 授权
  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. 授予 Permit2 子授权
  const tx = await permit2.approve(
    tokenAddress,
    spender,
    ethers.MaxUint160,
    now + 365 * 86400
  );
  await tx.wait();
}
```
