The rule: while it rains in Valencia, trading costs 3%. Otherwise it costs 1%. It sounds like a joke, and that's exactly why it needs a careful spec. This is an example build, not a deployed hook.
The spec
- The pool uses a dynamic fee; the hook overrides it on every swap.
- Weather comes from an oracle feed that reports "raining" as a boolean with a timestamp.
- If the latest reading is older than one hour, the hook uses the base fee of 1%.
- The fee can never go above 3%, whatever the oracle says.
The hook
function beforeSwap(address, PoolKey calldata key, SwapParams calldata, bytes calldata)
external override onlyPoolManager
returns (bytes4, BeforeSwapDelta, uint24)
{
(bool raining, uint256 updatedAt) = weather.latest();
bool fresh = block.timestamp - updatedAt <= 1 hours;
uint24 fee = (fresh && raining) ? RAIN_FEE : BASE_FEE; // 30_000 or 10_000
return (
this.beforeSwap.selector,
BeforeSwapDeltaLibrary.ZERO_DELTA,
fee | LPFeeLibrary.OVERRIDE_FEE_FLAG
);
}
Tests
The oracle is mocked to report rain, no rain, stale data and a malicious value. In every case the fee stays between 1% and 3%. The fork test replays a week of real swaps against both fee levels to show the creator what the rule would have earned.
What it will never do
Charge more than 3%, trust a stale reading, or block a swap because the oracle is down.