bait// the feedingwhitepaper
robinhood chain

bait

whitepaper 1.0
robinhood chain · uniswap v4 hook bonding curve

bait

a uniswap v4 hook that owns its pool, prices its token along an exponential curve, and answers to nobody.

bait is a small contract experiment on the sepolia testnet: an exponential bonding curve implemented as a uniswap v4 hook, with a deeper scale parameter so the implied terminal valuation is on the order of one billion dollars at typical eth prices. fees compound into ethCum rather than being withdrawable, and fair minted supply is derived live from that accumulator.

this document explains what bait is, why it is shaped the way it is, and what it does not do.

compared to sat0

public sat0-class curves did the hard work of proving the uniswap v4 hook pattern and compounding fees back into curve state, but they were not ambitious enough on economics: a tight S keeps the terminal valuation in "interesting" territory instead of forcing the mechanism to mean something at global scale, and the story stops at a clever demo rather than at a sink sized for serious long-term flow. bait is the same family of constraints — hook is sole issuer, no admin, no rescue — with the curve deepened so the asymptote lines up with billions in implied market cap, and with the on-chain manifesto stating that design intent bluntly, ending where the law of the hook meets the phrase billions is programmed.

1. motivation

ethereum has spent ten years routing trades through automatic market makers that share a common pattern: a passive pool of two reserves, an invariant that ties their product, and a fee that compensates whoever donated those reserves. liquidity is a service, and the service is paid for.

bonding curves invert that arrangement. there is no reserve donor. the contract itself is the counterparty. when somebody mints, the curve dictates the new price and creates the tokens directly; when somebody burns, the curve refunds eth out of the same pool. the contract publishes a price function, an issuance function, and an explicit terminal supply, and then refuses to accept any other instructions for the rest of its life.

uniswap v4 hooks make this style of token native to the most-used dex on ethereum. the hook can take over the pool entirely with a beforeSwap returning a delta — replacing the constant-product invariant with whatever math it wants, while still letting wallets and aggregators see the asset as a normal v4 pool.

bait uses that capability to publish exactly two operations:

  • mint: send eth, receive bait at the current marginal price along an exponential curve.
  • burn: send bait, receive eth from the curve at the current marginal price minus a fixed fee.

there is no setOwner, no pause, no withdrawFees, no rescueTokens. the only privileged call on the token contract is the one-shot setMinter performed during deployment, after which the minter slot is locked forever to the hook address.

2. the curve

the price function is exponential in the cumulative eth that has ever been spent into the curve:

price(ethCum) = (S / K) * exp(ethCum / S)

and the inverse — the total supply that has been minted at a given level of ethCum — is

minted(ethCum) = K * (1 - exp(-ethCum / S))

two constants govern its shape:

  • K is the asymptote: the maximum supply the curve approaches as ethCum → ∞. bait fixes K = 21,000,000 tokens.
  • S is the scale of the curve: the eth that has to flow through it to mint roughly 63% of K. a common earlier choice in public writeups is S = 500 eth (terminal valuation in the low nine figures in usd terms). bait sets S = 5,000 eth, which deepens the curve so its terminal price implies a market cap close to one billion dollars at typical eth prices.

a deeper curve buys two things and gives up one. it buys (a) much higher terminal valuation, and (b) a flatter price impact for any given mint size, so individual buys move the price less. it gives up early-stage scarcity: the first buyer pays less, in eth-per-token, than they would on a tighter curve.

selfdeprecation

since the curve never reaches K, bait imposes a hard cap on ethCum at 99% of K:

depCap = S * ln(100)  ≈  23,025.85 eth

after ethCum crosses that threshold, selfDeprecated latches to true and all future mints revert. burns continue to work — anyone holding bait can still cash out — but the supply does not grow further. this halt is often called self-deprecation in writeups about this style of curve: stop pretending the asymptote is reachable, and let the contract retire on a clean public number.

3. fee model

every swap pays $30$ basis points (0.3%). the fee is taken from the output side of the swap:

  • on mint, the curve is moved by the gross eth received, but the user receives only $99.7%$ of the curve's quoted token amount.
  • on burn, the curve is moved by the gross tokens burnt, but the user receives only $99.7%$ of the curve's quoted eth amount.

