Documentation

DEX overview

Two AMMs on ApeChain, a Uniswap V2 fork and a Uniswap V3 fork, with the addresses, init code hashes and fee tiers that differ from upstream.

On this page

Armory ships two automated market makers on ApeChain. Both are Uniswap forks that stay byte-equivalent to upstream except for the modifications listed on this page.

That rule is the reason this integration is cheap. If you already have a Uniswap V2 or V3 integration, the interfaces are the ones you know. The interface types even keep their IUniswap* names, deliberately, so existing tooling resolves against them. What changes is the addresses, the two CREATE2 init code hashes, and the V3 fee tier set.

The two AMMs

V2V3
Upstream@uniswap/v2-core 1.0.1, @uniswap/v2-periphery 1.1.0-beta.0 (Router02)Uniswap/v3-core v1.0.0, Uniswap/v3-periphery 1.4.4
Compiler0.5.16 (core), 0.6.6 (periphery)0.7.6
Liquidityfull range, fungible LP ERC-20concentrated, ERC-721 positions
Feefixed 0.3%four tiers: 0.1%, 0.3%, 1%, 2.5%
Entry pointArmoryV2RouterSwapRouter, NonfungiblePositionManager
QuotinggetAmountsOut (a view)QuoterV2 (reverts by design, so simulate it)
Oracleprice0CumulativeLast / price1CumulativeLastring buffer via observe

Which to target

Target V3 when you need range orders, tick-level data, or the 2.5% tier. Target V2 when you want a view quote with no simulation round trip, a fungible LP token you can lock or collateralize, or the simplest possible path encoding.

New token launches on this venue land on V3's 2.5% tier by default. If you are routing, quote both. The same pair can exist on a V2 pair and on up to four V3 pools simultaneously, and nothing forces them to agree.

Deployment facts

Chain is ApeChain mainnet, chain id 33139. There is no testnet target.

Wrapped native APE is WAPE. Every place upstream Uniswap says WETH or WETH9 (the V2 router's WETH() getter, the V3 periphery's WETH9() getter, unwrapWETH9, swapExactETHForTokens) that identifier is unchanged in the source and resolves to WAPE. The names were not renamed; only the wiring changed. Read the address off the contract rather than assuming.

ContractAddressApeScan
WAPE0x48b6…B557
Wrapped APE. Not deployed by us, referenced by every native leg.
const wape = await publicClient.readContract({
  address: CONTRACTS.v2Router,
  abi: V2_ROUTER_ABI,
  functionName: "WETH",
});

Init code hashes

Two CREATE2 init code hashes let you derive pair and pool addresses off-chain with no RPC call. Both are compiled into periphery libraries.

Value
V2 pair0x21fb0317b1cb8af900b47ec04f932891e3d91dda70b5d0ddcd0f33aca7486b85
V3 pool0xe34f199b19b2b4f47f68442619d555527d244f78a3297ea89325f843f87b8b54

The V2 hash is Armory-specific because the LP token's name and symbol change the pair creation code. The V3 hash is Uniswap's canonical mainnet pool init code hash.

Each hash is documented with its derivation on the page that owns it: V2 core and V3 core.

Contract map

ContractAddressApeScan
ArmoryV2Factory0x7AA7…50D5
ArmoryV2Router0x98ca…5D7D
ArmoryV3Factory0xAb52…434F
NonfungiblePositionManager0x7530…306a
SwapRouter0x4718…C46b
QuoterV20xbA1E…e7e0
TickLens0xb26B…85Ce
UniswapInterfaceMulticall0x0Cdb…d697
ArmoryDexAdmin0x9a8d…2e27
ArmoryDexFeeManager0xb904…49Ad
The DEX itself. Roles and ownership are on the access control page.

The lockers, the aggregator and the integrator referral router are separate product surfaces documented elsewhere. They compose these contracts and do not alter them. The aggregator's platform fee is read from chain at trade time and is not a property of the AMMs below.

ContractAddressApeScan
ArmoryTokenLocker0xD5d7…259F
ArmoryV3Locker0x98B8…d123
ArmoryFeeModuleRegistry0xA9De…0A23
ArmoryFeeSplitter0x5616…1B4b
ArmoryLockRouter0x44c0…8033
ReferralRouter0xc6be…7E36
ArmoryTradeManager0x2cea…Dd9F
ArmoryAdapter0xfF7D…c06d
CamelotAdapter0xe3C1…2497
ArmoryTradeCashBackReceiver0x9B10…4a03

What is different from stock Uniswap

The complete modification list:

  1. Renames. UniswapV2Factory/Pair/ERC20, UniswapV2Router02, UniswapV3Factory/Pool/PoolDeployer become Armory*. Interfaces keep their IUniswap* names. Zero bytecode impact except where item 3 applies.
  2. V3 fee tiers. Set in the ArmoryV3Factory constructor. Factory bytecode only.
  3. Branding strings. V2 LP token is Armory V2 / ARMORY-V2; the V3 position NFT is Armory V3 Positions NFT-V1 / ARMORY-V3-POS. The LP token strings are what move the V2 pair init code hash.
  4. The V2 init code hash constant in UniswapV2Library, patched to match. PoolAddress needed no patch.
  5. Pragma caps (<0.8.0 on open-ended pragmas) and the core-v3 SPDX header updated from BUSL-1.1 to GPL-2.0-or-later, reflecting Uniswap's own 2023-04-01 license conversion.

Nothing else. No fee-on-swap hook, no transfer tax, no pause switch, no upgradeable proxy, no allowlist. A V2 pair and a V3 pool here behave exactly as their upstream counterparts do.