Bonding Curves
Every Superhero community token is priced by one deterministic function of its own supply. Buying mints new tokens and moves you up the curve; selling burns tokens and moves you down it. Because price is computed from supply, there is always a quote and always liquidity. There is no order book, no matching engine and no counterparty on the other side of your trade.
Superhero uses an exponential curve, implemented by the BondingCurveExponential contract. The
contract evaluates e^x as a bounded Taylor series in integer arithmetic (at most 100 terms,
stopping as soon as a term floors to zero), which is what curve_type() means when it returns
"TAYLOR_EXPONENTIAL_V1". The series agrees with the closed form below to within 4e-19 AE at
every supply in the examples below. The integer the contract returns is the price you are charged;
Curve Parameters & Units has a reference implementation that reproduces
it exactly.
The formulas
buy(x) = 0.001 · e^(0.00000001 · x) − 0.0009999
sell(x) = buy(x) · 0.995x is the circulating supply in whole tokens; the result is the instantaneous (spot) price in AE
per token at that supply. Three constants do all the work:
| Constant | Value | Stored on-chain as | Role |
|---|---|---|---|
a | 0.001 | a = 10^15 | Scale factor on the exponential |
k | 0.00000001 (1e-8) | k = 10^10 | Growth rate per token of supply |
c | 0.0009999 | not stored | Offset that pulls the launch price down to a near-zero number |
The contract holds a and k scaled by 10^18, plus initial_price = 10^11, the spot price at
supply zero, 0.0000001 AE. The offset c is a − initial_price and is never stored. See
Curve Parameters & Units for the full constant table.
At supply 0 the spot price is 0.001 − 0.0009999 = 0.0000001 AE, one ten-millionth of an AE per
token. The curve is almost flat at the start and steep later.
What you pay is never the spot price. It is the integral of the curve across the range of supply you are minting into:
buy price = ∫ from supply to (supply + amount) of buy(x) dx
sell return = ∫ from (supply − amount) to supply of sell(x) dxThe spread (the community DAO's share) is the area between the two curves:
spread = ∫ from 0 to supply of buy(x) dx − ∫ from 0 to supply of sell(x) dxIntegrating the curve
For F'(x) = a·e^(k·x) − c:
F(x) = (a / k) · e^(k · x) − c · x
with a = 0.001, k = 0.00000001, c = 0.0009999:
a / k = 0.001 / 0.00000001 = 100000
F(x) = 100000 · e^(0.00000001 · x) − 0.0009999 · xSo the cost of buying n tokens starting from supply S is:
cost(S, n) = F(S + n) − F(S)
= 100000 · ( e^(0.00000001·(S+n)) − e^(0.00000001·S) ) − 0.0009999 · nThat is the whole pricing model. Everything below is arithmetic on this one line.
Worked example 1: 1,000 tokens at supply 0
cost(0, 1000) = 100000 · ( e^(0.00000001 · 1000) − e^0 ) − 0.0009999 · 1000
= 100000 · ( e^0.00001 − 1 ) − 0.9999
e^0.00001 = 1.000010000050000166667…
e^0.00001 − 1 = 0.000010000050000166667…
× 100000 = 1.0000050000166667…
− 0.9999 = 0.0001050000166667…
cost = 0.000105000017 AE (about 0.000105 AE)The average price paid is 0.000105000017 / 1000 = 1.05000017e-7 AE per token, against a spot
price of 1.0e-7 AE when you started. You paid 5.00% above spot for a thousand tokens, because
by the thousandth token the spot price had already risen to 1.10e-7 AE.
Worked example 2: 1,000 tokens at supply 10,000,000
cost(10000000, 1000)
= 100000 · ( e^(0.00000001 · 10001000) − e^(0.00000001 · 10000000) ) − 0.9999
= 100000 · ( e^0.10001 − e^0.1 ) − 0.9999
e^0.1 = 1.10517091807564762481…
e^0.10001 = 1.10518196984008711139…
difference = 0.00001105176444865756…
× 100000 = 1.10517644394865756…
− 0.9999 = 0.10527644394865756…
cost = 0.105276443949 AEThe same thousand tokens now cost 0.10528 AE instead of 0.000105 AE, about 1,003 times more.
Average price 1.052764e-4 AE, spot price at supply 10,000,000 1.052709e-4 AE: this time you
paid only 0.0052% above spot.
The same trade size is proportionally far more expensive near supply zero than deep into the
curve. Near zero, the −0.0009999 offset has cancelled almost all of 0.001·e^(kx), so the tiny
residual price doubles over a very short span of supply. Further out, the offset is negligible and
the curve is locally almost linear, so a thousand tokens barely move it.
Curve slippage
You are charged the area under a rising curve, but the quoted spot price is only its height at the
left-hand edge. The bigger the trade, the worse your average fill. All of these are buys starting
from supply 10,000,000, where spot is 1.052709e-4 AE:
| Tokens bought | Total AE cost | Average price (AE) | Average vs spot |
|---|---|---|---|
| 1,000 | 0.105276 | 1.05276e-4 | +0.0052% |
| 100,000 | 10.582369 | 1.05824e-4 | +0.525% |
| 1,000,000 | 110.815238 | 1.10815e-4 | +5.267% |
| 10,000,000 | 1,624.184008 | 1.62418e-4 | +54.29% |
| 50,000,000 | 21,699.788231 | 4.33996e-4 | +312.3% |
Buying 10,000,000 tokens in one transaction doubles the supply and costs a 54% premium to spot. Splitting the order does not help: the curve is path-independent, so ten buys of 1,000,000 from a rising supply cost exactly the same total as one buy of 10,000,000. Only trade size and starting supply change your average price.
A large sell realises an average price below the quoted spot for the same reason, in reverse.
minimal_return_required protects you from that. See
Buying & Selling.
Shape of the curve
Both curves over the first 100 million tokens of supply, with # the buy curve and . the sell
curve where it separates:
price (AE per token)
1.72e-03 | ##
| ##.
| ###
1.37e-03 | ##.
| ###
| ###
1.03e-03 | ###
| ###
| ####
6.87e-04 | ####
| ####
| ####
3.44e-04 | #####
| #####
| #####
0.00e+00 |####
+--------------------------------------------------------
0 25M 50M 75M 100M
supply (tokens)The sell curve sits 0.5% below the buy curve everywhere. The gap between them is the DAO's cut: small per trade, meaningful in aggregate. Spot prices at a few reference supplies:
| Supply | Buy spot (AE) | Sell spot (AE) |
|---|---|---|
| 0 | 1.000000e-7 | 9.950000e-8 |
| 1,000,000 | 1.015017e-5 | 1.009942e-5 |
| 10,000,000 | 1.052709e-4 | 1.047446e-4 |
| 50,000,000 | 6.488213e-4 | 6.455772e-4 |
| 100,000,000 | 1.718382e-3 | 1.709790e-3 |
| 200,000,000 | 6.389156e-3 | 6.357210e-3 |
The curve is tuned on the expectation that only 10–20% of the total supply will ever be reached, which is why the interesting price action is packed into the first couple of hundred million tokens.
Why the reserve is always solvent
The sell curve sits strictly below the buy curve at every supply level, so the AE paid into the sale contract always exceeds the AE it could ever be asked to pay out. Selling the entire circulating supply back to the curve is always possible.
At a supply of 10,000,000 tokens, buyers have paid in 518.09 AE in total, and selling every one of
those tokens back would return 515.50 AE. The 2.59 AE difference is the DAO's accumulated
spread, and it never has to be given back.
The spread
The sell() curve returns 99.5% of buy(), and the sale contract adds a 0.5% affiliation fee on
buys, so the total spread between buy and sell price is 1% of the curve value: 0.5% to the
community DAO and 0.5% to the affiliation system.
From the buyer's side: you hand over 1.005 × the curve integral and can immediately sell back for
0.995 × it, so a round trip at unchanged supply returns 0.995 / 1.005 = 0.99502… of what you
paid, a 0.995% loss on an instant round trip. See Fees & Slippage
for the full breakdown and Risks for what that means for a position.
Compared with other curve families
| Property | Superhero (exponential) | Linear curve | Constant product (Uniswap-style) |
|---|---|---|---|
| Price rule | price = a·e^(k·supply) − c | price = m·supply + b | price = reserve_y / reserve_x, with x·y = k |
| What backs it | AE reserve accumulated from buys | AE reserve accumulated from buys | Two-sided pool funded by liquidity providers |
| Who supplies liquidity | Nobody: the contract mints and burns | Nobody | Liquidity providers, who can withdraw |
| Supply | Elastic: minted on buy, burned on sell | Elastic | Fixed; the pool only swaps existing tokens |
| Price at zero activity | Defined by the formula | Defined by the formula | Undefined until someone seeds the pool |
| Cost of a trade | Integral of the curve over the minted range | Integral of the curve over the minted range | Determined by the invariant x·y = k |
| Price impact of a big buy | Compounding: grows exponentially | Proportional to size | Grows as the pool is drained; unbounded |
| Fee model | 1% spread baked into two curves | Implementation-defined | Explicit swap fee (e.g. 0.30%) to LPs |
| Rug-pull surface | No LP to withdraw | No LP to withdraw | LPs can remove liquidity |
Two practical consequences. There is no liquidity to pull: the reserve is held by the sale contract
and is sufficient to redeem everything. And an exponential curve punishes large late buys much
harder than a constant-product pool of comparable depth. The price impact of doubling the supply
is a factor of e^(k·supply), not a bounded ratio.
Community tokens trade only against their own curve. Superhero's AMM for ordinary token pairs is the DEX.
Reading the curve from the contract
| Entrypoint | Returns |
|---|---|
calculate_buy_price(total_supply, count) | Cost to buy count tokens from total_supply, in aettos |
calculate_sell_return(total_supply, sell_tokens) | AE returned for selling sell_tokens, in aettos |
buy_curve(x) / sell_curve(x) | The spot curve value as a Frac.frac rational |
buy_price(total_supply) / sell_price(total_supply) | The same value rounded to an integer (see below) |
get_k(), get_initial_price(), get_minimum_count() | 10^10, 10^11, 10^12 |
get_sell_return_percentage() | 9950; the sell factor is 9950 / 10000 = 0.995 |
curve_type(), supported_decimals() | "TAYLOR_EXPONENTIAL_V1", 18 |
Every one of these takes and returns integers in the contract's own units. Read Curve Parameters & Units before calling them. Passing whole tokens where the contract expects 18-decimal units gives an answer that is wrong by a factor of 10^18.
buy_price() and sell_price() round a value like 1.05e-4 AE per token to an integer, so
buy_price() returns 1 and sell_price() returns 0 for every supply under roughly 690 million
tokens. Use calculate_buy_price and calculate_sell_return for quotes, or buy_curve for the
exact spot value.
get_minimum_count() returns 10^12, and every pricing call requires count >= minimum_count
(MINIMUM_TOKENS_REQUIRED). Since counts are in 18-decimal units that floor is 10^-6 tokens, a
guard against a trade rounding to zero inside the integer arithmetic, not an order minimum. It fires
when a caller passes a whole-token count where the contract expected token decimal units.
Related
- Curve Parameters & Units: the decimals, fixed-point and
Frac.fracconventions you need before calling any entrypoint above - Fees & Slippage: the 1% spread, the affiliation split and the slippage guards
- Buying & Selling: how to execute against the curve and defend a sell with
minimal_return_required - Bonding curve contract reference: the entrypoint-level reference for
BondingCurveExponential - Risks: what the curve's shape means for a position you hold
- Bonding Curves Explained (opens in a new tab): background on the general mechanism