
hooks的代码位置在这,它是是组织校验,调用用户创建钩子的类库。
标志位
首先看其中定义的常量:
uint160 internal constant ALL_HOOK_MASK = uint160((1 << 14) - 1);
uint160 internal constant BEFORE_INITIALIZE_FLAG = 1 << 13;
uint160 internal constant AFTER_INITIALIZE_FLAG = 1 << 12;
uint160 internal constant BEFORE_ADD_LIQUIDITY_FLAG = 1 << 11;
uint160 internal constant AFTER_ADD_LIQUIDITY_FLAG = 1 << 10;
uint160 internal constant BEFORE_REMOVE_LIQUIDITY_FLAG = 1 << 9;
uint160 internal constant AFTER_REMOVE_LIQUIDITY_FLAG = 1 << 8;
uint160 internal constant BEFORE_SWAP_FLAG = 1 << 7;
uint160 internal constant AFTER_SWAP_FLAG = 1 << 6;
uint160 internal constant BEFORE_DONATE_FLAG = 1 << 5;
uint160 internal constant AFTER_DONATE_FLAG = 1 << 4;
uint160 internal constant BEFORE_SWAP_RETURNS_DELTA_FLAG = 1 << 3;
uint160 internal constant AFTER_SWAP_RETURNS_DELTA_FLAG = 1 << 2;
uint160 internal constant AFTER_ADD_LIQUIDITY_RETURNS_DELTA_FLAG = 1 << 1;
uint160 internal constant AFTER_REMOVE_LIQUIDITY_RETURNS_DELTA_FLAG = 1 << 0;
我们知道IHooks 接口中定义了 10 个核心方法,分别对应上面的标志位:
| 标志位 | 描述 | 对应的接口方法 |
|---|---|---|
BEFORE_INITIALIZE_FLAG |
初始化前触发 | beforeInitialize |
AFTER_INITIALIZE_FLAG |
初始化后触发 | afterInitialize |
BEFORE_ADD_LIQUIDITY_FLAG |
添加流动性前触发 | beforeAddLiquidity |
AFTER_ADD_LIQUIDITY_FLAG |
添加流动性后触发 | afterAddLiquidity |
BEFORE_REMOVE_LIQUIDITY_FLAG |
移除流动性前触发 | beforeRemoveLiquidity |
AFTER_REMOVE_LIQUIDITY_FLAG |
移除流动性后触发 | afterRemoveLiquidity |
BEFORE_SWAP_FLAG |
交换前触发 | beforeSwap |
AFTER_SWAP_FLAG |
交换后触发 | afterSwap |
BEFORE_DONATE_FLAG |
捐赠前触发 | beforeDonate |
AFTER_DONATE_FLAG |
捐赠后触发 | afterDonate |
这些标志位直接对应 IHooks 接口中的方法,用于标识 Hook 合约是否支持这些方法。
RETURNS_DELTA_FLAG
除了上述 10 个标志位,还有 4 个额外的标志位用于标识扩展功能。这些标志位与返回 Delta 值 的能力相关:
| 标志位 | 描述 | 扩展功能 |
|---|---|---|
BEFORE_SWAP_RETURNS_DELTA_FLAG |
交换前返回 Delta 值 | 返回 BeforeSwapDelta |
AFTER_SWAP_RETURNS_DELTA_FLAG |
交换后返回 Delta 值 | 返回 int256 Delta 值 |
AFTER_ADD_LIQUIDITY_RETURNS_DELTA_FLAG |
添加流动性后返回 Delta 值 | 返回 BalanceDelta |
AFTER_REMOVE_LIQUIDITY_RETURNS_DELTA_FLAG |
移除流动性后返回 Delta 值 | 返回 BalanceDelta |
这几个RETURNS_DELTA标志位用于标识 Hook 合约是否支持在特定操作后返回一个 Delta 值。Delta 值通常表示某种状态的变化,例如交易金额的调整、流动性变化或其他相关的数值。
举个例子,假设我们有一个 Hook 合约,它在交易(swap)之前动态调整交易金额。这个 Hook 合约会返回一个 Delta 值,用于修改交易的输入金额。
contract ExampleHook is IHooks {
function beforeSwap(
address sender,
PoolKey calldata key,
IPoolManager.SwapParams calldata params,
bytes calldata hookData
) external returns (bytes4, int256 delta) {
// 返回一个 Delta 值,用于调整交易金额
delta = params.amountSpecified / 10; // 调整金额的 10%
return (this.beforeSwap.selector, delta);
}
}
此时我们创建合约的时候就要将BEFORE_SWAP_RETURNS_DELTA_FLAG设置为1。
这个时候hooks库在调用用户钩子的beforeSwap方法后,就可以从Hook 返回的数据中解析出 Delta 值并正确调整流动性提供者的余额。我们可以看到hooks库的beforeSwap方法对于BEFORE_SWAP_RETURNS_DELTA_FLAG的运用。
function beforeSwap(IHooks self, PoolKey memory key, IPoolManager.SwapParams memory params, bytes calldata hookData)
internal
returns (int256 amountToSwap, BeforeSwapDelta hookReturn, uint24 lpFeeOverride)
{
amountToSwap = params.amountSpecified;
if (self.hasPermission(BEFORE_SWAP_FLAG)) {
bytes memory result = callHook(self, abi.encodeCall(IHooks.beforeSwap, (msg.sender, key, params, hookData)));
// 检查返回数据的长度是否符合预期
if (result.length != 96) InvalidHookResponse.selector.revertWith();
// 如果启用了 RETURNS_DELTA 标志位,则解析 Delta 值
if (self.hasPermission(BEFORE_SWAP_RETURNS_DELTA_FLAG)) {
hookReturn = BeforeSwapDelta.wrap(result.parseReturnDelta());
// 使用 Delta 值调整交易金额
int128 hookDeltaSpecified = hookReturn.getSpecifiedDelta();
if (hookDeltaSpecified != 0) {
bool exactInput = amountToSwap < 0;
amountToSwap += hookDeltaSpecified;
// 确保交易类型(exact input/output)不发生变化
if (exactInput ? amountToSwap > 0 : amountToSwap < 0) {
HookDeltaExceedsSwapAmount.selector.revertWith();
}
}

最低0.47元/天 解锁文章
536

被折叠的 条评论
为什么被折叠?



