Skip to content

How it works

TIDE turns one idea into a full lifecycle: holding the token is providing liquidity. The entire fixed supply of 10000 TIDE lives in a single protocol-owned ETH/TIDE Uniswap v4 position. You never deposit, never manage a range, and can never be liquidated — you just hold TIDE, and a DN404-style mirror materializes one tradable Tide-LP NFT for every whole token you hold. Each NFT is 1/10000 of the pool and the unit of fee accounting.

This page walks the whole journey end to end. Each step links to the page that documents it in depth.

flowchart TD
A["1 · Buy TIDE\nETH → TIDE in the v4 pool"] --> B["Whole tokens auto-mint\nTide-LP NFTs (you are now liquidity)"]
B --> C["2 · Every swap accrues fees\npro-rata to live shares"]
C --> D["3 · Claim\nyour ETH fee share buys TIDE in-pool"]
D --> E["4 · Claimed TIDE vests\nlinearly over the vesting window"]
E -->|hold to maturity| F["Withdraw vested TIDE"]
E -->|sell/transfer NFT early| G["5 · Forfeit unvested TIDE\n→ lottery for another holder"]
G -->|prize unclaimed in window| H["6 · Treasury collects\n→ buyback-burn"]

Step 1 — Buy TIDE and become liquidity instantly

Section titled “Step 1 — Buy TIDE and become liquidity instantly”

You acquire TIDE by swapping ETH for it in the canonical pool (the dapp’s swap widget does this for you). The pool is currency0 = address(0) (native ETH) and currency1 = TIDE, with tickSpacing = 200 and a dynamic fee.

Settlement runs through the hook’s DN404 sync engine: every time your balance crosses a whole-UNIT threshold (UNIT = 1 ether, i.e. 1e18), the hook mints you one Tide-LP NFT. The protocol maintains the invariant:

nftBalanceOf(you) === balanceOf(you) / UNIT // integer floor

So a buy that leaves you holding 222 whole TIDE mints 222 NFTs — exactly what happened on the live Sepolia launch. You did not stake, lock, or range anything: holding the token already is the LP position. Fractional dust below one whole token earns nothing until it completes a token.

→ Full mechanic: ../mechanics/hold-equals-lp.md

Step 2 — Every swap accrues fees, pro-rata to your shares

Section titled “Step 2 — Every swap accrues fees, pro-rata to your shares”

Each swap against the pool pays a fee, split into two streams: ETH (currency0) and TIDE (currency1). The hook tracks them with two cumulative accumulators, accFeesPerShareETH and accFeesPerShareTIDE, scaled by ACC_SCALE = 1e12.

Anyone can call pokeFees() — it is permissionless and idempotent — to harvest collected fees out of the v4 position and roll them into those accumulators:

accFeesPerShareETH += ethGained * ACC_SCALE / totalShares;

totalShares is the count of live (minted, not burned) NFTs; it is the fee denominator. Every NFT you hold accrues its pro-rata slice. Because the denominator is live shares, when other holders sell and their NFTs burn, the remaining shares each accrue more — exits enrich those who stay.

→ Full mechanic: ../mechanics/hold-equals-lp.md · per-position math in ../contracts/tidehook.md

Step 3 — Claim: your ETH fee share buys TIDE in-pool

Section titled “Step 3 — Claim: your ETH fee share buys TIDE in-pool”

When you claim(tokenId) or claimMany(tokenIds), the hook pokes fees, harvests the named NFTs to their current owners, then converts only your owed balance. Critically, there is no direct ETH payout: the protocol takes the ETH leg of your fees and buys TIDE back in the same pool to pay you, then hands you the TIDE leg as-is.

// inside _process(user): the ETH owed is spent buying TIDE in-pool,
// then (tideOwed + bought) is sent to vesting — never paid out as ETH.

Two consequences:

  • Every claim creates buy pressure on TIDE, supporting price. The protocol’s own buyback is fee-exempt (sender == address(this) ⇒ fee 0), so it doesn’t pay the launch fee back into the pool.
  • The in-pool buyback derives its minOut from spot price with a 10% slippage floor (MAX_BUYBACK_SLIPPAGE_BPS = 1000), so large claims are sandwichable — keep individual claims modest. See ../security/known-limitations.md.

Claiming always pays the NFT’s current owner and only processes the caller’s owed, so you cannot restart a victim’s vesting clock by claiming on their NFT.

→ Full mechanic: ../mechanics/claim-and-buyback.md

Claimed gains do not arrive all at once. They unlock linearly over vestingDuration (production: 259200 seconds = 72 hours; the live Sepolia deployment compresses this to ~5 minutes). This applies to all claims, including activated lottery prizes.

grossVested = lockedTotal * elapsed / vestingDuration; // capped at lockedTotal

You watch claimable rise and locked fall in the claim dashboard, then call withdrawVested() to take the unlocked TIDE. Two behaviors worth internalizing:

  • A new claim re-locks the still-locked remainder over a fresh window — deliberate, to discourage claim-and-dump.
  • A withdrawal does not restart the clock. Already-vested TIDE is yours to keep even if you later sell.

→ Full mechanic: ../mechanics/vesting.md

Step 5 — Sell early, and your unvested TIDE feeds the lottery

Section titled “Step 5 — Sell early, and your unvested TIDE feeds the lottery”

If you sell or transfer a Tide-LP NFT before your vesting completes, you forfeit the still-unvested portion (you keep whatever has already vested). That forfeited amount is then raffled to another holder:

  1. A random eligible holder is drawn (RNG seeded from block.prevrandao); the seller and the counterparty are excluded from that draw only.
  2. The winner gets a pending prize and a window (prizeActivationWindow; production 172800 seconds = 48 hours, compressed on Sepolia) to activatePrize() — a pull payment, winner pays gas.
  3. An activated prize re-vests over the vesting window like any other gain.
  4. If no eligible winner exists, the forfeit is redistributed pro-rata to all live shares instead.

Each sale only redistributes its own forfeit (no shared pot to farm). This is “exits enrich those who stay,” with a playful twist.

→ Full mechanic: ../mechanics/lottery.md

Step 6 — Treasury collects expired prizes and can buyback-burn

Section titled “Step 6 — Treasury collects expired prizes and can buyback-burn”

A prize that is not activated within its window routes to the Treasury contract via expirePrize(winner). The Treasury is a deliberately minimal sink:

  • The only privileged role is the guardian, and its only outward action is executeBuyback(), which burns all TIDE the Treasury holds (tide.burn(bal)), reducing supply and lifting every holder’s share.
  • There is no withdrawal function to the dev anywhere — the contract is structurally incapable of seizing user funds. “The dev holds the button, not the cashbox”: the guardian controls the timing of supply reduction, never the custody.

→ Full mechanic: ../mechanics/treasury.md · trust model: ../security/trust-model.md

StepYou doThe protocol doesDetailed page
1Buy TIDEAuto-mints one Tide-LP NFT per whole token../mechanics/hold-equals-lp.md
2HoldAccrues swap fees pro-rata to live shares../mechanics/hold-equals-lp.md
3claim / claimManyBuys TIDE in-pool with your ETH fees (buy pressure)../mechanics/claim-and-buyback.md
4withdrawVestedVests claimed TIDE linearly over the window../mechanics/vesting.md
5Sell/transfer earlyForfeits unvested TIDE into a holder lottery../mechanics/lottery.md
6(nothing)Collects expired prizes, can buyback-burn../mechanics/treasury.md