Developers
Integration Guide
A developer-facing tour of the protocol. Whether you're a project team listing your token, an aggregator routing through Topaz, or a builder reading pool state for an oracle, this is the entry point.
Common integration paths
- ✓Aggregator / router integration — quote Topaz pools and execute swaps through Router (v2) or SwapRouter (Slipstream).
- ✓Token listing as a project — get whitelisted, create your pool, request a gauge, post incentives.
- ✓Oracle consumer — read TWAPs from Slipstream pools for your dapp.
- ✓Vault / strategy builder — automate concentrated-liquidity range management or veTOPAZ voting strategies.
Routing & quoting
For programmatic swaps, three quoter contracts cover all routes:
- ✓
Router— v2-style multihop swaps. UsegetAmountsOutfor quoting. - ✓
QuoterV2— Slipstream-only multihop quotes. Off-chain only (it reverts to return data — the standard Uniswap V3 quoter pattern). - ✓
MixedRouteQuoterV1— quotes that mix v2 and Slipstream pools in a single path. Use this when routing across both pool types.
Encoding a Slipstream path:
// Single hop
bytes memory path = abi.encodePacked(
tokenIn, // 20 bytes
uint24(tickSpacing), // 3 bytes
tokenOut // 20 bytes
);
// Multi-hop via WBNB
bytes memory path = abi.encodePacked(
tokenIn, // 20 bytes
uint24(50), // tickSpacing for first hop (low-vol)
WBNB, // 20 bytes
uint24(200), // tickSpacing for second hop (volatile)
tokenOut // 20 bytes
);See Contracts for all addresses including the mixed-route quoter and Swaps & Routing for end-user routing concepts.
Listing a token / pool (for projects)
The complete checklist for bringing a new token onto Topaz:
- 1Deploy or identify the ERC-20 contract on BNB Chain. Standard ERC-20 only — fee-on-transfer tokens are partially supported by the v2 router but not by the Slipstream periphery.
- 2Create the pool. For v2:
PoolFactory.createPool(tokenA, tokenB, stable). For Slipstream:CLFactory.createPool(tokenA, tokenB, tickSpacing, sqrtPriceX96). Both are permissionless. - 3Seed initial liquidity. Provide both tokens at a price you're willing to defend. First deposit sets the price; subsequent depositors must match the ratio.
- 4Request whitelisting. Two whitelists matter: (a) token whitelist for use as bribe rewards, and (b) for new tokens, token whitelist on the Voter to allow permissionless gauge creation. Coordinate with governance — reach out via Telegram or governance forum.
- 5Get a gauge created. Once your token is whitelisted (or for a fully-whitelisted pair, by anyone), call
Voter.createGauge(poolFactory, pool). Without a gauge, the pool exists but receives no emissions. - 6Post incentives. Approve and call
BribeVotingReward.notifyRewardAmount(token, amount)on the gauge's bribe contract to attract votes. See Incentives (Bribes).
Reading pool state on-chain
Common reads:
- ✓
PoolFactory.getPool(tokenA, tokenB, stable)— fetch v2 pool address (returns 0x0 if absent). - ✓
CLFactory.getPool(tokenA, tokenB, tickSpacing)— fetch Slipstream pool address. - ✓
Voter.gauges(pool)— fetch a pool's gauge address (0x0 if none). - ✓
Voter.isAlive(gauge)— check whether a gauge is currently active. - ✓
CLPool.slot0()— current sqrtPriceX96, tick, observation index, etc. - ✓
CLPool.observe([secondsAgo1, secondsAgo2])— compute a TWAP from the in-pool oracle. See Oracles & TWAP.
Working with the gauge directly
For programmatic LP integrations:
// v2 LP token staking
ILpToken(lpToken).approve(gauge, amount);
IGauge(gauge).deposit(amount);
// Claim emissions
IGauge(gauge).getReward(msg.sender);
// Withdraw
IGauge(gauge).withdraw(amount);
// Slipstream NFT staking
INonfungiblePositionManager(npm).approve(gauge, tokenId);
ICLGauge(gauge).deposit(tokenId);
ICLGauge(gauge).getReward(tokenId);
ICLGauge(gauge).withdraw(tokenId);Gauges follow the standard notifyRewardAmount /rewardPerToken /earnedpattern from MasterChef / Synthetix. Rewards stream linearly across 604,800 seconds after each epoch's emission allocation.
Voting on behalf of a contract
Smart-contract vaults that hold veTOPAZ NFTs can vote and claim like any wallet. Standard flow:
// One-time setup: vault must own (or be approved for) the veNFT
IVoter(voter).vote(
tokenId,
[pool1, pool2, ...],
[weight1, weight2, ...]
);
// Each epoch, after the flip:
IVoter(voter).claimBribes(
[bribeContract1, ...],
[[token1A, token1B], ...],
tokenId
);
IVoter(voter).claimFees(
[feeContract1, ...],
[[token1A, token1B], ...],
tokenId
);Indexing & subgraph
Topaz emits standard events at every state change — pool creates, swaps, mints, burns, votes, gauge distributions, and reward claims. Indexers can subscribe to these directly via BscScan log endpoints or run a custom subgraph. If you build public indexing infrastructure for the protocol, get in touch via Telegram for cross-linking.
