Technical Design

Core Mechanism: AMM with Concentrated Liquidity

DAMM implements the constant-product formula x * y = k, where x and y are the reserves of the two tokens and k is the invariant maintained across swaps (excluding fees).

Unlike traditional AMMs that spread liquidity uniformly across all prices, DAMM concentrates liquidity within a defined price range. Pool creators establish a lower tick (T_L) and upper tick (T_U) during initialization — all liquidity deposits operate within that band, improving capital efficiency.

Prices are discretized into ticks:

P(i) = 1.0001^i

The tick_spacing parameter controls granularity — smaller spacing allows finer price resolution but costs more gas per swap. Each fee tier maps to a specific tick spacing.

When the current price is within a position's range, that position's liquidity is active and earns fees. If the price moves outside the range, the position becomes inactive and holds only one token.

Fee Architecture

DAMM implements a multi-layered fee system:

total_fee = base_fee + variable_fee

All fee calculations use 9-decimal precision (denominator = 1,000,000,000).

Base Fee

A fixed percentage established at pool creation (e.g., 0.25%, 0.30%, 1%), applied to every swap. This is the minimum fee when no fee scheduler is active.

Dynamic Fee

The dynamic fee adjusts based on real-time market volatility. It adds a variable component on top of the base fee:

variable_fee = (volatility_accumulator × tick_spacing)² × variable_fee_control / 100

The volatility_accumulator tracks price movement per swap and decays over time via filter_period, decay_period, and reduction_factor. The mechanism is similar to the Volatility Accumulator which explained in DLMM's Dynamic Fee session. Higher volatility leads to increased fees to protect LPs; calm markets bring the variable fee back to zero.

Fee Caps

Limit
Value

Max total fee

50%

Max base fee rate

10%

Min fee after decay

0.01%

Max protocol share

30% of total fee

Anti-Sniper Fee Scheduler

The fee scheduler deters bots from sniping tokens during early trading by starting with high fees that decrease over time. It overrides the base fee with a decaying cliff fee (up to 50%).

Linear decay:

Exponential decay:

Example: A pool might launch with an initial fee of 10%, which decays gradually to 0.3% over a period of 24 hours or 1,000 slots. For highly volatile tokens, such as meme coins, the initial fee can be as high as 80% at launch to mitigate the risks of sudden price swings.

Once the scheduler completes all periods, the fee settles back to the static fee_rate

The linear fee decay from initial fee formular: F(t)=Finit(FinitFfinalT)tF(t) = F_{\text{init}} - \left( \frac{F_{\text{init}} - F_{\text{final}}}{T} \right) \cdot t

Where:

  • F(t)F(t) : Fee at time (t)

  • FinitF_{\text{init}} : Initial fee, eg: 50%

  • Ffinal F_{\text{final}} : Final fee, eg: 0.3%

  • T : total decay duration

  • t : elapsed time or slots

Linear decay function over the time (t)

The exponential fee decay equation calculates the fee F(t)F(t) over time using a decay constant λ{\lambda} , as described below: F(t)=Ffinal+(FinitFfinal)eλtF(t) = F_{\text{final}} + (F_{\text{init}} - F_{\text{final}}) \cdot e^{-\lambda t}

Exponential decay function over the time (t)

The chart above shows that the fee is quite high at launch (e.g., 38% at 5 minutes after launch) but decreases to a normal rate once trading stabilizes (e.g., 0.54% at 50 minutes after launch).

Protocol Fee

A configurable share of the total fee is routed to the Ferra protocol. The remainder goes to LPs.

LP Fee Collect Mode

Pool creators choose how swap fees are collected:

Mode
Value
Behavior

ON_BOTH

0

Fee taken from the input token

ON_QUOTE

1

Fee taken from the quote asset (set via is_quote_y)

ON_QUOTE ensures one specific token always accumulates as fee revenue — useful when the quote asset (e.g., USDC, SUI) is preferred.

Swap Mechanics

Swap Flow

  1. Fee Calculation — Aggregate base fee, dynamic fee, and anti-sniper fee into total_fee_rate

  2. Fee Deduction — Deduct fee from input or output based on collect_fee_mode

  3. Price Calculation — Compute output via constant-product formula:

  4. Price Range Validation — Swaps crossing tick boundaries iterate step by step through ticks

  5. Reserve Updatesx_new = x + Δx, y_new = y - Δy, maintaining the invariant

  6. Fee Accumulation — Split fee into LP fee and protocol fee, update fee_growth_global

  7. Volatility Update — Update dynamic fee volatility parameters if enabled

Example: For a 100 SUI input with a 0.36% total fee, 0.36 SUI is deducted, leaving 99.64 SUI for the swap calculation.

Swap Result

Each swap emits a detailed breakdown:

Pre-Swap Simulation

Use calculate_swap_result to simulate a swap off-chain without executing it — returns the same result structure including all fee breakdowns and step details.

Whitelist (Pre-Launch Access)

  • Before activation_timestamp, only whitelisted addresses can swap

  • After activation_timestamp, the pool is open to everyone

  • Pool creator or CONFIG_ROLE manages the whitelist

Liquidity Provision

Adding Liquidity

LPs deposit tokens into a pool and receive an NFT position representing their share. Deposits must be proportional to the current pool price within the established range.

For single-sided contributions, the contract calculates the equivalent based on the current pool price. Supported operations:

  • Open Position — Create a new position at a tick range

  • Add Liquidity — Increase liquidity by exact amount or by fixing one coin

  • Add Liquidity (Fix Coin) — Specify one token amount; the contract computes the other

Removing Liquidity

LPs call remove_liquidity to withdraw tokens proportional to their pool share. Fee claims are separate from withdrawal — LPs must explicitly collect accumulated fees.

Collecting Fees & Rewards

  • Collect Fee — Claim accumulated LP fees (non-auto-compounded)

  • Collect Reward — Claim reward token emissions

  • Close Position — Remove all liquidity + collect fees, then burn the NFT

Liquidity Locks

Positions support an on-chain lock_until timestamp (in milliseconds):

  • While locked, liquidity cannot be decreased or removed

  • Fee and reward collection remain available during lock

  • Lock duration is immutable once set — cannot be shortened, no admin override

  • lock_until = 0 means unlocked

  • Max lock: ~100 years

Permanent locks tokenize as tradeable NFTs, enabling governance participation or secondary market trading of locked positions.

Single-Sided Liquidity

DAMM supports depositing only one token when creating a pool. The contract initializes the pool with a starting price, allowing swaps to bootstrap the other side. This is ideal for token launches where the creator supplies only the launch token.

Note: Single-sided LPs face higher impermanent loss risk due to price volatility during the bootstrapping phase.

Pool Creation

Creation Flow

  1. Verify system is not paused and package version is current

  2. Check pool creation permission (open or POOL_MANAGER_ROLE required)

  3. At least one coin type must be in the global token whitelist

  4. Load fee scheduler and dynamic fee config from the FeeTier for the given tick_spacing

  5. activation_timestamp must be >= current time

  6. Generate deterministic pool key from coin types + tick spacing + feature flags

  7. Create pool, open initial position, add initial liquidity

  8. Share pool object on-chain

  9. Return (Position, remaining_Coin_A, remaining_Coin_B)

Custom Pool Activation

Pool creators assign an activation_timestamp (Unix timestamp) controlling when swaps become available. Before this time, only whitelisted addresses can swap — enabling coordinated launches.

Last updated