Protocol
Fees
Who earns what on curve trades and on swaps.
Two fee regimes#
A launch earns fees in two phases. On the curve it is 2% per trade, one-off and finite — it ends when the curve sells out. On the DEX it is 0.30% per swap, and it keeps going as long as the pool trades.
| Curve | JoseonSwap | |
|---|---|---|
| Rate | 2.00% | 0.30% |
| Charged in | ETH | the input token |
| Creator | 70% of the fee | 50% of the fee (launch pairs) |
| Protocol | 30% of the fee | 30% of the fee |
| LPs | — | the remainder |
| Duration | until graduation | indefinitely |
Curve trades: 2%#
Charged on both buys and sells, always in ETH. On a buy the fee comes off the gross ETH before the curve moves; on a sell it comes off the gross ETH out before payout. Neither burns tokens.
creatorFee = fee × 7000 / 10000
protocolFee = fee - creatorFeeCreator fees accrue per recipient address and are claimed with claimCreatorFees(recipient). The recipient is read
from LaunchRegistry.feeRecipientOf(token) at the time of each trade, which matters for handovers: if a CTO takes
over, fees already accrued stay with the previous recipient and only later trades accrue to the new one.
A full curve, with no sells, produces:
| ETH | |
|---|---|
| Total fee | ~0.07346938775510204 |
| Creator (70%) | ~0.051428571428571428 |
| Protocol (30%) | ~0.022040816326530612 |
Fees are held inside the curve's ETH balance but excluded from what sells can pay out and from what graduation migrates, so they can never be spent by someone else's trade.
Splitting the creator share#
The UI lets a creator divide their share across several wallets in basis points. On-chain accrual targets a single
feeRecipient, so the split is recorded as off-chain metadata (feeShares) and displayed, not enforced by the
contract. If you need trustless splitting, point feeRecipient at a splitter contract.
Swaps: 0.30%#
The rate is the same for every pair. Only the split differs.
| Recipient | Launch pair | Plain pair |
|---|---|---|
| Creator / approved CTO | 50% → 0.15% | — |
| Protocol | 30% → 0.09% | 30% → 0.09% |
| LPs | 20% → 0.06% | 70% → 0.21% |
| Total | 0.30% | 0.30% |
Traders are unaffected by the split. The AMM prices a swap against the input net of the entire fee no matter who receives it, so this redirects value rather than charging more.
Why launch pairs pay a creator share#
A graduated pool's initial LP position is locked forever. Before this split, that pool's entire 0.30% accrued to the share value of a position nobody can ever redeem — value that was economically stranded. Routing 50% to the creator and 30% to the protocol turns it into something claimable, and the 20% left in reserves still rewards anyone who adds liquidity later.
Plain pairs keep 70% with LPs because they have no creator and voluntary liquidity is the only thing they run on.
Curve fees end, swap fees do not#
Curve fees are capped at roughly 0.051 ETH for the creator, once. Swap fees are 0.15% of volume, forever. Past ~34 ETH of cumulative post-graduation volume, a creator has earned more from swaps than the entire curve paid them.
For the protocol the same logic applies, which is why swap fees — not launch fees — are the long-run revenue line.
Claiming#
| What | Call | Paid to |
|---|---|---|
| Curve creator fees | BondingCurvePool.claimCreatorFees(recipient) | that recipient |
| Swap creator fees | JoseonSwapPairV2.claimCreatorFees() | LaunchRegistry.feeRecipientOf(launchToken) |
| Swap protocol fees | JoseonSwapPairV2.claimProtocolFees() | JoseonSwapFactoryV3.feeTo() |
All three are pull-based. The two swap claims are permissionless — anyone can trigger them, and the funds still go to the registered recipient — so a creator is never dependent on us running a job.
The app surfaces claimable balances in Portfolio and on each token page. Contract calls has the raw versions.
Token creation#
Free on testnet. Whether mainnet charges a small anti-spam fee is an open decision, to be made against real gas costs rather than guessed now.
feeToSetter is currently a single EOA that controls the protocol fee stream. Moving it to a multisig with a timelock
is a known requirement — see security.