{
  "$schema": "https://hookforge.pages.dev/schema/hook-manifest.json",
  "slug": "retro-rebate",
  "name": "RetroRebate",
  "contract": "RetroRebateHook",
  "version": "1.0.0",
  "family": "Liquidity provider economics",
  "summary": "A volume rebate the pool pays out of its own flow, settled on-chain at the end of each epoch, with no Merkle root, no off-chain calculation and nobody who can decline to publish it.",
  "description": "Volume rebates are how every venue rewards its best flow, and on-chain they are almost always a lie about where the computation happens. A team totals volume off-chain, posts a Merkle root, and traders claim against it. The rebate is real; the decentralisation is not. Whoever runs the script chooses who is in the tree, can publish late, can publish never, and is the only party who can tell you whether the number is right. The reason it is done that way is that per-trader accounting looks expensive, and in a continuous scheme it is: paying a share of a pot that is still growing means either an accumulator per trader or an unbounded loop. Epochs make it cheap. The hook skims `skimBps` of every swap into that epoch's pot and records the volume each account traded in it, which is two storage writes. Once an epoch has closed, both numbers are final, so a claim is one multiplication and a transfer:   payout = pot(epoch) * volume(epoch, account) / totalVolume(epoch) There is nothing to publish, nothing to compute off-chain, and nothing anybody can withhold. A trader who never claims simply leaves their share, and because a closed epoch's pot is fixed, that costs nobody else anything. Volume is attributed to whatever address the swap names in `hookData`, and this deliberately needs no signature. Naming somebody else credits them with volume you paid for, so the only thing a forged attribution achieves is giving away your own rebate. A swap that names nobody credits the router it came through, which lets a router run the rebate for its users and split it however it likes.",
  "priorArt": "Volume rebates, referral fees and loyalty discounts all exist as hooks, and all of them either discount at the point of trade (which cannot depend on a total that is not known yet) or settle against an off-chain Merkle root. Doing the accounting on-chain in closed epochs, so the rebate is a division anybody can verify and nobody can withhold, is the contribution here.",
  "limitation": "The rebate arrives after the epoch ends, so it is worth less than the same value taken off the trade, and a trader who wants a discount now is better served by a hook that discounts now. Epoch length is a real tradeoff rather than a parameter to shrug at: short epochs pay out sooner and let a single large trade dominate a small pot, long ones smooth that out and make the rebate feel remote.",
  "tags": [
    "rebate",
    "volume",
    "epochs",
    "no-merkle",
    "no-admin"
  ],
  "recommendedChains": [
    "base",
    "arbitrum",
    "unichain",
    "robinhood",
    "ethereum",
    "optimism",
    "polygon",
    "bnb"
  ],
  "source": "contracts/src/hooks/RetroRebateHook.sol",
  "docs": "https://hookforge.pages.dev/hooks/retro-rebate",
  "repo": null,
  "site": null,
  "permissions": {
    "afterRemoveLiquidityReturnsDelta": false,
    "afterAddLiquidityReturnsDelta": false,
    "afterSwapReturnsDelta": true,
    "beforeSwapReturnsDelta": false,
    "afterDonate": false,
    "beforeDonate": false,
    "afterSwap": true,
    "beforeSwap": false,
    "afterRemoveLiquidity": false,
    "beforeRemoveLiquidity": false,
    "afterAddLiquidity": false,
    "beforeAddLiquidity": false,
    "afterInitialize": true,
    "beforeInitialize": false
  },
  "permissionsSource": "declaration",
  "properties": {
    "dynamicFee": false,
    "upgradeable": false,
    "requiresCustomSwapData": true,
    "vanillaSwap": true,
    "swapAccess": "none"
  },
  "configure": null,
  "errors": [
    {
      "signature": "AlreadyClaimed(uint256)",
      "notice": "This account has already taken its share of that epoch."
    },
    {
      "signature": "EpochNotClosed(uint256)",
      "notice": "The epoch is still running, so its pot and its total are not final."
    },
    {
      "signature": "HookFeeTooLarge()",
      "notice": "Fee is higher than the maximum allowed fee."
    },
    {
      "signature": "HookNotImplemented()",
      "notice": "The hook function is not implemented."
    },
    {
      "signature": "InvalidEpoch()",
      "notice": "An epoch length of zero would make every swap its own epoch and every pot a rounding error."
    },
    {
      "signature": "InvalidPool()",
      "notice": "The pool is not configured to use this hook."
    },
    {
      "signature": "NothingToClaim(uint256)",
      "notice": "The account traded nothing in that epoch."
    },
    {
      "signature": "PayoutNotPoolManager()",
      "notice": "Only the `PoolManager` may drive the callback. Named distinctly because `BaseHook` declares its own."
    },
    {
      "signature": "SkimTooLarge()",
      "notice": "The skim must leave the swap worth doing."
    },
    {
      "signature": "WrongPool()",
      "notice": "This hook serves one pool, bound at its first initialization."
    }
  ],
  "deployments": [],
  "abi": [
    {
      "type": "constructor",
      "inputs": [
        {
          "name": "_poolManager",
          "type": "address",
          "internalType": "contract IPoolManager"
        },
        {
          "name": "_skimBps",
          "type": "uint24",
          "internalType": "uint24"
        },
        {
          "name": "_epochLength",
          "type": "uint32",
          "internalType": "uint32"
        }
      ],
      "stateMutability": "nonpayable"
    },
    {
      "type": "function",
      "name": "afterAddLiquidity",
      "inputs": [
        {
          "name": "sender",
          "type": "address",
          "internalType": "address"
        },
        {
          "name": "key",
          "type": "tuple",
          "internalType": "struct PoolKey",
          "components": [
            {
              "name": "currency0",
              "type": "address",
              "internalType": "Currency"
            },
            {
              "name": "currency1",
              "type": "address",
              "internalType": "Currency"
            },
            {
              "name": "fee",
              "type": "uint24",
              "internalType": "uint24"
            },
            {
              "name": "tickSpacing",
              "type": "int24",
              "internalType": "int24"
            },
            {
              "name": "hooks",
              "type": "address",
              "internalType": "contract IHooks"
            }
          ]
        },
        {
          "name": "params",
          "type": "tuple",
          "internalType": "struct ModifyLiquidityParams",
          "components": [
            {
              "name": "tickLower",
              "type": "int24",
              "internalType": "int24"
            },
            {
              "name": "tickUpper",
              "type": "int24",
              "internalType": "int24"
            },
            {
              "name": "liquidityDelta",
              "type": "int256",
              "internalType": "int256"
            },
            {
              "name": "salt",
              "type": "bytes32",
              "internalType": "bytes32"
            }
          ]
        },
        {
          "name": "delta0",
          "type": "int256",
          "internalType": "BalanceDelta"
        },
        {
          "name": "delta1",
          "type": "int256",
          "internalType": "BalanceDelta"
        },
        {
          "name": "hookData",
          "type": "bytes",
          "internalType": "bytes"
        }
      ],
      "outputs": [
        {
          "name": "",
          "type": "bytes4",
          "internalType": "bytes4"
        },
        {
          "name": "",
          "type": "int256",
          "internalType": "BalanceDelta"
        }
      ],
      "stateMutability": "nonpayable"
    },
    {
      "type": "function",
      "name": "afterDonate",
      "inputs": [
        {
          "name": "sender",
          "type": "address",
          "internalType": "address"
        },
        {
          "name": "key",
          "type": "tuple",
          "internalType": "struct PoolKey",
          "components": [
            {
              "name": "currency0",
              "type": "address",
              "internalType": "Currency"
            },
            {
              "name": "currency1",
              "type": "address",
              "internalType": "Currency"
            },
            {
              "name": "fee",
              "type": "uint24",
              "internalType": "uint24"
            },
            {
              "name": "tickSpacing",
              "type": "int24",
              "internalType": "int24"
            },
            {
              "name": "hooks",
              "type": "address",
              "internalType": "contract IHooks"
            }
          ]
        },
        {
          "name": "amount0",
          "type": "uint256",
          "internalType": "uint256"
        },
        {
          "name": "amount1",
          "type": "uint256",
          "internalType": "uint256"
        },
        {
          "name": "hookData",
          "type": "bytes",
          "internalType": "bytes"
        }
      ],
      "outputs": [
        {
          "name": "",
          "type": "bytes4",
          "internalType": "bytes4"
        }
      ],
      "stateMutability": "nonpayable"
    },
    {
      "type": "function",
      "name": "afterInitialize",
      "inputs": [
        {
          "name": "sender",
          "type": "address",
          "internalType": "address"
        },
        {
          "name": "key",
          "type": "tuple",
          "internalType": "struct PoolKey",
          "components": [
            {
              "name": "currency0",
              "type": "address",
              "internalType": "Currency"
            },
            {
              "name": "currency1",
              "type": "address",
              "internalType": "Currency"
            },
            {
              "name": "fee",
              "type": "uint24",
              "internalType": "uint24"
            },
            {
              "name": "tickSpacing",
              "type": "int24",
              "internalType": "int24"
            },
            {
              "name": "hooks",
              "type": "address",
              "internalType": "contract IHooks"
            }
          ]
        },
        {
          "name": "sqrtPriceX96",
          "type": "uint160",
          "internalType": "uint160"
        },
        {
          "name": "tick",
          "type": "int24",
          "internalType": "int24"
        }
      ],
      "outputs": [
        {
          "name": "",
          "type": "bytes4",
          "internalType": "bytes4"
        }
      ],
      "stateMutability": "nonpayable"
    },
    {
      "type": "function",
      "name": "afterRemoveLiquidity",
      "inputs": [
        {
          "name": "sender",
          "type": "address",
          "internalType": "address"
        },
        {
          "name": "key",
          "type": "tuple",
          "internalType": "struct PoolKey",
          "components": [
            {
              "name": "currency0",
              "type": "address",
              "internalType": "Currency"
            },
            {
              "name": "currency1",
              "type": "address",
              "internalType": "Currency"
            },
            {
              "name": "fee",
              "type": "uint24",
              "internalType": "uint24"
            },
            {
              "name": "tickSpacing",
              "type": "int24",
              "internalType": "int24"
            },
            {
              "name": "hooks",
              "type": "address",
              "internalType": "contract IHooks"
            }
          ]
        },
        {
          "name": "params",
          "type": "tuple",
          "internalType": "struct ModifyLiquidityParams",
          "components": [
            {
              "name": "tickLower",
              "type": "int24",
              "internalType": "int24"
            },
            {
              "name": "tickUpper",
              "type": "int24",
              "internalType": "int24"
            },
            {
              "name": "liquidityDelta",
              "type": "int256",
              "internalType": "int256"
            },
            {
              "name": "salt",
              "type": "bytes32",
              "internalType": "bytes32"
            }
          ]
        },
        {
          "name": "delta0",
          "type": "int256",
          "internalType": "BalanceDelta"
        },
        {
          "name": "delta1",
          "type": "int256",
          "internalType": "BalanceDelta"
        },
        {
          "name": "hookData",
          "type": "bytes",
          "internalType": "bytes"
        }
      ],
      "outputs": [
        {
          "name": "",
          "type": "bytes4",
          "internalType": "bytes4"
        },
        {
          "name": "",
          "type": "int256",
          "internalType": "BalanceDelta"
        }
      ],
      "stateMutability": "nonpayable"
    },
    {
      "type": "function",
      "name": "afterSwap",
      "inputs": [
        {
          "name": "sender",
          "type": "address",
          "internalType": "address"
        },
        {
          "name": "key",
          "type": "tuple",
          "internalType": "struct PoolKey",
          "components": [
            {
              "name": "currency0",
              "type": "address",
              "internalType": "Currency"
            },
            {
              "name": "currency1",
              "type": "address",
              "internalType": "Currency"
            },
            {
              "name": "fee",
              "type": "uint24",
              "internalType": "uint24"
            },
            {
              "name": "tickSpacing",
              "type": "int24",
              "internalType": "int24"
            },
            {
              "name": "hooks",
              "type": "address",
              "internalType": "contract IHooks"
            }
          ]
        },
        {
          "name": "params",
          "type": "tuple",
          "internalType": "struct SwapParams",
          "components": [
            {
              "name": "zeroForOne",
              "type": "bool",
              "internalType": "bool"
            },
            {
              "name": "amountSpecified",
              "type": "int256",
              "internalType": "int256"
            },
            {
              "name": "sqrtPriceLimitX96",
              "type": "uint160",
              "internalType": "uint160"
            }
          ]
        },
        {
          "name": "delta",
          "type": "int256",
          "internalType": "BalanceDelta"
        },
        {
          "name": "hookData",
          "type": "bytes",
          "internalType": "bytes"
        }
      ],
      "outputs": [
        {
          "name": "",
          "type": "bytes4",
          "internalType": "bytes4"
        },
        {
          "name": "",
          "type": "int128",
          "internalType": "int128"
        }
      ],
      "stateMutability": "nonpayable"
    },
    {
      "type": "function",
      "name": "beforeAddLiquidity",
      "inputs": [
        {
          "name": "sender",
          "type": "address",
          "internalType": "address"
        },
        {
          "name": "key",
          "type": "tuple",
          "internalType": "struct PoolKey",
          "components": [
            {
              "name": "currency0",
              "type": "address",
              "internalType": "Currency"
            },
            {
              "name": "currency1",
              "type": "address",
              "internalType": "Currency"
            },
            {
              "name": "fee",
              "type": "uint24",
              "internalType": "uint24"
            },
            {
              "name": "tickSpacing",
              "type": "int24",
              "internalType": "int24"
            },
            {
              "name": "hooks",
              "type": "address",
              "internalType": "contract IHooks"
            }
          ]
        },
        {
          "name": "params",
          "type": "tuple",
          "internalType": "struct ModifyLiquidityParams",
          "components": [
            {
              "name": "tickLower",
              "type": "int24",
              "internalType": "int24"
            },
            {
              "name": "tickUpper",
              "type": "int24",
              "internalType": "int24"
            },
            {
              "name": "liquidityDelta",
              "type": "int256",
              "internalType": "int256"
            },
            {
              "name": "salt",
              "type": "bytes32",
              "internalType": "bytes32"
            }
          ]
        },
        {
          "name": "hookData",
          "type": "bytes",
          "internalType": "bytes"
        }
      ],
      "outputs": [
        {
          "name": "",
          "type": "bytes4",
          "internalType": "bytes4"
        }
      ],
      "stateMutability": "nonpayable"
    },
    {
      "type": "function",
      "name": "beforeDonate",
      "inputs": [
        {
          "name": "sender",
          "type": "address",
          "internalType": "address"
        },
        {
          "name": "key",
          "type": "tuple",
          "internalType": "struct PoolKey",
          "components": [
            {
              "name": "currency0",
              "type": "address",
              "internalType": "Currency"
            },
            {
              "name": "currency1",
              "type": "address",
              "internalType": "Currency"
            },
            {
              "name": "fee",
              "type": "uint24",
              "internalType": "uint24"
            },
            {
              "name": "tickSpacing",
              "type": "int24",
              "internalType": "int24"
            },
            {
              "name": "hooks",
              "type": "address",
              "internalType": "contract IHooks"
            }
          ]
        },
        {
          "name": "amount0",
          "type": "uint256",
          "internalType": "uint256"
        },
        {
          "name": "amount1",
          "type": "uint256",
          "internalType": "uint256"
        },
        {
          "name": "hookData",
          "type": "bytes",
          "internalType": "bytes"
        }
      ],
      "outputs": [
        {
          "name": "",
          "type": "bytes4",
          "internalType": "bytes4"
        }
      ],
      "stateMutability": "nonpayable"
    },
    {
      "type": "function",
      "name": "beforeInitialize",
      "inputs": [
        {
          "name": "sender",
          "type": "address",
          "internalType": "address"
        },
        {
          "name": "key",
          "type": "tuple",
          "internalType": "struct PoolKey",
          "components": [
            {
              "name": "currency0",
              "type": "address",
              "internalType": "Currency"
            },
            {
              "name": "currency1",
              "type": "address",
              "internalType": "Currency"
            },
            {
              "name": "fee",
              "type": "uint24",
              "internalType": "uint24"
            },
            {
              "name": "tickSpacing",
              "type": "int24",
              "internalType": "int24"
            },
            {
              "name": "hooks",
              "type": "address",
              "internalType": "contract IHooks"
            }
          ]
        },
        {
          "name": "sqrtPriceX96",
          "type": "uint160",
          "internalType": "uint160"
        }
      ],
      "outputs": [
        {
          "name": "",
          "type": "bytes4",
          "internalType": "bytes4"
        }
      ],
      "stateMutability": "nonpayable"
    },
    {
      "type": "function",
      "name": "beforeRemoveLiquidity",
      "inputs": [
        {
          "name": "sender",
          "type": "address",
          "internalType": "address"
        },
        {
          "name": "key",
          "type": "tuple",
          "internalType": "struct PoolKey",
          "components": [
            {
              "name": "currency0",
              "type": "address",
              "internalType": "Currency"
            },
            {
              "name": "currency1",
              "type": "address",
              "internalType": "Currency"
            },
            {
              "name": "fee",
              "type": "uint24",
              "internalType": "uint24"
            },
            {
              "name": "tickSpacing",
              "type": "int24",
              "internalType": "int24"
            },
            {
              "name": "hooks",
              "type": "address",
              "internalType": "contract IHooks"
            }
          ]
        },
        {
          "name": "params",
          "type": "tuple",
          "internalType": "struct ModifyLiquidityParams",
          "components": [
            {
              "name": "tickLower",
              "type": "int24",
              "internalType": "int24"
            },
            {
              "name": "tickUpper",
              "type": "int24",
              "internalType": "int24"
            },
            {
              "name": "liquidityDelta",
              "type": "int256",
              "internalType": "int256"
            },
            {
              "name": "salt",
              "type": "bytes32",
              "internalType": "bytes32"
            }
          ]
        },
        {
          "name": "hookData",
          "type": "bytes",
          "internalType": "bytes"
        }
      ],
      "outputs": [
        {
          "name": "",
          "type": "bytes4",
          "internalType": "bytes4"
        }
      ],
      "stateMutability": "nonpayable"
    },
    {
      "type": "function",
      "name": "beforeSwap",
      "inputs": [
        {
          "name": "sender",
          "type": "address",
          "internalType": "address"
        },
        {
          "name": "key",
          "type": "tuple",
          "internalType": "struct PoolKey",
          "components": [
            {
              "name": "currency0",
              "type": "address",
              "internalType": "Currency"
            },
            {
              "name": "currency1",
              "type": "address",
              "internalType": "Currency"
            },
            {
              "name": "fee",
              "type": "uint24",
              "internalType": "uint24"
            },
            {
              "name": "tickSpacing",
              "type": "int24",
              "internalType": "int24"
            },
            {
              "name": "hooks",
              "type": "address",
              "internalType": "contract IHooks"
            }
          ]
        },
        {
          "name": "params",
          "type": "tuple",
          "internalType": "struct SwapParams",
          "components": [
            {
              "name": "zeroForOne",
              "type": "bool",
              "internalType": "bool"
            },
            {
              "name": "amountSpecified",
              "type": "int256",
              "internalType": "int256"
            },
            {
              "name": "sqrtPriceLimitX96",
              "type": "uint160",
              "internalType": "uint160"
            }
          ]
        },
        {
          "name": "hookData",
          "type": "bytes",
          "internalType": "bytes"
        }
      ],
      "outputs": [
        {
          "name": "",
          "type": "bytes4",
          "internalType": "bytes4"
        },
        {
          "name": "",
          "type": "int256",
          "internalType": "BeforeSwapDelta"
        },
        {
          "name": "",
          "type": "uint24",
          "internalType": "uint24"
        }
      ],
      "stateMutability": "nonpayable"
    },
    {
      "type": "function",
      "name": "boundPool",
      "inputs": [],
      "outputs": [
        {
          "name": "",
          "type": "bytes32",
          "internalType": "PoolId"
        }
      ],
      "stateMutability": "view"
    },
    {
      "type": "function",
      "name": "claim",
      "inputs": [
        {
          "name": "epoch",
          "type": "uint256",
          "internalType": "uint256"
        },
        {
          "name": "to",
          "type": "address",
          "internalType": "address"
        }
      ],
      "outputs": [
        {
          "name": "amount0",
          "type": "uint256",
          "internalType": "uint256"
        },
        {
          "name": "amount1",
          "type": "uint256",
          "internalType": "uint256"
        }
      ],
      "stateMutability": "nonpayable"
    },
    {
      "type": "function",
      "name": "claimable",
      "inputs": [
        {
          "name": "epoch",
          "type": "uint256",
          "internalType": "uint256"
        },
        {
          "name": "account",
          "type": "address",
          "internalType": "address"
        }
      ],
      "outputs": [
        {
          "name": "amount0",
          "type": "uint256",
          "internalType": "uint256"
        },
        {
          "name": "amount1",
          "type": "uint256",
          "internalType": "uint256"
        }
      ],
      "stateMutability": "view"
    },
    {
      "type": "function",
      "name": "claimed",
      "inputs": [
        {
          "name": "",
          "type": "uint256",
          "internalType": "uint256"
        },
        {
          "name": "",
          "type": "address",
          "internalType": "address"
        }
      ],
      "outputs": [
        {
          "name": "",
          "type": "bool",
          "internalType": "bool"
        }
      ],
      "stateMutability": "view"
    },
    {
      "type": "function",
      "name": "currentEpoch",
      "inputs": [],
      "outputs": [
        {
          "name": "",
          "type": "uint256",
          "internalType": "uint256"
        }
      ],
      "stateMutability": "view"
    },
    {
      "type": "function",
      "name": "epochAt",
      "inputs": [
        {
          "name": "timestamp",
          "type": "uint256",
          "internalType": "uint256"
        }
      ],
      "outputs": [
        {
          "name": "",
          "type": "uint256",
          "internalType": "uint256"
        }
      ],
      "stateMutability": "view"
    },
    {
      "type": "function",
      "name": "epochLength",
      "inputs": [],
      "outputs": [
        {
          "name": "",
          "type": "uint32",
          "internalType": "uint32"
        }
      ],
      "stateMutability": "view"
    },
    {
      "type": "function",
      "name": "getHookPermissions",
      "inputs": [],
      "outputs": [
        {
          "name": "",
          "type": "tuple",
          "internalType": "struct Hooks.Permissions",
          "components": [
            {
              "name": "beforeInitialize",
              "type": "bool",
              "internalType": "bool"
            },
            {
              "name": "afterInitialize",
              "type": "bool",
              "internalType": "bool"
            },
            {
              "name": "beforeAddLiquidity",
              "type": "bool",
              "internalType": "bool"
            },
            {
              "name": "afterAddLiquidity",
              "type": "bool",
              "internalType": "bool"
            },
            {
              "name": "beforeRemoveLiquidity",
              "type": "bool",
              "internalType": "bool"
            },
            {
              "name": "afterRemoveLiquidity",
              "type": "bool",
              "internalType": "bool"
            },
            {
              "name": "beforeSwap",
              "type": "bool",
              "internalType": "bool"
            },
            {
              "name": "afterSwap",
              "type": "bool",
              "internalType": "bool"
            },
            {
              "name": "beforeDonate",
              "type": "bool",
              "internalType": "bool"
            },
            {
              "name": "afterDonate",
              "type": "bool",
              "internalType": "bool"
            },
            {
              "name": "beforeSwapReturnDelta",
              "type": "bool",
              "internalType": "bool"
            },
            {
              "name": "afterSwapReturnDelta",
              "type": "bool",
              "internalType": "bool"
            },
            {
              "name": "afterAddLiquidityReturnDelta",
              "type": "bool",
              "internalType": "bool"
            },
            {
              "name": "afterRemoveLiquidityReturnDelta",
              "type": "bool",
              "internalType": "bool"
            }
          ]
        }
      ],
      "stateMutability": "pure"
    },
    {
      "type": "function",
      "name": "handleHookFees",
      "inputs": [
        {
          "name": "",
          "type": "address[]",
          "internalType": "Currency[]"
        }
      ],
      "outputs": [],
      "stateMutability": "pure"
    },
    {
      "type": "function",
      "name": "hookName",
      "inputs": [],
      "outputs": [
        {
          "name": "",
          "type": "string",
          "internalType": "string"
        }
      ],
      "stateMutability": "pure"
    },
    {
      "type": "function",
      "name": "hookTags",
      "inputs": [],
      "outputs": [
        {
          "name": "tags",
          "type": "string[]",
          "internalType": "string[]"
        }
      ],
      "stateMutability": "pure"
    },
    {
      "type": "function",
      "name": "hookVersion",
      "inputs": [],
      "outputs": [
        {
          "name": "",
          "type": "string",
          "internalType": "string"
        }
      ],
      "stateMutability": "view"
    },
    {
      "type": "function",
      "name": "poolManager",
      "inputs": [],
      "outputs": [
        {
          "name": "",
          "type": "address",
          "internalType": "contract IPoolManager"
        }
      ],
      "stateMutability": "view"
    },
    {
      "type": "function",
      "name": "pot0",
      "inputs": [
        {
          "name": "",
          "type": "uint256",
          "internalType": "uint256"
        }
      ],
      "outputs": [
        {
          "name": "",
          "type": "uint256",
          "internalType": "uint256"
        }
      ],
      "stateMutability": "view"
    },
    {
      "type": "function",
      "name": "pot1",
      "inputs": [
        {
          "name": "",
          "type": "uint256",
          "internalType": "uint256"
        }
      ],
      "outputs": [
        {
          "name": "",
          "type": "uint256",
          "internalType": "uint256"
        }
      ],
      "stateMutability": "view"
    },
    {
      "type": "function",
      "name": "skimBps",
      "inputs": [],
      "outputs": [
        {
          "name": "",
          "type": "uint24",
          "internalType": "uint24"
        }
      ],
      "stateMutability": "view"
    },
    {
      "type": "function",
      "name": "specURI",
      "inputs": [],
      "outputs": [
        {
          "name": "",
          "type": "string",
          "internalType": "string"
        }
      ],
      "stateMutability": "pure"
    },
    {
      "type": "function",
      "name": "supportsInterface",
      "inputs": [
        {
          "name": "interfaceId",
          "type": "bytes4",
          "internalType": "bytes4"
        }
      ],
      "outputs": [
        {
          "name": "",
          "type": "bool",
          "internalType": "bool"
        }
      ],
      "stateMutability": "view"
    },
    {
      "type": "function",
      "name": "totalVolume",
      "inputs": [
        {
          "name": "",
          "type": "uint256",
          "internalType": "uint256"
        }
      ],
      "outputs": [
        {
          "name": "",
          "type": "uint256",
          "internalType": "uint256"
        }
      ],
      "stateMutability": "view"
    },
    {
      "type": "function",
      "name": "unlockCallback",
      "inputs": [
        {
          "name": "data",
          "type": "bytes",
          "internalType": "bytes"
        }
      ],
      "outputs": [
        {
          "name": "",
          "type": "bytes",
          "internalType": "bytes"
        }
      ],
      "stateMutability": "nonpayable"
    },
    {
      "type": "function",
      "name": "volumeOf",
      "inputs": [
        {
          "name": "",
          "type": "uint256",
          "internalType": "uint256"
        },
        {
          "name": "",
          "type": "address",
          "internalType": "address"
        }
      ],
      "outputs": [
        {
          "name": "",
          "type": "uint256",
          "internalType": "uint256"
        }
      ],
      "stateMutability": "view"
    },
    {
      "type": "event",
      "name": "HookBonus",
      "inputs": [
        {
          "name": "poolId",
          "type": "bytes32",
          "indexed": true,
          "internalType": "bytes32"
        },
        {
          "name": "amount0",
          "type": "uint128",
          "indexed": false,
          "internalType": "uint128"
        },
        {
          "name": "amount1",
          "type": "uint128",
          "indexed": false,
          "internalType": "uint128"
        }
      ],
      "anonymous": false
    },
    {
      "type": "event",
      "name": "HookFee",
      "inputs": [
        {
          "name": "poolId",
          "type": "bytes32",
          "indexed": true,
          "internalType": "bytes32"
        },
        {
          "name": "sender",
          "type": "address",
          "indexed": true,
          "internalType": "address"
        },
        {
          "name": "feeAmount0",
          "type": "uint128",
          "indexed": false,
          "internalType": "uint128"
        },
        {
          "name": "feeAmount1",
          "type": "uint128",
          "indexed": false,
          "internalType": "uint128"
        }
      ],
      "anonymous": false
    },
    {
      "type": "event",
      "name": "HookModifyLiquidity",
      "inputs": [
        {
          "name": "poolId",
          "type": "bytes32",
          "indexed": true,
          "internalType": "bytes32"
        },
        {
          "name": "sender",
          "type": "address",
          "indexed": true,
          "internalType": "address"
        },
        {
          "name": "amount0",
          "type": "int128",
          "indexed": false,
          "internalType": "int128"
        },
        {
          "name": "amount1",
          "type": "int128",
          "indexed": false,
          "internalType": "int128"
        }
      ],
      "anonymous": false
    },
    {
      "type": "event",
      "name": "HookSwap",
      "inputs": [
        {
          "name": "poolId",
          "type": "bytes32",
          "indexed": true,
          "internalType": "bytes32"
        },
        {
          "name": "sender",
          "type": "address",
          "indexed": true,
          "internalType": "address"
        },
        {
          "name": "amount0",
          "type": "int128",
          "indexed": false,
          "internalType": "int128"
        },
        {
          "name": "amount1",
          "type": "int128",
          "indexed": false,
          "internalType": "int128"
        },
        {
          "name": "hookLPfeeAmount0",
          "type": "uint128",
          "indexed": false,
          "internalType": "uint128"
        },
        {
          "name": "hookLPfeeAmount1",
          "type": "uint128",
          "indexed": false,
          "internalType": "uint128"
        }
      ],
      "anonymous": false
    },
    {
      "type": "event",
      "name": "RebateClaimed",
      "inputs": [
        {
          "name": "epoch",
          "type": "uint256",
          "indexed": true,
          "internalType": "uint256"
        },
        {
          "name": "account",
          "type": "address",
          "indexed": true,
          "internalType": "address"
        },
        {
          "name": "amount0",
          "type": "uint256",
          "indexed": false,
          "internalType": "uint256"
        },
        {
          "name": "amount1",
          "type": "uint256",
          "indexed": false,
          "internalType": "uint256"
        }
      ],
      "anonymous": false
    },
    {
      "type": "event",
      "name": "VolumeRecorded",
      "inputs": [
        {
          "name": "epoch",
          "type": "uint256",
          "indexed": true,
          "internalType": "uint256"
        },
        {
          "name": "account",
          "type": "address",
          "indexed": true,
          "internalType": "address"
        },
        {
          "name": "volume",
          "type": "uint256",
          "indexed": false,
          "internalType": "uint256"
        }
      ],
      "anonymous": false
    },
    {
      "type": "error",
      "name": "AlreadyClaimed",
      "inputs": [
        {
          "name": "epoch",
          "type": "uint256",
          "internalType": "uint256"
        }
      ]
    },
    {
      "type": "error",
      "name": "EpochNotClosed",
      "inputs": [
        {
          "name": "epoch",
          "type": "uint256",
          "internalType": "uint256"
        }
      ]
    },
    {
      "type": "error",
      "name": "HookFeeTooLarge",
      "inputs": []
    },
    {
      "type": "error",
      "name": "HookNotImplemented",
      "inputs": []
    },
    {
      "type": "error",
      "name": "InvalidEpoch",
      "inputs": []
    },
    {
      "type": "error",
      "name": "InvalidPool",
      "inputs": []
    },
    {
      "type": "error",
      "name": "NotPoolManager",
      "inputs": []
    },
    {
      "type": "error",
      "name": "NothingToClaim",
      "inputs": [
        {
          "name": "epoch",
          "type": "uint256",
          "internalType": "uint256"
        }
      ]
    },
    {
      "type": "error",
      "name": "PayoutNotPoolManager",
      "inputs": []
    },
    {
      "type": "error",
      "name": "SkimTooLarge",
      "inputs": []
    },
    {
      "type": "error",
      "name": "WrongPool",
      "inputs": []
    }
  ]
}
