Trinity: Implementation Evaluation


What We're Building


Contracts (Solidity, Foundry)


1. TrinityToken.sol — Standard ERC-20, 1B supply, non-upgradeable. Mints entire supply to deployer (Safe) on construction. Nothing custom — OpenZeppelin ERC20 only.

2. TrinityBondingCurve.sol — One contract deployed three times with different config:
• Constructor params: (trinityToken, quoteAsset, basePrice, slope, feeRecipient)
buy(uint256 quoteAmount) — user sends quote asset, receives TRINITY
sell(uint256 trinityAmount) — user sends TRINITY, receives quote asset, 1% burned
currentPrice() — spot price view
quoteTokensOut(uint256 quoteIn) — preview buy
quoteAssetOut(uint256 trinityIn) — preview sell
totalSold, totalBurned — public counters
• Ownable (Safe), no withdraw, no pause (prototype)

3. TrinityGauge.sol — RewardGauge for ETH staking rewards. Can reuse the existing RewardGauge contract pattern from packages/contracts/src/RewardGauge.sol — it already handles ERC-20 staking with periodic reward distribution.

Frontend (Next.js, within ArbMe or standalone)


• Trade page: pool selector (USDC / ETH / CHAOSLP), buy/sell form, price chart
• Dashboard: burn counter, total volume, reserve balances, current prices across all pools
• Staking page: stake TRINITY → earn ETH rewards (reuse existing staking UI pattern from chaos-theory)
• Existing infrastructure: wagmi, RainbowKit, Safe detection, viem — all already in place

Gnosis Safe


• Deploy all contracts from the Rails Multisig (0xb7DD467A573809218aAE30EB2c60e8AE3a9198a0)
• Pattern already established: deploy via EOA with Foundry → transferOwnership(MULTISIG)
• Safe receives USDC buy fees directly (no intermediary)
• Safe holds 100M treasury TRINITY (unfenced — prototype; LPs, partnerships)
• Existing Safe Apps SDK integration in ArbMe frontend can be reused



Critical Technical Issues


1. Bonding Curve Math — Linear Curve (RESOLVED)


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.


2. USDC 6-Decimal Precision (KNOWN ISSUE)


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:

1. Enforce minimum trade size — e.g., 100 TRINITY minimum per buy. At even $0.0001/TRINITY that's $0.01 = 10,000 USDC units. Plenty of precision.
2. Scale curve math internally to 18 decimals — do all math in 18-decimal precision, convert to 6-decimal USDC only at the transfer boundary. This is how the existing swap.ts handles it (decimal adjustment multiplier).
3. Round in protocol's favor — always 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.


3. MEV / Sandwich Attack Surface (MEDIUM RISK)


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:

• 1% fee on each leg = 2% round-trip cost for attacker
• Sell burns 1% of TRINITY — attacker loses tokens
• Total attacker cost: ~3% of position. Sandwich only profitable if victim's trade moves price >3%.

Additional protections to implement:

1. Slippage parameter on buy/sellmaxPrice on buys, minOutput on sells. Already standard in our swap.ts pattern.
2. Block-based rate limiting — optional: cap max trade size per block to limit single-block manipulation. Adds gas overhead though.
3. Private submission — document that users can submit via Flashbots Protect RPC to bypass public mempool. This is a frontend config, not a contract change.

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.


4. Reserve Solvency Invariant (MUST PROVE)


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):

• On buy: curve gains 0.99Q quote assets and issues T tokens. Reserve += 0.99Q.
• On sell: curve pays out integral for 0.99T tokens. But the original buy paid for T tokens worth of curve. The sell only claims 0.99T tokens worth — strictly less.
• Additionally, the buy fee was already extracted (only 0.99Q entered the reserve), so the sell payout is computed from the same curve the buy was computed from — the integrals match.
Burns make this better over time: burned tokens were "sold" but can never be "returned." The quote assets that backed those tokens remain in the reserve permanently. The curve becomes over-collateralized.

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.


