Documentation

Contracts

Inference Markets is one set of Solidity contracts, built with Foundry on Solidity 0.8.26 and deployed to Base. There are fourteen of them, they own everything the protocol holds, and there is no operator among them: no key can set a price or pay a holder. The interesting behavior is in five: the InferenceIndex that writes the price of intelligence, the PegManager that keeps a coin at that price, the Launchpad that owns every market's liquidity, the LaunchToken that pays its own holders, and the RedemptionVault that pays out at the index.

Chain Base, chain ID 8453, OP-stack L2, ETH for gas
RPC https://mainnet.base.org
Explorer https://basescan.org
Addresses contracts/deployments/8453.json, written by the deploy script and read by the site

Inference Markets contracts

Contract Role Who may call what
PriceFeed USD prices for the catalogue under keccak256(symbol), USD × 1e18 per coin. Chainlink and Aerodrome TWAP assets are read live at call time; the three class prices are pushed. owner: registerPushed, registerChainlink, registerTwap, setPusher, setActive. pusher (the InferenceIndex): push, and only for pushed assets. anyone: getPrice, peek, isFresh.
InferenceIndex Chainlink Functions consumer. Stores hourly OpenRouter samples in a 168-slot ring and publishes the median as INT, OPEN and AGENT. Config (source, model lists, subscription, DON) lives on-chain. anyone: request (55-minute spacing), publish. Functions router only: the fulfillment callback. owner: proposeConfig → 24 h → applyConfig. reads: median, latestSample, count, head, config, pendingConfig.
InferenceCoin One ERC-20 per synthetic unit, 18 decimals. Two fixed addresses: the minter and the burner. minter (PegManager): mint, burn. burner (RedemptionVault): burn. owner: setMinter, setBurner.
PegManager Owns each synthetic coin's single-sided V3 ask and bid, forwards dollars above the bid target to the vault. Sole minter. anyone: reprice, refill. owner: registerCoin, setBidTarget, setVault (once). reads: needsReprice, needsRefill, askCoin, bidUsd, feedBand, pegOf, usdReserve.
LaunchTokenFactory Deploys LaunchTokens for the launchpad, so the launchpad's own bytecode stays under the EIP-170 size limit. launchpad only: create. setLaunchpad is bound once at deployment, by the deployer only.
LaunchToken A market's ERC-20: 18 decimals, 1,000,000,000 fixed supply minted to the launchpad, immutable metadataURI, and the per-share fee accumulator that pays its holders every block. distributor only: notifyFees, harvest. launchpad only: setExcluded. anyone: transfers, pendingOf, excluded, eligibleSupply, accCoinPerShare, accTokenPerShare.
Launchpad Creates markets, owns both liquidity positions, collects fees and routes them: coin side 50 / 30 / 20, token side to holders. Holds the pair allowlist. Has no liquidity-removal function. anyone: launch, collectFees. router only: launchFor. owner: setPair, setExcluded, setRouter, setTreasury, setDistributor. reads: marketOf, marketAt, marketCount, pairInfoOf, ledgerOf, collectedOf, splitCoin.
Distributor Holds every market's holder share and pays it on claim, in the holder's chosen asset, converting through the router in the same transaction. Holds refused deliveries. holder: claim, claimMany, claimHeld, setPayoutPreference. launchpad only: notify. owner: setPayoutAsset, setRouter. reads: pendingOf, preferenceOf, heldOf, payoutAssetAllowed.
Treasury Ledger of the protocol's buyback and protocol shares per market, and the permissionless sweeps that realize them with feed-derived floors. anyone: sweepToBuyback, sweepProtocol, topUpVault (only under 100% coverage). launchpad only: notifyCollected. owner: setRouter, setVault, setBuyback, setProtocolWallet. reads: ledgerOf, minEthOut, minUsdOut.
RedemptionVault Holds USDC and DIEM per synthetic coin, burns coin on redemption and pays at the index in the same transaction. Computes coverage. Keeps its DIEM share in band. anyone: redeem, fund, rebalance. router only: redeemFor. owner: configure, sweepSurplus (above 110%), setAdapter, setRouter, setTrancheUsd. reads: quoteRedeem, canRedeem, coverageBps, outstanding, usdOf, diemOf, diemShareBps, needsRebalance, redeemedToday, diemDelivered, configOf.
LaunchRouter One-transaction routes between ETH, USDC, pair coin, market token, DIEM and payout assets; vault-first sells for synthetics; quotes. Stateless, holds nothing between calls. anyone: buyWithEth/Usd/Coin, sellForEth/Usd/Coin, sellForDiem, launchWithEth/Usd, swapUsdForCoin, swapCoinForUsd, swapCoinForEth, swapCoinForAsset, quoteBuy, quoteSell, quoteCoinForAsset. distributor only: swapCoinForAssetFor (a claim's conversion, with the vault's caps charged to the claiming wallet). No owner.
AerodromeAdapter Owner-set routes made of two kinds of leg. V2: an Aerodrome v2 pool through the Aerodrome Router, used for USDC → WETH → VVV → DIEM and back (the USDC/VVV v2 pool is nearly empty; the VVV/WETH pool is the deep one). CL: an Aerodrome Slipstream concentrated pool swapped directly with the V3-style callback, no router trusted, used for USDC ↔ each stock. Holds no funds between calls. quoteExactIn is not a view: CL legs are simulated so a quote equals execution in the same block. owner: setRoute, which checks that legs chain and that a CL pool holds exactly the leg's two tokens. anyone: swapExactIn (pulls the input from the caller), quoteExactIn, routeOf, hasRoute.
PAIDIN The exchange token: ERC-20, 18 decimals, 1,000,000,000 fixed supply, burnable, no mint path after construction. anyone: burn their own. No owner.
Buyback Receives ETH from the Treasury, spends its whole balance on the protocol token in a bound native-ETH v4 pool, and burns what it buys. executor only: execute. owner: setExecutor, setPool (once). reads: totalBurned, totalEthSpent, poolSet, executor.

