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

# 整条路由滑点

> 为整条路由设置一个滑点预算，并获得该路由的单一最低输出，由交易以及（在跨链路由上）由 bridge 共同保障。

整条路由滑点会把 `slippage` 变成整条路由的单一预算，而不是每个步骤的容忍度。你发送 `slippageScope=route`，LI.FI 会以 `toAmountMin` 返回该路由的单一最低输出。构建的交易会确保用户至少收到这个数量。如果做不到，交易会回滚，或者该转账被报告为未履行。

该功能按请求选择启用。省略 `slippageScope`，或发送 `slippageScope=step`，都会完全保持现有的按步骤滑点行为。

***

## 按步骤滑点与整条路由滑点

`slippage` 有两种应用方式，通过每个请求的 `slippageScope` 选择：

* **按步骤（`step`，默认）。**`slippage` 是每个带有价格风险的步骤的容忍度。每个步骤有各自的最低值。
* **整条路由（`route`）。**`slippage` 是整条路由的单一预算。LI.FI 会把它分配给这些步骤，并返回整条路由的单一最低值。

| | 按步骤（默认） | 整条路由 |
| - | - | - |
| `slippage` 的含义 | 每个步骤的容忍度 | 整条路由的预算 |
| `toAmountMin` | 由各步骤的最低值推导 | 单一下限：`ceil(预期输出 × (1 − slippage))` |
| `0.01` 时的 swap + 自行定价输出的 bridge | 每个步骤最多可使用 1% | 整条路由合计最多使用 1% |
| 重新构建时价格变差 | 在各步骤的容忍度内被接受 | 仅当仍能达到下限时才会构建；下限永远不会被降低 |

## 工作原理

整条路由滑点涉及三个数值：

* \*\*预算（`slippage`）。\*\*你为整条路由允许的总滑点，以小数表示。`0.01` 即 1%。
* \*\*预期输出（`routeSlippage.referenceToAmount`）。\*\*报价时该路由预期交付的数量。
* **下限（`routeSlippage.minimumToAmount`）。**`ceil(referenceToAmount × (1 − slippage))`，以目标代币的基础单位表示。它同时作为 `toAmountMin` 返回。

LI.FI 会把预算分配给带有价格风险的步骤：swap，以及会改变代币或自行定价的 bridge。费用收取、wrap 和同代币 bridge 不分配份额。

LI.FI 只返回其报价金额能够达到下限的路由。此后，下限在路由的整个生命周期内保持不变。每次构建交易仍须达到该数量，否则会被拒绝。

**1. 请求**

在[报价](https://docs.li.fi/api-reference/get-a-quote-for-a-token-transfer.md)或[路由](https://docs.li.fi/api-reference/advanced/get-a-set-of-routes-for-a-request-that-describes-a-transfer-of-tokens.md)请求中添加 `slippageScope=route`。

**2. 展示下限**

将 `toAmountMin` 展示为用户收到的最低数量。路由及其步骤都带有 `routeSlippage` 对象。

**3. 构建**

报价已包含 `transactionRequest`。对于路由，请将每个步骤原样（包括 `routeSlippage`）提交到 [`/v1/advanced/stepTransaction`](https://docs.li.fi/api-reference/advanced/populate-a-step-with-transaction-data)。重组或序列化步骤时不要丢弃该字段：未携带该字段的步骤会改用按步骤滑点构建。

**4. 跟踪**

轮询 [`/v1/status`](https://docs.li.fi/api-reference/check-the-status-of-a-cross-chain-transfer)。转账最终确定后，`routeSlippage.outcome` 会告诉你是否达到了下限。

***

## 支持的路由

整条路由滑点覆盖最多包含一次 swap 的 EVM 路由：

| 路由 | 下限如何强制执行 | 无法达到下限时 |
| - | - | - |
| 单条 EVM 链上的 swap，可选 LI.FI 费用收取或代币 wrap | swap 的最低输出即为下限。`settlement` 为 `atomic`。 | 交易回滚。用户保留输入代币，仅支付 gas。 |
| 两条 EVM 链之间向接收方交付的 bridge，源链上可有一次 swap，也可没有 | 源链交易将 swap 约束在一个检查点：它必须交给 bridge 的数量。此后由 bridge 保障下限，详见[跨链结算](#跨链结算)。`settlement` 为 `conditional`。 | 低于检查点时，源链交易回滚。此后，无法交付其最低值的 bridge 会退款或恢复，而不是交付低于下限的数量，`/v1/status` 报告 `NOT_FULFILLED`。 |

以下路由不受保护：

* bridge 之后在目标链上有 swap 或合约调用的路由
* 包含多次 swap 的路由
* 起点或终点位于非 EVM 链（如 Solana、Bitcoin、Sui 或 Tron）的路由
* 转账时收取费用的代币
* 经过 Allbridge、Hyperliquid 存款或 Smart Deposits 的路由，以及同链基于 intent 的 swap
* 精确输出报价（`/v1/quote/toAmount`）和合约调用报价（`/v1/quote/contractCall` 和 `/v1/quote/contractCalls`）。这些接口会以 `400` 拒绝 `slippageScope=route`。

无法受到保护的路由绝不会降级为按步骤滑点。它会被排除在响应之外，并给出以 `ROUTE_SLIPPAGE_UNSUPPORTED` 开头的原因：

* 路由请求会将其列在 `unavailableRoutes.filteredOut` 中。
* 如果没有任何路由可被保护，报价请求会返回 `404`，并在 `errors.filteredOut` 中列出原因。

### 跨链结算

LI.FI 的合约只在源链上强制执行数量。在跨链路由上，源链交易将 swap 约束在检查点，随后由 bridge 在目标链上交付。此后下限如何被保障，取决于所用的 bridge：

* \*\*Mayan、Across 和 Stargate V2。\*\*bridge 自身的订单至少携带下限，因此 bridge 不会以低于下限的数量结算。Mayan 订单携带最低输出，Across 按精确的输出数量成交，Stargate V2 在低于其最低值时会让源链交易回滚。同代币的 Mayan MCTP 转账不携带最低值，因为它交付的是销毁数量减去交易中已固定的费用。
* \*\*其他 bridge。\*\*下限不在交易中。系统按源链交易所保证的数量向 bridge 询价，只有当 bridge 对该数量给出的最低值达到下限时，才会构建交易。此后的交付依赖 bridge 履行该最低值。

`/v1/status` 会对每笔受保护的转账对照下限进行判断。退款或交付了另一种代币，会被报告为 `NOT_FULFILLED`，并带有 `REFUNDED` 或 `DIFFERENT_TOKEN`。`BELOW_FLOOR` 并不是预期的结算方式：它表示 bridge 交付了承诺的代币，但低于其构建时所依据的最低值。系统报告它，是为了确保这种交付绝不会被计为 `FULFILLED`。

***

## 请求受路由保护的报价

`/v1/quote` 返回一个步骤，其交易已按下限构建：

```bash curl theme={"system"}
curl --request GET \
  --url 'https://li.quest/v1/quote?fromChain=42161&toChain=42161&fromToken=0xaf88d065e77c8cC2239327C5EDb3A432268e5831&toToken=0x82aF49447D8a07e3bd95BD0d56f35241523fBab1&fromAmount=1000000000&fromAddress=0xYOUR_USER_ADDRESS&integrator=YOUR_INTEGRATOR_NAME&slippage=0.01&slippageScope=route' \
  --header 'x-lifi-api-key: YOUR_API_KEY'
```

```ts TypeScript theme={"system"}
const params = new URLSearchParams({
  fromChain: '42161',                                       // Arbitrum
  toChain: '42161',
  fromToken: '0xaf88d065e77c8cC2239327C5EDb3A432268e5831',  // USDC
  toToken: '0x82aF49447D8a07e3bd95BD0d56f35241523fBab1',    // WETH
  fromAmount: '1000000000',                                 // 1,000 USDC (6 decimals)
  fromAddress: '0xYOUR_USER_ADDRESS',
  integrator: 'YOUR_INTEGRATOR_NAME',
  slippage: '0.01',                                         // 1% for the whole route
  slippageScope: 'route',
})

const quote = await fetch(`https://li.quest/v1/quote?${params}`, {
  headers: { 'x-lifi-api-key': process.env.LIFI_API_KEY! },
}).then((res) => res.json())

console.log(quote.estimate.toAmountMin)                     // the floor
console.log(quote.routeSlippage.minimumToAmount)            // the same floor
```

如需比较多条路由，请在路由请求的 options 中设置 `slippageScope`：

```bash curl theme={"system"}
curl --request POST \
  --url 'https://li.quest/v1/advanced/routes' \
  --header 'Content-Type: application/json' \
  --header 'x-lifi-api-key: YOUR_API_KEY' \
  --data '{
    "fromChainId": 42161,
    "fromAmount": "1000000000",
    "fromTokenAddress": "0xaf88d065e77c8cC2239327C5EDb3A432268e5831",
    "fromAddress": "0xYOUR_USER_ADDRESS",
    "toChainId": 8453,
    "toTokenAddress": "0x0000000000000000000000000000000000000000",
    "options": {
      "integrator": "YOUR_INTEGRATOR_NAME",
      "slippage": 0.01,
      "slippageScope": "route"
    }
  }'
```

```ts TypeScript theme={"system"}
const { routes, unavailableRoutes } = await fetch('https://li.quest/v1/advanced/routes', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'x-lifi-api-key': process.env.LIFI_API_KEY!,
  },
  body: JSON.stringify({
    fromChainId: 42161,                                           // Arbitrum
    fromAmount: '1000000000',                                     // 1,000 USDC
    fromTokenAddress: '0xaf88d065e77c8cC2239327C5EDb3A432268e5831',
    fromAddress: '0xYOUR_USER_ADDRESS',
    toChainId: 8453,                                              // Base
    toTokenAddress: '0x0000000000000000000000000000000000000000', // ETH
    options: {
      integrator: 'YOUR_INTEGRATOR_NAME',
      slippage: 0.01,
      slippageScope: 'route',
    },
  }),
}).then((res) => res.json())

// Routes that can't be protected are listed here, with a ROUTE_SLIPPAGE_* reason
console.log(unavailableRoutes.filteredOut)
```

`slippage` 必须是大于等于 `0` 且小于 `1` 的小数，最多八位小数。需要更高精度的值会被拒绝，而不是被四舍五入，因为四舍五入会改变下限。如果省略 `slippage`，预算即为 LI.FI 原本会应用的默认滑点。

***

## 读取响应

在受路由保护的响应中：

* `toAmountMin` 是下限。
* `toAmount` 是当前估算值。它可能在不同请求之间变化，而下限不会变。
* 该步骤的 `action.slippage` 是整个预算。
* 每个被纳入的步骤的 `action.slippage` 是其分得的预算份额。

路由及其每个步骤都带有 `routeSlippage` 承诺：

| 字段 | 说明 |
| - | - |
| `scope` | 始终为 `route` |
| `slippage` | 预算，以小数字符串表示，例如 `"0.01"` |
| `referenceToAmount` | 计算下限所依据的预期输出，以目标代币的基础单位表示 |
| `minimumToAmount` | 下限：`ceil(referenceToAmount × (1 − slippage))` |
| `toChainId`、`toTokenAddress` | 下限适用的链和代币 |
| `toAddress` | 衡量到账数量的接收方 |
| `settlement` | 单笔交易为 `atomic`，跨链转账为 `conditional` |
| `checkpoints` | 沿途强制执行的数量。`atomic` 只有一项，即下限本身。`conditional` 有两项：先是源链检查点，然后是下限。 |

同链示例，1,000 USDC 兑换 WETH，预算为 1%：

```json theme={"system"}
{
  "estimate": {
    "toAmount": "400000000000000000",
    "toAmountMin": "396000000000000000"
  },
  "routeSlippage": {
    "scope": "route",
    "slippage": "0.01",
    "referenceToAmount": "400000000000000000",
    "minimumToAmount": "396000000000000000",
    "toChainId": 42161,
    "toTokenAddress": "0x82aF49447D8a07e3bd95BD0d56f35241523fBab1",
    "toAddress": "0xYOUR_USER_ADDRESS",
    "settlement": "atomic",
    "checkpoints": [
      {
        "stepId": "0x48f0a2f93b0d0a9dab992d07c46bca38516c945101e8f8e08ca42af05b9e6aa9",
        "chainId": 42161,
        "tokenAddress": "0x82aF49447D8a07e3bd95BD0d56f35241523fBab1",
        "minimumAmount": "396000000000000000"
      }
    ]
  }
}
```

***

## 构建并发送交易

报价已包含按下限构建的 `transactionRequest`。像发送其他报价一样发送它即可。

对于路由，请将每个步骤原样（包括 `routeSlippage`）提交到 [`/v1/advanced/stepTransaction`](https://docs.li.fi/api-reference/advanced/populate-a-step-with-transaction-data)。LI.FI 会为每个步骤重新报价以构建交易，然后对照承诺检查交易的字节码：

* 如果最新报价仍能交付下限，交易会编码该下限，响应返回相同的 `toAmountMin`。
* 如果不能，请求会失败，返回 `409` 和 `ROUTE_SLIPPAGE_FLOOR_UNREACHABLE`。请重新请求报价，并向用户展示新的下限。LI.FI 绝不会为了让构建通过而降低下限。

> [!WARNING]
>
> 提交之前，请不要编辑 `routeSlippage`，也不要更改该步骤的接收方。
>
> * 与步骤不匹配的承诺会失败，返回 `400` 和 `ROUTE_SLIPPAGE_COMMITMENT_INVALID`。例如：下限不等于 `ceil(referenceToAmount × (1 − slippage))`，或接收方或目标代币不同。
> * 调高下限只会让交易更严格。如果最新报价无法达到该下限，构建会以 `409` 失败。
> * 未带 `routeSlippage` 提交的步骤会改用按步骤滑点构建。

***

## 跟踪结果

对于受路由保护的转账，[`/v1/status`](https://docs.li.fi/api-reference/check-the-status-of-a-cross-chain-transfer) 会增加两个字段：

* `quote.routeSlippage` 是构建交易时使用的承诺。
* `routeSlippage` 是判定结果。

| `routeSlippage` 字段 | 说明 |
| - | - |
| `outcome` | 转账进行中为 `PENDING`。承诺的代币已在承诺的链上到账且不低于下限时为 `FULFILLED`。其他情况为 `NOT_FULFILLED`。 |
| `minimumToAmount` | 下限 |
| `deliveredAmount` | 以承诺的代币实际到账的数量（已知时） |
| `shortfall` | 未达到下限的原因。`REVERTED`：源链交易回滚，用户保留了输入代币。`REFUNDED`：bridge 已退款。`DIFFERENT_TOKEN`：到账的是另一种代币，例如被恢复的 bridge 代币。`BELOW_FLOOR`：承诺的代币已到账，但低于下限，这不是预期的结果（参见[跨链结算](#跨链结算)）。 |

```json theme={"system"}
{
  "status": "DONE",
  "routeSlippage": {
    "outcome": "FULFILLED",
    "minimumToAmount": "396000000000000000",
    "deliveredAmount": "398700000000000000"
  }
}
```

退款或到账的是另一种代币，绝不会被报告为 `FULFILLED`。

***

## 错误

整条路由滑点的错误使用标准的[错误代码](https://docs.li.fi/api-reference/error-codes.md)。该原因是 `message` 的稳定前缀，也是 `filteredOut` 中 `reason` 的稳定前缀，因此你无需解析其余内容即可匹配：

```json theme={"system"}
{
  "message": "ROUTE_SLIPPAGE_FLOOR_UNREACHABLE: <detail>",
  "code": 1007
}
```

| 原因 | HTTP 状态码 | 代码 | 触发时机 | 处理方式 |
| - | - | - | - | - |
| `ROUTE_SLIPPAGE_UNAVAILABLE` | 422 | 1004 | 整条路由滑点已被关闭 | 不要静默退回按步骤滑点重试。若切换模式，须重新报价、说明保护条件的变化、展示新的最低到账量，并在执行前获得用户确认。 |
| `ROUTE_SLIPPAGE_INVALID_SLIPPAGE` | 400 | 1011 | `slippage` 不是大于等于 `0` 且小于 `1` 的小数，或超过八位小数 | 发送有效的预算，例如 `0.01` |
| `ROUTE_SLIPPAGE_UNSUPPORTED` | 列在 `filteredOut` 中 | — | 该路由无法受到保护（参见[支持的路由](#支持的路由)） | 选择支持保护的路由。若改用按步骤滑点，须重新报价、说明保护条件的变化、展示新的最低到账量，并在执行前获得用户确认。 |
| `ROUTE_SLIPPAGE_FLOOR_UNREACHABLE` | 构建时为 409；报价时列在 `filteredOut` 中 | 1007 | 没有任何报价能够交付下限 | 重新请求报价；由用户确认新的下限 |
| `ROUTE_SLIPPAGE_COMMITMENT_INVALID` | 400 | 1011 | 提交的步骤中的 `routeSlippage` 被修改或格式错误 | 原样提交返回的步骤 |

***

## 后续步骤

* 如果你的 integrator 已启用 [Smart Slippage](https://docs.li.fi/enterprise/smart-slippage.md)，可参考其建议来选择预算。
* 通过[状态跟踪](https://docs.li.fi/introduction/user-flows-and-examples/status-tracking.md)跟进转账直至完成。


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.