Skip to main content
In a Sauce program, swap with @sauce/router’s function for the venue (uniswapV2, uniswapV3, uniswapV4, curve, balancerV2, …; Slipstream, PancakeSwap V3 and Algebra pools through uniswapV3), with a minimum output and, where the pool takes one, a price limit (the @sauce/router reference; several pools under one limit, the distributed swap).
DEX on BNB Chain using the constant product AMM model (x*y=k). Forked from Uniswap V2 with additional features like yield farming and lottery.

When to use it

  • A Uniswap V2 fork with a 0.25% fee; the same Router interface.

Pitfalls for a program

  • As Uniswap V2: amountOutMin is the only bound; through the Router, approve exactly amountIn and pass a deadline.
  • The 0.25% fee differs from Uniswap V2’s 0.3%: quote with this protocol’s Router (getAmountsOut), not Uniswap’s formula, and give uniswapV2 the pair’s fee, 2500 ppm.

In a Sauce program

Sell the Pot’s USDC for WETH at the pair:
uniswapV2 prices the output from the pair’s reserves with its 0.25% fee (2500 ppm), pushes amountIn to the pair, pays recipient and reverts below minOut. The pair takes the whole input or the program reverts, so no input is left to return.

What it offers

  • swap: Swap exact input tokens through a routing path
  • addLiquidity: Deposit two tokens to mint CAKE-LP tokens
  • removeLiquidity: Burn LP tokens to withdraw underlying tokens

Notes

  • Same Uniswap V2 interface; 0.25% fee per swap (0.17% to LPs, 0.03% to treasury, 0.05% to CAKE buyback)
  • BSC Router address differs from other chains (BSC was the original deployment)
  • Arbitrum, Base, Linea, and opBNB share the same Factory and Router addresses
  • LP tokens can be staked in MasterChef for CAKE rewards
  • Use PancakeSwap V3 for concentrated liquidity
  • From a Pot program, @sauce/router trades a PancakeSwap V2 pair directly, with no router and no approval: uniswapV2(pair, tokenIn, tokenOut, amountIn, 2500, minOut, recipient) — 2500 ppm is PancakeSwap V2’s 0.25% fee — reads the pair’s getReserves, prices the output in the program with the pair’s fee in parts per million, transfers the input to the pair and calls pair.swap with empty data, returning the amount out. The direction is the sort order of tokenIn and tokenOut (token0 is the lower address), so there is no argument to get wrong. The swap consumes its whole input or reverts; there is no refund path. tryUniswapV2 takes the same arguments and returns 0, moving nothing, when the pair cannot fill the whole input at the floor. The uniswapV2Swap action is the same call

Its names in a program

On Ethereum, PancakeswapV2 is a namespace: its contracts need no import.

Deployments

ABI

Where a line says what an address it returns is, a program that calls the function through its namespace calls that contract’s methods on the result directly: <Namespace>.<Contract>.<function>(...).<method>(...). A token’s methods are the ERC-20 functions, and its writes are SafeERC20.

PancakeSwapV2FactoryABI

import PancakeSwapV2FactoryABI from "./protocols/pancakeswap-v2/PancakeSwapV2FactoryABI.json"; Speaks for: factory.
  • getPair(address tokenA, address tokenB) view returns (address pair): the address is a PancakeswapV2.Pair
  • createPair(address tokenA, address tokenB) returns (address pair)

PancakeSwapV2PairABI

import PancakeSwapV2PairABI from "./protocols/pancakeswap-v2/PancakeSwapV2PairABI.json";
  • getReserves() view returns (uint112 _reserve0, uint112 _reserve1, uint32 _blockTimestampLast)
  • token0() view returns (address): the address is a token
  • token1() view returns (address): the address is a token
  • swap(uint256 amount0Out, uint256 amount1Out, address to, bytes data)

PancakeSwapV2RouterABI

import PancakeSwapV2RouterABI from "./protocols/pancakeswap-v2/PancakeSwapV2RouterABI.json"; Speaks for: router.
  • swapExactTokensForTokens(uint256 amountIn, uint256 amountOutMin, address[] path, address to, uint256 deadline) returns (uint256[] amounts)
  • swapTokensForExactTokens(uint256 amountOut, uint256 amountInMax, address[] path, address to, uint256 deadline) returns (uint256[] amounts)
  • addLiquidity(address tokenA, address tokenB, uint256 amountADesired, uint256 amountBDesired, uint256 amountAMin, uint256 amountBMin, address to, uint256 deadline) returns (uint256 amountA, uint256 amountB, uint256 liquidity)
  • removeLiquidity(address tokenA, address tokenB, uint256 liquidity, uint256 amountAMin, uint256 amountBMin, address to, uint256 deadline) returns (uint256 amountA, uint256 amountB)
  • getAmountsOut(uint256 amountIn, address[] path) view returns (uint256[] amounts)

Next steps