# BASE167 > A meme coin on Base you cannot buy -- only claim, and only if your wallet has made > 167 or more transactions on Base mainnet. Plus Degen Games, a monthly on-chain > trading competition for holders, ranked by percentage gain rather than wallet size. > This index points AI assistants and agents at everything needed to use the project > without a browser. Chain: Base mainnet (chainId 8453). Site: https://base167.com ## No live numbers in this file Claim counts, remaining supply and season phase change constantly. They are deliberately NOT written here, because a stale number in a static file is worse than no number. Read them at request time: - `POST /api/check` -- a wallet's transaction count and eligibility - `GET /api/games/state` -- season, phase, config, boards - On chain: `claimCount()` and `rewardsRemaining()` on the token ## Contracts - BASE167 token: `0x2Bf0234d7E9C25687521D2d2192d1dAE70aA4f2B` - SeasonFactory: `0x8Cf6ae46C03801D8Ae7Fbdc643AF34003E83b345` - EntryNFT (season 1): `0x6e403A853CBC6962f29E0C766e4fDD611A2a769b` - WinnersNFT (season 1): `0xA7762135805D3b7E9CA6F9a990d99A861E8b4a41` ## Prizes -- what a season pays Every monthly season pays a pot of **300,000,000 BASE167**, split across the podium only: - 1st: 150,000,000 BASE167 - 2nd: 100,000,000 BASE167 - 3rd: 50,000,000 BASE167 The annual Finals pay **1,200,000,000 BASE167**. **Money stops at three; glory does not.** Ten places count as winners: everyone in the top ten can mint a rank-stamped Winner badge NFT and takes a seat in the Finals. Only the podium is paid. Read `winnersCount` from `/api/games/state` rather than assuming ten -- it is a per-season setting. Every figure here is stated in BASE167 and never as a cash value. Prizes are paid by hand from the treasury; see the section below on why there is no claim function. ## Who can enter Two gates, in this order. Passing the first does not enrol you. 1. **The holder snapshot.** At `snapshotAt` the top BASE167 holders are recorded from chain state. Only an address in that snapshot may claim the season's Entry pass. The size of the list is the `topHolders` setting in the season config, so read it rather than assuming a number. A few addresses are excluded by design (the treasury, the burn address, the token itself and the liquidity pool). 2. **The enrolment window.** Between `enrollOpenAt` and `enrollCloseAt` a pass holder registers a competition wallet. That is the act that enters you. The Entry pass is an NFT (`EntryNFT`). Enrolling **locks** the pass you enrolled with, so it cannot be sold out from under the season; the lock expires at the closing bell, after which `EntryNFT.releaseLock(tokenId)` is permissionless. Holding several passes makes you a Collector, which is what the collector board ranks and what the Finals seats are drawn from (`finalsCollectorSeats` in the config). ## The season schedule Dates are NOT written here, because seasons move -- season 1 was itself rescheduled. Read the five timestamps from `config` in `GET /api/games/state`. All are unix seconds. - `snapshotAt` -- the holder snapshot is taken; the Entry pass becomes claimable - `enrollOpenAt` -- enrolment opens - `enrollCloseAt` -- enrolment closes - `openingBellAt` -- trading starts, and the competition wallet is judged on its balances - `closingBellAt` -- trading ends; scoring and then publication follow `phase` in the same response tells you where you are without doing the arithmetic. It has six values, and they are not the four an earlier version of this file listed: - `pre` -- before the snapshot - `seatMarket` -- snapshot taken; Entry passes are claimable and tradeable - `setup` -- the enrolment and funding window - `preGame` -- enrolment closed, waiting for the opening bell - `game` -- trading, between the bells - `settled` -- the closing bell has passed `nextBoundary` is the unix time of the next transition. Branch on `phase`; do not infer it from the timestamps. ## How every action works The same shape throughout: **POST a wallet address to an endpoint, receive a server-signed voucher plus ready-to-send calldata, then send one transaction.** There is no login, no session, no cookie and no CAPTCHA. Each response includes a `call` object -- `{ chainId, to, data, value }` -- so nothing needs to know our ABI. Vouchers are short-lived and bind `msg.sender`, so the wallet that sends the transaction must be the wallet the voucher was issued for. 1. **Claim BASE167** -- `POST /api/check` `{ address }` -> send `call` (Base167Token.claim) 2. **Claim the Entry pass** -- `POST /api/games/claim-entry` `{ address }` -> send `call` 3. **Register a competition wallet** -- `POST /api/games/enroll` `{ player, gameWallet }` -> send `call` 4. **Claim a Winner badge** -- `POST /api/games/claim-winner` `{ address }` -> send `call` 5. **Release the pass lock** after the season -- `EntryNFT.releaseLock(tokenId)`, permissionless ## Setting a display name or X handle These two are the only actions where YOU produce the signature, and the only ones that send no transaction -- they store a label on our server, so there is no `call` in the response. - `POST /api/games/set-name` `{ address, name, signature, expiry }` - `POST /api/games/set-handle` `{ address, handle, signature, expiry }` Sign this exact string as a personal_sign / EIP-191 message. It must byte-match or the answer is `401`: Set my Degen Games name to: {name} Domain: base167.com Degen Games Expires: {expiry} The X handle uses a different prefix, on purpose, so a signature captured for one action can never be replayed as the other: Set my Degen Games X handle to: {handle} Domain: base167.com Degen Games Expires: {expiry} `{name}` and `{handle}` are trimmed of surrounding whitespace before signing; send an empty value to clear. `{expiry}` is unix seconds, must be in the future, and may be at most 900 seconds ahead -- that bound is what limits the replay window, so an open-ended expiry is rejected rather than ignored. There is no trailing newline. Smart-contract wallets work here: ERC-1271, ERC-6492 for accounts not yet deployed, and ERC-8010 for 7702-delegated EOAs. A `503` means no chain could be reached to check the signature -- it is a retry, NOT a rejection. ## Reading the boards - `GET /api/games/leaderboard` -- top holders and the live collector board, cached 60s - `GET /api/games/results` -- published finals for completed seasons; an empty list before the first season ends is normal, not an error ## Wallet support - Any wallet type may claim, enrol and compete: plain EOAs, ERC-4337 smart accounts, Base Account, Safe, and EIP-7702 delegated EOAs. - Setting a display name or X handle requires a signature, and **smart-contract wallets are supported** -- ERC-1271, ERC-6492 (counterfactual) and ERC-8010. - **The competition wallet can also be any wallet, smart account included, and it may have a past.** What matters is the balance at the opening bell: at least $5 of USDC, at most 0.0002 ETH of gas, and nothing else of value. Scoring counts USDC only, so an unscored asset held at the bell and sold during the season would read as profit -- which is why more than the gas allowance is disqualified. ## Prizes are paid manually -- there is no claim function Do not look for one. `claimWinner` mints a rank-stamped badge NFT and moves no value. Season prize payouts are sent by hand from the treasury. An agent cannot claim a prize, and neither can a person. ## Limits and errors - Rate limit: 5 requests per minute per IP on the POST routes, `429` with `Retry-After: 60`. The three GET reads (`state`, `leaderboard`, `results`) are not rate limited -- poll them rather than caching a stale answer. - Request bodies are capped at 1KB (512 bytes on `/api/check`). - `409` means a window is closed (for example enrolment before it opens) -- expected, not a fault. - **`403` from enrol straight after minting the Entry pass is TEMPORARY.** Pass ownership is read at the chain's `safe` block, which trails the head by roughly 15-35 blocks -- about 30 to 60 seconds on Base. Your pass is real; it is simply not visible at that block yet. Wait and retry rather than concluding you do not hold one. Steps 2 and 3 are the one place in this API where doing two actions back to back needs a pause. - `422` means input was rejected on a rule (a used competition wallet, a bad name). - `503` from the naming routes means a chain could not be reached to verify a signature. It does NOT mean the signature was bad. Retry. ## MCP server There is a remote MCP (Model Context Protocol) server at https://base167.com/mcp. It is the easiest way to use BASE167: instead of reading this file and driving the JSON routes by hand, an assistant connects once and gets the actions as named tools. It needs no API key, no account and no OAuth -- add the URL as a custom connector and it works. Transport is streamable HTTP over POST. Both the current protocol revision and the older 2025-era handshake are served from the same endpoint, so old and new clients both connect. Seven tools, covering the same nine routes documented above: - base167_get_season -- season, phase, schedule, prize pot, entry gates, field, standings - base167_get_leaderboard -- live standings, or published finals with final=true - base167_check_claim -- claim eligibility for a wallet, plus the transaction if eligible - base167_claim_entry_pass -- claim the season Entry pass NFT - base167_enroll_wallet -- register the competition wallet that will be scored - base167_claim_winner_badge -- claim the rank-stamped Winner badge NFT - base167_set_display_name -- set a display name or X handle (two steps: get the message, sign it, send it back) The tools return the same answers as the HTTP routes because each one calls the same handler. Every tool that produces a transaction returns it UNSIGNED: this service never signs for a user and never holds keys, and the user approves the transaction in their own wallet. ## Machine-readable - MCP server: https://base167.com/mcp - OpenAPI 3.1 schema: https://base167.com/openapi.json - Base MCP plugin spec: https://base167.com/base-mcp-plugin.md - Agent Plugins 1.0.0 package: https://base167.com/plugin/plugin.json (its MCP server config is https://base167.com/plugin/mcp.json and its skill is https://base167.com/plugin/skills/base167/SKILL.md) - Agent identity (ERC-8004): https://base167.com/agent.json - Tool manifest (ERC-8257): https://base167.com/.well-known/ai-tool/base167-claim-check.json - Human and agent overview: https://base167.com/agents - Terms: https://base167.com/terms ## Pages as markdown Every page below is also served as clean markdown, which is smaller than the HTML and needs no conversion. Fetch the `.md` URL directly -- these are the canonical addresses, and the ordinary page URL always returns HTML. - https://base167.com/index.md -- what BASE167 is, and how to claim - https://base167.com/games.md -- the Degen Games rules, entry and prizes - https://base167.com/agents.md -- the whole journey for an agent, endpoint by endpoint - https://base167.com/terms.md -- terms and risk disclosures The two board pages have NO markdown variant on purpose: /leaderboard and /results are live data, and a markdown copy of a board would be stale the moment it was written. Read `GET /api/games/leaderboard` and `GET /api/games/results` instead.