5. Curve Parameter Selection (V2 — RESOLVED)


Linear curve: price(s) = BASE_PRICE + SLOPE * s. Three pools with differentiated slopes and supply. 90% of supply locked in curves, 10% treasury.


USDC Pool (1.5× slope, 334M supply)

Parameter Value Meaning
BASE_PRICE0.0001 USDCFloor price (~$0.0001 per TRINITY)
SLOPE4.95 × 10⁻¹¹ USDC/token1.5× steeper than baseline
Price at 0% sold$0.0001Early buyer price
Price at 10% sold (33.4M)$0.00175Early action zone (~1.5% impact per $1K)
Price at 50% sold (167M)$0.00837Mid-curve price
Price at 100% sold (334M)$0.01663Fully sold price
Total cost to buy all 334M$2,794,400

ETH Pool (baseline slope, 333M supply)

Parameter Value Meaning
BASE_PRICE4.85 × 10⁻⁸ WETHFloor price (~$0.0001 at ETH=$2,062)
SLOPE1.6 × 10⁻¹⁴ WETH/tokenBaseline slope
Price at 0% sold$0.0001Early buyer price
Price at 50% sold (166.5M)$0.00560Mid-curve price
Price at 100% sold (333M)$0.01109Fully sold price
Total cost to buy all 333M$1,863,000

$CHAOSLP Pool (baseline slope, 233M supply — shorter)

Parameter Value Meaning
BASE_PRICE3,889.77 CLPFloor price (~$0.0001 at CLP=$0.0000000257)
SLOPE1.28 × 10⁻³ CLP/tokenSame USD-equivalent slope as ETH
Price at 0% sold$0.0001Early buyer price
Price at 50% sold (116.5M)$0.00394Mid-curve price
Price at 100% sold (233M)$0.00779Fully sold price (shorter curve)
Total cost to buy all 233M$919,100

Market cap projections:

• At 50% sold across all pools (~450M circulating): ~$0.006 avg × 450M = ~$2.7M market cap
• Total cost to buy out all curves: $5,576,500

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.


Contract Deployment Parameters


All values are Solidity-ready. Contract uses 18-decimal (WAD) fixed-point math internally: price = basePrice + slope * totalSold / 1e18.


Token Addresses (Base Mainnet)

Token Address Decimals
USDC0x833589fCD6eDb6E08f4c7C32D4f71b54bdA029136
WETH0x420000000000000000000000000000000000000618
$CHAOSLP0x8454d062506a27675706148ecdd194e45e44067a18
Multisig0xb7DD467A573809218aAE30EB2c60e8AE3a9198a0

TrinityBondingCurve Constructor

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




Implementation Plan


Phase 1: Contracts



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

Phase 2: Deployment (via Safe)



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.


Phase 3: Frontend



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

Phase 4: Non-Curve Additional Pairs


Once the three bonding curves are live, additional TRINITY pairs can be created on Uniswap V3/V4 permissionlessly:


• TRINITY/CLANKER, TRINITY/FLAY, TRINITY/VIRTUAL, etc.
• These are standard Uniswap pools — no custom contracts
• Pool creation already supported via core-lib buildCreatePoolTransaction()
• Each new pair = new arb surface back to the bonding curves
• Volume on these pairs generates Uniswap LP fees (separate from Trinity fees)
• The bonding curves remain the "canonical" price — external pools arb against them



Known Issues & Mitigations Summary


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



Dependencies & Tooling


Contracts:

• OpenZeppelin Contracts (already in packages/contracts) — ERC20, Ownable, ReentrancyGuard
• Foundry (already configured) — forge build, test, deploy scripts
• No new dependencies needed

Frontend:

• viem, wagmi, RainbowKit (already in packages/nextjs)
• Safe Apps SDK (already in packages/nextjs)
• No new dependencies needed

Deployment:

• Foundry scripts (existing pattern)
• Safe multisig (existing)
• Basescan verification (existing workflow)

No new packages required. Everything builds on existing infrastructure.