Contract Addresses
Deployment status of every Motoswap contract on Ethereum, the deployed addresses, and how to read them at runtime.
Read addresses at runtime from
GET https://api.motoswap.org/config. That endpoint is the canonical source. Every address below was checked against it and against code on chain (eth_getCodeplus one identifying call). If this page and/configever disagree,/configwins.
The plain-language list for users, with Etherscan links and one line on what each contract does, is Contracts.
Deployment status on Ethereum (chain 1)
Status is per contract. A contract is either deployed at the address shown, or not deployed yet. A
contract that is not deployed reads back from /config as
0x0000000000000000000000000000000000000000. The key is always present. Branch on the address
being 0x0, never on a key being absent, never send a transaction to a 0x0 address, and do not
integrate against any other address for a contract this table lists as not deployed.
/config returns addresses lowercase; the checksummed form is shown here.
| Contract | /config key | Status | Address |
|---|---|---|---|
MotoToken (MOTO, 18 decimals) | motoToken | Deployed | 0xBd965230588EAA536dE6aA45E8ebbc01638535e0 |
VampChef (the launch farming contract) | vampChef, and masterChef while launchPhase is vamp | Deployed | 0x51e648f08a9a08A724591938d9cbc483C809aCA4 |
UniswapZap (zap into a Uniswap V2 LP and stake it in the farm) | uniswapZap | Deployed | 0x532bFB5b8c9e3CeF20d36910B90cfbD919b18C31 |
RewardVestingEscrow | rewardVestingEscrow | Deployed | 0xB94bFadc535D96462854175D776Afc168196976b |
MotoStaking | motoStaking | Deployed | 0xCE88F2C6B49EfBb92555eE5475311f0e250C2528 |
TreasuryVesting | treasuryVesting | Deployed | 0x5730ABdF3C06c37940FB8B5291277e62D2c15278 |
| Motocat NFT collection | motocatNft | Deployed | 0x0B024b3D4ad38BFf1Acd303cd308D2C49c936E0A |
MotocatStaking | motocatStaking | Deployed | 0x11890Ee9eE6099Ac33fd4dfb702f8E8f6d651f17 |
MotoSwapFactory | factory | Deployed | 0x81C9CBC47d700dA1777aBd831D8dA3f526DfAe24 |
MotoSwapRouter02 | router | Deployed | 0x6F0b6a0D84C3cFf6f273D5294CDA147885225D5E |
FeeRouter | feeRouter | Deployed | 0x9f846ef584FD44d075B5E8dF00dDB4416da61a80 |
MotoSwapPair (every Motoswap pair) | none, derive from factory | Deployed per pair | none, one address per pair from factory |
MotoSwapZap | zap | Deployed | 0x26BffD661C3d97B3285AfA2a9F05232526A89129 |
Collector | collector | Deployed | 0xC13307272bBf73f2191cE57d0Fb714C2A9200cF3 |
QuoteAssetRegistry | quoteRegistry | Deployed | 0xFb8CA710B9B242e9f5027272592ef4C19D37E200 |
RakebackV2 | rakeback | Deployed | 0x89E2E1819Fc373e3cD840A0ceb2Ef1eAE79E2dB8 |
MasterChef (deployed; no sustain farm is running) | masterChef (holds the VampChef while launchPhase is vamp) | Deployed | 0x939f348b6658cE4DB7CDe088341b00DE341Fe085 |
CreatorFeeRegistry | creatorFeeRegistry | Deployed | 0x6CdEC7F49036Ccf1bba940011040fA044cFe6D08 |
CreatorFeeVault | creatorFeeVault | Deployed | 0x8cC7C8E76D9698E5B1026c720a94C1807e613e1f |
PveVault | pveVault, pveVaultV2 (two instances of one contract; either can read 0x0) | Deployed | 0x84303a885717C4dd9EffBdD2179BBE4b01756740 (pveVault; pveVaultV2 reads 0x0) |
BuybackBurner | buybackBurner | Deployed | 0x85B5A2800d7E2D948F21Cb8F6E610D2c9B19AE3d |
| moto.fun curve and lens | launchpadCurve, launchpadLens | Deployed | curve 0xb65b67e986d7B097652920d72202F2c78319BC2C, lens 0xb631697124c8e6Bb6C221Cc017e47D4168bd3411 |
Third-party contracts that /config also serves:
| Contract | /config key | Address |
|---|---|---|
MOTO/WETH pair for the phase (a Uniswap V2 pair during vamp) | motoUniswapPair | 0xAD1a21F61d653c6101b92c335f61140459C81C79 |
Uniswap V2 Router02 (canonical, the farm's trading venue during vamp) | uniswapV2Router | 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D |
| Uniswap V2 factory (canonical) | uniswapV2Factory | 0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f |
| WETH (canonical) | weth | 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2 |
| USDC (canonical, 6 decimals) | usdc | 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48 |
| USDT (canonical, 6 decimals) | usdt | 0xdAC17F958D2ee523a2206206994597C13D831ec7 |
| Permit2 (canonical) | permit2 | read the value /config serves, see below |
/config.launchPhase summarises the same thing. It reads dex once the DEX contracts are deployed,
and it reads vamp only while the farm is deployed and the DEX is not, which is how it read before
the DEX opened.
Read /config.addresses.masterChef rather than assuming what is behind it. While launchPhase
was vamp it held the same address as vampChef, and that contract is a VampChef, not a
MasterChef: VampChef.withdraw returns your LP in one call, it has no claimWithdrawal and no
deposit fee, and its PoolAdded and PoolSet events carry no depositFeeBps. Every
row of GET /farms carries a chef field, so use that as the deposit target instead of assuming a
key.
VampChef, RewardVestingEscrow, MotoStaking, TreasuryVesting and MotocatStaking are ERC-1967
proxies. MotoToken is not upgradeable and has no owner.
Verify any of these yourself with one call each: symbol() on motoToken returns MOTO,
rewardToken() on vampChef returns the MOTO address, vestingEscrow() on vampChef returns the
rewardVestingEscrow address, and collection() on motocatStaking returns the motocatNft
address.
Notes on the zero keys
permit2 is a feature switch as much as an address. Canonical Permit2 is deployed on chain 1 at
0x000000000022D473030F116dDEE9F6B43aC78BA3, and the key carries that address once FeeRouter,
which owns the Permit2 path, is deployed. Use the value /config gives you. A 0x0 there is a
configuration fault worth reporting, not a phase.
launchpadCurve and launchpadLens also read 0x0 whenever motofunEnabled is false, so gating
on the address alone is correct.
Keys that stay zero
/config key | Why |
|---|---|
tokenLauncher | Retired contract. It is not deployed and the key stays 0x0. Launches happen on moto.fun. |
buybackDistributor | Not deployed. Nothing schedules this contract. |
vaultCompounder | Legacy key. No contract sits behind it. |
vaults[0..3] | Legacy array. MotoStaking holds every lock option in one contract. |
The rest of the response
/config also returns chainId, launchPhase (prelaunch, vamp or dex), splitSwapEnabled,
motofunEnabled, motofunUrl, bridgeMotoEnabled, pveComboEnabled (dead: nothing reads it), and
misconfigured: string[] (empty in normal operation; it names any address a transaction would
target that is unset for the current phase). It does not return an RPC URL. Bring your own.
Not exposed by /config
Only the Snapshotter (operational tooling) has no /config key. Everything else is served
directly, with no on-chain getter chase needed.
Deriving pairs
Derive any Motoswap pair from the factory rather than hard-coding it:
factory.getPair(tokenA, tokenB). The Uniswap V2 pools the farm used during vamp derive the same
way, from uniswapV2Factory.
rewardVestingEscrow also has an on-chain getter, vestingEscrow() on the chef, which is worth
preferring since it survives a redeploy that /config has not caught up with.
If an address is not in /config and not discoverable from a /config contract's getters, do not
integrate against it. Contracts published under Motoswap-adjacent repos are sibling experiments,
not the Motoswap DEX.
Local development
There is no public local stack and no public test deployment of the Motoswap contracts. To work
locally, fork Ethereum mainnet with your own node tooling and use the chain 1 addresses from
GET https://api.motoswap.org/config. A fork only carries what was already deployed at the block
you fork from, so pin a recent block, and read the interfaces in the
contracts inventory when you need the shape of a call
before you make it.
Sanity check: addresses vary per environment
MOTO and every Motoswap contract have a different address on every environment, and sibling
experiments carry their own mocks. Always resolve via /config, and check chainId in the same
response. Never assume addresses match across projects or deploys.