External contracts on Base

Contract Address Notes
USDC 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913 Circle native USDC, 6 decimals
WETH 0x4200000000000000000000000000000000000006 OP-stack predeploy
Uniswap V3 factory 0x33128a8fC17869897dcE68Ed026d694621f6FDfD peg pools, 0.30% tier, tick spacing 60
WETH/USDC V3 pool 0xd0b53D9277642d899DF5C87A3966A349A798F224 0.05% fee; the ETH ↔ USD leg of every route
Uniswap v4 PoolManager 0x498581fF718922c3f8e6A244956aF099B2652b2b every market pool, and the protocol token pool
Uniswap v4 PositionManager 0x7C5f5A4bBd8fD63184577525326123B519429bDc not used for launchpad positions
Uniswap v4 StateView 0xA3c0c9b65baD0b08107Aa264b0f3dB444b867A71 the site reads pool state through it
Uniswap v4 Quoter 0x0d5e0F971ED27FBfF6c2837bf31316121532048D reads
Uniswap v4 UniversalRouter 0x6fF5693b99212Da76ad316178A184AB56D299b43
Permit2 0x000000000022D473030F116dDEE9F6B43aC78BA3 canonical
Chainlink ETH/USD 0x71041dddad3595F9CEd3DcCFBe3D1F4b0a16Bb70 8 decimals, 20-minute heartbeat; read live, stale after 2 hours; prices ETH for sweeps and the VVV/WETH leg
Chainlink Functions router 0xf9B8fc078197181C841c296C876945aaa425B278 DON id fun-base-mainnet-1; the InferenceIndex is a consumer of a funded subscription
DIEM 0xF4d97F2da56e8c3098f3a8D538DB630A2606a024 Venice AI, ERC-20, 18 decimals
VVV 0xacfE6019Ed1A7Dc6f7B508C02d1b04ec88cC21bf Venice AI; the middle hop of the DIEM route
Aerodrome VVV/WETH pool 0x01784ef301D79e4B2DF3a21ad9a536d4cF09A5Ce volatile, about $14M; the VVV price source, quote(VVV, 1e18, 12)
Aerodrome VVV/DIEM pool 0xbB345D35450BF9Ee76F3D2cE214E8e7AC5e1071d volatile, about 2,350 DIEM of depth; the DIEM price source, quote(DIEM, 1e18, 12), and the DIEM venue
Aerodrome Router 0xcF77a3Ba9A5CA399B7c97c74d54e5b1Beb874E43 verified 2026-09-16; executes the v2 DIEM legs; its defaultFactory() is the PoolFactory below
Aerodrome PoolFactory 0x420DD381b31aEf6683db6B902084cB0FFECe40Da verified 2026-09-16; getPool(VVV, DIEM, false) is the VVV/DIEM pool above; the factory field of every v2 leg
Aerodrome Slipstream USDC/stock pools six, one per stock concentrated, tick spacing 10, on an Aerodrome-approved CL factory; swapped directly by the adapter

