Integrating with DollarPad
For third parties — trading bots, aggregators, DEX screeners, Telegram/Discord bots — adding support for tokens launched on DollarPad. This is a bonding-curve launchpad on Stable mainnet (chain id 988), not a standard AMM/DEX. Generic DEX-integration code will not work here without the specifics below.
Contract addresses
| DollarPad (production) | 0x94F7A88d8650A727b2a6667E631E3C37a827d383 |
| Uniswap V2 Router (Stable canonical) | 0xa571dc7c4f2369F1cA24D3a7E8a35c07Ff52bfC0 |
| Uniswap V2 Factory (Stable canonical) | 0x25D2d657F539F2bB16eC82773cBE5ee49ddD3c69 |
| USDT0 (ERC-20 interface of native gas) | 0x779Ded0c9e1022225f8E0630b35a9b54bE713736 |
| Multicall3 | 0xcA11bde05977b3631167028862bE2a173976CA11 |
RPC: https://rpc.stable.xyz · Explorer: https://stablescan.xyz · Full ABI in web/lib/abi.ts of the repo, or read directly from the verified contract on StableScan.
⚠️ The one thing that will break your integration if you skip it
Stable’s native gas token is USDT0, with 18 decimals — not ETH. Every price, every buy/sell value, and every quoted amount in DollarPad is denominated in native currency (18 decimals), sent as msg.value — exactly like ETH on any other EVM chain, just worth $1 per unit. There is a separate ERC-20 interface to the same balance at 6 decimals (0x779Ded0c9e1022225f8E0630b35a9b54bE713736), used only internally at graduation. Don’t confuse the two.
Also: the router’s registered WETH() address is a revert-all placeholder on this chain. Never call swapExactETHForTokens or similar *ETH router functions expecting WETH-like behavior — it will revert.
Core mechanics
- Every token is fixed-supply (1,000,000,000), no mint, no tax, no blacklist.
- Pre-graduation: the token contract reverts on any transfer that isn’t to/from DollarPad. A token is not tradeable anywhere else until it graduates — check
getTokenState(token).graduatedbefore attempting any swap-based trade. - Post-graduation: transfers are unrestricted and the token trades on the Uniswap V2 pair created automatically at graduation (LP burned to
0x…dEaD). Standard Uniswap V2 integration works fine from this point on. - Pricing follows a constant-product curve over virtual reserves — always use
quoteBuy/quoteSell, don’t compute prices frombalanceOfyourself.
Current production launch parameters
Each token freezes the params version live when it was created — call curves(token).paramsId → paramsHistory(paramsId) for the exact params a specific token launched with.
| Creation fee | 1 USDT |
| Graduation fee | 200 USDT (deducted from the raise) |
| Starting virtual USDT reserve | 3,500 USDT |
| Starting virtual token reserve | 1,080,000,000 |
| Curve supply (sellable) | 800,000,000 |
| LP supply (reserved for graduation) | 200,000,000 |
| Trade fee | 1% (0.5% creator / 0.5% protocol) |
| Anti-snipe cap | 2% of supply per wallet |
| Anti-snipe window | 100 blocks (~70s at 0.7s/block) |
Approximate full-curve raise: ~$10,000 net before graduation.
⚠️ Anti-snipe window — read before building a sniper bot
For the first 100 blocks after a token’s creation, buy() enforces a per-wallet cap of 2% of supply. Any buy pushing a wallet over that cap reverts — including from a bot. This is intentional anti-rug protection. Either size buys to respect the cap during the window (check snipeWindowBought(token, wallet) and createdBlock), or only target tokens where block.number > createdBlock + 100.
Key read functions
function getTokenState(address token) external view returns (TokenState memory);
function getTokenStates(uint256 offset, uint256 limit) external view returns (TokenState[] memory);Returns graduated, vUsdt/vToken (virtual reserves), priceUsdt18, marketCapUsdt, raisedUsdt, progressBps, plus name/symbol/metadataURI — everything in one call.
function quoteBuy(address token, uint256 usdtIn)
external view returns (uint256 tokensOut, uint256 usdtUsed, bool wouldGraduate);usdtIn is gross native USDT (18 decimals). If the buy would exhaust the curve, usdtUsed will be less than usdtIn (the rest refunds on-chain) and wouldGraduate is true — size msg.value off usdtUsed, not your original amount.
function quoteSell(address token, uint256 tokenAmount) external view returns (uint256 usdtOut);Net payout in native USDT (18 decimals) after the 1% fee.
Key write functions
function create(string name, string symbol, string metadataURI, uint256 minTokensOut)
external payable returns (address token);msg.value must be ≥ the current creation fee; any excess is spent as an immediate dev-buy in the same transaction.
function buy(address token, uint256 minTokensOut, uint256 deadline, address referrer) external payable;
function sell(address token, uint256 tokenAmount, uint256 minUsdtOut, uint256 deadline, address referrer) external;Standard slippage and deadline (unix seconds) protection. referrer is optional (pass address(0) for none) — referrers earn 10% of the protocol fee slice, pulled via claimReferralFees(). sell requires a prior approve(STABLEPAD_ADDRESS, tokenAmount).
Events to watch
event TokenCreated(address indexed token, address indexed creator, string name, string symbol, string metadataURI, uint32 paramsId);
event Trade(address indexed token, address indexed trader, bool isBuy, uint256 usdtAmount, uint256 tokenAmount, uint128 vUsdt, uint128 vToken);
event Graduated(address indexed token, address indexed pair, uint256 usdt6ToLp, uint256 tokensToLp);Trade includes the post-trade virtual reserves directly — a full price chart can be built purely from these logs, no indexer or extra state reads needed (exactly what DollarPad’s own frontend does).
Graduated fires in the same transaction as the completing Trade — watch for it to know the moment a token switches from buy/sell to normal Uniswap V2 swaps (which will revert with AlreadyGraduated afterward).
Minimal integration flow for a bot
- Watch
TokenCreated(or pollgetTokenStates) to discover new tokens. - Before a “snipe,” check
graduated == falseand whether the anti-snipe window is still active for that token. - Call
quoteBuy(token, intendedUsdtIn)for expectedtokensOut; apply your slippage tolerance forminTokensOut. - Send
buy(token, minTokensOut, deadline, referrer)withvalue: usdtUsed(native, 18 decimals). - Watch for
Graduated— once fired, switch to normal Uniswap V2 swap logic against the pair from the event (orfactory.getPair(token, USDT0)).
Questions about this integration guide can be directed to the DollarPad team.