An automated market maker whose execution fees/spreads and price bands are steered by an off-chain model, while the chain enforces strict bounds, rate limits, and a challenge path. Everything runs locally: Foundry contracts + Python indexer/model/bot + demo script.
- Explainable constant-product core with deterministic fees/spreads.
- AI only sets risk knobs:
feeBps,spreadBps,bandBps,maxTradePctBps. It never predicts prices or sets reserves. - Hard safety: per-parameter bounds, per-update deltas, min update interval, optional challenge window, and freeze switch.
- Infra completeness: indexer → model → bot loop, plus backtests and demo script.
[Traders] -> AIMMxPool (CPMM w/ dynamic fee+spread+band)
^ | reads params from ParamOracle
| v
[Bot w/ model sig] -> AIMMxController -> ParamOracle
| ^
v |
apps/model (FastAPI) apps/indexer (FastAPI+SQLite) apps/bot (Web3 signer)
\ / ^
\ / |
sim/backtest + scripts/demo.sh
AIMMxPool: Constant-product AMM with dynamic fee/spread/band, trade caps, min-out checks, band enforcement vs reference oracle, and LP tokenization.AIMMxController: Governance + param entrypoint. Verifies signer, bounds, deltas, min interval, optional challenge window, and can freeze updates.ParamOracle: Stores latestParamSetper pool (timestamp + model hash).AIMMxFactory: Creates pools and wires reference oracles.KeeperUpdateRouter: Optional allowlisted forwarder for keepers/bots.MockOracle/MockERC20: Local demo dependencies.libraries/Math.sol: Fixed-point helpers;libraries/AIMMxTypes.sol: shared structs/constants.
feeBps≤ 100,spreadBps≤ 150,bandBpsbetween 10 and 1000,maxTradePctBps≤ 5000.- Per-update deltas: fee ≤ 10 bps, spread ≤ 15 bps, band ≤ 100 bps, trade cap ≤ 500 bps.
MIN_UPDATE_INTERVAL: 10 minutes between accepted updates.- Optional
challengePeriod: pending params can be challenged (off by default, configurable by owner). freezeswitch halts new updates.
apps/indexer: Listens to pool/controller events, stores swaps/params in SQLite, exposes/swaps,/metrics,/windowfor model training.apps/model: FastAPI server + training script. Emits bounded params and amodelHash(SHA-256 of payload). Uses simple linear regression with heuristic fallback.apps/bot: Polls model server, signs params withMODEL_SIGNER_PRIVATE_KEY, and callsAIMMxController.proposeParams. SupportsDRY_RUN.sim/backtest.py: Quick CPMM vs adaptive-param comparison to estimate slippage/LP PnL proxy.sim/trader.py: Sends random swaps to a deployed pool for demos.- Frontend:
apps/frontend(React + Vite) dashboard that reads on-chain params/reserves and off-chain indexer/model outputs.
Prereqs: Foundry (forge/cast), Python 3.10+, pip install -r for each app.
forge test # run unit/fuzz/invariant tests
make demo # full local demo (anvil + deploy + services + swaps)
python sim/backtest.py # offline backtestmake demo runs scripts/demo.sh, which:
- launches anvil,
- deploys contracts + seeds liquidity via
script/DeployAIMMx.s.sol, - starts indexer, model server, and bot (dry-run by default),
- fires a short swap stream to show parameter updates and band enforcement,
- tails metrics.
- Contracts:
contracts/*.sol, interfaces undercontracts/interfaces. - Tests:
test/AIMMxPool.t.sol(unit + fuzz + invariant coverage). - Scripts:
script/DeployAIMMx.s.sol,scripts/demo.sh. - Docs:
docs/THREAT_MODEL.md,docs/INVARIANTS.md,docs/PARAMS.md,docs/AI_MODEL.md,docs/DEMO.md.
- Bands: Trades revert if post-trade implied price breaches
[reference*(1-band), reference*(1+band)]. Reference is provided byIReferenceOracle(mocked locally). - Fees/Spreads: Applied to input side; fee + spread must stay < 100%.
- Max trade size: Input capped as % of reserves to blunt toxic flow spikes.
- Model honesty:
modelHash+ signed params provide attestation; controller enforces bounds regardless of model output.
source apps/indexer/.env.example && uvicorn apps.indexer.main:app --reload
source apps/model/.env.example && uvicorn apps.model.serve:app --reload --port 8002
source apps/bot/.env.example && python apps/bot/main.py # DRY_RUN=true by default
cd apps/frontend && cp .env.example .env && npm install && npm run devUpdate POOL_ADDRESS/CONTROLLER_ADDRESS in env files after deployment (deployments/local.json).
- Demo oracle is a mock; integrate a production feed (e.g., Chainlink) via
IReferenceOracle. - Model ignores cross-asset info and uses only swap-derived features.
- Challenge flow is simplified (owner-only for demo).
forge fmt && forge testbefore changes.- Keep docs in
docs/consistent with code bounds/invariants.