GLASSHOUSE
The Garden whitepaper

The Garden
Compendium

hortus vitreus, in catena.
Edited by the Curator
Vol. I, Spring 2026
Printed in three colours on hot-press cotton
Cream, Sage, Terracotta. No black
Index
  1. I.What Garden is, in plain wordsp. 1
  2. II.The ERC-404 hybridp. 2
  3. III.The four stages of growthp. 3
  4. IV.The bonding curvep. 4
  5. V.The Uniswap V4 hookp. 5
  6. VI.Anti-whale guardsp. 6
  7. VII.The on-chain rendererp. 7
  8. VIII.Risks and assumptionsp. 8
  9. IX.Glossariump. 9
Cap. I, p. 1
Caput Primum

What Garden is,
in plain words.

Garden is a token contract on Ethereum mainnet that wears two hats. The fungible side behaves like any ERC-20: it has a symbol (GARDEN), eighteen decimals, ten thousand total supply, transfer and approve like every other token you have ever held. The non-fungible side ticks underneath. Whenever a whole GARDEN unit lands in a wallet, a one-of-one NFT plant is minted to that wallet at the same address. When a whole unit leaves, a plant withers.

The plant ages while the wallet keeps it. Six days makes a sapling, thirty days a bloom, ninety days a cultivar. None of this requires any action from the holder. The clock starts at the moment the NFT is minted and resets only if the underlying whole unit changes hands.

The point of the aging is the Uniswap V4 hook. Swaps on the Garden pool read the oldest plant in the trader's wallet and quote a fee from three percent down to a quarter of one percent. The longer you have held without flinching, the cheaper your next trade. There is no other lever. No staking, no claim, no vesting wheel. Hold, age, trade cheap. Sell, the plants are gone, the timer resets.

This document explains how each of those moving parts is wired, what numbers were chosen and why, and what assumptions a holder is taking on.

Cap. II, p. 2
Caput Secundum

The ERC-404
hybrid.

The Garden token implements both the ERC-20 and the ERC-721 surface in a single contract. This pattern is sometimes called ERC-404, after the first project (Pandora) to ship it on mainnet. It is not a formal standard. It is a design.

The fungible balance is held in a normal mapping from address to uint256, units of wei. The non-fungible state is a parallel structure: each NFT id stores its owner and its mint timestamp, and each address keeps a small ordered array of the ids it currently holds. The fungible balance and the NFT array are linked by a single invariant. The number of NFTs an address holds always equals the floor of its GARDEN balance divided by one whole unit.

Mint and burn on transfer

Inside the transfer routine, the contract computes how many whole-unit thresholds the sender's balance crossed downward and how many the receiver's balance crossed upward. For each downward crossing it pops the newest NFT id from the sender's stack and emits a burn. For each upward crossing it mints a new NFT id to the receiver and stamps the current block timestamp as the plant's mintTime.

Exempt addresses

Liquidity sloshing would mint and burn NFTs on every swap, which is gas waste and a poor experience. The contract avoids this by marking pool addresses, the bonding curve, and the deployer as exempt. Exempt addresses skip both the mint-on-receive and the burn-on-send logic. The token side of the transfer still happens normally. The NFT side just does not see it.

Approve ambiguity

ERC-20 and ERC-721 both define a function called approve(address, uint256). ERC-20 returns a bool, ERC-721 returns nothing. The Pandora pattern disambiguates inside the function body. If the uint256 argument matches a known NFT id, the call is treated as an ERC-721 approval. Otherwise it is treated as an ERC-20 allowance set. The function returns bool regardless, which the ERC-721 spec permits because callers ignore the return value.

function approve(address to, uint256 amountOrId) returns (bool) {
    if (amountOrId != 0 && _nftOwner[amountOrId] != address(0)) {
        // ERC-721 approve
    } else {
        // ERC-20 approve
    }
}

Specimen identity

Each NFT id is permanent and unique. Once minted, it keeps its species and the visual seed derived from its id. What changes is the stage, which is computed live at view time from the difference between the current block timestamp and the plant's mintTime. A transfer that triggers a burn truly destroys that id; the next holder of a whole unit will see a fresh id with a new mintTime, not a recycled one.

Cap. III, p. 3
Caput Tertium

The four stages
of growth.

A specimen passes through four stages, decided purely by how long the plant has been continuously held without moving the underlying whole unit. The thresholds are written as constants in the renderer and read by the V4 hook through the token's highestStage(address) view.

StageThresholdTrade feeVisual
No plantbalance < 1 GARDEN3.00%nothing
Seedlingday 0 to 62.00%thin stem, two leaves
Saplingday 6 to 301.25%crooked stem, four leaves
Bloomday 30 to 900.50%flower at the tip, six leaves
Cultivarday 90 and after0.25%gold pollen, eight leaves

The hook reads the oldest plant in the trader's wallet. A holder with one cultivar and ten seedlings will get the cultivar's fee, not an average. This makes the design easy to reason about. If you have held one whole unit for ninety days, you get the floor rate, even on a swap that pushes thousands of new tokens through your wallet.

