{
  "$schema": "https://hookforge.pages.dev/schema/hook-manifest.json",
  "slug": "markout-fee",
  "name": "MarkoutFee",
  "contract": "MarkoutFeeHook",
  "version": "1.0.0",
  "family": "Order flow and MEV",
  "summary": "A fee that learns. The pool measures whether its own past trades turned out to be informed, and charges the next one accordingly.",
  "description": "Every dynamic-fee hook published so far prices a swap from something observable at the moment it arrives: the size, the recent volatility, the gas it bid, the distance from an oracle. All of those are proxies for the question that actually matters, which is whether the person on the other side knew something. None of them measure it, because at the moment a swap arrives that fact has not happened yet. It has happened a few seconds later. If a swap pushed the price down and the price kept falling, the seller was right and the liquidity that filled them lost; that is an informed trade, and it is the cost the LP literature calls adverse selection. If the price came back, the swap was noise and the fee it paid was pure revenue. This is the markout that every market maker computes on their own flow, and a pool has everything needed to compute it: the tick it was left at, and the tick it is at now. So this hook grades each swap after the fact. On the next swap it compares the current tick to the tick the previous swap left behind, decides whether that swap was informed, and folds the verdict into an exponentially weighted average. The fee it quotes is:   fee = baseFee + maxSurcharge * toxicity A pool whose flow is mostly retail converges toward `baseFee` and becomes cheap. A pool being picked off converges toward the cap and becomes expensive, without anybody deciding that, and without an oracle to manipulate or a governance process to capture. The score is public, so anything else on-chain can read a pool's measured toxicity rather than guessing at it. Two details keep the measurement honest. A verdict is only recorded once `minHorizon` seconds have passed, because a comparison inside the same block is measuring the swap's own price impact rather than what happened next. And the verdict is graded by magnitude rather than treated as a coin flip: a move that continues by a tenth of a tick is weak evidence, a move that continues by a hundred ticks is strong, so the observation is scaled and clamped instead of being rounded to a yes or a no. {FlowClassifierHook} measures a related quantity and deliberately does nothing with it; this hook is the other half of that pair, the one that acts on what it measures. The hook takes no fee for itself, custodies nothing, and has no privileged role. `baseFee`, the cap, the smoothing and the horizon are fixed before the pool exists and can never be changed.",
  "priorArt": "Dynamic fees keyed on realized volatility, swap size, price movement or an oracle gap are all well covered, and markout is the standard way a market maker grades its own flow off-chain. Computing markout on-chain, from the pool's own tick history, and feeding it back as the pool's fee, is the contribution here. It is the difference between reacting to a proxy for adverse selection and measuring the thing itself.",
  "limitation": "The verdict on a swap arrives with the next swap, so a pool that trades once a day prices today's flow on yesterday's evidence, and a pool with no second swap never grades the first. It is a lagging signal by construction: a regime change is paid for at the old rate until the average catches up. Note also that a sustained one-directional run grades as informed, because every swap in it is followed by one pushing the same way. That is the intended reading rather than a flaw, but it does mean a pool tracking a strong trend will quote its trend-following flow expensively even when that flow is not picking anyone off.",
  "tags": [
    "mev",
    "dynamic-fee",
    "markout",
    "adverse-selection",
    "oracle-free"
  ],
  "recommendedChains": [
    "base",
    "arbitrum",
    "unichain",
    "robinhood",
    "ethereum",
    "optimism",
    "polygon",
    "bnb"
  ],
  "source": "contracts/src/hooks/MarkoutFeeHook.sol",
  "docs": "https://hookforge.pages.dev/hooks/markout-fee",
  "repo": "https://github.com/nirholas/markout-fee",
  "site": "https://markout-fee.pages.dev",
  "permissions": {
    "afterRemoveLiquidityReturnsDelta": false,
    "afterAddLiquidityReturnsDelta": false,
    "afterSwapReturnsDelta": false,
    "beforeSwapReturnsDelta": false,
    "afterDonate": false,
    "beforeDonate": false,
    "afterSwap": true,
    "beforeSwap": true,
    "afterRemoveLiquidity": false,
    "beforeRemoveLiquidity": false,
    "afterAddLiquidity": false,
    "beforeAddLiquidity": false,
    "afterInitialize": true,
    "beforeInitialize": false
  },
  "permissionsSource": "declaration",
  "properties": {
    "dynamicFee": true,
    "upgradeable": false,
    "requiresCustomSwapData": false,
    "vanillaSwap": true,
    "swapAccess": "none"
  },
  "configure": {
    "signature": "configure((address,address,uint24,int24,address),(uint24,uint24,uint64,uint32,uint24))",
    "fields": [
      {
        "name": "baseFee",
        "type": "uint24"
      },
      {
        "name": "maxSurcharge",
        "type": "uint24"
      },
      {
        "name": "alphaWad",
        "type": "uint64"
      },
      {
        "name": "minHorizon",
        "type": "uint32"
      },
      {
        "name": "saturationTicks",
        "type": "uint24"
      }
    ]
  },
  "errors": [
    {
      "signature": "FeeTooLarge(uint24)",
      "notice": "A fee was configured above the protocol maximum of 100%."
    },
    {
      "signature": "HookNotImplemented()",
      "notice": "The hook function is not implemented."
    },
    {
      "signature": "InvalidPool()",
      "notice": "The pool is not configured to use this hook."
    },
    {
      "signature": "InvalidSaturation()",
      "notice": "`saturationTicks` of zero would make every move maximally informed."
    },
    {
      "signature": "InvalidSmoothing()",
      "notice": "`alphaWad` must be in (0, 1e18]: zero never learns, above one overshoots."
    },
    {
      "signature": "NotDynamicFee()",
      "notice": "The hook was attempted to be initialized with a non-dynamic fee."
    },
    {
      "signature": "PoolAlreadyInitialized()",
      "notice": "The pool already exists, so its configuration is final."
    },
    {
      "signature": "PoolNotConfigured()",
      "notice": "The pool was initialized without a configuration for this hook."
    },
    {
      "signature": "SurchargeTooLarge()",
      "notice": "`baseFee + maxSurcharge` must leave room under the 100% protocol maximum."
    }
  ],
  "deployments": [],
  "abi": [
    {
      "type": "constructor",
      "inputs": [
        {
          "name": "_poolManager",
          "type": "address",
          "internalType": "contract IPoolManager"
        }
      ],
      "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": "configOf",
      "inputs": [
        {
          "name": "",
          "type": "bytes32",
          "internalType": "PoolId"
        }
      ],
      "outputs": [
        {
          "name": "baseFee",
          "type": "uint24",
          "internalType": "uint24"
        },
        {
          "name": "maxSurcharge",
          "type": "uint24",
          "internalType": "uint24"
        },
        {
          "name": "alphaWad",
          "type": "uint64",
          "internalType": "uint64"
        },
        {
          "name": "minHorizon",
          "type": "uint32",
          "internalType": "uint32"
        },
        {
          "name": "saturationTicks",
          "type": "uint24",
          "internalType": "uint24"
        }
      ],
      "stateMutability": "view"
    },
    {
      "type": "function",
      "name": "configure",
      "inputs": [
        {
          "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": "cfg",
          "type": "tuple",
          "internalType": "struct MarkoutFeeHook.Config",
          "components": [
            {
              "name": "baseFee",
              "type": "uint24",
              "internalType": "uint24"
            },
            {
              "name": "maxSurcharge",
              "type": "uint24",
              "internalType": "uint24"
            },
            {
              "name": "alphaWad",
              "type": "uint64",
              "internalType": "uint64"
            },
            {
              "name": "minHorizon",
              "type": "uint32",
              "internalType": "uint32"
            },
            {
              "name": "saturationTicks",
              "type": "uint24",
              "internalType": "uint24"
            }
          ]
        }
      ],
      "outputs": [],
      "stateMutability": "nonpayable"
    },
    {
      "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": "gradedCount",
      "inputs": [
        {
          "name": "",
          "type": "bytes32",
          "internalType": "PoolId"
        }
      ],
      "outputs": [
        {
          "name": "",
          "type": "uint64",
          "internalType": "uint64"
        }
      ],
      "stateMutability": "view"
    },
    {
      "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": "isPoolInitialized",
      "inputs": [
        {
          "name": "id",
          "type": "bytes32",
          "internalType": "PoolId"
        }
      ],
      "outputs": [
        {
          "name": "",
          "type": "bool",
          "internalType": "bool"
        }
      ],
      "stateMutability": "view"
    },
    {
      "type": "function",
      "name": "markOf",
      "inputs": [
        {
          "name": "",
          "type": "bytes32",
          "internalType": "PoolId"
        }
      ],
      "outputs": [
        {
          "name": "tick",
          "type": "int24",
          "internalType": "int24"
        },
        {
          "name": "timestamp",
          "type": "uint64",
          "internalType": "uint64"
        },
        {
          "name": "zeroForOne",
          "type": "bool",
          "internalType": "bool"
        },
        {
          "name": "present",
          "type": "bool",
          "internalType": "bool"
        }
      ],
      "stateMutability": "view"
    },
    {
      "type": "function",
      "name": "poolManager",
      "inputs": [],
      "outputs": [
        {
          "name": "",
          "type": "address",
          "internalType": "contract IPoolManager"
        }
      ],
      "stateMutability": "view"
    },
    {
      "type": "function",
      "name": "previewGrade",
      "inputs": [
        {
          "name": "id",
          "type": "bytes32",
          "internalType": "PoolId"
        }
      ],
      "outputs": [
        {
          "name": "observationWad",
          "type": "uint256",
          "internalType": "uint256"
        },
        {
          "name": "gradeable",
          "type": "bool",
          "internalType": "bool"
        }
      ],
      "stateMutability": "view"
    },
    {
      "type": "function",
      "name": "quoteFee",
      "inputs": [
        {
          "name": "id",
          "type": "bytes32",
          "internalType": "PoolId"
        }
      ],
      "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": "toxicityOf",
      "inputs": [
        {
          "name": "",
          "type": "bytes32",
          "internalType": "PoolId"
        }
      ],
      "outputs": [
        {
          "name": "",
          "type": "uint256",
          "internalType": "uint256"
        }
      ],
      "stateMutability": "view"
    },
    {
      "type": "event",
      "name": "FlowGraded",
      "inputs": [
        {
          "name": "id",
          "type": "bytes32",
          "indexed": true,
          "internalType": "PoolId"
        },
        {
          "name": "continuationTicks",
          "type": "int256",
          "indexed": false,
          "internalType": "int256"
        },
        {
          "name": "observationWad",
          "type": "uint256",
          "indexed": false,
          "internalType": "uint256"
        },
        {
          "name": "toxicityWad",
          "type": "uint256",
          "indexed": false,
          "internalType": "uint256"
        }
      ],
      "anonymous": false
    },
    {
      "type": "event",
      "name": "FlowPriced",
      "inputs": [
        {
          "name": "id",
          "type": "bytes32",
          "indexed": true,
          "internalType": "PoolId"
        },
        {
          "name": "toxicityWad",
          "type": "uint256",
          "indexed": false,
          "internalType": "uint256"
        },
        {
          "name": "fee",
          "type": "uint24",
          "indexed": false,
          "internalType": "uint24"
        }
      ],
      "anonymous": false
    },
    {
      "type": "event",
      "name": "PoolConfigured",
      "inputs": [
        {
          "name": "id",
          "type": "bytes32",
          "indexed": true,
          "internalType": "PoolId"
        },
        {
          "name": "baseFee",
          "type": "uint24",
          "indexed": false,
          "internalType": "uint24"
        },
        {
          "name": "maxSurcharge",
          "type": "uint24",
          "indexed": false,
          "internalType": "uint24"
        },
        {
          "name": "alphaWad",
          "type": "uint64",
          "indexed": false,
          "internalType": "uint64"
        },
        {
          "name": "minHorizon",
          "type": "uint32",
          "indexed": false,
          "internalType": "uint32"
        }
      ],
      "anonymous": false
    },
    {
      "type": "error",
      "name": "FeeTooLarge",
      "inputs": [
        {
          "name": "fee",
          "type": "uint24",
          "internalType": "uint24"
        }
      ]
    },
    {
      "type": "error",
      "name": "HookNotImplemented",
      "inputs": []
    },
    {
      "type": "error",
      "name": "InvalidPool",
      "inputs": []
    },
    {
      "type": "error",
      "name": "InvalidSaturation",
      "inputs": []
    },
    {
      "type": "error",
      "name": "InvalidSmoothing",
      "inputs": []
    },
    {
      "type": "error",
      "name": "NotDynamicFee",
      "inputs": []
    },
    {
      "type": "error",
      "name": "NotPoolManager",
      "inputs": []
    },
    {
      "type": "error",
      "name": "PoolAlreadyInitialized",
      "inputs": []
    },
    {
      "type": "error",
      "name": "PoolNotConfigured",
      "inputs": []
    },
    {
      "type": "error",
      "name": "SurchargeTooLarge",
      "inputs": []
    }
  ]
}
