(trinityToken, quoteAsset, basePrice, slope, feeRecipient)buy(uint256 quoteAmount) — user sends quote asset, receives TRINITYsell(uint256 trinityAmount) — user sends TRINITY, receives quote asset, 1% burnedcurrentPrice() — spot price viewquoteTokensOut(uint256 quoteIn) — preview buyquoteAssetOut(uint256 trinityIn) — preview selltotalSold, totalBurned — public countersRewardGauge contract pattern from packages/contracts/src/RewardGauge.sol — it already handles ERC-20 staking with periodic reward distribution.0xb7DD467A573809218aAE30EB2c60e8AE3a9198a0)transferOwnership(MULTISIG)A quadratic curve price(s) = BASE + SLOPE * s² would require computing s³ for the cost integral, which overflows uint256 at 334M tokens in wei. We chose a linear curve instead:
price(s) = BASE_PRICE + SLOPE * s
cost(s₁ → s₂) = BASE_PRICE * (s₂ - s₁) + SLOPE * (s₂² - s₁²) / 2
At s = 334M in wei (3.34 * 10²⁶): s² = 1.12 * 10⁵³ — comfortably fits uint256 (max 1.16 * 10⁷⁷). No overflow risk.
Linear is the simplest, safest option. It still gives early buyers a better price (100× range from floor to terminal), and the flat slope creates tight arb bands for high-frequency cross-pool correction. The 1.5× steeper USDC slope provides enough mid-curve price movement (~1.5% per $1K trade at 10% sold) to drive arb volume without scaring off retail.
This already bit us — the USDC gauge was dropped from ChaosLP V2 because 6-decimal rounding made small reward distributions unviable. The bonding curve faces the same class of problem.
Where it hits:
| Scenario | TRINITY Price | USDC Amount (6 dec) | Precision |
|---|---|---|---|
| Buy 1,000 TRINITY at $0.01 | $0.01 | 10,000,000 (10 USDC) | Fine |
| Buy 100 TRINITY at $0.001 | $0.001 | 100,000 (0.1 USDC) | Fine |
| Buy 1 TRINITY at $0.0001 | $0.0001 | 100 (0.0001 USDC) | Tight |
| Buy 0.01 TRINITY at $0.0001 | $0.000001 | 1 | Minimum unit |
| Buy 0.001 TRINITY at $0.0001 | $0.0000001 | 0 — ROUNDS TO ZERO | Broken |
Mitigations:
floor() on outputs to user, ceil() on inputs from user.The USDC pool will work fine as long as we enforce a minimum trade size and do internal math at 18-decimal precision. The gauge rounding issue was different — it was dividing tiny reward streams across many stakers, losing precision at each division. The bonding curve deals with individual trades, which are larger discrete amounts.
Bonding curves are deterministic — an attacker can predict exact output for any input. Sandwich attack flow:
1. Attacker sees victim's buy(1000 USDC) in mempool
2. Attacker frontruns: buy(5000 USDC) — pushes price up
3. Victim's buy executes at inflated price
4. Attacker backruns: sell(tokens) — pockets difference minus fees
Natural protections we already have:
Additional protections to implement:
maxPrice on buys, minOutput on sells. Already standard in our swap.ts pattern.Assessment: The 1% fee + burn makes sandwiching expensive enough that it's only viable on very large trades (>$50K+). Slippage parameters handle the rest. No exotic MEV protection needed.
The curve must always have enough quote asset to honor all possible sells. Let's trace the math:
Buy flow:
User sends Q quote asset
Fee: Q * 1% = 0.01Q → sent to channel
Curve receives: 0.99Q
Curve issues: T tokens (calculated by integrating curve from totalSold to totalSold + T)
The integral guarantees: 0.99Q = ∫ price(s) ds from totalSold to totalSold + T
Sell flow:
User sends T tokens
Burn: T * 1% = 0.01T → burned
Curve takes back: 0.99T tokens
Curve pays: ∫ price(s) ds from (totalSold - 0.99T) to totalSold
totalSold decreases by 0.99T
Solvency proof (simplified):
Edge case: first buyer, immediate sell:
Buy 10,000 TRINITY for X USDC (1% fee extracted, 0.99X enters reserve)
Immediately sell 10,000 TRINITY (1% burn = 100 TRINITY burned, 9,900 returned)
Curve pays out integral for 9,900 TRINITY ≤ integral for 10,000 TRINITY = 0.99X
Reserve after: 0.99X - payout for 9,900 ≥ 0 ✓
This is solvent by construction. The 1% buy fee does NOT create insolvency because the curve only issues tokens proportional to the 99% that entered the reserve. The sell payout is computed from the same curve. Formal verification in tests is still recommended.
Linear curve: price(s) = BASE_PRICE + SLOPE * s. Three pools with differentiated slopes and supply. 90% of supply locked in curves, 10% treasury.
| Parameter | Value | Meaning |
|---|---|---|
| BASE_PRICE | 0.0001 USDC | Floor price (~$0.0001 per TRINITY) |
| SLOPE | 4.95 × 10⁻¹¹ USDC/token | 1.5× steeper than baseline |
| Price at 0% sold | $0.0001 | Early buyer price |
| Price at 10% sold (33.4M) | $0.00175 | Early action zone (~1.5% impact per $1K) |
| Price at 50% sold (167M) | $0.00837 | Mid-curve price |
| Price at 100% sold (334M) | $0.01663 | Fully sold price |
| Total cost to buy all 334M | $2,794,400 |
| Parameter | Value | Meaning |
|---|---|---|
| BASE_PRICE | 4.85 × 10⁻⁸ WETH | Floor price (~$0.0001 at ETH=$2,062) |
| SLOPE | 1.6 × 10⁻¹⁴ WETH/token | Baseline slope |
| Price at 0% sold | $0.0001 | Early buyer price |
| Price at 50% sold (166.5M) | $0.00560 | Mid-curve price |
| Price at 100% sold (333M) | $0.01109 | Fully sold price |
| Total cost to buy all 333M | $1,863,000 |
| Parameter | Value | Meaning |
|---|---|---|
| BASE_PRICE | 3,889.77 CLP | Floor price (~$0.0001 at CLP=$0.0000000257) |
| SLOPE | 1.28 × 10⁻³ CLP/token | Same USD-equivalent slope as ETH |
| Price at 0% sold | $0.0001 | Early buyer price |
| Price at 50% sold (116.5M) | $0.00394 | Mid-curve price |
| Price at 100% sold (233M) | $0.00779 | Fully sold price (shorter curve) |
| Total cost to buy all 233M | $919,100 |
Market cap projections:
Why differentiated: The steeper USDC slope makes it the "premium" venue — arbers consistently buy ETH/$CHAOSLP and sell USDC, which means ETH fees flow to the gauge and $CHAOSLP fees flow to Chaos staking while sells on USDC burn TRI. The shorter $CHAOSLP pool caps exposure to the most volatile quote asset and sells through first.
All values are Solidity-ready. Contract uses 18-decimal (WAD) fixed-point math internally: price = basePrice + slope * totalSold / 1e18.
| Token | Address | Decimals |
|---|---|---|
| USDC | 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913 | 6 |
| WETH | 0x4200000000000000000000000000000000000006 | 18 |
| $CHAOSLP | 0x8454d062506a27675706148ecdd194e45e44067a | 18 |
| Multisig | 0xb7DD467A573809218aAE30EB2c60e8AE3a9198a0 | — |
(trinityToken, quoteAsset, basePrice, slope, feeRecipient, quoteDecimals)
USDC Pool:
quoteAsset: 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913
basePrice: 100000000000000 (1e14 = 0.0001 USDC in WAD)
slope: 49500000 (4.95e7 = 4.95e-11 * 1e18)
feeRecipient: 0xb7DD467A573809218aAE30EB2c60e8AE3a9198a0 (Multisig)
quoteDecimals: 6
depositAmount: 334000000000000000000000000 (334M * 1e18)
ETH Pool:
quoteAsset: 0x4200000000000000000000000000000000000006
basePrice: 48500000000 (4.85e10 = 4.85e-8 WETH in WAD)
slope: 16000 (1.6e4 = 1.6e-14 * 1e18)
feeRecipient: <GAUGE_ADDRESS> (TrinityGauge — deployed in step 2)
quoteDecimals: 18
depositAmount: 333000000000000000000000000 (333M * 1e18)
$CHAOSLP Pool:
quoteAsset: 0x8454d062506a27675706148ecdd194e45e44067a
basePrice: 3889770000000000000000 (3.89e21 = 3889.77 CLP in WAD)
slope: 1280000000000000 (1.28e15 = 1.28e-3 * 1e18)
feeRecipient: <CHAOS_REWARDS_ADDRESS> (Chaos Rewards multisig)
quoteDecimals: 18
depositAmount: 233000000000000000000000000 (233M * 1e18)
Verification: At terminal supply, basePrice + slope * depositAmount / 1e18 must equal expected terminal price in WAD. Checked for all three pools.
1. TrinityToken.sol
- Standard OZ ERC20
- Constructor mints 1B to msg.sender
- No mint/burn/pause functions (immutable supply, burns use transfer to 0xdead)
2. TrinityBondingCurve.sol
- Constructor(trinity, quoteAsset, basePrice, slope, feeRecipient, decimals)
- buy(uint256 quoteAmount, uint256 minTokensOut) ← slippage protection
- sell(uint256 trinityAmount, uint256 minQuoteOut) ← slippage protection
- No pause mechanism (prototype — wind down manually if needed)
- Internal math at 18-decimal precision, convert at transfer boundary
- ReentrancyGuard on buy and sell
- Events: Buy, Sell, Burn
3. TrinityGauge.sol
- Fork existing RewardGauge pattern
- Stake TRINITY → earn ETH (from ETH pool buy fees)
- 180-day reward periods (consistent with existing gauge infra)
4. Test suite (Foundry)
- Solvency invariant fuzzing
- Mixed-decimal precision tests (USDC 6-dec vs TRINITY 18-dec)
- Overflow boundary tests at 300M and 200M supply per pool
- Buy→sell round-trip loss verification
- Burn accounting accuracy
- Slippage revert tests
1. Deploy TrinityToken (EOA) → transfer 1B TRINITY to Safe
2. Deploy TrinityBondingCurve × 3 (EOA) → transferOwnership to Safe
3. Safe batch transaction:
a. Approve 334M TRINITY to USDC curve
b. Approve 333M TRINITY to ETH curve
c. Approve 233M TRINITY to CHAOSLP curve
d. Call deposit() on each curve (334M / 333M / 233M)
e. Retain 100M TRINITY in Safe treasury (LPs, partnerships)
4. Deploy TrinityGauge (EOA) → transferOwnership to Safe
5. Verify all contracts on Basescan
6. Trading opens
Follows the exact pattern in packages/contracts/script/DeployChaosLP.s.sol — deploy with EOA private key, optionally transfer ownership via TRANSFER_OWNERSHIP env flag.
1. Trade page
- Pool selector tabs: USDC | ETH | CHAOSLP
- Buy/sell form with quote preview (calls quoteTokensOut/quoteAssetOut)
- Slippage setting (default 1%)
- Price chart per pool (read totalSold, compute price curve)
- Safe detection (reuse WalletProvider.tsx isSafe pattern)
2. Dashboard
- Burn counter (totalBurned from each pool, aggregated)
- Reserve health (quote asset balance vs curve liability)
- Cross-pool price comparison
- Volume tracker
3. Staking page
- Stake TRINITY → earn ETH
- Reuse chaos-theory/app/stake/page.tsx pattern
- Same gauge ABI, same claim flow
Once the three bonding curves are live, additional TRINITY pairs can be created on Uniswap V3/V4 permissionlessly:
buildCreatePoolTransaction()| Issue | Severity | Status | Mitigation |
|---|---|---|---|
| Cubic overflow in quadratic curve | Blocker | Use linear curve instead | s² fits uint256 at 300M/200M supply. No overflow. |
| USDC 6-decimal rounding | High | Known from gauge experience | Internal 18-dec math + minimum trade size + round in protocol's favor |
| MEV/sandwich on curves | Medium | Manageable | 1% fee + burn = ~3% attacker cost. Slippage params. Flashbots Protect RPC. |
| Reserve insolvency | Critical | Solvent by construction | Fees extracted before curve math. Burns make it over-collateralized. Fuzz test. |
| Cross-pool price divergence | Low | By design — amplified in V2 | USDC always most expensive (1.5× slope). Arbers buy ETH/$CHAOSLP, sell USDC. |
| Treasury dump (100M unfenced) | Medium | Accepted (prototype) | 10% of supply in Safe, no vesting. Lower risk at 10% vs prior 20%. |
| Curve parameters | Resolved (V2) | USDC 1.5× slope, ETH baseline, $CHAOSLP 200M shorter. See Trinity-Curves.html. | |
| Pause behavior | Low | Skipped (prototype) | No pause mechanism. Manual wind-down if needed. |
Contracts:
Frontend:
Deployment:
No new packages required. Everything builds on existing infrastructure.