A note on aging: the clock runs on block timestamps, not blocks. Six days is exactly 518400 seconds. Thirty days is 2592000 seconds. Ninety days is 7776000 seconds. The contract does not store anything per-stage. Stages are derived on the fly, which means the renderer can ship a freshly grown plant on the very block a threshold is crossed without any extra transaction.

Cap. IV, p. 4
Caput Quartum

The bonding
curve.

Half the supply, five thousand GARDEN, is paired with one ETH and seeded into the Uniswap V4 pool at the moment the contract opens. That sets the launch price at 0.0002 ETH per GARDEN. The other half is parked in a separate contract called GardenBondingCurve, where anyone can mint with ETH.

The curve is the simplest one that does the job: a straight line. The marginal price for the next unit when k units have already been sold is:

unitPrice(k) = START_PRICE + k * (END_PRICE - START_PRICE) / CAP

START_PRICE = 0.001 ETH
END_PRICE   = 0.007 ETH
CAP         = 5,000 units

The first GARDEN minted from the curve costs 0.001 ETH, which is five times the pool price. The last GARDEN costs 0.007 ETH, which is thirty-five times the pool price. The average across all five thousand units is 0.004 ETH, so if the curve sells out the protocol has raised about 20 ETH.

Why start above the LP

If the curve started at or below the pool price, the first mover could mint cheap from the curve and immediately dump on the pool for a risk-free profit. The whole curve allocation would drain into the pool, push the pool price down, and the curve would never get past the bottom of its ramp. By starting at 0.001 ETH against a 0.0002 ETH pool, the smallest possible round-trip profit is deeply negative until the pool price climbs five-fold. Arbitrage works in the other direction (pool to curve), which is fine: it just means the two stay in rough sync as the pool rises.

Batch quoting

The cost for buying n units in one call is the sum of an arithmetic sequence. The contract computes it directly without a loop:

quote(n, soldUnits) =
    n * START_PRICE
  + slope / CAP * (n * soldUnits + n * (n-1) / 2)

Any ETH paid above the quote is refunded in the same transaction. Single-call batches are capped at twenty-five units, which is also the per-wallet maximum-tx limit on the main token (more on that in Cap. VI).

Treasury

ETH paid into the curve forwards to a treasury address on every mint. There is no buffer. The treasury defaults to the commander address and can be changed only by the commander. The expected use of those proceeds is later LP top-ups and a small operational reserve. None of this is enforced on chain; the curve is a sales mechanism, not a DAO.

Cap. V, p. 5
Caput Quintum

The Uniswap V4
hook.

Uniswap V4 lets a pool point at a hook contract. The hook is consulted on swap events, and (with the right permission bit) it can override the fee for that swap. Garden uses the beforeSwap permission only.

The permission encoding is done by the deployed address itself, not by a flag stored in state. To get the beforeSwap-only profile, the contract has to live at an address whose low fourteen bits equal 0x0080. The included HookForge deploys via CREATE2 and brute-forces a salt until the predicted address has that exact low-bit pattern.

Fee quoting

On every swap, the hook calls highestStage(trader) on the Garden token and maps the stage to a fee in pips, where one million pips equals one hundred percent:

stage 0  ->  30,000 pips  (3.00%)
stage 1  ->  20,000 pips  (2.00%)
stage 2  ->  12,500 pips  (1.25%)
stage 3  ->   5,000 pips  (0.50%)
stage 4  ->   2,500 pips  (0.25%)

The returned fee is OR-ed with the OVERRIDE_FEE_FLAG that V4 expects, so the pool uses the dynamic value instead of its base. There is also a floor (2,500 pips) below which no future parameter change can push the fee, which is intended to keep LPs whole even after a future governance tweak.

Trader resolution

V4 sometimes delivers swaps through routers, in which case msg.sender at the hook is the router, not the actual gardener. The hook accepts an optional twenty-byte address in the swap's hookData field, and falls back to tx.origin if nothing was hinted. This is the same pattern used in other V4 hooks that need to score the human behind the trade.

Administration

The fee bands and floor are settable by a commander address. The commander can also point the hook at a different Garden contract or hand over the role. None of those actions can lift any band above ten percent or below the floor, which limits the worst-case slippage a holder might face from governance.

Cap. VI, p. 6
Caput Sextum

Anti-whale
guards.

At deployment the token sets two limits. Maximum transaction is 0.25 percent of supply (25 GARDEN). Maximum wallet is 2.0 percent of supply (200 GARDEN). Both are enforced on every transfer between non-exempt addresses. Exempt addresses (LP, curve, deployer) skip both checks.

The limits exist for the first hours after launch, when liquidity is thin and a single large buy could absorb most of the LP. They can be relaxed by the commander but never below 0.1 percent for max-tx and 0.5 percent for max-wallet (a floor enforced in setLimits). They can also be removed entirely once the pool has matured. None of this is on a timelock; the commander can change limits in one transaction.

