Where the Money Goes
Every AE that enters a community token trade ends up in one of four places: the bonding curve reserve, the community's DAO treasury, the affiliation chain, or the network as gas. This page gives the full accounting, on both sides of a trade.
The buy side
On every community-token buy:
Buyer pays AE
├── 99.0% → Bonding curve reserve (redeemable by sellers)
├── 0.5% → Community DAO treasury (governed by token holders)
└── 0.5% → Affiliation system
├── 0.300% → Level 1 referrer
├── 0.125% → Level 2 referrer
├── 0.050% → Level 3 referrer
└── 0.025% → Level 4 referrer
(if no referrer: burned)
Buyer also receives:
└── ProtocolDAO tokens = 1,000 × AE value of the buyThe 1% total spread is the difference between the buy curve and the sell curve. It is not charged as a separate fee; it is built into the two curves. See Bonding Curves for the math.
The exact split
Write C for the curve cost of the slice you are buying: the integral of the buy curve from the
current supply to the supply after your purchase:
C = integral of buy(x) dx, from supply to supply + amount
where buy(x) = 0.001 * e^(0.00000001 * x) - 0.0009999The contract evaluates this curve as a Maclaurin expansion of e^x in integer arithmetic
(curve_type() returns "TAYLOR_EXPONENTIAL_V1"), terminating at 100 terms or when a term rounds
to zero:
function exp_helper(x : int, term : int, sum : int, i : int, scale : int) : int =
if (i > 100 || term < 1) sum
else
let next_term = (term * x) / (i * scale)
exp_helper(x, next_term, sum + next_term, i + 1, scale)The series matches the closed form to well below one aetto per token. Use the closed form to
reason about the shape; use price(count) when a number has to be exact.
The sell curve is sell(x) = buy(x) * 0.995, and that 0.5% gap funds the DAO. The sale contract adds
a further 0.5% affiliation fee on top of the curve price, so the total spread between buy and
sell price is 1%.
price(count) is the all-in figure, fee included. It is the number you quote against:
entrypoint price(count : int) : int =
require(count > 0, "COUNT_NOT_POSITIVE")
let bonding_curve_price = state.bonding_curve.calculate_buy_price(state.token_contract.total_supply(), count)
let affiliation_amount = affiliation_amount(bonding_curve_price)
bonding_curve_price + affiliation_amountprice(n) already equals 1.005 * C; do not multiply it by 1.005 again. buy uses the same
arithmetic and requires Call.value >= total_price, refunding any excess with
Chain.spend(Call.caller, overpaid_refund). That is why the agent CLI can attach price * 1.03
and get the difference back.
The affiliation fee rate is read from the treasury at call time: get_affiliation_fee_percentage()
returns 500 and get_affiliation_fee_precision() returns 10^5, so 500 / 100,000 = 0.5%.
The buyer's gross is 1.005 * C, and it splits exactly:
| Destination | Amount | Share of what the buyer pays |
|---|---|---|
| Bonding curve reserve | 0.995 * C | 99.005% |
| Community DAO treasury | 0.005 * C | 0.4975% |
| Affiliation chain (or burned) | 0.005 * C | 0.4975% |
| Total | 1.005 * C | 100% |
0.995 + 0.005 + 0.005 = 1.005, with no remainder. The 99.0 / 0.5 / 0.5 figures above are this
split rounded to one decimal place.
The four affiliation levels are percentages of the transaction value, not of the fee, which is
why they sum to 0.5% rather than to 100%. The transaction value handed to the treasury is C, the
bare curve price, so level 1 receives 0.300% of C, not of 1.005 * C.
How the split is executed
buy_with_affiliation_inner moves the money in this order:
| Step | Call | Amount |
|---|---|---|
| 1 | affiliation_treasury.record_sale_transaction(...) | affiliation_amount = 0.005 * C |
| 2 | Chain.spend(Call.caller, overpaid_refund) | whatever you attached above 1.005 * C |
| 3 | token_contract.mint(Call.caller, count) | your tokens |
| 4 | factory.mint_protocol_dao_token(Call.value - overpaid_refund, Call.caller) | ProtocolDAO tokens |
| 5 | dao_contract.record_sale_transaction(...) | Call.value - overpaid_refund - affiliation_amount - reserve |
The DAO's cut in step 5 is a residual, not a percentage. reserve is
calculate_sell_return(total_supply_after_mint, count), which is 0.995 * C: exactly what a
seller of that same slice could immediately redeem. Subtracting it and the affiliation fee from
1.005 * C leaves 0.005 * C for the DAO. The sale contract keeps precisely the sell-side
obligation and forwards the rest, which is what makes the solvency guarantee structural.
Both treasury calls are made with protected = true, so a failure in the DAO or the affiliation
treasury cannot block a buy.
The sell side
Selling is not the buy flow in reverse.
It is two transactions, not one. AEX-9 has no transfer-from without prior approval, so you first grant the sale contract an allowance over your tokens, then call sell:
1. create_allowance(sale_account, count) on the community AEX-9 token
(or change_allowance(sale_account, delta) if an allowance already exists)
2. sell(count, minimal_return_required) on the token sale contractminimal_return_required is your slippage floor: if the curve has moved against you between quote
and execution, the call reverts rather than paying out less. The web app shows the two steps as a
progress indicator; the agent CLI runs them back to back. The allowance is granted to the sale
contract's address rewritten from ct_ to ak_ form.
The payout is the sell-curve integral. Quote it before you sign with the read-only
sell_return(count) entrypoint on the sale contract:
return = integral of sell(x) dx, from supply - amount to supply
= 0.995 * (integral of buy(x) dx over the same interval)Nothing is deducted at sell time.
| Destination on a sell | Amount |
|---|---|
| Seller | the full sell_return(count) payout |
| Community DAO treasury | nothing |
| Affiliation chain | nothing |
| ProtocolDAO tokens minted | none |
The 0.5% gap relative to the buy curve is not a sell fee. It was taken when those tokens were
bought. The reserve grows by 0.995 * C per buy, which is exactly the sell-curve integral over the
same slice, so the reserve at supply S is always integral of sell(x) from 0 to S: precisely
enough to redeem the entire supply. Selling the entire supply back to the curve is always possible.
Your tokens are burned. Community tokens are minted on buy and burned on sell; the token
contract's Burn event on the sell receipt carries the amount destroyed.
sell does five things, in order:
- Reads
total_supplyand the current unit price. return = bonding_curve.calculate_sell_return(total_supply, count).require(return >= minimal_return_required, "MINIMAL_RETURN_NOT_MEET").token_contract.transfer_allowance(Call.caller, Contract.address, count)thentoken_contract.burn(count).Chain.spend(Call.caller, return), then emitsPriceChangeandSell.
The minimum tradable amount is enforced one level down: calculate_price requires
count >= minimum_count, where minimum_count is 10^12 aettos (10^-6 tokens).
The sale contract's trading entrypoints:
| Entrypoint | Signature | Notes |
|---|---|---|
sell_return | sell_return(count: int) -> int | Read-only quote |
sell | sell(count: int, minimal_return_required: int) -> int | Stateful, not payable, returns the AE paid out |
price | price(count: int) -> int | The buy-side counterpart |
buy | buy(count: int) -> unit | Stateful, payable |
buy_with_affiliation | buy_with_affiliation(count: int, affiliation_rewardee: address) -> unit | Stateful, payable |
There is a buy_with_affiliation and no sell_with_affiliation: referral rewards accrue on buys
only. Likewise the factory's mint_protocol_dao_token(int, address) is called on buys only. See
the contract reference.
Event arguments
| Event | Argument 0 | Argument 1 | Argument 2 |
|---|---|---|---|
Buy | total_price: all-in AE, fee included | affiliation_amount | total_supply before the mint |
Sell | return: AE paid to the seller | total_supply before the burn | n/a |
PriceChange | previous_price | next_price | n/a |
Buy and Sell omit count; take the token amount from the decoded call arguments, not the
event. Both unit prices in PriceChange come from calculate_unit_price(), which is price(10^18):
the all-in cost of one whole token at that moment, affiliation fee included.
A worked example
A token at supply zero. You buy a slice worth 10 AE of curve cost, which on this curve is about 1,400,993 tokens.
| Line | Amount |
|---|---|
Curve cost C | 10.000 AE |
Affiliation fee added on top (0.5% of C) | 0.050 AE |
| You send | 10.050 AE (plus gas) |
| → bonding curve reserve | 9.950 AE |
| → community DAO treasury | 0.050 AE |
| → affiliation chain | 0.050 AE |
| You receive | ≈ 1,400,993 tokens |
If your buy is attributed to a referrer, that 0.050 AE splits down the invite chain:
| Level | Rate on the 10 AE transaction value | Amount |
|---|---|---|
| 1 | 0.300% | 0.0300 AE |
| 2 | 0.125% | 0.0125 AE |
| 3 | 0.050% | 0.0050 AE |
| 4 | 0.025% | 0.0025 AE |
| Total | 0.500% | 0.0500 AE |
A level that does not exist (nobody invited your inviter) contributes nothing to anyone.
Now sell all 1,400,993 tokens straight back, before anyone else trades:
| Line | Amount |
|---|---|
| Curve value of the slice | 10.000 AE |
| Sell curve factor | × 0.995 |
| You receive | 9.950 AE (minus gas, on two transactions) |
Round trip: you paid 10.050 AE and got back 9.950 AE. The 0.100 AE difference is 0.995% of what you sent: the 1% spread, all of it collected on the way in. Gas is extra, and a sell costs two transactions' worth of it.
Slippage
None of the figures above account for other people trading between your quote and your transaction. That is what slippage protection is for, and the three clients default differently:
| Client | Default tolerance | Mechanism |
|---|---|---|
| Web app, community token trade card | 1% | Stored as tokenTrade:slippage, editable in the trade card |
| Web app, DEX swap | 5% | Stored as dex:slippage |
Agent CLI (superhero-token-swap.mjs) | 3% | Buy sends price * 1.03; sell passes sell_return * 0.97 as minimal_return_required |
On a buy, the tolerance is the extra AE you are willing to attach; unused AE is refunded, but treat the tolerance as a ceiling on your cost. On a sell it is a hard floor: the transaction reverts rather than executing below it. See Fees & Slippage.
Gas
Gas is a separate line item paid to the network in AE, never to Superhero, and never recoverable. Count transactions, not trades:
| Action | Transactions |
|---|---|
| Post or comment | 1 |
| Buy a token | 1 |
| Sell a token | 2: allowance, then sell |
| Create a token | 1 (deploys token, curve, sale, DAO and management contracts together) |
| Open a DAO vote | 1, plus a 555 AE payment to the DAO |
| Create a governance poll | 2: deploy, then register |
| Claim rewards | 1; a small gas fee applies |
Gas for every transaction follows the network's gas price at execution; æScan (opens in a new tab) shows the fee paid on each transaction.
What "burned" means
When a buyer has no inviter, the affiliation portion is burned. Mechanically, this is retention in a contract with no withdrawal path, not a transfer to an unspendable address.
The sale contract forwards the fee as Call.value on record_sale_transaction, so the AE lands in
the treasury's balance. update_inviters then walks the affiliation tree upward, crediting
payout_periods[period][inviter] at 300, 125, 50 and 25 parts in 100,000 for levels 1 to 4. When a
level does not exist, get_direct_inviter returns None and the recursion stops:
switch(get_direct_inviter(invitee))
None => ()
Some(inviter) =>
update_inviter_balance(inviter, (transaction_value * affiliation_percentage) / affiliation_fee_precision)
update_inviters(inviter, buyer, transaction_value, remaining_affiliation_fee_percentages)No entry is credited for a missing level. The only way AE leaves the treasury is withdraw(),
which pays get_accumulated_rewards(Call.caller), the sum of that caller's own ledger entries.
There is no owner, no admin entrypoint and no sweep, so uncredited AE stays in the contract balance
permanently. (Creating a collection, by contrast, sends its 555 AE fee to the burn address
ak_11111111111111111111111111111111273Yts.)
Two further amounts burn the same way, both consequences of withdraw():
- Rewards older than two payout periods.
get_accumulated_rewardssums only the current period and the one before it. A payout period isChain.timestamp / 2592000000(30 days in milliseconds), so anything credited more than roughly 30 to 60 days ago can no longer be withdrawn. - Rewards belonging to an inviter who has not qualified.
withdraw()requiresstate.unique_invitees[...] == ThresholdReached, and aborts withMINIMUM_ACCOUNTS_THRESHOLD_NOT_REACHEDotherwise. Reaching that state needsunique_invitee_count_threshold= 4 distinct invitees who have each bought at leastunique_invitee_buy_amount_threshold= 10 AE (10 * 10^18aettos), counted cumulatively per invitee. Rewards accrued before qualifying expire on the same 30-day clock.
ProtocolDAO tokens
Every buy also mints ProtocolDAO tokens to the buyer (a separate platform-wide AEX-9 token, not the community token you bought) at 1,000× the AE value of the buy, issued to the buyer's address at the time of purchase. Its governance functionality is not yet implemented.
The factory holds the multiplier as a single constant:
// mints protocol DAO tokens at a rate of 1000 times the buy value.
let protocol_dao_token_multiplier = 1000
stateful entrypoint mint_protocol_dao_token(buy_value : int, receiver : address) =
require(Set.member(Call.caller, state.known_token_sales), "NOT_KNOWN_TOKEN_SALE")
state.protocol_dao_token.mint(receiver, buy_value * protocol_dao_token_multiplier)The sale contract passes Call.value - overpaid_refund as buy_value: the all-in amount
debited, 1.005 * C, affiliation fee included. A buy whose curve cost is 10 AE costs 10.05 AE and
mints 10,050 ProtocolDAO tokens. Only a sale the factory itself deployed can mint
(known_token_sales). During create_community the factory mints the initial buy's ProtocolDAO
tokens directly, at the same 1,000× rate.
A buy receipt carries two Mint events: one on the community token and one on the ProtocolDAO
token contract.
The minted amount is 1,000× the AE debited; the Mint event on your own transaction is the
record.
Related
- Bonding Curves: the integral, the entrypoints, and how a quote is built.
- Fees & Slippage: the practical guide to setting tolerance before you trade.
- The Affiliation System: how the four-level chain is recorded and how payouts are claimed.
- The Treasury: what happens to the DAO's 0.5% once it arrives.
- ProtocolDAO Token: what the platform token is for, and what it is not yet.
- Buy or sell on superhero.com (opens in a new tab): the live token list and trade cards.