Skip to content

Repository files navigation

Minimal Fixed-Pair AMM with TWAP Oracle

An educational, unaudited implementation of a single Mock WETH / Mock USDC constant-product AMM with a cumulative-price TWAP oracle, built to understand core AMM mechani (constant-product pricing, LP share accounting, and spot-price manipulation resistance) in depth. This repository is for research and portfolio demonstration only; it must not be deployed with assets of value.

Verification status

  • Testnet deployment: deployed and source-verified on Ethereum Sepolia.
  • Verified contracts:
  • Automated verification: forge test and forge coverage --report summary pass locally.

Architecture

MockWETH (18 decimals) ─┐
                       ├── FixedPairAMM ── cumulative prices ── SimpleTwapOracle
MockUSDC (6 decimals) ─┘       │
                                └── ERC-20 LP shares
  • MockWETH and MockUSDC are unrestricted-mint test assets.
  • FixedPairAMM holds one immutable token pair, implements exact-input swaps and liquidity accounting, and is itself the LP-share ERC-20.
  • SimpleTwapOracle consumes the AMM’s two independent cumulative price series and publishes 30–60 minute averages.

Design decisions

The full normative rationale is in SPEC.md.

  • One fixed pair. Immutable WETH/USDC addresses keep the accounting surface small and avoid factory, registry, router, multi-hop, and upgrade logic. The 18/6-decimal pairing also exercises asymmetric token precision.
  • Immutable economics. The 0.30% fee, 10,000 basis-point denominator, 1,000 permanently locked LP units, and oracle timing constants are compile-time constants; no owner path can tune economics.
  • Fixed ownership scope. The owner can only pause or unpause the specified operations. Ownership transfer and renouncement are explicitly disabled so the AMM cannot acquire a new administrator or become ownerless.
  • Stored reserves are authoritative. Pricing and LP-share calculations use packed stored reserves, not raw balances. This makes unsolicited token transfers inert until public one-way synchronization.
  • Measured transfer deltas. Every swap and liquidity transfer measures the AMM balance immediately before and after movement and requires the exact expected delta. The design intentionally supports only standard ERC-20 behavior.
  • Permissionless initialization. The first LP chooses the pool ratio. This preserves the minimal fixed-pair model but makes the initial LP responsible for price-setting risk.
  • One-way sync(). Synchronization may preserve or increase reserves but never decrease them. There is no skim, recovery, rescue, or protocol-fee withdrawal path, avoiding an additional privileged extraction surface.
  • Two independent cumulative prices. Each direction is accumulated from the old reserves before any reserve update. The reverse price is never derived as a reciprocal, preserving specified rounding behavior.
  • Bounded TWAP lifecycle. The oracle requires a baseline plus a later 30–60 minute interval. Intervals over 60 minutes reset the baseline and invalidate an older average rather than publishing an unintended long-window quote.

Security considerations

The suite checks the following categories and associated controls:

Category Checked control
Reentrancy nonReentrant protects each external reserve-mutating entry point; callback-token tests verify inbound and outbound reentry reverts atomically.
Token-accounting mismatch Exact before/after AMM balance checks reject short receipts and extra outgoing debits.
Reserve and product integrity Packed uint112 reserve bounds, one common update path, old-reserve cumulative accounting, and swap-product assertions are unit-, fuzz-, and statefully tested.
Slippage and execution validity Minimum outputs/shares, maxima, deadlines, token direction, liquidity, and recipient checks are covered across swaps and liquidity operations.
Donation and synchronization Excess balances do not affect quotes before sync(); synchronization cannot lower a reserve and has no share-minting or recovery path.
Pause authority Pause blocks swaps, additions, and synchronization but not liquidity removal, views, or oracle updates; ownership transfer and renouncement both revert.
Oracle validity Baseline, timing, reset, staleness, decimal-direction, rounding, and manipulation-window behavior are tested.

Known limitations

  • This is unaudited and not suitable for production assets.
  • Mock token minting eliminates scarcity; it invalidates real-world economic-security conclusions.
  • Donation plus sync() can manipulate the stored reserve ratio. Spot price is not a manipulation-resistant oracle.
  • TWAP only mitigates short-interval manipulation and depends on third parties calling update() at suitable intervals.
  • A paused AMM can yield a fresh-looking TWAP at a frozen reserve ratio; freshness is not external-market validation.
  • First-liquidity price setting, arbitrage risk, impermanent loss, validator-controlled timestamp variation, and unsupported token behavior remain material risks.
  • There is deliberately no recovery path for accidental underlying-token or LP-token transfers.

Local verification

forge fmt --check
forge build
forge test
forge coverage --report summary

Deployment

script/DeployAMM.s.sol deploys the two mock tokens, AMM, and oracle without minting, approvals, or privileged liquidity initialization. The current Sepolia deployment is listed above. It remains educational and must not be initialized with assets of value.

About

Educational Solidity AMM with LP accounting, a TWAP oracle, fuzz/invariant tests, and Sepolia deployment.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages