Architecture Overview

Last modified:

Contract Architecture

CenturionDEX v3 is composed of core contracts (immutable protocol logic) and periphery contracts (convenience wrappers that most integrators use).

Core Contracts

Factory

The single entry point for pool creation. Calling createPool(tokenA, tokenB, fee) deploys a new Pool contract via CREATE2 (deterministic address). The factory also stores the mapping from (token0, token1, fee) → pool address.

Pool

Each pool is an independent contract holding reserves of two CRC-20 tokens at a specific fee tier. The pool implements:

  • swap() — executes a token swap against the pool's liquidity
  • mint() / burn() — low-level functions to add/remove liquidity at specific tick ranges
  • observe() — returns oracle observations for TWAP calculations

Pools are immutable and permissionless — anyone can swap or provide liquidity.

Periphery Contracts

SwapRouter02

The recommended entry point for swaps. Wraps the pool's low-level swap() with safety features:

  • Deadline enforcement
  • Minimum output amount checks
  • Multi-hop routing (swap through multiple pools in one transaction)
  • Exact input and exact output modes

NonfungiblePositionManager

Manages liquidity positions as CRC-721 NFTs. Each NFT represents a unique position (pool + tick range + liquidity amount). Provides:

  • mint() — create a new position
  • increaseLiquidity() — add more capital to an existing position
  • decreaseLiquidity() — withdraw capital
  • collect() — claim earned fees

QuoterV2

Simulates swaps off-chain without executing them. Returns the expected output amount, price impact, and gas estimate. Used by frontends to display quotes before the user confirms.

V3Migrator

Converts v2 LP positions into v3 positions in a single transaction.

How a Swap Flows

  1. User calls SwapRouter02.exactInputSingle(params)
  2. Router validates the deadline and resolves the pool address via the factory
  3. Router calls Pool.swap() with the user's parameters
  4. Pool iterates through active ticks, exchanging tokens according to the constant product formula within each tick range
  5. Pool transfers output tokens to the recipient
  6. Router verifies the output meets amountOutMinimum, reverts if not

How Providing Liquidity Works

  1. User calls NonfungiblePositionManager.mint(params) specifying token pair, fee tier, tick range, and amounts
  2. PositionManager calls Pool.mint() at the specified tick range
  3. Pool records the liquidity and transfers tokens from the user
  4. PositionManager mints an CRC-721 NFT representing the position
  5. As swaps occur within the position's range, fees accrue to the position
  6. User calls collect() to claim fees, or decreaseLiquidity() + collect() to withdraw

Further Reading