跳转到主要内容

什么是意图?

意图是一条签名消息,表示:“我想将 X 代币交换为至少 Y 代币,在此截止时间之前。” 它不是链上交易——它是一个无 Gas 签名,授权结算者在批量结算期间代表您执行交易。
与交换的关键区别:交换会立即对 AMM 执行。意图被收集、与其他意图批量处理,并以统一出清价格结算。您是与批次交易,而不是与池交易。

GeodeIntent 结构体

每个意图包含以下字段:
struct GeodeIntent {
    PoolId poolId;        // 针对哪个池(跨池重放保护)
    address owner;        // 签名者地址(代币所有者)
    address tokenIn;      // 卖出的代币
    address tokenOut;     // 接收的代币
    uint256 amountIn;     // 卖出数量
    uint256 minAmountOut; // 最低可接受输出(滑点保护)
    uint256 deadline;     // 过期时间戳
    uint256 nonce;        // Permit2 重放保护
}

隐含限价

意图没有明确的价格字段。限价从 amountInminAmountOut 推导:
  • 买入限价 = amountIn × Q128 / minAmountOut(愿意支付的最高价格)
  • 卖出限价 = minAmountOut × Q128 / amountIn(愿意接受的最低价格)
买入意图在限价 ≥ 出清价格时成交。卖出意图在限价 ≤ 出清价格时成交。不满足出清价格的意图被跳过——用户代币不会被移动。

Permit2 集成

Geode 使用 Permit2 进行无 Gas 代币授权和转账。

工作方式

1

一次性授权

用户授权 Permit2 合约花费其代币(标准 ERC20 approve)。每个代币只需一次——Permit2 在所有协议间共享。
2

签署意图

用户签署 Permit2 PermitWitnessTransferFrom 消息,包含:
  • Permitted:代币地址、金额、nonce、截止时间(标准 Permit2 字段)
  • Witness:poolId、tokenOut、minAmountOut(Geode 特定字段)
单个签名同时授权代币转账和交易参数。
3

结算者执行

geodeSettleBatch() 期间,Hook 为每个已成交意图调用 permit2.permitWitnessTransferFrom()。Permit2 验证签名、检查 nonce,并将代币从用户转到 PoolManager。

Witness 类型

Geode 特定的 witness 仅包含不在 Permit2 PermitTransferFrom 中的字段:
bytes32 constant GEODE_WITNESS_TYPEHASH = keccak256(
    "GeodeWitness(bytes32 poolId,address tokenOut,uint256 minAmountOut)"
);

重放保护

Permit2 Nonce

每个意图使用唯一的 Permit2 nonce。一旦使用,nonce 被消耗,签名变为无效。同一意图永远不能被执行两次。

池绑定

poolId 是签名 witness 的一部分。为池 A 签署的意图不能在池 B 上重放。

截止时间

每个意图都有过期时间戳。截止时间后,签名无效,代币无法被移动。

链 ID

Permit2 的 EIP-712 域分隔符包含链 ID。以太坊主网签名不能在其他链上重放。

意图生命周期

1

创建

用户在 UI 中配置交易并在钱包中签署 Permit2 消息。签名在本地产生——没有链上交易。
2

提交

签名的意图被发送给结算者。结算者为当前批次窗口收集意图。
3

评估

出清价格算法评估每个意图——限价兼容则成交,不满足则被跳过
4

结算

对于已成交的意图,Permit2 提取用户代币,结算通过内部撮合和/或 AMM 路由,输出代币分配到用户钱包。

如果我的意图没有成交怎么办?

如果出清价格不满足您的 minAmountOut,意图被跳过。代币不会被移动,Permit2 nonce 不会被消耗——可在未来批次中重用。

安全模型

Geode 使用 Permit2 的 SignatureTransfer(非 AllowanceTransfer)。每个意图签名都是一次性授权——nonce 消耗后签名永久失效。

有限的风险敞口

约束字段效果
金额amountIn可移动的最大代币数量
时间deadline签名到期后不可用
目标spender(Hook 地址)只有 Geode Hook 合约可使用
poolId(witness)不能在不同池上重放
一次性nonce首次使用后永久失效

结算者不能做什么

  • 不能更改金额 — Permit2 验证 amountIn 与签名匹配
  • 不能更改接收者 — 输出代币发送到 intent.owner,硬编码在结算逻辑中
  • 不能少付 — 出清价格不满足 minAmountOut 时意图被跳过
  • 不能重放签名 — Permit2 nonce 被原子性消耗
  • 不能抢跑 — 批次中所有意图获得相同的统一出清价格
面向集成者:意图可以使用任何 EIP-712 兼容库构建和签名。witness 类型字符串和 typehash 定义在 GeodeTypes.sol 中。