A second guard, the trading-live gate, blocks transfers between non-exempt addresses until the commander calls openTrading. This is a single-shot flag that cannot be toggled off, only on. It exists so the LP can be seeded and the curve can be funded before any retail trades occur.

Cap. VII, p. 7
Caput Septimum

The on-chain
renderer.

There is no IPFS pin, no off-chain server, no signed metadata. tokenURI(id) goes to the Garden contract, which delegates to GardenRenderer, which builds the JSON metadata and an SVG image entirely in Solidity, base64-encodes the lot, and returns a data URI.

The SVG is small (a few kilobytes per plant) and built from primitive shapes: a cubic-bezier stem perturbed by a seeded random offset, an ellipse per leaf rotated around its anchor, a circle for the bloom, a smaller gold circle for pollen, and a SVG feTurbulence filter that gives every plate a hand-pressed paper grain. The species (eight in total) and color palette are picked deterministically from the token id, so id 17 always looks like id 17 regardless of when it is rendered.

The stage is read from the live mintTime, which means an NFT marketplace that calls tokenURI after every block will see a fresh image when a plant ages over a threshold. There is no rerender transaction. The chain renders the plant in the call.

Species catalogue

LatinCommonPalette
Aetheria glaucinaGlassmoth Vinesage stem, peach bloom
Vitrum solareSun-Glassbright sage, gold bloom
Crinum florensCurving Lilysage stem, peach bloom
Pollinaria nocturnaNightpollendark sage, terracotta bloom
Ferrum cultivareIron Cultivariron grey, ochre bloom
Aurum vesperisEvening Goldsage stem, gold bloom
Susurrum nodosumWhisper-knotsage stem, peach bloom
Vespertina albaPale Eveninglight sage, bone bloom
Cap. VIII, p. 8
Caput Octavum

Risks &
assumptions.

A few things to keep in mind before holding GARDEN.

The commander is a single key

At launch, the commander is a single EOA. It can change fee bands within their bounds, change limits within their floors, set or remove the trading gate (one-way), and hand the role to a different address. It cannot mint new GARDEN, change total supply, change the curve math, drain LP, or unilaterally seize a holder's tokens. The intended migration is to a multisig once the protocol has settled.

Aging requires no action

The clock is on chain. Nothing has to be claimed, refreshed, or signed. The only thing that resets the clock is moving the underlying whole token. A swap that brings new tokens in mints a fresh plant with a fresh clock; the older plants in the wallet are untouched.

Sells burn the newest plant first

When you transfer a fraction that pushes you across a whole-unit boundary, the contract pops the newest NFT from your stack, not the oldest. The oldest plant, the one that earns you the lowest fee, is the most stable in your wallet. You have to drain almost everything to lose your cultivar tier.

The hook is in the address

V4 hook permissions are derived from the deployed address. If the hook ever needs to add an event (say afterSwap), the new contract has to live at a new mined address. A migration is not silent; LPs would have to move to a new pool. The current design uses only beforeSwap, which is enough for the fee mechanic.

This is an experimental token

ERC-404 is not a finalized standard. Dynamic-fee V4 hooks are new. The bonding curve is unaudited at launch. None of this is investment advice; treat it the way you would treat any other small-cap experimental token.

Cap. IX, p. 9
Caput Nonum

Glossarium.

A reference for the terms used throughout this compendium.

GARDEN

The protocol token, ERC-20 with 18 decimals, total supply 10,000.

Specimen

An NFT plant minted to a holder when their whole-token balance crosses a unit boundary upward. Each specimen has its own id, mintTime, and species, all permanent.

Stage

An integer from 0 to 4 (no plant, seedling, sapling, bloom, cultivar), derived from the age of the holder's oldest specimen. Used by the V4 hook to quote a fee.

Curve

GardenBondingCurve, the contract that sells the 5,000 GARDEN of curve allocation in exchange for ETH along a linear price ramp.

Hook

GardenHook, the Uniswap V4 contract that intercepts swaps on the GARDEN/WETH pool and quotes a dynamic fee from the trader's stage.

Commander

The administrative role on the token, the curve, and the hook. Single EOA at launch, intended to move to a multisig.

Exempt

An address flag on the Garden token. Exempt addresses (LP, curve, deployer) skip both NFT mint/burn on transfer and the max-tx/max-wallet limits. This is the technical reason large pools do not accidentally mint thousands of plants.

HookForge

A small CREATE2 deployer that brute-forces a salt until the predicted hook address has the right low-bit pattern for V4 permissions. Run once at deployment.

Set in Italiana for display, Crimson Text for the body, and JetBrains Mono for code and binomials.
Specimens drawn live from an L-system in the browser, and from a Solidity renderer on chain.
Printed at 200dpi on hot-press cotton in three colours: cream, sage, terracotta. No black.
Coll. the curator.