Uniswap v4 hook · Ethereum

The NFT is the position.

Buy the token, and the same transaction mints a Hex — an ERC‑721 that earns from every trade after it, in both currencies, and grows while you do nothing. No mint page. No staking. No claim button.

The machine

One swap. Two jobs.

Every trade in the pool pays the Hexes. Every buy also creates or grows one — in the same transaction, with no second step of any kind.

01

beforeSwap — 1% of the specified currency

The fee is minted as an ERC‑6909 claim rather than taken.

Why claims, not take(). v4 is delta‑based: the router settles the trader's input only after swap() returns, so on the input side those tokens have not arrived yet. take() there reverts with an underflow whenever the pool's reserve is thin — it passes on a deep pool and fails on a shallow one, which is the worst possible failure to find in production.

Click to read the reasoning +
02

afterSwap — 1% of the unspecified currency

Charging both sides is what makes the yield payable at all.

A Hex should earn ETH — what people want — and HEXFLOW, so the position compounds in the asset it is a position in. A one‑sided fee yields one currency, so getting both would mean swapping internally: paying slippage into your own pool and handing a sandwich to every observer, on every trade. Taking 1% from each side yields both, with no internal swap anywhere.

Click to read the reasoning +
03

Was it a buy? Mint or grow the Hex

Weighted by the tokens actually received, inside the PoolManager lock.

The mint uses no ERC‑721 receiver callback. A safeMint here would hand control to arbitrary code in the middle of a swap, inside the lock — the most dangerous place in v4 to make an external call. A second buy from the same wallet grows the Hex it already has rather than minting another.

Click to read the reasoning +
04

settle() — permissionless, out of band

Claims become real assets, and both currencies land on the Hexes.

Anyone may call it once enough has piled up, so distribution never depends on a team being awake. Keeping it out of the swap path also means a trade only does arithmetic and one storage write — redeeming and distributing cannot affect anybody's fill.

Click to read the reasoning +
0
fee per side
0
gas to mint a Hex
O(1)
fee distribution
0
art on‑chain
The Hex

It draws itself, on‑chain.

No IPFS. No gateway. No mutable baseURI. Every Hex is a data URI generated by the contract from live state — and the picture is the position. Drag the sliders.

Live renderer

The exact geometry the contract draws: six vertices on a circle, each curve controlled from the bisector at r/cos(30°). Amplitude follows your share, strands follow your buys, and the seal lights only once the Hex has really earned.

Token
HEX #7
Tier
Current
Share
4000 bps
Strands
4
Compounding

It grows while you do nothing.

HEXFLOW fees do not sit waiting to be claimed. They raise a global index, and weight = shares × index — so one number moves and every Hex in existence is worth more, in the same instant.

A Hex nobody touches — 73.3%
A Hex that unwinds its yield — 26.7%

Two Hexes, equal at the start. One is never touched again; the other unwinds its yield every round. Plotted from the shipped contract maths, not an illustration.

Contracts

Nothing owned. Nothing upgradeable.

The token has no admin functions at all. The hook's single wiring step erases its own permission on success. The renderer is an immutable, so the artwork can never be repointed.

NO OWNER
HexflowToken.sol

Fixed supply, EIP‑2612 permit, burn. No mint, no pause, no blacklist, no tax.

FlowHook.sol

The v4 hook. 1% per side, mints the Hex inside the swap, redeems claims out of band.

HexPositions.sol

The Hex. ERC‑721 plus the compounding index and the O(1) ETH accumulator.

ON‑CHAIN
HexRenderer.sol

SVG and metadata generated in the contract. No IPFS, no gateway, no server.

HookDeployer.sol

CREATE2 factory. Reverts unless the hook lands on its mined 0x20CC address.

V4Types.sol

Minimal v4 interfaces. No periphery dependency to drift out of date.

What we would rather you read here than find in an audit

tx.origin identifies the buyer In afterSwap the sender is the router. Without hookData — which the Uniswap interface cannot send — only tx.origin is left. Right for a person swapping from their own wallet; wrong for smart contract wallets and aggregators, where the Hex lands on the signing EOA. It is never used for authorisation, so the worst case is a misattributed position, never a stolen one.
Every first buy pays for an NFT About 118k gas on top of the swap against warm state. A minimum size stops dust buys paying it for a position worth nothing — they still pay the fee, and still feed every existing Hex.
Rounding always favours the contract The index and the ETH accumulator both round down, so an entitlement can be a wei or two light. That is the only safe direction: it can never promise more than it holds.
Not audited Reviewed by no one but its author. There is a test suite, including fuzz invariants and a fork test against real Uniswap v4 — that is not the same thing as an audit.