POLICYPOOL V2 · LIVE ON X LAYER MAINNET

Policy bends. LPs get paid.

A Uniswap v4 Hook on X Layer. Over-cap swaps either refuse, or pay LPs through donate + swap inside one transaction. Same exact-input order. Different pool policy. Different onchain outcome.

Featured proof SURGE donate + swap 0x1809…a9a8

§ 01 · Proof ledger

Seven receipts, all on X Layer.

Three pools, two enforcement modes, one trusted router. Every row links to the OKLink receipt.

  1. P01 MAX-SWAP ACCEPTED Loose pool · 5,000 mUSDC clears 0x1ee4…3396
  2. P02 MAX-SWAP REFUSED Strict pool · reverts MAX_SWAP_EXCEEDED 0xbc20…435a
  3. P03 DAILY-CAP ACCEPTED Fill 1 of 3 · 1,000 mUSDC 0x2a26…f178
  4. P04 DAILY-CAP ACCEPTED Fill 2 of 3 · 1,000 mUSDC 0xc608…292b
  5. P05 DAILY-CAP REFUSED Fill 3 · reverts DAILY_CAP_EXCEEDED 0x7113…771c
  6. P06 SURGE DONATE + SWAP 40 mUSDC donated to LPs · 5,000 mUSDC swap, same unlock 0x1809…a9a8
  7. P07 SPOOF GUARD BLOCKED Old router cannot fake hookData 0x4877…843a

§ 02 · Mechanism

Two numbers, one trusted router.

No oracle. No offchain matcher. No governance. The Hook checks two policy limits; the Surge router pays LPs before the swap clears.

v1 · policy gate
beforeSwap(amountIn):
    if amountIn > maxSwap            // revert MAX_SWAP_EXCEEDED
    if spentToday + amountIn > cap   // revert DAILY_CAP_EXCEEDED
    spentToday += amountIn
    emit SwapAccepted(poolId, trader, amountIn)

v2 · surge override
surgeRouter.swapWithDonate(amountIn, surgeFee):
    require(msg.sender == trustedRouter)
    PoolManager.donate(poolKey, surgeFee)    // LPs paid first
    PoolManager.swap(poolKey, amountIn)      // same unlock callback
    emit SurgeAccepted(poolId, trader, amountIn, surgeFee)

§ 03 · Reviewer notes

What the Hook actually guarantees.

The refusal is enforced by the Hook, not the UI. beforeSwap reverts inside Uniswap v4 PoolManager before any liquidity is consumed. The router only records the caught failure.

The donation is enforced by the trusted router. The Surge hook reads hookData from beforeSwap but only honors it when the unlock caller is the registered router. The deployed old router proves the spoof path reverts.

Mock assets, real swaps. Pools use mUSDC / mETH on X Layer to isolate Hook behavior from token noise. The Hook callback, the Donate event, and the swap settlement are all on chain 196.


§ 04 · Contracts

All Sourcify exact-match.

Click any address for the verified source on Sourcify.

PolicyPoolSurgeHook · v2
0xf44d9C1f9efF1231E53C60EDB9A73761aa99c080
PolicyPoolSurgeRouter · v2
0xd05AAD5b86f6FFCc10872803bEdb5fa911e0E1fD
PolicyPoolHook · v1
0x7D676FA819D8CDF0A2BB73B944a3533870868080
PolicyPoolDemoRouter · v1
0xCD46b2C1e6dD9d0fd3Edd9B26F0137E02F3Fc29e
Uniswap v4 PoolManager · X Layer
0x360E68faCcca8cA495c1B759Fd9EEe466db9FB32
Reproduce the receipts locally node scripts/verify-all.mjs
Public CI workflow