Architecture & Mechanics
Lista V3 Dex is a concentrated-liquidity automated market maker (AMM) deployed on BNB Smart Chain.
Lista V3 is a fork of Uniswap V3. The canonical Uniswap V3 model, math, contract interfaces, and SDKs (e.g.
@uniswap/v3-sdk,@uniswap/sdk-core) apply directly. Contracts are renamed (ListaV3Factory,ListaV3Pool) but their interfaces, events, and behaviour match Uniswap V3. Four things differ in Lista's deployment and will break a copied V3 integration if you miss them: the enabled fee tiers, the NFT name, an upgradeable position manager, and — for off-chain address derivation — a Lista-specific pool init-code hash (see Building on Lista V3). For the underlying math, use the Uniswap V3 whitepaper.
For deployed contract addresses see Smart Contract.
Component contracts
ProxyAdmin
Admin of the upgradeable proxies in the deployment (e.g. the position manager).
ListaV3Factory
Deploys and registers one pool per (token0, token1, fee) tuple; owns the enabled fee-tier → tick-spacing table.
ListaV3Pool
The core AMM contract for a single pair + fee tier. Holds liquidity, slot0 price/tick state, fee accumulators, ticks, and positions. Created by the factory.
NonfungiblePositionManager
Periphery contract that wraps liquidity positions as ERC-721 NFTs and handles mint / increase / decrease / collect / burn. Deployed behind a transparent proxy.
NonfungibleTokenPositionDescriptor
Renders on-chain token metadata (tokenURI) for position NFTs.
SwapRouter
Periphery contract for executing single-hop and multi-hop swaps with slippage and deadline protection.
The *Pool rows in Smart Contract are individual pools deployed by the factory, not a singleton — every distinct (token0, token1, fee) combination is its own ListaV3Pool instance.
AMM model
Factory → Pool
A pool is uniquely identified by the ordered token pair and the fee tier. Tokens are sorted by address so that token0 < token1; the factory stores the pool both ways in getPool[token0][token1][fee].
// ListaV3Factory
function createPool(address tokenA, address tokenB, uint24 fee) external returns (address pool);
function getPool(address tokenA, address tokenB, uint24 fee) external view returns (address pool);
function feeAmountTickSpacing(uint24 fee) external view returns (int24);
event PoolCreated(address indexed token0, address indexed token1, uint24 indexed fee, int24 tickSpacing, address pool);createPool derives tickSpacing from the fee tier, deploys the pool deterministically, and emits PoolCreated. A newly created pool must be initialized once via initialize(sqrtPriceX96) before liquidity can be added. The pool address is deterministic (CREATE2 from the pool key), but Lista's pools have their own bytecode, so off-chain derivation must use Lista's pool init-code hash — not Uniswap's — or simply read factory.getPool(token0, token1, fee). See Building on Lista V3 for the hash.
Positions as ERC-721 (NonfungiblePositionManager)
Liquidity positions are minted as ERC-721 NFTs. The collection is named Lista V3 Positions NFT with symbol LISTA-V3. Unlike Uniswap's immutable position manager, the Lista deployment is an upgradeable contract (transparent proxy + initialize()); the ERC-721 token semantics are otherwise standard and it supports EIP-712 permit.
Reading a position returns the full Uniswap V3 position tuple:
tokensOwed0 / tokensOwed1 are the position's uncollected balance, credited on liquidity changes and realized via collect. They hold more than fees: decreaseLiquidity adds the withdrawn principal to them rather than transferring it, so removing liquidity moves no tokens on its own — a follow-up collect is required to receive both the principal and the accrued fees.
Swaps (SwapRouter)
Swaps are routed through the SwapRouter, which supports exact-input and exact-output, single-hop and multi-hop. Single-hop selects a pool by (tokenIn, tokenOut, fee); multi-hop uses a packed path (20-byte token, 3-byte fee, 20-byte token, …).
amountOutMinimum / amountInMaximum enforce slippage limits, deadline bounds execution time, and sqrtPriceLimitX96 optionally caps the price movement within the swap.
Uniswap V3 mechanics
Lista V3 is a Uniswap V3 fork and the pool maths is unmodified: ticks (1.0001^i, MIN_TICK/MAX_TICK), slot0.sqrtPriceX96 in Q64.96, the feeGrowthGlobal{0,1}X128 accumulators, tick crossing, the observation ring buffer, and the Mint/Burn/Collect/Swap/Flash/Initialize event shapes all behave as documented upstream. Use the Uniswap V3 docs and @uniswap/v3-sdk (TickMath, SqrtPriceMath) for the maths rather than reimplementing it.
What differs from Uniswap is the deployed addresses, the fee tiers enabled on the Lista factory, and the pool-address derivation.
Fee tiers and tick spacing
Fee tiers are set in the ListaV3Factory. Each tier maps a fee (in hundredths of a basis point, i.e. 1e-6) to a tickSpacing. Five are enabled on the live factory:
Fee tier
fee (uint24)
tickSpacing
Notes
0.0002%
2
1
Enabled post-deployment; used by Lista stablecoin pools
0.01%
100
1
Enabled post-deployment; used by Lista LST pools
0.05%
500
10
Constructor
0.30%
3000
60
Constructor
1.00%
10000
200
Constructor
Lista's stablecoin and LST pools (noted in the table above) use the two lowest tiers, which are not in the constructor set. Do not assume that Uniswap's common
500/3000/10000tiers identify Lista pools; query the factory for the target pool's fee tier.
Additional tiers can be added by the factory owner via enableFeeAmount(fee, tickSpacing); a tier, once enabled, can never be removed, and feeAmountTickSpacing(fee) returns 0 for tiers that are not enabled. Read feeAmountTickSpacing(fee) (or watch the FeeAmountEnabled event) for the authoritative live list rather than hard-coding tiers.
Building on Lista V3
Because Lista V3 is a Uniswap V3 fork:
Use
@uniswap/v3-sdkand@uniswap/sdk-corefor price/tick math, position math, and route encoding, pointing them at the Lista contract addresses and BNB Smart Chain (chainId 56).The pool address is deterministic from
(factory, token0, token1, fee)via CREATE2, but you must use Lista's own pool init-code hash —0xa93d35cf943696a95cabbe3aa4b3d87ea5387169face953a337716fc15136ca2— in thePoolAddresscomputation. Uniswap V3's default init-code hash yields the wrong address for Lista pools. Alternatively, readfactory.getPool(token0, token1, fee)on-chain instead of deriving it.Pool, factory, and periphery interfaces match Uniswap V3
IUniswapV3Pool/IUniswapV3Factory/INonfungiblePositionManager/ISwapRouter, so existing V3 integrations port with minimal changes (renamed contracts, the upgradeable position manager, and the Lista-specific NFT name/symbol aside).
Related pages
V3 Dex overview — section landing page.
Last updated
Was this helpful?