AMM Pricing Formula

Deep dive into the Automated Market Maker (AMM) pricing mechanism used in Owna-DEX.


Core Concept: Constant Product Formula

Owna-DEX uses the Constant Product AMM formula, pioneered by Uniswap V2:

x × y = k

Where:

  • x = Reserve of Token 0 (e.g., YRT)

  • y = Reserve of Token 1 (e.g., USDC)

  • k = Constant product (must remain constant after trades, excluding fees)


How Pricing Works

Initial Pool Setup

When a property owner adds initial liquidity, the price is determined by the ratio:

Price = y / x = Reserve_USDC / Reserve_YRT

Example:

Initial Liquidity:
- 1000 YRT
- 1000 USDC

Initial Price:
- 1000 / 1000 = 1 USDC per YRT

Constant k:
- k = 1000 × 1000 = 1,000,000

Trading Mechanics

Buy Example: User Swaps USDC for YRT

Scenario: User wants to buy YRT with 100 USDC

Step 1: Calculate reserves before trade

Before:
- Reserve_YRT = 1000
- Reserve_USDC = 1000
- k = 1,000,000
- Price = 1 USDC/YRT

Step 2: Apply fee (0.3%)

Input after fee:
- User sends: 100 USDC
- Fee (0.3%): 100 × 0.003 = 0.3 USDC → Fee Recipient
- Effective input: 100 × 0.997 = 99.7 USDC

Step 3: Calculate output using constant product

Formula: x × y = k (constant)

New reserves must satisfy:
(Reserve_YRT - output) × (Reserve_USDC + input) = k

Solving for output:
output = (input × Reserve_YRT) / (Reserve_USDC + input)

Calculation:
output = (99.7 × 1000) / (1000 + 99.7)
output = 99,700 / 1099.7
output = 90.66 YRT

Step 4: New state after trade

After:
- Reserve_YRT = 1000 - 90.66 = 909.34 YRT
- Reserve_USDC = 1000 + 99.7 = 1099.7 USDC
- k = 909.34 × 1099.7 ≈ 1,000,000 ✓
- New Price = 1099.7 / 909.34 = 1.209 USDC/YRT (+20.9%)

Result:

  • User paid: 100 USDC

  • User received: 90.66 YRT

  • Effective price: 1.103 USDC/YRT

  • Price impact: +20.9%

  • Fee collected: 0.3 USDC


Sell Example: User Swaps YRT for USDC

Scenario: User wants to sell 50 YRT

Step 1: Current reserves

Before:
- Reserve_YRT = 909.34
- Reserve_USDC = 1099.7
- k = 1,000,000
- Price = 1.209 USDC/YRT

Step 2: Apply fee (0.3%)

Input after fee:
- User sends: 50 YRT
- Fee (0.3%): 50 × 0.003 = 0.15 YRT → Fee Recipient
- Effective input: 50 × 0.997 = 49.85 YRT

Step 3: Calculate output

output = (49.85 × 1099.7) / (909.34 + 49.85)
output = 54,808 / 959.19
output = 57.13 USDC

Step 4: New state

After:
- Reserve_YRT = 909.34 + 49.85 = 959.19 YRT
- Reserve_USDC = 1099.7 - 57.13 = 1042.57 USDC
- k ≈ 1,000,000 ✓
- New Price = 1042.57 / 959.19 = 1.087 USDC/YRT (-10.1%)

Result:

  • User paid: 50 YRT

  • User received: 57.13 USDC

  • Effective price: 1.143 USDC/YRT

  • Price impact: -10.1%


Key Formulas

Price Calculation

// Current spot price
price = Reserve_USDC / Reserve_YRT

// Example: 1000 USDC / 1000 YRT = 1 USDC/YRT

Swap Output (Exact Input)

// Output amount when user provides exact input
output = (input × 997 × Reserve_Out) / ((Reserve_In × 1000) + (input × 997))

// Where 997/1000 accounts for 0.3% fee

Swap Input (Exact Output)

// Input amount needed to get exact output
input = ((Reserve_In × output × 1000) / ((Reserve_Out - output) × 997)) + 1

Liquidity Provision

// LP tokens minted for first provider
liquidity = sqrt(amount0 × amount1) - MINIMUM_LIQUIDITY

// LP tokens minted for subsequent providers
liquidity = min(
    (amount0 × totalSupply) / reserve0,
    (amount1 × totalSupply) / reserve1
)


Price Impact

Price impact measures how much a trade changes the pool price.

Formula

priceImpact = ((newPrice - oldPrice) / oldPrice) × 100%

Example Calculations

Trade Size (USDC)
Output (YRT)
Price Impact
Effective Price

10

9.90

+1.0%

