BondingCurveTemplate
Curve trading, pricing, graduation trigger and the refund system. Deployed as a minimal proxy, one per token. Native-denominated; the logic is identical on every chain.
Minimal proxy (EIP-1167). Initialized once by the factory. No owner. Holds no per-user storage — user positions are read from the token contract.
Trading
buy(token_lots: uint256) external payableBuy lots. Mints token_lots × LOT_SIZE to the caller. If this reaches 800,000 lots, graduation runs in the same transaction.
Must equal quote_buy_price(token_lots)[2] exactly. There is no refund of overpayment.
"Below minimum"— fewer than 1 lot"Not initialized""Invalid state"— already graduated or in refund mode"Supply exceeded"— would push past 800,000 lots"User limit exceeded"— post-trade balance above 36,000 lots"Incorrect payment"—msg.valuedoes not match the quote"Insufficient native for graduation"— on the graduating buy
Buy(buyer, lots, native_sent, base_price, tax), then Graduated(token, deployer) if it graduates
sell(token_lots: uint256) externalSell lots back to the curve. Burns the tokens and pays out base - tax.
"Deployer locked"— the deployer can never sell"Not initialized""Invalid state"— graduated or in refund mode"Below minimum""Insufficient tokens"— balance belowtoken_lots × LOT_SIZE"Cannot sell at floor"— supply is at 60,000 lots"Insufficient contract balance"
Sell(seller, lots, native_returned, base_price, tax)
Refund Functions
initiate_refund() externalOpen refund mode after the bonding period lapses without graduation. Sends 10% of fees to the protocol and fixes refund_per_lot. Anyone can call.
"Protocol curve cannot refund""Period not over"— less than 259,200 s (3 days) elapsed"Invalid state"— already graduated or refunding"No refunds"— zero balance or no eligible lots
RefundInitiated(refund_per_lot)
refund_claim(token_lots: uint256) externalBurn tokens and claim token_lots × refund_per_lot. Must be called within 604,800 s (7 days) of refund mode opening.
"Not refund mode""Refund window closed""Below minimum""Deployer cannot refund""Insufficient tokens""Insufficient balance"
RefundClaimed(user, lots, native_received)
sweep_unclaimed_refunds() externalMove the unclaimed remainder to the protocol after the claim window. Anyone can call. Sets FLAG_SWEPT — runs once per curve, terminal.
"Not refund mode""Already swept""Refund window still open"
RefundsSwept(unclaimed_amount, swept_at)
Initialization
initialize(_token: address, _deployer: address, is_protocol: bool) external payableFactory only. is_protocol=True sets FLAG_PROTOCOL and requires zero value; is_protocol=False requires exactly DEPLOYER_INITIAL_PAYMENT.
On Gnosis this also calls GraduationManager.preInitializePool(token), initializing the V3 pool atomically with deployment.
"Already initialized""Invalid token"/"Invalid deployer""Unauthorized"— caller is not the factory"Protocol path sends no fee"/"Incorrect fee"
Quotes
| Function | Returns |
|---|---|
quote_buy_price(token_lots) | (base, tax, total) — send total with buy() |
quote_sell_price(token_lots) | (base, tax, proceeds) — you receive proceeds |
View Functions
| Function | Returns |
|---|---|
get_supply_lots() -> uint32 | Current supply in lots |
get_sales_balance() -> uint256 | Contract balance minus collected fees |
get_fees_collected() -> uint80 | Accumulated tax |
get_user_token_balance(user) -> uint256 | A user's holdings in lots |
is_graduated() -> bool | FLAG_GRADUATED |
is_refund_mode() -> bool | FLAG_REFUND_MODE |
is_protocol_curve() -> bool | FLAG_PROTOCOL |
is_swept() -> bool | FLAG_SWEPT |
refund_claim_deadline() -> uint256 | Unix timestamp claiming closes, or 0 if not refunding |
refund_per_lot() -> uint256 | Fixed payout rate per lot |
token() -> address | Paired token |
deployer() -> address | Curve deployer |
state() -> PackedState | (flags, current_supply_lots, deployment_timestamp, fees_collected, refund_initiated_timestamp) |
State Flags
| Flag | Bit | Meaning |
|---|---|---|
FLAG_INITIALIZED | 2 | Curve is live |
FLAG_GRADUATED | 4 | Graduated to DEX |
FLAG_REFUND_MODE | 8 | Refunds open |
FLAG_PROTOCOL | 16 | Protocol curve — cannot refund |
FLAG_SWEPT | 32 | Unclaimed refunds swept — terminal |