Build #002: a fee that follows the weather

The swap fee rises from 1% to 3% while it rains in a city the creator picks, and falls back safely if the oracle goes quiet.

Build #002 cover
fig. 00 · build #002 · 223 words

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.