1.010 USDC/YRT

50

47.62

+5.3%

1.050 USDC/YRT

100

90.66

+10.9%

1.103 USDC/YRT

500

333.33

+50.0%

1.500 USDC/YRT

1000

500.00

+100.0%

2.000 USDC/YRT

Key Insight: Large trades relative to pool size cause exponential price impact.


Slippage Protection

Slippage occurs when the execution price differs from the expected price due to:

  1. Price movement between quote and execution

  2. Front-running by other traders

  3. Low liquidity causing high price impact

Implementation

Router provides slippage protection via amountOutMin parameter:

// Example: User expects 90 YRT but sets 5% slippage tolerance
const expectedOutput = 90;
const slippageTolerance = 0.05; // 5%
const amountOutMin = expectedOutput * (1 - slippageTolerance);
// amountOutMin = 90 * 0.95 = 85.5 YRT

await router.swapExactTokensForTokens(
    parseUnits("100", 18),  // 100 USDC input
    parseUnits("85.5", 18), // Min 85.5 YRT output
    [USDC_ADDRESS, YRT_ADDRESS],
    userAddress,
    deadline
);

Fee Mechanism

Fee Structure

Swap Fee: 0.3% (30 basis points)
Fee Denominator: 10,000

Fee Distribution

Current Implementation:

  • 100% of fees go to feeRecipient wallet (property owner)

  • Fees are collected in the input token (USDC when buying YRT)

Fee Calculation Example

User swaps 100 USDC for YRT:
- Swap fee: 100 × 0.003 = 0.3 USDC
- Fee recipient receives: 0.3 USDC
- Effective input to pool: 99.7 USDC

Liquidity Provider Economics

LP Token Value

// Value of LP tokens
lpTokenValue = (reserve0 + reserve1) / totalSupply_LP

// Share of pool
shareOfPool = lpBalance / totalSupply_LP

Example: Adding Liquidity

Pool State:
- Reserve YRT: 1000
- Reserve USDC: 1000
- Total LP Supply: 1000

User adds:
- 100 YRT
- 100 USDC

LP tokens minted:
liquidity = min(
    (100 × 1000) / 1000 = 100,
    (100 × 1000) / 1000 = 100
) = 100 LP tokens

User's share:
100 / 1100 = 9.09% of pool

Removing Liquidity

User burns 100 LP tokens:

amount0 = (100 × 1100) / 1100 = 100 YRT
amount1 = (100 × 1100) / 1100 = 100 USDC

User receives: 100 YRT + 100 USDC + accumulated fees

Advanced Concepts

Impermanent Loss

Impermanent loss occurs when token price ratio changes after providing liquidity.

Formula:

IL = 2 × sqrt(priceRatio) / (1 + priceRatio) - 1

Example:

Initial: 1 YRT = 1 USDC
After: 1 YRT = 2 USDC (YRT doubled)

Price ratio = 2
IL = 2 × sqrt(2) / (1 + 2) - 1
IL = 2 × 1.414 / 3 - 1
IL = -5.7%

Holding: 100 YRT + 100 USDC = $300
LP position: ~$282.8 (5.7% loss vs holding)

Mitigation: Fees can offset impermanent loss over time.

Minimum Liquidity Lock

First liquidity provider permanently locks MINIMUM_LIQUIDITY = 1000 LP tokens to prevent division by zero attacks.


Price Oracle

The pool reserves can serve as a simple price oracle:

// Get current price
const reserves = await pool.getReserves();
const price = reserves.reserve1 / reserves.reserve0;

// Example: Spot price for property valuation
console.log(`Current YRT price: ${price} USDC`);

Warning: Spot price is manipulatable via flash loans. For critical price feeds, use time-weighted average price (TWAP) or Chainlink oracles.


Gas Optimization

Batching Swaps

For multiple swaps, batch through router to save gas:

// Instead of:
await router.swapExactTokensForTokens(...) // 150k gas
await router.swapExactTokensForTokens(...) // 150k gas
// Total: 300k gas

// Use:
await router.swapExactTokensForTokens([
    // multi-hop if needed
], ...) // 180k gas

Liquidity Management

Add/remove liquidity during low gas periods:

  • Base network: typically ~0.0001 ETH per transaction

  • Gas cost is relatively constant regardless of liquidity size



Formula Reference Card:

Price = Reserve_USDC / Reserve_YRT

Output = (Input × 997 × Reserve_Out) / ((Reserve_In × 1000) + (Input × 997))

LP = sqrt(amount0 × amount1) - MINIMUM_LIQUIDITY (first mint)

k = x × y (constant product)

Fee = Input × 0.003 (0.3%)

Last Updated: October 2025

Last updated