importantly, the contract does not transfer the fee anywhere. the fee compounds into ethCum. nothing accumulates in a feeRecipient; nothing waits in a pendingWithdrawals mapping. compounding fees into the curve state rather than skimming them to an admin is a refinement seen in later public deployments of this pattern; bait uses it for two reasons:

  1. there is no privileged role with a claim on the fees — there is no admin to withdraw them, so they cannot disappear.
  2. the fees behave like a small, pro-rated contribution to the curve's price: every swap nudges the marginal price up slightly, regardless of direction. this rewards holders by making each subsequent mint pay them.

a useful equality follows: the contract's eth balance equals the cumulative net flow into the curve, while ethCum equals that balance plus all fees ever paid. you can therefore read the total burnt-fee figure off-chain as ethCum − Σ(buy.ethIn) + Σ(sell.ethOut).

4. implementation

three contracts plus three peripherals:

| contract | what it does | |----------|-------------| | BaitToken | a standard ERC-20 with a one-shot setMinter. once the minter is set to the hook, no further setMinter calls succeed. only the minter can mint or burn. | | BaitHook | a uniswap v4 IHooks implementation. owns the pool. beforeSwap consumes the ETH/bait swap, computes the curve quote, settles deltas with the PoolManager, mints or burns, and updates ethCum. | | BaitSwapRouter | a thin user-facing entrypoint. unlocks the PoolManager, forwards the swap, and packs msg.sender into hookData so the hook can apply per-account rules (notably the one-block sell cooldown after a mint). | | BaitFaucet | a one-claim-per-address dispenser, seeded by an initial mint+transfer. used on the testnet only. | | BaitManifest | an immutable on-chain registry of all contract addresses, the genesis block, the manifesto string, and the canonical website url. so the wallet/explorer integration story stays clean. | | Curve | a pure library that implements the math above using prb-math's UD60x18 for exp/ln. |

swap flow

user → BaitSwapRouter.buy{value: x}(minOut)
    → PoolManager.unlock(callback)
        ← unlockCallback receives delta-bookkeeping
            → settle x ETH into the PoolManager
            → PoolManager.swap(zeroForOne=true, amountSpecified=-x, hookData=msg.sender)
                ← BaitHook.beforeSwap (decodes swapper from hookData)
                    → compute tokensOut from current ethCum and x
                    → take fee from tokensOut → user mint amount
                    → PoolManager.mint(BAIT_CURRENCY, …) for the user delta
                    → BaitToken.mint(swapper, tokensOut)
                    → ethCum += x
            → take tokensOut to user, return remaining deltas

burns are the mirror image, with one extra rule: a swapper who minted in this same block is rejected with CooldownActive. that single-block delay is the simplest defense against atomic mint-then-burn extraction of the entropy-window noise.

entropy window

for the first 100 blocks after deployment, the hook adds a small deterministic noise term to the mint output, derived from block.prevrandao xor'd with the previous blockhash. the noise is bounded to roughly ±10% and is meant only to disincentivize same-block sniping in the moment when the curve is most price-sensitive. after the window, the curve is purely deterministic.

5. what bait is not

  • not audited. the contracts are tested (unit, fuzz, invariant, fork-mainnet integration), but no third party has reviewed them. do not put real money in.
  • not on mainnet. addresses below are all sepolia. the deployment scripts can target mainnet but have not been pointed at it.
  • not affiliated with any other token or team. bait is its own deployment on sepolia. nothing here is an endorsement of, or by, any third party.
  • not a security. bait has no team, no roadmap, no promises. minting it gives you exactly one thing: the right to burn it back along the same curve.

6. risks (non-exhaustive)

  • bugs in the curve library, the hook, the router, or any of their dependencies (v4-core, prb-math, openzeppelin-contracts).
  • mev: large mints in public mempools may be sandwiched. consider a private rpc or an mev-protected route.
  • rpc dependence for the frontend's analytics. all "24h" stats and the holder count are computed in the browser from eth_getLogs. if your rpc rate-limits or doesn't support multi-thousand-block windows, the page will degrade quietly.
  • testnet eth has no value and the underlying chainlink eth/usd feed on sepolia tracks mainnet eth — usd numbers shown are real-world prices, not testnet prices. valuations on this site are illustrative.

7. references

  1. uniswap v4 — IHooks, BeforeSwapDelta, and the lock/unlock mechanism: docs.uniswap.org
  2. prb-math: signed/unsigned 60.18 fixed-point math for solidity.
  3. related public writeups (for comparison only, not affiliation): sat0 whitepaper, sat1 whitepaper