Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 9 additions & 5 deletions pkg/liquidity-source/uniswap/v4/hooks/gluehook/constant.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,17 @@ import (
"github.com/ethereum/go-ethereum/common"
)

// GlueHook is deployed via CREATE from a nonce-0 deployer, so it lives at the SAME address on
// every chain it supports (Ethereum, Base, Unichain, Arbitrum, Optimism, BNB, Polygon,
// Avalanche, X Layer, World Chain, Soneium, MegaETH, Robinhood).
// GlueHook V3 is deployed via CREATE from a nonce-0 deployer, so it lives at the SAME address on
// every chain it supports (Ethereum, Base, Unichain, Arbitrum, Optimism, BNB, Polygon, Avalanche,
// X Layer, World Chain, Soneium, MegaETH, Robinhood, Arc). Permission bits 0x2040 —
// beforeInitialize | afterSwap only: no beforeSwap, no return delta, so quoting is vanilla V4.
//
// This REPLACES the V2 address 0x0F41715dc432692b66A5aDF8dCfef6Ac407b20c8 registered in #1599.
// V2 stays deployed for its existing pools but is superseded — new pools land on V3 only.
var HookAddresses = []common.Address{
common.HexToAddress("0x0F41715dc432692b66A5aDF8dCfef6Ac407b20c8"),
common.HexToAddress("0x03D482cB3Ff339C2d29736818D0F72c66dD6A040"),
}

// Worst-case extra gas a GlueHook pot action can add to a swap, from the audited gas suite
// (idle ~8-12k, shield ~+38k, pump ~+88k, in-swap auto-harvest + compound ~+111k).
// (idle ~8-12k, pump ~+88k, in-swap auto-harvest + compound ~+111k).
const maxHookGas = 120_000
6 changes: 3 additions & 3 deletions pkg/liquidity-source/uniswap/v4/hooks/gluehook/hook.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ import (
// self-compounding LP position owned by the hook itself.
//
// Quoting is a pure passthrough: the hook NEVER changes the swapper's amounts.
// - Pump executes after the swap, spending the pot's own balance;
// - Shield absorbs a sell while paying the seller the pool's EXACT output
// (fee and tick impact included), so the quoted output is identical either way;
// - V3 has no beforeSwap and returns no delta — the swapper's trade is the pool's plain
// execution; the pump is the hook's own swap in afterSwap, spending the pot's own balance
// (at most 0.8·fee·depth per swap, paced by a spend bucket and a time-weighted reference);
// - auto-harvest/compound only moves the hook's own LP fees.
//
// Every hook action is wrapped in try/catch — a swap can never revert on hook state or
Expand Down
15 changes: 9 additions & 6 deletions pkg/liquidity-source/uniswap/v4/hooks/gluehook/hook_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,17 @@ import (

func TestHookRegistered(t *testing.T) {
t.Parallel()
hook, ok := uniswapv4.GetHook(HookAddresses[0], nil)
require.True(t, ok)
assert.Equal(t, string(valueobject.ExchangeUniswapV4GlueHook), hook.GetExchange())
// the V3 address (the only one registered) resolves to the passthrough hook
for _, addr := range HookAddresses {
hook, ok := uniswapv4.GetHook(addr, nil)
require.True(t, ok, addr.Hex())
assert.Equal(t, string(valueobject.ExchangeUniswapV4GlueHook), hook.GetExchange())
}
}

// GlueHook never changes the swapper's amounts (pump runs after the swap from the pot's own
// balance; shield pays the seller the pool's exact output) — the simulation must be a pure
// passthrough with only a gas budget on top.
// GlueHook never changes the swapper's amounts (no beforeSwap; the pump is the hook's own swap
// in afterSwap from the pot's balance) — the simulation must be a pure passthrough with only a
// gas budget on top.
func TestPassthroughQuoting(t *testing.T) {
t.Parallel()
hook, _ := uniswapv4.GetHook(HookAddresses[0], nil)
Expand Down
Loading