Launch App

Liquidity & Reserves

Understanding how Uniswap V2 pairs calculate trading prices on-chain, how price impact/slippage operates under the Constant Product formula, and how market forces drive oracle-pair convergence.

Uniswap V2 Pair Reserves

Unlike mainnet stock trading which flows through complex off-chain RFQ (Request-for-Quote) or Uniswap V3 Concentrated Liquidity, stock tokens on Robinhood Chain testnet and early L2 mainnet settle inside standard Uniswap V2 Constant Product pools (x × y = k).

Each pool pairs a stock token (e.g. TSLA, decimals 18) against the default gas-pegged stablecoin (USDG, decimals 6). You can query the reserves directly:

fetch-reserves.ts
import { parseAbi } from "viem";

const pairAbi = parseAbi([
  "function getReserves() view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast)",
  "function token0() view returns (address)",
]);

const factoryAbi = parseAbi([
  "function getPair(address tokenA, address tokenB) view returns (address pair)",
]);

// 1 — Resolve the pool pair address
const pairAddress = await publicClient.readContract({
  address: UNISWAP_V2_FACTORY,
  abi: factoryAbi,
  functionName: "getPair",
  args: [TSLA, USDG],
});

// 2 — Query pair reserves
const [res0, res1] = await publicClient.readContract({
  address: pairAddress,
  abi: pairAbi,
  functionName: "getReserves",
});

const token0Address = await publicClient.readContract({
  address: pairAddress,
  abi: pairAbi,
  functionName: "token0",
});

// 3 — Match reserves to tokens
const [reserveTsla, reserveUsdg] = token0Address.toLowerCase() === TSLA.toLowerCase() 
  ? [res0, res1] 
  : [res1, res0];

console.log(`Pool Reserves: ${Number(reserveTsla) / 1e18} TSLA | ${Number(reserveUsdg) / 1e6} USDG`);

Constant Product Pricing Formula

Uniswap V2 calculates output tokens using the constant product swap equation with a flat 0.3% pool fee. To calculate the exact output amount dy for a given input dx, use this math:

swap-pricing.ts
// dx = amount of TSLA to sell (1.0 * 1e18)
// x = reserveTsla, y = reserveUsdg
// 0.3% fee: dxWithFee = dx * 997

const dx = 1_000000000000000000n; // 1 TSLA
const dxWithFee = dx * 997n;
const numerator = dxWithFee * reserveUsdg;
const denominator = (reserveTsla * 1000n) + dxWithFee;

const dyAmountOut = numerator / denominator; // Output in USDG (6 decimals)
const executionPrice = Number(dyAmountOut) / 1e6; // Price received per TSLA

Price Impact vs. Oracle Prices

Price impact is size-dependent, not oracle-dependent.The Chainlink price feed acts solely as the *trigger threshold* for limit orders. The actual execution swap price is determined entirely by the Uniswap V2 pool reserves at the block of execution. If a user places an order of $10,000 in a shallow pool with only $20,000 of reserves, the swap will experience significant slippage (nearly 33% price impact) regardless of what NASDAQ quotes!

Arbitrage Mechanics

Because trading pools are on-chain 24/7 while traditional markets close, pool prices can drift. Arbitrageurs keep the on-chain pool prices aligned with Chainlink/NASDAQ stock quotes:

  • Pool Discount — If the pool price of TSLA falls below the Chainlink trigger price, arbitrageurs buy TSLA on-chain and hold it, pushing the pool price back up.
  • Pool Premium — If the pool price climbs above NASDAQ quotes, traders sell stock tokens into the pool to take a USDG profit, depressing the pool price back to equilibrium.