# MDOG Puppy Pad > Puppy Pad is the launchpad built by the MDOG community. It runs on Arc testnet (chain id 5042002) and nowhere else, by design: it is a testing ground for the MDOG community and for AI agents, and nothing on it is real money. Liquidity is locked by a contract with no withdraw function and the 1% trading fee is split 50/50 with the creator. No API key, no account, no backend. Everything works over a public RPC with eth_call and eth_sendTransaction. ## Status - Arc testnet only, chain id 5042002. There is no mainnet factory and no way to select one from the site. - RPC: https://rpc.testnet.arc.io Explorer: https://explorer.testnet.arc.io - Factory (LaunchFactory), Arc testnet: 0x732e6Beac348AE1BC77f2C94F1aeF76E90B52811 - Testnet USDC comes from Circle's faucet: https://faucet.circle.com - MDOG, the community token this pad is named after, is on Arc at 0x83fD0BDDdafA9a499582899d49515060C361b9aa. It is not the pad, it is not a testnet token, and it is not yet usable as a quote asset here. ## Pages - [Board](https://mdog.fun/): every launch, read live from the chain, ranked by market cap - [Token](https://mdog.fun/token?ca=0xADDRESS&chain=5042002): one token, its trade panel and its on-chain facts. This is the per-token URL pattern; the pages are noindex because the names on them are written by whoever deployed the token - [Launch](https://mdog.fun/launch): the creator surface - [Proof](https://mdog.fun/proof): the addresses and the exact read-only calls to check every claim - [For agents](https://mdog.fun/agents): the three calls - [Share](https://mdog.fun/share): the contract address, the chart, the faucet, and lines to copy - [Contact](https://mdog.fun/contact): report a bug, send feedback. A message is enough, contact details are optional - [pad.json](https://mdog.fun/pad.json): addresses, selectors, curve parameters and limits in one fetch - [llms-full.txt](https://mdog.fun/llms-full.txt): the full text of the pages ## The calls - launch((string,string,uint256,uint256,address,uint8,bool,bool)) on the factory, selector 0xc7008810. The fields are name, symbol, supply, creatorAllocation, quote, curveId, burnTokenFees, burnQuoteFees - launchCount() 0x27cca59f, then launches(uint256) 0x7b443a76, which returns token, locker, creator, curveId, the pool key and the pool id - creatorEligible() 0xc7485d6b and creatorMinHold() 0x37a0b3f0 on a launch's locker; positionCount() 0xe7702d05 and positions(uint256) 0x99fbab88 for the locked positions; collect() 0xe5225381 is the only path by which value leaves the locker - getSlot0(bytes32) 0xc815641c on Uniswap's StateView for the live price - quoteExactInputSingle(((address,address,uint24,int24,address),bool,uint128,bytes)) 0xaa9d21cb on the v4 Quoter, then execute(bytes,bytes[],uint256) 0x3593564c on the Universal Router to trade - Launched(address,address,address,uint8,uint256,uint256,bytes32) has topic 0x75affb636e6fc233dfaee3912bccefe284b416c890c83b5b1db90fc5caa33cc6 ## What it does - **Discover.** A board of every launch ranked by market cap, read live from the chain, showing whether the liquidity is locked, what the creator kept, whether they still hold it, and how many launches have never traded above their opening price. - **Trade.** Buy and sell through Uniswap's own Universal Router. Lightweight, not a full dex. - **Create.** One transaction deploys a fixed-supply token, opens a pair on Uniswap v4, mints the liquidity and locks it. ## What the contracts enforce - Liquidity goes to a locker contract with no withdraw function. Not a timelock, not a promise. - The 1% fee comes from the pool's own fee tier, so no code of the pad runs inside a trade. Half to the creator, half to the treasury. Where burnQuoteFees is set, the platform half is burned rather than paid to the treasury. - The creator half stops permanently once the creator no longer holds their launch allocation. It tracks one address. Moving the allocation to another wallet counts as selling and trips it too. It does not cover a creator who takes a small allocation and buys more from wallets it never sees. - Creator allocation is capped at 10% of supply, enforced by the factory. - The quote asset must have 18 decimals; the factory refuses anything else. - No owner, no admin, no upgrade path, anywhere. - The factory retains nothing from a launch. Anyone can send it tokens afterwards, so read its balance rather than assuming. - Curves are fixed presets: a creator cannot pass their own ticks. On the Standard curve, 3,800 USDC buys at most about 12% of supply, which is an upper bound and not an estimate, and splitting a buy across wallets or blocks does not help, because every buyer walks the same curve. ## What it does not do Anyone can launch anything. Nothing on the board is vetted, endorsed or filtered, names and tickers can be copied, and most tokens go to zero. Locked liquidity means the pool cannot be drained by whoever made it, and nothing more than that. This is testnet, so none of it is real money either way. The contract source is not published and the contracts are not verified on the explorer, so nothing on this site depends on a reader inspecting the code and no claim here should be taken on trust. Every claim above is meant to be checked from the chain, by behaviour: who owns the position, which functions revert because they do not exist, and what the factory holds. Nobody outside the project has seen the contract source. ## Key facts - Gas on Arc is USDC itself, so the quote side of every pair is the native currency (address zero, 18 decimals) - Uniswap v4 on Arc testnet: PoolManager 0x8366a39CC670B4001A1121B8F6A443A643e40951, PositionManager 0x6049c9a0e26405C0985f9E3685C87d0aE917f82B, StateView 0xF3334192D15450CdD385c8B70e03f9A6bD9E673b, Quoter 0x8Dc178eFB8111BB0973Dd9d722ebeFF267c98F94, UniversalRouter 0x4fcA4a51Ab4F23A7447b3284fBd7D73289A89Fb1, Permit2 0x000000000022D473030F116dDEE9F6B43aC78BA3 - Source: /app.js, /abi.js, /config.js, /sel.js, /board.js, /token.js, /launch.js, /proof.js, /static.js, /contact.js. No dependencies and no third-party scripts. The content security policy is default-src 'none' with script-src 'self'; the only external host any page contacts is the form service behind /contact, and only when the form is sent - Contracts: LaunchToken, Curves, FeeLocker, LaunchFactory --- # The pages, in full The site is six pages plus a per-token page. Every page carries the same masthead, the same testnet bar ("Testnet. Nothing here is real money. Get testnet USDC from Circle."), the same MDOG hero, and the same footer. Text that a page reads from the chain at load time is described rather than quoted, because it changes. # https://mdog.fun/ (the board) Hero: Liquidity goes to a contract with no withdraw function. The 1% fee splits 50/50, and the creator's half stops for good if they sell their own bag. A testing ground for the MDOG community and for agents. Launch one, trade it, try to break it. MDOG contract address: 0x83fD0BDDdafA9a499582899d49515060C361b9aa, with a copy button and a link to the MDOG chart on DexScreener. Board. Sorted by market cap or by newest. A line of counts is read from the chain: how many launches there are on Arc testnet, how many are still at the price the curve opened at, and how many have a creator who has sold. Warning, shown above the board: anyone can launch anything here. Nothing is vetted, names can be copied, and most tokens go to zero. Check the contract address, not the ticker. Each launch is a card: a mark generated from its contract address, its rank, ticker and name, its market cap, tags for whether the liquidity is locked, whether the creator still holds their allocation, and whether the pool has never moved off its opening price, then the curve it used and a short form of its address. The card links to /token?ca=0x...&chain=5042002. Note under the board: market cap is price times supply, read from the pool on every load. "At launch price" means the pool price has not moved off the tick the curve opened at, so nobody has bought. That is where most launches stay, and we show it rather than dress it up. Two tiles: Launch a token ("One transaction deploys the token, opens the pair, mints the liquidity and locks it. Your allocation is capped at 10%, and you earn 0.5% of every trade while you still hold it") and What is enforced ("The addresses, the contracts, and the exact read-only calls you can run yourself to confirm the locker owns the liquidity and nobody can take it back"). Footer, on every page: Puppy Pad is the launchpad built by the MDOG community. Permissionless means anyone can launch anything: we do not check, endorse or vet tokens, and most of them will go to zero. Nothing here is financial advice. No cookies, no tracking, no third-party scripts. The page talks to an Arc RPC, and to a form service only if you choose to send feedback. # https://mdog.fun/launch Hero: One transaction deploys the token, opens the pair, mints the liquidity and locks it. Your allocation is capped at 10%, and your half of the 1% fee pays only while you hold it. Testnet only, so launch the mistake here rather than somewhere it costs money. Lede: your half of the fee pays for exactly as long as you still hold your own allocation. Sell it and your half stops, permanently, by contract. That is the deal, and it is the deal your buyers can read before they buy. 01 What you get. - 0.5% of every trade. The trading fee is 1% and it is split 50/50: half to you, half to the treasury. It comes from the pool's own fee tier, so no code of ours runs inside a trade. If your launch is paired against MDOG, the platform half is burned as MDOG rather than paid to the treasury; your half is the same either way. - For as long as you hold. The creator half is paid while the creator still holds their launch allocation. Sell it and the half stops, permanently. It tracks one address. Moving the allocation elsewhere counts as selling. It does not cover a creator who takes a small allocation and buys more from other wallets, keeping earning. We would rather say that than hide it. - A lock a buyer can check. The pool position is owned by a locker contract with no withdraw function. Not a timelock, not a promise, not a multisig that says it will behave. - Nothing you can be blamed for later. No owner, no admin, no upgrade path, anywhere. Your allocation is capped at 10% by the factory, and the cap is visible on chain from the first block. The factory retains nothing from your launch. 02 Launch a token. A form: name, ticker, supply (fixed at launch, there is no mint function), creator allocation as a percentage (capped at 10% by the contract), the quote asset to pair against, the curve, whether to burn the token side of the fees, and a computed preview of the opening market cap. Curves are fixed presets: a creator cannot pass their own ticks. On Standard, splitting a buy across wallets or across blocks does not help a sniper, because every buyer walks the same curve, and 3,800 USDC buys at most about 12% of supply. Opening market cap is the curve's opening price times the supply entered, computed on the page rather than stored. The quote asset must have 18 decimals; the factory refuses anything else. 03 What launching does not do. It does not make anyone buy. It does not vet you, and it does not vet anyone else. It does not let you undo anything: there is no owner and no upgrade path, so a mistyped name or a wrong supply is permanent. It does not give you the liquidity back: the locker has no withdraw function, so the liquidity you seed is not yours to retrieve, ever. # https://mdog.fun/proof Hero: Every claim on this site is a read-only call you can run yourself. Here are the addresses, the commands, and what each answer has to say. If an answer disagrees with this page, the page is wrong and you should act on that. Commands are written for Foundry's cast; any JSON-RPC client does the same job with eth_call. The RPC is https://rpc.testnet.arc.io. 01 What the contracts enforce. The list is generated from RULES in config.js: - Liquidity is locked by a contract with no withdraw function. Every position is owned by a locker contract that has no function to decrease liquidity or move the NFT. Not a timelock, not a promise. - 1% fee, split 50/50. Half to the creator, half to the treasury. It comes from the pool's own fee tier, so no code of ours runs inside your trade. Where a launch sets burnQuoteFees, the platform half is burned instead of paid to the treasury. - Sell your allocation and the creator half stops, permanently. It tracks one address, and moving the allocation elsewhere counts as selling. We would rather say that than hide it. - Creator allocation is capped at 10%. Enforced by the factory at launch, visible on chain from the first block. - No owner, no admin, no upgrade path, anywhere. There is no privileged address on the factory, the locker or a launched token. - The quote asset must have 18 decimals. The factory refuses anything else, so the price maths cannot be quietly wrong. - The factory retains nothing from a launch. The rounding dust left by the liquidity maths is burned at the end of launch(). Anyone can send tokens to the factory afterwards, so check its balance yourself rather than taking the word for it. That list is the whole list. Anything the contracts do not enforce is not claimed anywhere on this site. 02 The addresses, read from config.js for the selected network: LaunchFactory 0x732e6Beac348AE1BC77f2C94F1aeF76E90B52811, Uniswap PositionManager 0x6049c9a0e26405C0985f9E3685C87d0aE917f82B, StateView 0xF3334192D15450CdD385c8B70e03f9A6bD9E673b, Quoter 0x8Dc178eFB8111BB0973Dd9d722ebeFF267c98F94, UniversalRouter 0x4fcA4a51Ab4F23A7447b3284fBd7D73289A89Fb1, Permit2 0x000000000022D473030F116dDEE9F6B43aC78BA3. 03 Confirm the locker owns the liquidity: cast call "launchCount()(uint256)" --rpc-url https://rpc.testnet.arc.io cast call "launches(uint256)(address,address,address,uint8,(address,address,uint24,int24,address),bytes32)" 0 --rpc-url https://rpc.testnet.arc.io cast call "positionCount()(uint256)" --rpc-url https://rpc.testnet.arc.io cast call "positions(uint256)(uint256)" 0 --rpc-url https://rpc.testnet.arc.io cast call "ownerOf(uint256)(address)" --rpc-url https://rpc.testnet.arc.io The last one must answer with the locker address. 04 Confirm there is no way back out. The contract source is not published, so this is settled against the chain rather than by reading anything. withdraw(), owner() and transferOwnership(address) must all revert on the locker, because the functions are not there at all. collect() is the only path by which value leaves the locker, it takes no arguments, anyone may call it, and it splits the fee the same way whoever calls it. 05 Confirm nobody is holding the bag behind you. Read the factory's balance of a launched token and its native balance; check that owner() and implementation() revert on the factory and that the EIP-1967 implementation slot reads as zero. Be careful how you read the first one: the factory retains nothing from a launch, because the rounding dust is burned at the end of launch(), but it does not follow that the factory holds nothing, because anyone can send tokens to any address afterwards. Check the balance, do not assume it. 06 Confirm what the creator kept: creatorMinHold() on the locker over totalSupply() on the token is the allocation, and the factory rejects anything above 10%, so it cannot exceed 0.1. creatorEligible() says whether they still hold it. It reads one address. A creator who moves their allocation to a second wallet they also control will read as having sold; a creator who splits their allocation before launch is not covered by it at all. That is a real limit of the mechanic and it is not going to be fixed by wording. 07 What none of this protects you from. Anyone can launch anything: nothing on the board is vetted, endorsed or filtered, and a ticker and a name can copy a real project exactly; only the contract address cannot. Most tokens go to zero: locked liquidity does not make a token worth anything, it means the pool cannot be drained by whoever made it, and nothing more than that. A creator with two wallets. Everything outside the contracts: coordinated buying, a paid group, a promise made on a social account. You cannot read the contracts: the source is not published and they are not verified on the explorer, so nothing here should be believed because the site said it. And this is testnet: Arc testnet is the only network this pad runs on, by design, and nothing on it is real money. 08 What you can check, and what you cannot. The contracts are LaunchToken, Curves, FeeLocker and LaunchFactory. Their source is not published and they are not verified on the explorer, so there is nothing for a reader to inspect and no reason to take the site's word for what is in them. The page is built out of behaviour instead: the locker demonstrably holds the positions, the calls that would remove liquidity are not there to be called, owner() reverts on the factory and its EIP-1967 implementation slot reads as zero, so it is not a proxy. All of that comes from the chain alone. The site itself is plain HTML, CSS and ES modules, with no framework, no bundler and no dependencies. The content security policy is default-src 'none' with script-src 'self', so no code, style, font or image is loaded from anywhere else, and there is no analytics or tracking of any kind. The only external host the site may contact at all is the form service behind /contact, and only when the form is sent. # https://mdog.fun/agents Hero: No API key, no account, no backend. One transaction to launch, plain eth_call to read, Uniswap's own router to trade. Arc testnet, chain 5042002. Start at /pad.json for the addresses, selectors and limits. 01 Why it is easy. One transaction: launch() deploys the token, opens the pool, mints the liquidity and locks it. Gas is USDC: on Arc the gas coin is USDC itself, with 18 decimals, and testnet USDC comes from Circle's faucet. Reads are plain eth_call against the factory and Uniswap's own StateView and Quoter, with no indexer in the path. Nothing is gated: no allowlist, no captcha, no rate limit, no terms to click through. 02 The three calls. - Launch: launch((string,string,uint256,uint256,address,uint8,bool,bool)) on the factory, selector 0xc7008810. Quote is address(0) for native USDC, or an ERC20 such as MDOG. Set the last flag to burn the quote side of the fees. Curve id 0 is Standard. Creator allocation is capped at 10% of supply. - Read the board: launchCount() then launches(uint256), which returns the token, its locker, the creator, the curve id, the pool key and the pool id. Feed the pool id to getSlot0(bytes32) on StateView for the live price. Every launch also has a shareable page at /token?ca=0x...&chain=5042002. - Trade: execute(bytes,bytes[],uint256) on the Universal Router with the V4_SWAP command. Quote first with quoteExactInputSingle on the v4 Quoter. Selling needs a Permit2 approval first, buying does not. 03 The factory. Arc testnet, chain id 5042002, the only network this pad runs on. Factory 0x732e6Beac348AE1BC77f2C94F1aeF76E90B52811. RPC https://rpc.testnet.arc.io, explorer https://explorer.testnet.arc.io. Machine-readable copies of all of it at /pad.json, /llms.txt and /llms-full.txt. 04 What an agent should check before buying. Is the liquidity really locked (positionCount() on the locker, then ownerOf on the position manager). Has the creator sold (creatorEligible() on the locker). Which curve was used (on curve 0, 3,800 USDC buys at most about 12% of supply; curve 1 is a single flat range, where the same money reaches far more of it). How much did the creator keep (the allocation is in the Launched event, and their balance is one balanceOf away). # https://mdog.fun/share Hero: A launchpad the MDOG community can test in public, on Arc testnet. Take the contract address, take a line, post it. Testnet only. Nothing here is real money, which is the point of it. What it is: a launchpad (one transaction deploys a fixed-supply token, opens a Uniswap v4 pair, mints the liquidity and locks it in a contract with no withdraw function; the 1% fee is split 50/50; the creator's half stops permanently once they no longer hold their allocation; the allocation is capped at 10%; no owner, no admin, no upgrade path) and a testing ground (Arc testnet, chain 5042002, and nothing else). The addresses and links: MDOG contract 0x83fD0BDDdafA9a499582899d49515060C361b9aa with a copy button; pad factory 0x732e6Beac348AE1BC77f2C94F1aeF76E90B52811; the pad at https://mdog.fun/; the MDOG chart on DexScreener; testnet USDC at https://faucet.circle.com; @mdogarc on X; mdog.fun. The chart is MDOG itself, which trades on Arc. The pad and everything launched on it are on Arc testnet, where nothing is real money. Those are two different things and it is worth saying so when you post. Four blocks of text ready to copy, for a short post, for creators, for agents and for sceptics. No embeds, no trackers and no scripts from anywhere else. # https://mdog.fun/contact Hero: This pad is on testnet so that it can be broken in public. If something is wrong, tell us: a bug found here is a bug that never reaches real money. A message is enough. Contact details are optional. A form with three fields: what it is (a bug, feedback, or something else), the message, and an optional way to reach you. The message is the only field that has to be filled in. It is posted with fetch to a form service, which emails it on. That is the one external host any page here talks to, and only when send is pressed. No account, no cookie, and nothing is stored in the browser. What helps most: the contract address (a ticker is not enough to find anything), the transaction hash if a transaction was involved, the exact words of any error, the browser and wallet if the problem is a wallet one, and the page and the width if something looks wrong at phone width. # https://mdog.fun/token?ca=0xADDRESS&chain=5042002 One launch. Everything on it is read from the chain at load time: ticker and name, market cap from the pool, tags for the lock, the creator allocation and whether the creator still holds it, and the contract address. Then the facts in full: the token, the liquidity locker, the creator, how many positions the locker holds, the creator allocation as a percentage of supply, whether creatorEligible() is still true, the creator's balance now, the supply, the curve and the opening market cap for that supply, the fee, and the pool id. Then a trade panel that routes through Uniswap's own Universal Router, and the cast commands to check the lock, the creator and the supply for that specific token. These pages are noindex, follow, because the name and ticker on them are written by whoever deployed the token.