The six B20 stock tokens, their Chainlink feeds and their Slipstream pools are listed in AI stocks.

Ownership and trust

Every contract with an owner uses OpenZeppelin Ownable2Step, so a transfer has to be accepted by the new owner. There is no operator role anywhere. The only non-owner privileged addresses are the PriceFeed's pusher, which is the InferenceIndex contract and not a person, and the Buyback executor.

Who Can
nobody set a price by hand, pay a holder, mint a launch token or the protocol token after construction, remove a market's liquidity
the chain price stocks and ETH (Chainlink, live), VVV and DIEM (Aerodrome TWAPs, live), and the three class prices (Chainlink Functions through the InferenceIndex)
owner register feed sources and switch assets on or off; set adapter routes (v2 legs through the Aerodrome Router, Slipstream legs on a named pool); set the pair allowlist; allow payout assets; configure the vault (caps, fee, spread, tranche size); set bid targets; exclude a protocol contract from accrual; propose and, 24 hours later, apply a new index config (source, model lists, subscription, DON); sweep vault surplus above 110% coverage; set the executor; bind the buyback pool once
executor Buyback.execute, which spends the Buyback's ETH on the protocol token and burns it, with a floor it supplies
launchpad Distributor.notify, Treasury.notifyCollected, LaunchToken.setExcluded, LaunchTokenFactory.create
router Launchpad.launchFor, RedemptionVault.redeemFor
distributor LaunchToken.notifyFees, LaunchToken.harvest
a holder claim, claimMany, claimHeld, setPayoutPreference
anyone launch, trade, redeem, fund, and every maintenance call in Automation: request, publish, reprice, refill, collectFees, the three Treasury sweeps, rebalance

The owner's powers are configuration, and several of them matter: a changed feed source changes what every contract believes a coin is worth, a changed adapter route changes where DIEM and stock trades execute, and a changed model list changes the index over the following three and a half days. The index change is the only one with a built-in delay. The recommendation before mainnet, recorded in SPEC.md §7, is to hand OWNER to a TimelockController so that every owner action is visible before it takes effect. The executor is a single key, and its blast radius is the ETH sitting in the Buyback at the moment it acts. Risks states all of this again.

Decimals

Asset Decimals
Inference coins, launch tokens, DIEM, VVV, the protocol token 18
USDC 6
B20 stocks 8
Feed prices USD × 1e18 per whole coin
Index samples USD × 1e18 per million tokens
Vault USD accounting 6, USDC's own
Accumulator precision 1e36 per share

The launchpad reads decimals() from the pair coin rather than assuming, which is what lets an 8-decimal stock be a pair. The recurring conversion in the vault is usdValue = amount × price / 1e30, which takes an 18-decimal amount and an 18-decimal price to a 6-decimal dollar figure.

Tests

The suite is 186 tests across 20 suites, hermetic: no fork and no RPC. The v4 PoolManager and the V3 factory are deployed locally from vendored artifacts; USDC, WETH, DIEM, VVV, a B20 stock with a policy block, a pause and a multiplier, Aerodrome v2 pools with a quote TWAP behind a mock router, a Slipstream-style concentrated pool for the stock, Chainlink aggregators and the Chainlink Functions router are all mocked. The fixture's maintenance helpers are called by a stranger to prove nothing needs an operator, and an invariant suite drives launches, trades, collections, claims, sweeps and repricings from an unprivileged handler. contracts/TESTING.md maps every suite to what it covers.