Pre-launch. The protocol is not publicly live yet. This documentation describes the contracts as implemented; deployed addresses are published at launch.

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.

Contract Type

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 payable

Buy lots. Mints token_lots × LOT_SIZE to the caller. If this reaches 800,000 lots, graduation runs in the same transaction.

Value

Must equal quote_buy_price(token_lots)[2] exactly. There is no refund of overpayment.

Reverts
  • "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.value does not match the quote
  • "Insufficient native for graduation" — on the graduating buy
Emits

Buy(buyer, lots, native_sent, base_price, tax), then Graduated(token, deployer) if it graduates

sell(token_lots: uint256) external

Sell lots back to the curve. Burns the tokens and pays out base - tax.

Reverts
  • "Deployer locked" — the deployer can never sell
  • "Not initialized"
  • "Invalid state" — graduated or in refund mode
  • "Below minimum"
  • "Insufficient tokens" — balance below token_lots × LOT_SIZE
  • "Cannot sell at floor" — supply is at 60,000 lots
  • "Insufficient contract balance"
Emits

Sell(seller, lots, native_returned, base_price, tax)

Refund Functions

initiate_refund() external

Open refund mode after the bonding period lapses without graduation. Sends 10% of fees to the protocol and fixes refund_per_lot. Anyone can call.

Reverts
  • "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
Emits

RefundInitiated(refund_per_lot)

refund_claim(token_lots: uint256) external

Burn tokens and claim token_lots × refund_per_lot. Must be called within 604,800 s (7 days) of refund mode opening.

Reverts
  • "Not refund mode"
  • "Refund window closed"
  • "Below minimum"
  • "Deployer cannot refund"
  • "Insufficient tokens"
  • "Insufficient balance"
Emits

RefundClaimed(user, lots, native_received)

sweep_unclaimed_refunds() external

Move the unclaimed remainder to the protocol after the claim window. Anyone can call. Sets FLAG_SWEPT — runs once per curve, terminal.

Reverts
  • "Not refund mode"
  • "Already swept"
  • "Refund window still open"
Emits

RefundsSwept(unclaimed_amount, swept_at)

Initialization

initialize(_token: address, _deployer: address, is_protocol: bool) external payable

Factory 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.

Reverts
  • "Already initialized"
  • "Invalid token" / "Invalid deployer"
  • "Unauthorized" — caller is not the factory
  • "Protocol path sends no fee" / "Incorrect fee"

Quotes

FunctionReturns
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

FunctionReturns
get_supply_lots() -> uint32Current supply in lots
get_sales_balance() -> uint256Contract balance minus collected fees
get_fees_collected() -> uint80Accumulated tax
get_user_token_balance(user) -> uint256A user's holdings in lots
is_graduated() -> boolFLAG_GRADUATED
is_refund_mode() -> boolFLAG_REFUND_MODE
is_protocol_curve() -> boolFLAG_PROTOCOL
is_swept() -> boolFLAG_SWEPT
refund_claim_deadline() -> uint256Unix timestamp claiming closes, or 0 if not refunding
refund_per_lot() -> uint256Fixed payout rate per lot
token() -> addressPaired token
deployer() -> addressCurve deployer
state() -> PackedState(flags, current_supply_lots, deployment_timestamp, fees_collected, refund_initiated_timestamp)

State Flags

FlagBitMeaning
FLAG_INITIALIZED2Curve is live
FLAG_GRADUATED4Graduated to DEX
FLAG_REFUND_MODE8Refunds open
FLAG_PROTOCOL16Protocol curve — cannot refund
FLAG_SWEPT32Unclaimed refunds swept — terminal