# Table of Contents - [BattleChain Docs](#battlechain-docs) - [BattleChain Docs](#battlechain-docs) - [Going Attackable: End-to-End Protocol Tutorial](#going-attackable-end-to-end-protocol-tutorial) - [Using BattleChain with AI](#using-battlechain-with-ai) - [Deploying Contracts to BattleChain](#deploying-contracts-to-battlechain) - [How to Create a Safe Harbor Agreement](#how-to-create-a-safe-harbor-agreement) - [How to Request Attack Mode](#how-to-request-attack-mode) - [How to Promote to Production](#how-to-promote-to-production) - [How to Find Attackable Contracts](#how-to-find-attackable-contracts) - [How to Execute an Attack](#how-to-execute-an-attack) - [Review Your First Request](#review-your-first-request) - [Attack a Contract](#attack-a-contract) - [How to Claim Bounties](#how-to-claim-bounties) - [How to Approve or Reject Requests](#how-to-approve-or-reject-requests) - [How to Use Instant Promotion](#how-to-use-instant-promotion) - [How to Add BattleChain to MetaMask](#how-to-add-battlechain-to-metamask) - [Approving Requests: DAO Member Tutorial](#approving-requests-dao-member-tutorial) - [Configure Your AI Tools](#configure-your-ai-tools) - [How Deployment Works](#how-deployment-works) - [Vercel Security Checkpoint](#vercel-security-checkpoint) - [Vercel Security Checkpoint](#vercel-security-checkpoint) - [Vercel Security Checkpoint](#vercel-security-checkpoint) - [Vercel Security Checkpoint](#vercel-security-checkpoint) - [Vercel Security Checkpoint](#vercel-security-checkpoint) - [Vercel Security Checkpoint](#vercel-security-checkpoint) - [Vercel Security Checkpoint](#vercel-security-checkpoint) - [Vercel Security Checkpoint](#vercel-security-checkpoint) - [Vercel Security Checkpoint](#vercel-security-checkpoint) - [Vercel Security Checkpoint](#vercel-security-checkpoint) - [Vercel Security Checkpoint](#vercel-security-checkpoint) - [Vercel Security Checkpoint](#vercel-security-checkpoint) - [Vercel Security Checkpoint](#vercel-security-checkpoint) - [Vercel Security Checkpoint](#vercel-security-checkpoint) - [Vercel Security Checkpoint](#vercel-security-checkpoint) - [Vercel Security Checkpoint](#vercel-security-checkpoint) - [Vercel Security Checkpoint](#vercel-security-checkpoint) - [Vercel Security Checkpoint](#vercel-security-checkpoint) --- # BattleChain Docs ![BattleChain documentation hero](https://docs.battlechain.com/images/other/docs_hero.png?dpl=dpl_Gu1nCEyZSpzy9UkqWL6yBexJ2hbo) [Get Started](https://docs.battlechain.com/battlechain/quickstart/deploy-your-contract) The Problem Web3 has a fundamental gap in its development lifecycle. Code goes from audit to mainnet with nothing in between — and the industry pays for it. Projects go from $0 to $5M TVL overnight after an audit. Bug bounties don't attract serious testing. The industry loses billions to preventable exploits. Web3 Today Dev → Testnet → Mainnet Testnet uses fake money. Bugs are discovered _after_ millions are at risk. With BattleChain Dev → Testnet → BattleChain → Mainnet Real funds, controlled risk. Bugs are found _before_ they matter. How It Works ------------ BattleChain is a **pre-mainnet, post-testnet environment** with real funds. Protocols deploy audited contracts, whitehats legally attack them for bounties, and battle-tested contracts promote to mainnet with confidence. 1 Audit Get your contracts reviewed 2 Deploy Deploy contracts to BattleChain 3 Stress Test Whitehats attack under Safe Harbor 4 Promote DAO approves battle-tested contracts 5 Mainnet Ship with confidence Every contract on BattleChain exists in one of two modes: Attack Mode Open season for ethical hacking. Whitehats can legally exploit vulnerabilities, earn bounties, and operate under Safe Harbor protection. Protocols learn about weaknesses before they matter. Production Mode Protected like mainnet. No Safe Harbor coverage for attacks — same security expectations apply. Contracts typically reach this state once battle-tested and DAO-promoted. ### Why an L2? BattleChain runs as a ZKSync-based L2 to keep attacks isolated from mainnet liquidity, track contract states at the protocol level, and keep deployment costs low. It's purpose-built for this workflow — not a repurposed testnet. Choose Your Path ---------------- BattleChain serves three roles — jump to your starting point: [Protocol Teams\ \ Deploy your contracts, create a Safe Harbor agreement, and open them for whitehat attack.](https://docs.battlechain.com/battlechain/tutorials/going-attackable) [Whitehats\ \ Find live targets through the explorer API, exploit them legally, and claim bounties.](https://docs.battlechain.com/battlechain/how-to/find-attackable-contracts) [DAO Members\ \ Review attack requests and promote battle-tested contracts to production.](https://docs.battlechain.com/battlechain/how-to/approve-reject-requests) Learn More ---------- [The Contract Lifecycle\ \ Learn how contracts move through attack mode to production](https://docs.battlechain.com/battlechain/explanation/contract-lifecycle) [Safe Harbor Protection\ \ Understand the legal framework protecting whitehats](https://docs.battlechain.com/battlechain/explanation/safe-harbor) [Best Practices\ \ Guidelines for protocols, whitehats, and DAO members](https://docs.battlechain.com/battlechain/explanation/best-practices) Build with AI ------------- BattleChain is designed for AI-assisted development. Deploy contracts, create agreements, and run attacks — all through your AI coding tool. Start with **[Using BattleChain with AI](https://docs.battlechain.com/battlechain/using-battlechain-with-ai) ** — install the skill, connect the MCP server, or point any agent at the machine-readable docs. [One-Prompt Demo\ \ Run the full security demo with zero coding in Claude Code or Claude Desktop — Claude does everything](https://docs.battlechain.com/battlechain/quickstart/one-prompt-demo) [Deploy and Battle-Test\ \ Deploy a vulnerable vault and open it for attack — with AI or manually](https://docs.battlechain.com/battlechain/quickstart/deploy-your-contract) [Configure Your AI Tools\ \ Add BattleChain context to Claude Code, Cursor, Copilot, and other AI tools](https://docs.battlechain.com/battlechain/how-to/configure-ai-tools) ℹ️ BattleChain Mainnet (chain ID 626) and BattleChain Testnet (chain ID 627) are both live. The tutorials and quickstarts in these docs use the testnet, which has free test ETH and mock dependency contracts. Both networks have a block explorer and contract verification. --- # BattleChain Docs ![BattleChain documentation hero](https://docs.battlechain.com/images/other/docs_hero.png?dpl=dpl_Gu1nCEyZSpzy9UkqWL6yBexJ2hbo) [Get Started](https://docs.battlechain.com/battlechain/quickstart/deploy-your-contract) The Problem Web3 has a fundamental gap in its development lifecycle. Code goes from audit to mainnet with nothing in between — and the industry pays for it. Projects go from $0 to $5M TVL overnight after an audit. Bug bounties don't attract serious testing. The industry loses billions to preventable exploits. Web3 Today Dev → Testnet → Mainnet Testnet uses fake money. Bugs are discovered _after_ millions are at risk. With BattleChain Dev → Testnet → BattleChain → Mainnet Real funds, controlled risk. Bugs are found _before_ they matter. How It Works ------------ BattleChain is a **pre-mainnet, post-testnet environment** with real funds. Protocols deploy audited contracts, whitehats legally attack them for bounties, and battle-tested contracts promote to mainnet with confidence. 1 Audit Get your contracts reviewed 2 Deploy Deploy contracts to BattleChain 3 Stress Test Whitehats attack under Safe Harbor 4 Promote DAO approves battle-tested contracts 5 Mainnet Ship with confidence Every contract on BattleChain exists in one of two modes: Attack Mode Open season for ethical hacking. Whitehats can legally exploit vulnerabilities, earn bounties, and operate under Safe Harbor protection. Protocols learn about weaknesses before they matter. Production Mode Protected like mainnet. No Safe Harbor coverage for attacks — same security expectations apply. Contracts typically reach this state once battle-tested and DAO-promoted. ### Why an L2? BattleChain runs as a ZKSync-based L2 to keep attacks isolated from mainnet liquidity, track contract states at the protocol level, and keep deployment costs low. It's purpose-built for this workflow — not a repurposed testnet. Choose Your Path ---------------- BattleChain serves three roles — jump to your starting point: [Protocol Teams\ \ Deploy your contracts, create a Safe Harbor agreement, and open them for whitehat attack.](https://docs.battlechain.com/battlechain/tutorials/going-attackable) [Whitehats\ \ Find live targets through the explorer API, exploit them legally, and claim bounties.](https://docs.battlechain.com/battlechain/how-to/find-attackable-contracts) [DAO Members\ \ Review attack requests and promote battle-tested contracts to production.](https://docs.battlechain.com/battlechain/how-to/approve-reject-requests) Learn More ---------- [The Contract Lifecycle\ \ Learn how contracts move through attack mode to production](https://docs.battlechain.com/battlechain/explanation/contract-lifecycle) [Safe Harbor Protection\ \ Understand the legal framework protecting whitehats](https://docs.battlechain.com/battlechain/explanation/safe-harbor) [Best Practices\ \ Guidelines for protocols, whitehats, and DAO members](https://docs.battlechain.com/battlechain/explanation/best-practices) Build with AI ------------- BattleChain is designed for AI-assisted development. Deploy contracts, create agreements, and run attacks — all through your AI coding tool. Start with **[Using BattleChain with AI](https://docs.battlechain.com/battlechain/using-battlechain-with-ai) ** — install the skill, connect the MCP server, or point any agent at the machine-readable docs. [One-Prompt Demo\ \ Run the full security demo with zero coding in Claude Code or Claude Desktop — Claude does everything](https://docs.battlechain.com/battlechain/quickstart/one-prompt-demo) [Deploy and Battle-Test\ \ Deploy a vulnerable vault and open it for attack — with AI or manually](https://docs.battlechain.com/battlechain/quickstart/deploy-your-contract) [Configure Your AI Tools\ \ Add BattleChain context to Claude Code, Cursor, Copilot, and other AI tools](https://docs.battlechain.com/battlechain/how-to/configure-ai-tools) ℹ️ BattleChain Mainnet (chain ID 626) and BattleChain Testnet (chain ID 627) are both live. The tutorials and quickstarts in these docs use the testnet, which has free test ETH and mock dependency contracts. Both networks have a block explorer and contract verification. --- # Going Attackable: End-to-End Protocol Tutorial Going Attackable: End-to-End Protocol Tutorial ============================================== A complete tutorial for protocols to deploy, configure, and enter attack mode on BattleChain This tutorial covers the full journey of taking your protocol from deployment to attack mode on BattleChain. You'll learn not just the mechanics, but _why_ each step matters for your security. ℹ️ **Audience**: Protocol teams and developers preparing contracts for BattleChain. **Prerequisites**: An audited smart contract and test funds for liquidity. [Why Go Attackable?](https://docs.battlechain.com/battlechain/tutorials/going-attackable#why-go-attackable) ------------------------------------------------------------------------------------------------------------ Traditional security audits review code statically. BattleChain adds a dynamic layer: real attackers with real economic incentives trying to break your contracts. This means: * **Exploits get found before mainnet** — whitehats are motivated by bounties, not just reports * **You control the risk** — set your own bounty terms and liquidity levels * **Legal protection works both ways** — Safe Harbor protects whitehats, and you set the rules [Part 1: Deploy Your Contracts](https://docs.battlechain.com/battlechain/tutorials/going-attackable#part-1-deploy-your-contracts) ---------------------------------------------------------------------------------------------------------------------------------- The recommended approach is to use `battlechain-lib`, which handles BattleChainDeployer routing and AttackRegistry registration automatically: forge install cyfrin/battlechain-lib Deploy using the `bcDeployCreate*` helpers — they route through `BattleChainDeployer` on BattleChain (auto-registering with `AttackRegistry`) and through CreateX on other chains: import { BCScript } from "battlechain-lib/BCScript.sol"; import { Contact } from "battlechain-lib/types/AgreementTypes.sol"; contract Deploy is BCScript { function _protocolName() internal pure override returns (string memory) { return "My Protocol"; } function _contacts() internal pure override returns (Contact[] memory) { Contact[] memory c = new Contact[](1); c[0] = Contact({ name: "Security Team", contact: "security@myprotocol.com" }); return c; } function _recoveryAddress() internal view override returns (address) { return msg.sender; } function run() external { vm.startBroadcast(); bytes32 salt = keccak256("my-vault-v1"); address myVault = bcDeployCreate2(salt, type(MyVault).creationCode); // ... continue with agreement creation and attack mode vm.stopBroadcast(); } } 💡 Deploy the **exact same bytecode** you'll use on mainnet. Only change constructor parameters like oracle addresses or chain-specific config. Testing different code defeats the purpose. ⚠️ **Required: `--skip-simulation` flag** Forge's local gas estimation doesn't work reliably on BattleChain. All `forge script` calls must include `--skip-simulation` or they may fail. Add it to every deployment and interaction script: forge script ... --skip-simulation See [How Deployment Works](https://docs.battlechain.com/battlechain/explanation/how-deployment-works#foundry-on-battlechain) for the full list of BattleChain Foundry flags and how the deploy stack fits together. See the [deploying contracts tutorial](https://docs.battlechain.com/battlechain/tutorials/deploying-contracts) for details on all deployment methods, including direct `BattleChainDeployer` usage. [Part 2: Create Your Safe Harbor Agreement](https://docs.battlechain.com/battlechain/tutorials/going-attackable#part-2-create-your-safe-harbor-agreement) ---------------------------------------------------------------------------------------------------------------------------------------------------------- The agreement defines the rules of engagement for whitehats. With `battlechain-lib`, you can create an agreement with sensible defaults in one call: // Inside your BCScript's run() function: address agreement = createAndAdoptAgreement( defaultAgreementDetails( _protocolName(), _contacts(), getDeployedContracts(), _recoveryAddress() ), msg.sender, keccak256("agreement-v1") ); `defaultAgreementDetails` auto-detects the chain and builds the correct scope: * **BattleChain**: Uses BattleChain CAIP-2 chain ID and `BATTLECHAIN_SAFE_HARBOR_URI` * **Other chains**: Uses the current chain's CAIP-2 ID and the generic `SAFE_HARBOR_V3_URI` `createAndAdoptAgreement` handles three steps in one: creates the agreement, sets a 14-day commitment window, and adopts it. ### [Customizing Terms](https://docs.battlechain.com/battlechain/tutorials/going-attackable#customizing-terms) For full control over bounty terms, build the agreement manually: BountyTerms memory bountyTerms = BountyTerms({ bountyPercentage: 10, bountyCapUsd: 5_000_000, retainable: true, identity: IdentityRequirements.Anonymous, diligenceRequirements: "", aggregateBountyCapUsd: 0 }); AgreementDetails memory details = defaultAgreementDetails( _protocolName(), _contacts(), getDeployedContracts(), _recoveryAddress() ); details.bountyTerms = bountyTerms; address agreement = createAgreement(details, msg.sender, keccak256("agreement-v1")); setCommitmentWindow(agreement, 30); // 30 days adoptAgreement(agreement); | Decision | Recommended | Why | | --- | --- | --- | | Bounty % | 10% | Industry standard, attracts serious researchers | | Cap | $1M - $5M | High enough to motivate deep analysis | | Retainable | `true` | Simpler for whitehats — they keep bounty from recovered funds | | Identity | `Anonymous` | Maximizes participation | For the full configuration reference, see [How to Create a Safe Harbor Agreement](https://docs.battlechain.com/battlechain/how-to/create-agreement) . [Part 3: Request Attack Mode](https://docs.battlechain.com/battlechain/tutorials/going-attackable#part-3-request-attack-mode) ------------------------------------------------------------------------------------------------------------------------------ Request attack mode using the `battlechain-lib` helper. This is the only BattleChain-specific step — it reverts on other chains: if (_isBattleChain()) { requestAttackMode(agreement); } Your contracts are now in `ATTACK_REQUESTED` state. The DAO will review and check: * Is this a new contract (not a mainnet copy)? * Are the bounty terms reasonable? * Is the scope clearly defined? Once approved, state moves to `UNDER_ATTACK` and whitehats can begin testing. Approval works differently depending on the network: ℹ️ **Testnet:** approval is instant — the `MockRegistryModerator` is a permissionless contract you call yourself instead of waiting for a real DAO action. See [How to Request Attack Mode](https://docs.battlechain.com/battlechain/how-to/request-attack-mode#testnet-instant-approval) for the exact command. ℹ️ **Mainnet:** the BattleChain DAO reviews and approves the request — there is no self-approval. Approval is a governance action by the registry moderator, so expect a review period before your contracts enter `UNDER_ATTACK`. See [How to Request Attack Mode](https://docs.battlechain.com/battlechain/how-to/request-attack-mode) for full details and troubleshooting. [Part 4: During the Attack Period](https://docs.battlechain.com/battlechain/tutorials/going-attackable#part-4-during-the-attack-period) ---------------------------------------------------------------------------------------------------------------------------------------- Once the DAO approves, your contracts enter `UNDER_ATTACK` state. Here's what to expect: ### [Monitor Activity](https://docs.battlechain.com/battlechain/tutorials/going-attackable#monitor-activity) Watch for unusual transactions on your contracts. Whitehats may: * Drain liquidity pools * Exploit reentrancy or flash loan vectors * Test access control boundaries ### [If a Vulnerability is Found](https://docs.battlechain.com/battlechain/tutorials/going-attackable#if-a-vulnerability-is-found) 1. Whitehats extract funds and send the remainder to your recovery address 2. You keep your assets minus the bounty 3. Consider whether the vulnerability affects your mainnet plans ### [When You're Confident](https://docs.battlechain.com/battlechain/tutorials/going-attackable#when-youre-confident) After sufficient testing (see [best practices for timing](https://docs.battlechain.com/battlechain/explanation/best-practices) ), promote to production: attackRegistry.promote(agreement); // 3-day countdown begins — contracts are still attackable // After 3 days, contracts enter PRODUCTION See [How to Promote to Production](https://docs.battlechain.com/battlechain/how-to/promote-to-production) for the full promotion flow. [Summary](https://docs.battlechain.com/battlechain/tutorials/going-attackable#summary) --------------------------------------------------------------------------------------- | Step | Action | Result | | --- | --- | --- | | 1 | Deploy via `bcDeployCreate*` | Contracts registered (auto via BattleChainDeployer) | | 2 | Create Safe Harbor agreement | Terms defined (auto-scoped per chain) | | 3 | Request attack mode | DAO reviews (BattleChain only) | | 4 | DAO approves | Whitehats can attack | | 5 | Promote to production | Battle-tested and ready for mainnet | * * * [Troubleshooting](https://docs.battlechain.com/battlechain/tutorials/going-attackable#troubleshooting) ------------------------------------------------------------------------------------------------------- ### [Stuck or pending transactions](https://docs.battlechain.com/battlechain/tutorials/going-attackable#stuck-or-pending-transactions) Transactions can get stuck if the fee is too low for the current base fee. To replace a stuck transaction, send a no-op at the same nonce with a higher fee: # Get current base fee cast gas-price --rpc-url https://testnet.battlechain.com # Send a replacement with a higher max fee (e.g. 2x the current base fee) cast send \ --account \ --rpc-url https://testnet.battlechain.com \ --nonce \ --max-fee-per-gas <2x-current-base-fee> \ --value 0 \ 0x0000000000000000000000000000000000000000 Find the stuck nonce via: cast nonce --rpc-url https://testnet.battlechain.com --- # Using BattleChain with AI Using BattleChain with AI ========================= Give your AI coding agent full BattleChain context — skills, machine-readable docs, and MCP server BattleChain is built for AI-native development. Whether you're using Claude Code, Cursor, or any tool with a built-in chat, you can give your agent full BattleChain context in seconds. [Run the Whole Workflow Through Your Agent](https://docs.battlechain.com/battlechain/using-battlechain-with-ai#run-the-whole-workflow-through-your-agent) ---------------------------------------------------------------------------------------------------------------------------------------------------------- You can do **everything** on BattleChain through your AI agent — deploy contracts, create a Safe Harbor agreement, go attackable, execute attacks, and claim bounties — **without writing code yourself**. Your agent reads these docs, runs the commands, and pauses for you to approve each step. * **Just want to watch it work?** The [no-code demo](https://docs.battlechain.com/battlechain/quickstart/one-prompt-demo) deploys a vulnerable vault and exploits it end to end from a single prompt in Claude Code — nothing to install. * **Building for real?** Install the skill below, then tell your agent _"deploy my contracts to BattleChain"_ and it runs the full lifecycle with you — deploy, agreement, attack mode, and promotion. [The BattleChain Skill](https://docs.battlechain.com/battlechain/using-battlechain-with-ai#the-battlechain-skill) ------------------------------------------------------------------------------------------------------------------ The fastest way to give your AI agent BattleChain context is to install the Cyfrin skills package: npx skills add cyfrin/solskill This installs three skills: | Skill | What it does | | --- | --- | | `solidity` | Production-grade Solidity standards: code quality, testing, security, Foundry workflows | | `battlechain` | BattleChain reference: deploying, Safe Harbor, whitehat attacks, contract lifecycle | | `battlechain-tutorial` | Interactive wizard: scans your project, asks guided questions, generates all scripts | Once installed, tell your agent "Deploy my contracts to BattleChain" and `battlechain-tutorial` will walk you through the full process. The skills are open source at [github.com/Cyfrin/solskill](https://github.com/Cyfrin/solskill) . [Claude Code Plugin](https://docs.battlechain.com/battlechain/using-battlechain-with-ai#claude-code-plugin) ------------------------------------------------------------------------------------------------------------ If you use Claude Code, the same skills are also published as a [plugin marketplace](https://docs.claude.com/en/docs/claude-code/plugins) . This is the most native install path for Claude Code — plugins are managed with `/plugin` and update in place. Inside a Claude Code session, add the marketplace: /plugin marketplace add Cyfrin/solskill Then install whichever plugins you want: /plugin install solidity@solskill /plugin install battlechain@solskill /plugin install battlechain-tutorial@solskill Restart Claude Code so the new plugins load: /exit claude --continue ⚠️ Claude Code may suggest `/reload-plugins` after install. That command does not pick up newly installed plugins — exit the session and run `claude --continue` instead. [Read the Docs as Markdown](https://docs.battlechain.com/battlechain/using-battlechain-with-ai#read-the-docs-as-markdown) -------------------------------------------------------------------------------------------------------------------------- BattleChain publishes machine-readable versions of these docs so AI agents can ingest them directly: | File | Contents | Size | | --- | --- | --- | | [`/llms.txt`](https://docs.battlechain.com/llms.txt) | Table of contents with page titles, descriptions, and links | ~4 KB | | [`/llms-full.txt`](https://docs.battlechain.com/llms-full.txt) | Complete text of every page as clean markdown | ~100 KB | Both files follow the [llms.txt](https://llmstxt.org/) convention and are regenerated on every deploy. Start a conversation with full BattleChain docs loaded as context: [![](https://docs.battlechain.com/images/other/claude.svg)\ \ Open in Claude](https://claude.ai/new?q=Read%20https%3A%2F%2Fdocs.battlechain.com%2Fllms-full.txt%20and%20use%20it%20to%20answer%20my%20questions%20about%20BattleChain.) [Open in ChatGPT](https://chatgpt.com/?q=Read%20https%3A%2F%2Fdocs.battlechain.com%2Fllms-full.txt%20and%20use%20it%20to%20answer%20my%20questions%20about%20BattleChain.) Or paste this prompt into any AI: Read https://docs.battlechain.com/llms-full.txt and use it to answer my questions about BattleChain. [Cursor](https://docs.battlechain.com/battlechain/using-battlechain-with-ai#cursor) ------------------------------------------------------------------------------------ Add BattleChain as a doc source so Cursor indexes it automatically. Go to **Cursor Settings → Features → Docs**, click **Add**, and enter: https://docs.battlechain.com/llms-full.txt Once indexed, Cursor's AI will have full BattleChain context when you reference `@docs` in chat. [MCP Server](https://docs.battlechain.com/battlechain/using-battlechain-with-ai#mcp-server) -------------------------------------------------------------------------------------------- BattleChain publishes an [MCP (Model Context Protocol)](https://modelcontextprotocol.io/) server that gives AI tools programmatic access to search and read these docs. **Server URL:** https://docs.battlechain.com/api/mcp ### [Claude Code](https://docs.battlechain.com/battlechain/using-battlechain-with-ai#claude-code) claude mcp add --transport http battlechain-docs https://docs.battlechain.com/api/mcp ### [Claude Desktop](https://docs.battlechain.com/battlechain/using-battlechain-with-ai#claude-desktop) Add to your Claude Desktop config (`claude_desktop_config.json`): { "mcpServers": { "battlechain-docs": { "url": "https://docs.battlechain.com/api/mcp" } } } Any MCP-compatible client can connect using the server URL above. The server exposes three tools: | Tool | Args | Description | | --- | --- | --- | | `search_docs` | `query: string` | Search documentation by keyword or topic | | `read_page` | `path: string` | Read the full content of a specific page as clean markdown | | `list_pages` | _(none)_ | List all available documentation pages | ### [Example prompts](https://docs.battlechain.com/battlechain/using-battlechain-with-ai#example-prompts) Once connected, just ask your agent a docs question — it picks the right tool automatically: * _"How do I deploy a contract to BattleChain testnet?"_ * _"What is Safe Harbor and how do I enable it on my contracts?"_ * _"Walk me through the going-attackable tutorial step by step."_ * _"List every page under quickstart."_ [Custom Agents](https://docs.battlechain.com/battlechain/using-battlechain-with-ai#custom-agents) -------------------------------------------------------------------------------------------------- If you're building an agent that interacts with BattleChain, fetch the docs at startup and include them as context: * **Full context** — fetch `/llms-full.txt` and add it to the system prompt (~100 KB, fits in most context windows) * **Selective context** — fetch `/llms.txt` to build a page index, then retrieve individual pages on demand for RAG pipelines import httpx docs = httpx.get("https://docs.battlechain.com/llms-full.txt").text messages = [\ {"role": "system", "content": f"BattleChain documentation:\n\n{docs}"},\ {"role": "user", "content": user_question},\ ] [Going Further](https://docs.battlechain.com/battlechain/using-battlechain-with-ai#going-further) -------------------------------------------------------------------------------------------------- Want your AI agent to deploy to BattleChain by default and set up Safe Harbor automatically? See [Configure Your AI Tools](https://docs.battlechain.com/battlechain/how-to/configure-ai-tools) for the deployment prompt block and per-tool config file paths (`CLAUDE.md`, `.cursor/rules`, `AGENTS.md`, and others). --- # Deploying Contracts to BattleChain Deploying Contracts to BattleChain ================================== Learn how to deploy smart contracts using BattleChainDeployer and understand deployment options This tutorial teaches you how to deploy contracts to BattleChain and why the deployment method matters for the attack mode workflow. ℹ️ **Audience**: Developers deploying contracts to BattleChain. **Prerequisites**: Familiarity with Solidity and smart contract deployment. New to the BattleChain deploy stack? [How Deployment Works](https://docs.battlechain.com/battlechain/explanation/how-deployment-works) explains how `just`, `battlechain-lib`, `BattleChainDeployer`, and CreateX fit together. [Using battlechain-lib (Recommended)](https://docs.battlechain.com/battlechain/tutorials/deploying-contracts#using-battlechain-lib-recommended) ------------------------------------------------------------------------------------------------------------------------------------------------ The easiest way to deploy is with `battlechain-lib`, which handles address resolution, CreateX routing, and AttackRegistry registration automatically: forge install cyfrin/battlechain-lib Add the remapping to `foundry.toml`: remappings = [\ "battlechain-lib/=lib/battlechain-lib/src/",\ ] ⚠️ **Contract size limit: 24,576 bytes** BattleChain enforces the standard EVM contract size limit (EIP-170). If your compiled bytecode exceeds 24,576 bytes, deployment will fail. Enable the Solidity optimizer in `foundry.toml` to reduce bytecode size: [profile.default] optimizer = true optimizer_runs = 200 ### [Deploy with helpers](https://docs.battlechain.com/battlechain/tutorials/deploying-contracts#deploy-with-helpers) Inherit `BCDeploy` (deploy only) or `BCScript` (deploy + agreement + attack mode): import { BCDeploy } from "battlechain-lib/BCDeploy.sol"; contract Deploy is BCDeploy { function run() external { vm.startBroadcast(); // Simple deployment address token = bcDeployCreate(type(MyToken).creationCode); // Deterministic address (same across chains) bytes32 salt = keccak256("vault-v1"); address vault = bcDeployCreate2( salt, abi.encodePacked(type(MyVault).creationCode, abi.encode(token)) ); vm.stopBroadcast(); } } On BattleChain, `bcDeployCreate*` calls go through `BattleChainDeployer`, which wraps CreateX and auto-registers your contracts with the `AttackRegistry`. On any other supported chain (190+ EVM chains), the same functions route directly through [CreateX](https://github.com/pcaversaccio/createx) (`0xba5Ed...`), giving you deterministic addresses without any code changes. 💡 Use `bcDeployCreate2` when you need deterministic addresses. On the 190+ chains that share the canonical CreateX deployment (`0xba5Ed...`), the same salt + bytecode produces the same address everywhere. BattleChain's CreateX and BattleChainDeployer live at different addresses, so addresses computed on BattleChain differ from those chains — and between BattleChain mainnet and testnet. Your contracts' constructor parameters (oracles, tokens, external protocols) point at network-specific dependencies: Point them at the [mock dependency contracts](https://docs.battlechain.com/battlechain/reference/mock-contracts) — they share the same interfaces as the real ones, so you can deploy your exact production bytecode and only swap the addresses. Use the real dependency addresses, exactly as you would on Ethereum mainnet. ### [Available deploy helpers](https://docs.battlechain.com/battlechain/tutorials/deploying-contracts#available-deploy-helpers) | Helper | Address Determinism | Notes | | --- | --- | --- | | `bcDeployCreate(bytecode)` | Nonce-based | Simplest option | | `bcDeployCreate2(salt, bytecode)` | Salt + bytecode | Same address cross-chain | | `bcDeployCreate3(salt, bytecode)` | Salt only | Address independent of code | All deployed addresses are tracked automatically. Call `getDeployedContracts()` to retrieve them for use with Safe Harbor agreement scoping. * * * [Why BattleChainDeployer?](https://docs.battlechain.com/battlechain/tutorials/deploying-contracts#why-battlechaindeployer) --------------------------------------------------------------------------------------------------------------------------- BattleChain tracks which contracts are eligible for attack mode through the `AttackRegistry`. When you deploy via `BattleChainDeployer` (which `bcDeployCreate*` uses automatically on BattleChain), your contracts are **automatically registered**, which means: * You're recorded as the deployer on-chain * You can request attack mode without extra authorization steps * The DAO has on-chain proof of deployment origin Without BattleChainDeployer, you can still enter attack mode, but the process requires more DAO scrutiny. [Direct BattleChainDeployer Usage](https://docs.battlechain.com/battlechain/tutorials/deploying-contracts#direct-battlechaindeployer-usage) -------------------------------------------------------------------------------------------------------------------------------------------- If you prefer not to use `battlechain-lib`, you can call `BattleChainDeployer` directly. It wraps [CreateX](https://github.com/pcaversaccio/createx) , giving you access to all standard deployment patterns: ### [CREATE (Simple Deployment)](https://docs.battlechain.com/battlechain/tutorials/deploying-contracts#create-simple-deployment) BattleChainDeployer deployer = BattleChainDeployer(BATTLECHAIN_DEPLOYER_ADDRESS); // Simple deployment bytes memory bytecode = type(MyContract).creationCode; address deployed = deployer.deployCreate(bytecode); ### [CREATE2 (Deterministic Address)](https://docs.battlechain.com/battlechain/tutorials/deploying-contracts#create2-deterministic-address) // Deterministic address based on salt + bytecode bytes32 salt = keccak256("my-contract-v1"); bytes memory bytecode = type(MyContract).creationCode; address deployed = deployer.deployCreate2(salt, bytecode); ### [CREATE3 (Address Independent of Bytecode)](https://docs.battlechain.com/battlechain/tutorials/deploying-contracts#create3-address-independent-of-bytecode) // Address depends only on salt, not bytecode bytes32 salt = keccak256("my-contract-v1"); bytes memory bytecode = type(MyContract).creationCode; address deployed = deployer.deployCreate3(salt, bytecode); ### [All Available Methods](https://docs.battlechain.com/battlechain/tutorials/deploying-contracts#all-available-methods) | Method | Address Determinism | Notes | | --- | --- | --- | | `deployCreate()` | Nonce-based | Simplest option | | `deployCreateAndInit()` | Nonce-based | Deploys + calls init | | `deployCreateClone()` | Nonce-based | EIP-1167 proxy | | `deployCreate2()` | Salt + bytecode | Same address cross-chain | | `deployCreate2AndInit()` | Salt + bytecode | Deploy + init | | `deployCreate2Clone()` | Salt + impl | Deterministic proxy | | `deployCreate3()` | Salt only | Address independent of code | | `deployCreate3AndInit()` | Salt only | Deploy + init | [What Happens After Deployment](https://docs.battlechain.com/battlechain/tutorials/deploying-contracts#what-happens-after-deployment) -------------------------------------------------------------------------------------------------------------------------------------- Every deployment through BattleChainDeployer (or `bcDeployCreate*` on BattleChain) automatically calls `AttackRegistry.registerDeployment()`, which: 1. Records the contract address 2. Sets its state to `NEW_DEPLOYMENT` 3. Records you as the deployer 4. Authorizes you as the agreement owner for that contract // You can verify registration address deployer = attackRegistry.getContractDeployer(myContract); // deployer == your address IAttackRegistry.ContractState state = attackRegistry.getAgreementState(myContract); // state == NEW_DEPLOYMENT (1) [Deploying Without BattleChainDeployer](https://docs.battlechain.com/battlechain/tutorials/deploying-contracts#deploying-without-battlechaindeployer) ------------------------------------------------------------------------------------------------------------------------------------------------------ If your contracts are already deployed (e.g., through a custom factory or script), you can still enter the attack flow: 1. Create your Safe Harbor agreement as normal 2. Use `requestUnderAttackByNonAuthorized()` instead of `requestUnderAttack()` attackRegistry.requestUnderAttackByNonAuthorized(agreementAddress); ⚠️ Non-BattleChainDeployer contracts face extra DAO scrutiny because there's no on-chain proof of deployment origin. The DAO may take longer to approve or may request additional information. [Next Steps](https://docs.battlechain.com/battlechain/tutorials/deploying-contracts#next-steps) ------------------------------------------------------------------------------------------------ [Going Attackable\ \ Full end-to-end protocol tutorial](https://docs.battlechain.com/battlechain/tutorials/going-attackable) [Contract API Reference\ \ Complete BattleChainDeployer API](https://docs.battlechain.com/battlechain/reference/contracts) --- # How to Create a Safe Harbor Agreement How to Create a Safe Harbor Agreement ===================================== Create and configure your Safe Harbor agreement with bounty terms and scope [Overview](https://docs.battlechain.com/battlechain/how-to/create-agreement#overview) -------------------------------------------------------------------------------------- A Safe Harbor agreement defines the terms under which whitehats can attack your contracts. This guide covers all configuration options. [Quick Start with battlechain-lib](https://docs.battlechain.com/battlechain/how-to/create-agreement#quick-start-with-battlechain-lib) -------------------------------------------------------------------------------------------------------------------------------------- The fastest way to create an agreement is with `battlechain-lib`, which handles chain detection, scope building, and URI selection automatically: import { BCSafeHarbor } from "battlechain-lib/BCSafeHarbor.sol"; import { Contact, BountyTerms, IdentityRequirements } from "battlechain-lib/types/AgreementTypes.sol"; contract CreateAgreement is BCSafeHarbor { function run() external { vm.startBroadcast(); Contact[] memory contacts = new Contact[](1); contacts[0] = Contact({ name: "Security Team", contact: "security@myprotocol.com" }); address[] memory contracts_ = new address[](1); contracts_[0] = vm.envAddress("VAULT_ADDRESS"); // Creates agreement with correct scope and URI for the current chain address agreement = createAndAdoptAgreement( defaultAgreementDetails("My Protocol", contacts, contracts_, msg.sender), msg.sender, keccak256("my-protocol-v1") ); vm.stopBroadcast(); } } `defaultAgreementDetails` auto-selects: * **BattleChain**: BattleChain CAIP-2 scope + `BATTLECHAIN_SAFE_HARBOR_URI` * **Other chains**: Current chain's CAIP-2 scope + `SAFE_HARBOR_V3_URI` (SEAL) `createAndAdoptAgreement` handles create + 14-day commitment window + adopt in one call. [Manual Creation with AgreementFactory](https://docs.battlechain.com/battlechain/how-to/create-agreement#manual-creation-with-agreementfactory) ------------------------------------------------------------------------------------------------------------------------------------------------ For full control, use `AgreementFactory` directly: AgreementDetails memory details = AgreementDetails({ protocolName: "My Protocol", contactDetails: contacts, chains: chains, bountyTerms: bountyTerms, agreementURI: "ipfs://QmYourAgreementHash" }); bytes32 salt = keccak256("my-protocol-v1"); address agreement = agreementFactory.create(details, owner, salt); [Configure Contact Details](https://docs.battlechain.com/battlechain/how-to/create-agreement#configure-contact-details) ------------------------------------------------------------------------------------------------------------------------ Provide emergency contacts for whitehats: Contact[] memory contacts = new Contact[](2); contacts[0] = Contact({ name: "Security Lead", contact: "security@myprotocol.com" }); contacts[1] = Contact({ name: "Emergency Telegram", contact: "@myprotocol_security" }); [Define Chain Scope](https://docs.battlechain.com/battlechain/how-to/create-agreement#define-chain-scope) ---------------------------------------------------------------------------------------------------------- Specify which contracts on which chains are covered: Account[] memory accounts = new Account[](2); accounts[0] = Account({ accountAddress: "0x1234...MyVault", childContractScope: ChildContractScope.All }); accounts[1] = Account({ accountAddress: "0x5678...MyStrategy", childContractScope: ChildContractScope.None }); Chain[] memory chains = new Chain[](1); chains[0] = Chain({ caip2ChainId: "eip155:627", // BattleChain Testnet (626 on mainnet) assetRecoveryAddress: "0xYourRecoveryMultisig", accounts: accounts }); ### [Child Contract Scope Options](https://docs.battlechain.com/battlechain/how-to/create-agreement#child-contract-scope-options) | Value | Meaning | | --- | --- | | `None` | Only the listed contract | | `ExistingOnly` | Contract + children created before agreement | | `All` | Contract + all children (past and future) | | `FutureOnly` | Contract + children created after agreement | [Configure Bounty Terms](https://docs.battlechain.com/battlechain/how-to/create-agreement#configure-bounty-terms) ------------------------------------------------------------------------------------------------------------------ BountyTerms memory bountyTerms = BountyTerms({ bountyPercentage: 10, // 10% of recovered funds bountyCapUsd: 5_000_000, // Max $5M per whitehat retainable: true, // Whitehat keeps bounty from recovered identity: IdentityRequirements.Anonymous, diligenceRequirements: "", // Only for Named identity aggregateBountyCapUsd: 0 // 0 = no aggregate cap }); ### [Retainable vs Return-All](https://docs.battlechain.com/battlechain/how-to/create-agreement#retainable-vs-return-all) * **Retainable** (`true`): Whitehat keeps bounty from recovered funds, sends rest to recovery * **Return-All** (`false`): Whitehat sends all funds to recovery, protocol pays bounty separately ### [Identity Options](https://docs.battlechain.com/battlechain/how-to/create-agreement#identity-options) | Level | Requirement | | --- | --- | | `Anonymous` | No identity verification | | `Pseudonymous` | Consistent pseudonym required | | `Named` | Legal name verification (specify process in `diligenceRequirements`) | [Extend Commitment Window](https://docs.battlechain.com/battlechain/how-to/create-agreement#extend-commitment-window) ---------------------------------------------------------------------------------------------------------------------- Agreements must commit to terms for at least 7 days: // Extend to 30 days agreement.extendCommitmentWindow(block.timestamp + 30 days); During the commitment window, you cannot make unfavorable changes to whitehats. [Adopt the Agreement](https://docs.battlechain.com/battlechain/how-to/create-agreement#adopt-the-agreement) ------------------------------------------------------------------------------------------------------------ Link your protocol to the agreement: safeHarborRegistry.adoptSafeHarbor(agreement); [Modify an Existing Agreement](https://docs.battlechain.com/battlechain/how-to/create-agreement#modify-an-existing-agreement) ------------------------------------------------------------------------------------------------------------------------------ You can update agreements, with restrictions during commitment: // Always allowed agreement.setProtocolName("New Name"); agreement.setContactDetails(newContacts); agreement.addAccounts("eip155:627", newAccounts); // Only favorable changes during commitment agreement.setBountyTerms(betterTerms); // Blocked during commitment agreement.removeChains(chainIds); // Reverts agreement.removeAccounts(chainId, addrs); // Reverts [How to Request Attack Mode\ \ Next: Submit your contracts for attack mode](https://docs.battlechain.com/battlechain/how-to/request-attack-mode) --- # How to Request Attack Mode How to Request Attack Mode ========================== Submit your contracts for DAO approval to enter attack mode [Overview](https://docs.battlechain.com/battlechain/how-to/request-attack-mode#overview) ----------------------------------------------------------------------------------------- After deploying contracts and creating an agreement, request attack mode to enable Safe Harbor protection and allow whitehats to test your contracts. [Prerequisites](https://docs.battlechain.com/battlechain/how-to/request-attack-mode#prerequisites) --------------------------------------------------------------------------------------------------- Before requesting: 1. Contracts deployed (via `BattleChainDeployer` or any other method) 2. Agreement created via `AgreementFactory` 3. Agreement adopted via `adoptSafeHarbor()` 4. Commitment window extends at least 7 days [Request Attack Mode](https://docs.battlechain.com/battlechain/how-to/request-attack-mode#request-attack-mode) --------------------------------------------------------------------------------------------------------------- Call `requestUnderAttack` on the `AttackRegistry`: castFoundry script cast send 0x22134e878c409a0Eab7259d873b38e26Ca966d3C \ "requestUnderAttack(address)" $AGREEMENT_ADDRESS \ --account battlechain \ --rpc-url https://testnet.battlechain.com Run the Foundry script with: forge script script/RequestAttackMode.s.sol \ --account battlechain \ --rpc-url https://testnet.battlechain.com \ --broadcast This validates: * Agreement was created by official factory * You're the agreement owner * All contracts were deployed via BattleChainDeployer * Commitment window meets minimum requirements [For Non-BattleChainDeployer Contracts](https://docs.battlechain.com/battlechain/how-to/request-attack-mode#for-non-battlechaindeployer-contracts) --------------------------------------------------------------------------------------------------------------------------------------------------- If your contracts weren't deployed via `BattleChainDeployer`, call `requestUnderAttackByNonAuthorized` instead. This must be called by the **agreement owner** — the same address that created the agreement via `AgreementFactory`. castFoundry script cast send 0x22134e878c409a0Eab7259d873b38e26Ca966d3C \ "requestUnderAttackByNonAuthorized(address)" $AGREEMENT_ADDRESS \ --account battlechain \ --rpc-url https://testnet.battlechain.com ⚠️ This path requires extra DAO scrutiny since there's no on-chain proof of deployment. [Skip Attack Mode Entirely](https://docs.battlechain.com/battlechain/how-to/request-attack-mode#skip-attack-mode-entirely) --------------------------------------------------------------------------------------------------------------------------- To go directly to production without attack testing: cast send 0x22134e878c409a0Eab7259d873b38e26Ca966d3C \ "goToProduction(address)" $AGREEMENT_ADDRESS \ --account battlechain \ --rpc-url https://testnet.battlechain.com This immediately sets state to `PRODUCTION` with no Safe Harbor protection. [Check Request Status](https://docs.battlechain.com/battlechain/how-to/request-attack-mode#check-request-status) ----------------------------------------------------------------------------------------------------------------- cast call 0x22134e878c409a0Eab7259d873b38e26Ca966d3C \ "getAgreementState(address)(uint8)" $AGREEMENT_ADDRESS \ --rpc-url https://testnet.battlechain.com | Output | Meaning | | --- | --- | | `0` | `NOT_DEPLOYED` — rejected or not requested | | `2` | `ATTACK_REQUESTED` — waiting for DAO | | `3` | `UNDER_ATTACK` — approved | [What Happens Next](https://docs.battlechain.com/battlechain/how-to/request-attack-mode#what-happens-next) ----------------------------------------------------------------------------------------------------------- | Outcome | Timeline | | --- | --- | | DAO Approves | Immediate → `UNDER_ATTACK` | | DAO Rejects | Immediate → `NOT_DEPLOYED` | | DAO Takes No Action | 14 days → `PRODUCTION` (auto-promote) | [Instant Approval (Testnet Only)](https://docs.battlechain.com/battlechain/how-to/request-attack-mode#instant-approval-testnet-only) ------------------------------------------------------------------------------------------------------------------------------------- On testnet the registry moderator is a `MockRegistryModerator` — a permissionless contract that forwards any `approveAttack` call straight to the `AttackRegistry`. You can approve your own request immediately: cast send 0x3DdA228A38b4d7438bBF5D5137c8D1090DcaF6bF \ "approveAttack(address)" $AGREEMENT_ADDRESS \ --account battlechain \ --rpc-url https://testnet.battlechain.com [Request Attack Mode](https://docs.battlechain.com/battlechain/how-to/request-attack-mode#request-attack-mode-1) ----------------------------------------------------------------------------------------------------------------- Call `requestUnderAttack` on the `AttackRegistry` (`0x24876e481eC7198CAC95af739Df2a852CE65A415` on mainnet): cast send 0x24876e481eC7198CAC95af739Df2a852CE65A415 \ "requestUnderAttack(address)" $AGREEMENT_ADDRESS \ --account battlechain \ --rpc-url https://mainnet.battlechain.com [For Non-BattleChainDeployer Contracts](https://docs.battlechain.com/battlechain/how-to/request-attack-mode#for-non-battlechaindeployer-contracts-1) ----------------------------------------------------------------------------------------------------------------------------------------------------- cast send 0x24876e481eC7198CAC95af739Df2a852CE65A415 \ "requestUnderAttackByNonAuthorized(address)" $AGREEMENT_ADDRESS \ --account battlechain \ --rpc-url https://mainnet.battlechain.com ⚠️ This path requires extra DAO scrutiny since there's no on-chain proof of deployment. [Skip Attack Mode Entirely](https://docs.battlechain.com/battlechain/how-to/request-attack-mode#skip-attack-mode-entirely-1) ----------------------------------------------------------------------------------------------------------------------------- cast send 0x24876e481eC7198CAC95af739Df2a852CE65A415 \ "goToProduction(address)" $AGREEMENT_ADDRESS \ --account battlechain \ --rpc-url https://mainnet.battlechain.com This immediately sets state to `PRODUCTION` with no Safe Harbor protection. [Check Request Status](https://docs.battlechain.com/battlechain/how-to/request-attack-mode#check-request-status-1) ------------------------------------------------------------------------------------------------------------------- cast call 0x24876e481eC7198CAC95af739Df2a852CE65A415 \ "getAgreementState(address)(uint8)" $AGREEMENT_ADDRESS \ --rpc-url https://mainnet.battlechain.com | Output | Meaning | | --- | --- | | `0` | `NOT_DEPLOYED` — rejected or not requested | | `2` | `ATTACK_REQUESTED` — waiting for DAO | | `3` | `UNDER_ATTACK` — approved | [What Happens Next](https://docs.battlechain.com/battlechain/how-to/request-attack-mode#what-happens-next-1) ------------------------------------------------------------------------------------------------------------- | Outcome | Timeline | | --- | --- | | DAO Approves | Immediate → `UNDER_ATTACK` | | DAO Rejects | Immediate → `NOT_DEPLOYED` | | DAO Takes No Action | 14 days → `PRODUCTION` (auto-promote) | On mainnet the registry moderator is a controlled DAO role — there is no instant self-approval. ℹ️ Track your request without scripting on the **[Approvals dashboard](https://approvals.battlechain.com/) ** — your agreement appears there as soon as it's requested, showing its current state and full details for moderators to review. [Troubleshooting](https://docs.battlechain.com/battlechain/how-to/request-attack-mode#troubleshooting) ------------------------------------------------------------------------------------------------------- | Error | Solution | | --- | --- | | `InvalidAgreement` | Agreement not from official factory | | `NotAgreementOwner` | Only agreement owner can request | | `AgreementOwnerNotAuthorized` | Call `authorizeAgreementOwner()` for each contract | | `InsufficientCommitment` | Extend commitment window to 7+ days | | `EmptyContractArray` | Add contracts to agreement's BattleChain scope | [How to Promote to Production\ \ Next: Promote after stress testing](https://docs.battlechain.com/battlechain/how-to/promote-to-production) --- # How to Promote to Production How to Promote to Production ============================ Move your contracts from attack mode to production after stress testing [Overview](https://docs.battlechain.com/battlechain/how-to/promote-to-production#overview) ------------------------------------------------------------------------------------------- After successful stress testing, promote your contracts to production mode. This removes Safe Harbor protection and treats contracts like mainnet deployments. ⚠️ Once promoted, there's no going back. Contracts cannot re-enter attack mode. [Request Promotion](https://docs.battlechain.com/battlechain/how-to/promote-to-production#request-promotion) ------------------------------------------------------------------------------------------------------------- // Only the attack moderator can promote attackRegistry.promote(agreementAddress); This starts a 3-day countdown. During this time: * Contracts are still attackable * Safe Harbor still applies * You can cancel if issues are found [Cancel Promotion](https://docs.battlechain.com/battlechain/how-to/promote-to-production#cancel-promotion) ----------------------------------------------------------------------------------------------------------- If an issue is discovered during the 3-day wait: attackRegistry.cancelPromotion(agreementAddress); This returns the agreement to `UNDER_ATTACK` state. [Check Promotion Status](https://docs.battlechain.com/battlechain/how-to/promote-to-production#check-promotion-status) ----------------------------------------------------------------------------------------------------------------------- IAttackRegistry.AgreementInfo memory info = attackRegistry.getAgreementInfo(agreementAddress); if (info.promotionRequestedTimestamp > 0) { uint256 promotionTime = info.promotionRequestedTimestamp + 3 days; if (block.timestamp >= promotionTime) { // Now in PRODUCTION } else { // Still in PROMOTION_REQUESTED, can cancel } } [Mark as Corrupted](https://docs.battlechain.com/battlechain/how-to/promote-to-production#mark-as-corrupted) ------------------------------------------------------------------------------------------------------------- If a whitehat successfully exploits your contracts: attackRegistry.markCorrupted(agreementAddress); This sets state to `CORRUPTED` (terminal), signaling the contracts are compromised. [Transfer Attack Moderator](https://docs.battlechain.com/battlechain/how-to/promote-to-production#transfer-attack-moderator) ----------------------------------------------------------------------------------------------------------------------------- The attack moderator controls promotion. To transfer: attackRegistry.transferAttackModerator(agreementAddress, newModerator); [After Promotion](https://docs.battlechain.com/battlechain/how-to/promote-to-production#after-promotion) --------------------------------------------------------------------------------------------------------- 1. **Deploy to mainnet**: Your contracts are battle-tested 2. **Keep monitoring**: Continue to watch your BattleChain deployment 3. **Mirror updates**: Keep BattleChain and mainnet in sync 4. **Use for staging**: Future updates can use BattleChain's attack mode [Best Practices\ \ Learn best practices for using BattleChain](https://docs.battlechain.com/battlechain/explanation/best-practices) --- # How to Find Attackable Contracts How to Find Attackable Contracts ================================ Query the AttackRegistry to discover contracts you can legally attack [Overview](https://docs.battlechain.com/battlechain/how-to/find-attackable-contracts#overview) ----------------------------------------------------------------------------------------------- The `AttackRegistry` tracks which contracts are in attack mode. This guide shows how to find and verify targets. You can browse agreement statuses and contracts under scope on the [BattleChain explorer](https://explorer.testnet.battlechain.com/agreements) or the [Approvals dashboard](https://approvals.battlechain.com/) — filter to **Under Attack** to see what's currently live, with bounty terms shown per request — or enumerate them programmatically with the API below. [List Attackable Contracts (HTTP API)](https://docs.battlechain.com/battlechain/how-to/find-attackable-contracts#list-attackable-contracts-http-api) ----------------------------------------------------------------------------------------------------------------------------------------------------- The block explorer exposes a JSON API that lists agreements by state — the fastest way for a script or AI agent to enumerate live targets, with no wallet, RPC, or Foundry FFI required. # Every contract currently open to attack (paginated) curl "https://block-explorer-api.testnet.battlechain.com/battlechain/agreements?state=UNDER_ATTACK" Valid `state` values for finding targets are `UNDER_ATTACK` (open now) and `PROMOTION_REQUESTED` (still attackable, on a countdown to production). Paginate with `page` and `limit`. The response is `{ items, meta }`, where `meta` holds pagination (`totalItems`, `totalPages`, `currentPage`) and each item describes one agreement: | Field | Meaning | | --- | --- | | `agreementAddress` | The Safe Harbor agreement | | `protocolName` / `owner` | Who deployed it | | `state` | `UNDER_ATTACK` or `PROMOTION_REQUESTED` | | `coveredContracts` | Addresses in scope — the contracts you may attack | | `coveredAccounts[].childContractScope` | Whether child contracts are also in scope | | `bountyPercentage` / `bountyCapUsd` / `aggregateBountyCapUsd` | What you can earn ([Bounty Terms](https://docs.battlechain.com/battlechain/reference/bounty-terms)
) | | `retainable` | Whether you keep recovered funds or return them ([Execute an Attack](https://docs.battlechain.com/battlechain/how-to/execute-attack)
) | | `contactDetails` | How to reach the protocol | | `valuePricedUsd` / `valueBand` | Estimated value at risk | | `commitmentDeadline` | When the protocol's commitment window ends | Look up a single agreement, find the agreement covering a contract, or read a contract's state directly: # One agreement's full details curl "https://block-explorer-api.testnet.battlechain.com/battlechain/agreement/" # Which agreement (if any) covers a given contract curl "https://block-explorer-api.testnet.battlechain.com/battlechain/agreement/by-contract/" # A contract's current security state curl "https://block-explorer-api.testnet.battlechain.com/battlechain/contract-state/" The `by-contract` endpoint is what `battlechain-lib`'s `isAttackable` calls under the hood. It returns `{ "hasCoverage": bool, "agreements": [{ "state": ... }] }` — a contract is attackable when `hasCoverage` is `true` and any agreement's `state` is `UNDER_ATTACK` or `PROMOTION_REQUESTED`. For **mainnet**, use the `https://block-explorer-api.mainnet.battlechain.com` host instead. 💡 Point your AI agent straight at this API — e.g. _"Fetch the `UNDER_ATTACK` agreements from the BattleChain explorer API and summarize the highest-bounty ones with their covered contracts."_ [Check a Specific Contract (in Solidity)](https://docs.battlechain.com/battlechain/how-to/find-attackable-contracts#check-a-specific-contract-in-solidity) ----------------------------------------------------------------------------------------------------------------------------------------------------------- Inside a Foundry script, the easiest way to check whether a contract is attackable is with `isAttackable` from `battlechain-lib`. It queries the block explorer API and handles the full scope hierarchy — including child contracts spawned by in-scope factories. **Standalone usage** (lightweight, no deploy/agreement overhead): import { BCQuery } from "battlechain-lib/BCQuery.sol"; contract CheckTarget is BCQuery { function run() external { bool attackable = isAttackable(targetAddress); if (attackable) { // Contract is covered by an agreement in UNDER_ATTACK or PROMOTION_REQUESTED state } } } If you're already using `BCScript` for the full deploy + agreement flow, `isAttackable` is available directly — `BCScript` inherits `BCQuery`. Run with the `--ffi` flag since the function uses `vm.ffi` to call the explorer API: forge script script/CheckTarget.s.sol --ffi --rpc-url https://testnet.battlechain.com ℹ️ `isAttackable` requires `--ffi` and `curl` on your PATH. For on-chain-only contexts where `vm.ffi` isn't available, you can use `attackRegistry.isTopLevelContractUnderAttack(address)` — but this only checks top-level contracts and will miss child contracts spawned by in-scope factories. [Monitor for New Targets](https://docs.battlechain.com/battlechain/how-to/find-attackable-contracts#monitor-for-new-targets) ----------------------------------------------------------------------------------------------------------------------------- Watch for `AgreementStateChanged` events: event AgreementStateChanged(address indexed agreementAddress, ContractState newState); // newState = 3 (UNDER_ATTACK) - newly attackable // newState = 4 (PROMOTION_REQUESTED) - still attackable, 3-day countdown // newState = 5 (PRODUCTION) - no longer attackable // newState = 6 (CORRUPTED) - no longer attackable [Get Agreement Details](https://docs.battlechain.com/battlechain/how-to/find-attackable-contracts#get-agreement-details) ------------------------------------------------------------------------------------------------------------------------- // Get agreement for a contract address agreementAddr = attackRegistry.getAgreementForContract(contractAddress); // Get all contracts in scope IAgreement agreement = IAgreement(agreementAddr); address[] memory contracts = agreement.getBattleChainScopeAddresses(); // Get bounty terms BountyTerms memory terms = agreement.getBountyTerms(); [Verify Agreement Validity](https://docs.battlechain.com/battlechain/how-to/find-attackable-contracts#verify-agreement-validity) --------------------------------------------------------------------------------------------------------------------------------- Always verify before attacking: // Check agreement was created by official factory bool isValid = safeHarborRegistry.isAgreementValid(agreementAddress); // Verify contract is in scope bool inScope = agreement.isContractInScope(targetContract); // Double-check state IAttackRegistry.ContractState state = attackRegistry.getAgreementState(agreementAddress); require( state == ContractState.UNDER_ATTACK || state == ContractState.PROMOTION_REQUESTED, "Not attackable" ); [Check Time Remaining](https://docs.battlechain.com/battlechain/how-to/find-attackable-contracts#check-time-remaining) ----------------------------------------------------------------------------------------------------------------------- For contracts in `PROMOTION_REQUESTED`: IAttackRegistry.AgreementInfo memory info = attackRegistry.getAgreementInfo(agreementAddress); if (info.promotionRequestedTimestamp > 0) { uint256 productionAt = info.promotionRequestedTimestamp + 3 days; uint256 timeLeft = productionAt - block.timestamp; // Attack must complete before productionAt } [Red Flags](https://docs.battlechain.com/battlechain/how-to/find-attackable-contracts#red-flags) ------------------------------------------------------------------------------------------------- ⚠️ Be cautious of: * Suspiciously high bounties * Very new agreements (less community vetting) * Missing contact details * Contracts identical to mainnet protocols [How to Execute an Attack\ \ Next: Execute your attack properly](https://docs.battlechain.com/battlechain/how-to/execute-attack) --- # How to Execute an Attack How to Execute an Attack ======================== Properly execute an attack and handle recovered funds [Overview](https://docs.battlechain.com/battlechain/how-to/execute-attack#overview) ------------------------------------------------------------------------------------ Once you've found an attackable contract, execute your exploit and handle funds according to the Safe Harbor terms. [Before Attacking](https://docs.battlechain.com/battlechain/how-to/execute-attack#before-attacking) ---------------------------------------------------------------------------------------------------- 1. Verify contract is in `UNDER_ATTACK` or `PROMOTION_REQUESTED` state 2. Confirm contract is in the agreement's scope 3. Note the recovery address 4. Understand the bounty terms // Verify everything require(attackRegistry.isTopLevelContractUnderAttack(target), "Not attackable"); require(agreement.isContractInScope(target), "Not in scope"); // Get recovery address string memory recoveryStr = agreement.getAssetRecoveryAddress("eip155:627"); address recovery = parseAddress(recoveryStr); // Get bounty terms BountyTerms memory terms = agreement.getBountyTerms(); [Execute Your Exploit](https://docs.battlechain.com/battlechain/how-to/execute-attack#execute-your-exploit) ------------------------------------------------------------------------------------------------------------ There are no restrictions on how you attack in-scope contracts: contract Attacker { function attack(address target) external { // Your exploit logic here IVulnerable(target).vulnerableFunction(); } } [Handle Recovered Funds](https://docs.battlechain.com/battlechain/how-to/execute-attack#handle-recovered-funds) ---------------------------------------------------------------------------------------------------------------- ### [If Retainable = true](https://docs.battlechain.com/battlechain/how-to/execute-attack#if-retainable--true) Keep your bounty, send the rest: uint256 recovered = address(this).balance; uint256 bountyPercent = terms.bountyPercentage; // Calculate bounty (respect the cap) uint256 bounty = (recovered * bountyPercent) / 100; // Note: Convert bountyCapUsd to token amount using oracle // Send remainder to recovery payable(recovery).transfer(recovered - bounty); ### [If Retainable = false](https://docs.battlechain.com/battlechain/how-to/execute-attack#if-retainable--false) Send all funds to recovery: // Send everything payable(recovery).transfer(address(this).balance); // Protocol pays your bounty separately [Multiple Token Types](https://docs.battlechain.com/battlechain/how-to/execute-attack#multiple-token-types) ------------------------------------------------------------------------------------------------------------ Handle each token type: // ETH payable(recovery).transfer(address(this).balance - ethBounty); // ERC20 IERC20(token).transfer(recovery, balance - tokenBounty); // ERC721 (typically return all) IERC721(nft).transferFrom(address(this), recovery, tokenId); [Bounty Calculation](https://docs.battlechain.com/battlechain/how-to/execute-attack#bounty-calculation) -------------------------------------------------------------------------------------------------------- How the bounty is calculated — the formula, the USD cap, and retainable vs return-all settlement — is defined in **[Bounty Terms → Calculation and Settlement](https://docs.battlechain.com/battlechain/reference/bounty-terms#bounty-calculation-and-settlement) **. [After the Attack](https://docs.battlechain.com/battlechain/how-to/execute-attack#after-the-attack) ---------------------------------------------------------------------------------------------------- 1. **Document everything**: Keep transaction hashes, calculations 2. **Meet identity requirements**: If required by the agreement 3. **Consider mainnet implications**: If vulnerability exists on mainnet, contact the protocol privately ⚠️ If the vulnerability also exists on mainnet, do NOT publicly disclose. Contact the protocol through their security contacts instead. [How to Claim Bounties\ \ Learn more about bounty terms and caps](https://docs.battlechain.com/battlechain/how-to/claim-bounties) --- # Review Your First Request Review Your First Request ========================= Evaluate an attack mode request as a DAO member — check for mainnet copycats, verify terms, and approve or reject. ⚖️ You are the DAO A protocol wants to open their contracts for attack. You decide if they're allowed to. Your job is to prevent abuse — mainly ensuring no one copies a live mainnet protocol onto BattleChain to have it "attacked" and drained under Safe Harbor cover. ℹ️ **Prerequisites**: You must be the registry moderator or part of the DAO multisig to approve or reject requests. 💡 Prefer a UI? The **[Approvals dashboard](https://approvals.battlechain.com/) ** lists every pending request with full protocol details, and lets you approve or reject directly once you connect the moderator Safe — no `cast` needed. The steps below show the equivalent on-chain calls. * * * [Find Pending Requests](https://docs.battlechain.com/battlechain/quickstart/review-first-request#find-pending-requests) ------------------------------------------------------------------------------------------------------------------------ Watch for `AgreementStateChanged` events where `newState = 2` (`ATTACK_REQUESTED`), or query directly: cast call 0x22134e878c409a0Eab7259d873b38e26Ca966d3C \ "getAgreementState(address)(uint8)" \ $AGREEMENT_ADDRESS \ --rpc-url https://testnet.battlechain.com | Value | State | | --- | --- | | `2` | `ATTACK_REQUESTED` — needs your review | | `3` | `UNDER_ATTACK` — already approved | * * * [Get the Agreement Details](https://docs.battlechain.com/battlechain/quickstart/review-first-request#get-the-agreement-details) -------------------------------------------------------------------------------------------------------------------------------- Pull the full agreement to review scope and terms: IAgreement agreement = IAgreement(agreementAddress); AgreementDetails memory details = agreement.getDetails(); string memory protocolName = details.protocolName; BountyTerms memory terms = details.bountyTerms; // terms.bountyPercentage, terms.bountyCapUsd, terms.retainable ... Check which contracts are in scope and how they were deployed: address[] memory contracts = agreement.getBattleChainScopeAddresses(); for (uint i = 0; i < contracts.length; i++) { address deployer = attackRegistry.getContractDeployer(contracts[i]); // address(0) = NOT deployed via BattleChainDeployer — extra scrutiny required } * * * [Review Checklist](https://docs.battlechain.com/battlechain/quickstart/review-first-request#review-checklist) -------------------------------------------------------------------------------------------------------------- Is this a legitimate new deployment? Is it NOT a mainnet copycat? Are bounty terms reasonable? Is scope clearly defined? * * * [Make Your Decision](https://docs.battlechain.com/battlechain/quickstart/review-first-request#make-your-decision) ------------------------------------------------------------------------------------------------------------------ ### [Approve](https://docs.battlechain.com/battlechain/quickstart/review-first-request#approve) cast send 0x22134e878c409a0Eab7259d873b38e26Ca966d3C \ "approveAttack(address)" \ $AGREEMENT_ADDRESS \ --rpc-url https://testnet.battlechain.com \ --account battlechain This moves the agreement to `UNDER_ATTACK`, enables Safe Harbor protection, and opens the contracts to whitehats. ### [Reject](https://docs.battlechain.com/battlechain/quickstart/review-first-request#reject) cast send 0x22134e878c409a0Eab7259d873b38e26Ca966d3C \ "rejectAttackRequest(address)" \ $AGREEMENT_ADDRESS \ --rpc-url https://testnet.battlechain.com \ --account battlechain This returns the agreement to `NOT_DEPLOYED`. The protocol can fix whatever was wrong and resubmit. * * * [Red Flags](https://docs.battlechain.com/battlechain/quickstart/review-first-request#red-flags) ------------------------------------------------------------------------------------------------ ⚠️ Reject or investigate further if you see: * **Bytecode matches a known mainnet contract** * **Protocol name mimics a live protocol** * **No verifiable contact information** * **Bounty percentage above 25%** * **Non-BattleChainDeployer submission with no explanation** * * * [What's Next](https://docs.battlechain.com/battlechain/quickstart/review-first-request#whats-next) --------------------------------------------------------------------------------------------------- [Instant Promotion\ \ Emergency promotion for situations where a copycat is suspected post-approval](https://docs.battlechain.com/battlechain/how-to/instant-promotion) [Governance Parameters\ \ The parameters you control as a DAO member](https://docs.battlechain.com/battlechain/reference/governance-parameters) --- # Attack a Contract Attack a Contract ================= Find the vulnerability in a BattleChain vault, exploit it, collect your bounty, and walk away clean under Safe Harbor. ⚔️ You are the Whitehat There's a vulnerable vault on BattleChain. The DAO approved it. Safe Harbor is in place. Your job is to find the bug, drain the vault, keep your bounty, and return the rest. Everything you're about to do is legal, structured, and profitable. Choose your path AI CLI (foundry)Manual (foundry) [Prerequisites](https://docs.battlechain.com/battlechain/tutorials/attacking-contracts#prerequisites) ------------------------------------------------------------------------------------------------------ You need a deployed, attackable vault to target. If you completed the [Quickstart](https://docs.battlechain.com/battlechain/quickstart/deploy-your-contract) , you already have one — your `.env` has everything you need. If you're attacking someone else's vault, you need their `VAULT_ADDRESS` and `TOKEN_ADDRESS` (find these on the [BattleChain explorer](https://explorer.testnet.battlechain.com/) or by querying the `AttackRegistry`). Your AI coding tool with terminal access (Claude Code, Cursor, Windsurf, etc.). If you completed the quickstart, continue in the same session. * * * [Step 1 — Verify the Vault is Attackable](https://docs.battlechain.com/battlechain/tutorials/attacking-contracts#step-1--verify-the-vault-is-attackable) --------------------------------------------------------------------------------------------------------------------------------------------------------- Before doing anything, confirm the vault is in `UNDER_ATTACK` state. Run `just check-state` and tell me the result. I need it to be 3 (UNDER_ATTACK). * * * [Step 2 — Understand the Exploit](https://docs.battlechain.com/battlechain/tutorials/attacking-contracts#step-2--understand-the-exploit) ----------------------------------------------------------------------------------------------------------------------------------------- Open `src/Attacker.sol`. The attack exploits two things working together: the CEI violation in `VulnerableVault` and the hook system in `MockToken`. **MockToken's hook system:** Any address can register a hook contract via `setTransferHook(address hook)`. When tokens are transferred _to_ that address, the token calls `hook.onTokenTransfer()` after the transfer completes. **The vault's CEI violation:** `withdrawAll()` calls `TOKEN.transfer()` _before_ zeroing `balances[msg.sender]`: function withdrawAll() external { uint256 amount = balances[msg.sender]; require(amount > 0, "nothing to withdraw"); TOKEN.transfer(msg.sender, amount); // external call first balances[msg.sender] = 0; // balance zeroed too late } Put them together and the reentrancy chain looks like this: attack() TOKEN.setTransferHook(address(this)) register as our own hook vault.deposit(seedAmount) establish a balance vault.withdrawAll() TOKEN.transfer(attacker, amount) onTokenTransfer() hook fires, balance not yet zeroed vault.withdrawAll() TOKEN.transfer(attacker, amount) onTokenTransfer() still not zeroed ... repeats until vault is empty Once the vault is drained, the Safe Harbor settlement runs automatically: uint256 total = TOKEN.balanceOf(address(this)); // 1,100 = vault's 1,000 + your 100 seed uint256 recovered = total - SEED_AMOUNT; // 1,000 — the protocol's funds only uint256 bounty = (recovered * BOUNTY_BPS) / 10_000; // 10% of recovered = 100 TOKEN.transfer(RECOVERY_ADDRESS, recovered - bounty); // return 900 to the protocol TOKEN.transfer(BENEFICIARY, bounty + SEED_AMOUNT); // keep 100 bounty + your 100 seed The bounty is taken on the protocol's recovered funds only — you don't earn a bounty on the seed you deposited, and you get that seed back. You're not stealing. The protocol gets the majority of funds back minus the agreed bounty. Everyone knew the rules when the agreement was signed. * * * [Step 3 — Execute the Attack](https://docs.battlechain.com/battlechain/tutorials/attacking-contracts#step-3--execute-the-attack) --------------------------------------------------------------------------------------------------------------------------------- Run this yourself in your terminal (you'll be prompted for your keystore password): just attack Watch the output: Vault balance before: 1000 tokens Deploying Exploit (approves attack mode + drains in one tx)... --- Vault drained --- Vault before: 1000 tokens Vault after: 0 tokens Returned to protocol: 900 tokens Bounty kept (yours): 100 tokens (plus your reclaimed seed) ✅ You've executed a legal reentrancy exploit on BattleChain. The vault is empty, the protocol has their funds back minus your bounty, and you're protected under Safe Harbor. * * * [Step 4 — Verify on the Explorer](https://docs.battlechain.com/battlechain/tutorials/attacking-contracts#step-4--verify-on-the-explorer) ----------------------------------------------------------------------------------------------------------------------------------------- Search your `VAULT_ADDRESS` on the [BattleChain explorer](https://explorer.testnet.battlechain.com/) . You should see: * The attack transaction * The vault balance dropping to zero * The bounty transfer to your wallet * The remaining funds sent to the recovery address ### [Check the Math](https://docs.battlechain.com/battlechain/tutorials/attacking-contracts#check-the-math) The agreement set a 10% bounty (`BOUNTY_BPS = 1_000`). To drive the reentrancy, the exploit first deposits 100 tokens of its own as seed, so 1,100 gets drained (the vault's 1,000 + your 100 seed). The bounty is 10% of the **recovered protocol funds** — your own seed doesn't earn a bounty: * **Recovered (protocol funds):** 1,100 − 100 seed = 1,000 tokens * **Bounty (yours):** 1,000 × 10% = 100 tokens * **Returned to protocol:** 1,000 − 100 = 900 tokens * Your 100-token seed comes back to you on top, so your wallet nets **+100**. If the numbers don't look right, check that `RECOVERY_ADDRESS` in your `.env` matches the address in the agreement. * * * [What Just Happened](https://docs.battlechain.com/battlechain/tutorials/attacking-contracts#what-just-happened) ---------------------------------------------------------------------------------------------------------------- You played the whitehat side of a BattleChain engagement: 1. **Verified** the vault was in attack mode with a valid Safe Harbor agreement 2. **Found** the reentrancy vulnerability (CEI violation + token hooks) 3. **Exploited** it to drain the vault 4. **Settled** automatically — kept your 10% bounty, returned 90% to the protocol The protocol now knows their vault has a reentrancy bug. If the same code were deployed on mainnet with real TVL, the loss would have been real. That's the whole point. * * * [Beyond This Tutorial](https://docs.battlechain.com/battlechain/tutorials/attacking-contracts#beyond-this-tutorial) -------------------------------------------------------------------------------------------------------------------- ### [Handling Funds in Real Attacks](https://docs.battlechain.com/battlechain/tutorials/attacking-contracts#handling-funds-in-real-attacks) The starter repo settles funds automatically. In real attacks, you're responsible for correct settlement: **If retainable = true** (you keep bounty from recovered funds): uint256 recovered = token.balanceOf(address(this)); uint256 bounty = (recovered * bountyPercent) / 100; // Respect the cap if set token.transfer(recoveryAddress, recovered - bounty); // Keep your bounty **If retainable = false** (protocol pays bounty separately): // Send everything to recovery token.transfer(recoveryAddress, token.balanceOf(address(this))); Mishandling funds can void your Safe Harbor protection. See [Bounty Terms](https://docs.battlechain.com/battlechain/reference/bounty-terms) for details. ### [Finding Real Targets](https://docs.battlechain.com/battlechain/tutorials/attacking-contracts#finding-real-targets) The starter repo gives you a known vulnerability. In practice, you find targets by querying the `AttackRegistry`: bool attackable = attackRegistry.isTopLevelContractUnderAttack(targetContract); Or monitor for new targets via events: event AgreementStateChanged(address indexed agreementAddress, ContractState newState); // newState = 3 (UNDER_ATTACK) -> newly attackable See [How to Find Attackable Contracts](https://docs.battlechain.com/battlechain/how-to/find-attackable-contracts) for advanced techniques. ### [Mainnet Implications](https://docs.battlechain.com/battlechain/tutorials/attacking-contracts#mainnet-implications) ⚠️ If the vulnerability you found also exists on mainnet: * **Do NOT publicly disclose** the vulnerability * **Contact the protocol** through their security contacts * **Consider traditional bug bounty** for the mainnet instance * Using a BattleChain exploit on mainnet is NOT protected by Safe Harbor * * * [Next Steps](https://docs.battlechain.com/battlechain/tutorials/attacking-contracts#next-steps) ------------------------------------------------------------------------------------------------ [Safe Harbor Protection\ \ Understand the legal framework protecting whitehats](https://docs.battlechain.com/battlechain/explanation/safe-harbor) [Bounty Terms Reference\ \ All bounty configuration options explained](https://docs.battlechain.com/battlechain/reference/bounty-terms) [Find Attackable Contracts\ \ Advanced querying and monitoring techniques](https://docs.battlechain.com/battlechain/how-to/find-attackable-contracts) [Claim Bounties\ \ Detailed fund handling and calculation examples](https://docs.battlechain.com/battlechain/how-to/claim-bounties) --- # How to Claim Bounties How to Claim Bounties ===================== Understand bounty calculations, caps, and the claiming process [Overview](https://docs.battlechain.com/battlechain/how-to/claim-bounties#overview) ------------------------------------------------------------------------------------ Each Safe Harbor agreement defines bounty terms. Understanding these ensures you receive fair compensation. [Read Bounty Terms](https://docs.battlechain.com/battlechain/how-to/claim-bounties#read-bounty-terms) ------------------------------------------------------------------------------------------------------ BountyTerms memory terms = agreement.getBountyTerms(); uint256 percentage = terms.bountyPercentage; // e.g., 10 for 10% uint256 cap = terms.bountyCapUsd; // e.g., 5_000_000 bool canRetain = terms.retainable; // Keep from recovered? IdentityRequirements identity = terms.identity; // KYC level uint256 aggregateCap = terms.aggregateBountyCapUsd; // Total cap across whitehats [How Much You Earn](https://docs.battlechain.com/battlechain/how-to/claim-bounties#how-much-you-earn) ------------------------------------------------------------------------------------------------------ Your bounty amount, the USD cap and how to convert it to tokens, the aggregate cap, and retainable vs return-all settlement are all defined by the agreement's bounty terms. See **[Bounty Terms → Calculation and Settlement](https://docs.battlechain.com/battlechain/reference/bounty-terms#bounty-calculation-and-settlement) ** for the formula, worked examples, and conversions. [Get Recovery Address](https://docs.battlechain.com/battlechain/how-to/claim-bounties#get-recovery-address) ------------------------------------------------------------------------------------------------------------ string memory recoveryStr = agreement.getAssetRecoveryAddress("eip155:627"); // Parse to address for transfers [Tax Considerations](https://docs.battlechain.com/battlechain/how-to/claim-bounties#tax-considerations) -------------------------------------------------------------------------------------------------------- ⚠️ Bounties are likely taxable income. Keep records of: * Date of attack * Assets recovered (types and amounts) * Bounty received * USD value at time of receipt [Safe Harbor Protection\ \ Understand your legal protections](https://docs.battlechain.com/battlechain/explanation/safe-harbor) --- # How to Approve or Reject Requests How to Approve or Reject Requests ================================= Process attack mode requests as a DAO member [Overview](https://docs.battlechain.com/battlechain/how-to/approve-reject-requests#overview) --------------------------------------------------------------------------------------------- As the registry moderator, you review attack requests and decide whether to approve or reject them. [Approvals Dashboard (recommended)](https://docs.battlechain.com/battlechain/how-to/approve-reject-requests#approvals-dashboard-recommended) --------------------------------------------------------------------------------------------------------------------------------------------- The easiest way to do this is the **[Approvals dashboard](https://approvals.battlechain.com/) ** — a public index of every attack-mode request and its state. Browsing requires no wallet; each request links through to the protocol's details, bounty terms, contracts in scope, and a verification flag for the agreement's terms URI. To act on a request, connect the **registry-moderator Safe** (the dashboard supports WalletConnect, so you can pair the Safe from your wallet of choice). Once connected as the moderator, each pending request shows **Approve** and **Reject** buttons that submit the same calls below through the Safe — no `cast` or scripting required. ℹ️ The dashboard is the recommended path. The contract calls below remain available for scripting, batch processing, or programmatic workflows. [Approve a Request](https://docs.battlechain.com/battlechain/how-to/approve-reject-requests#approve-a-request) --------------------------------------------------------------------------------------------------------------- If the request passes review: attackRegistry.approveAttack(agreementAddress); Effects: * State changes to `UNDER_ATTACK` * Safe Harbor protection begins * Whitehats can attack [Reject a Request](https://docs.battlechain.com/battlechain/how-to/approve-reject-requests#reject-a-request) ------------------------------------------------------------------------------------------------------------- If the request fails review: attackRegistry.rejectAttackRequest(agreementAddress); Effects: * State returns to `NOT_DEPLOYED` * Contract mappings cleared * Protocol can resubmit with fixes [Review Checklist](https://docs.battlechain.com/battlechain/how-to/approve-reject-requests#review-checklist) ------------------------------------------------------------------------------------------------------------- Before deciding, verify: 1. **Deployment method**: Deployed via BattleChainDeployer? 2. **Not a copycat**: Bytecode doesn't match mainnet contracts 3. **Legitimate protocol**: Has web presence, audit reports, valid contacts 4. **Reasonable terms**: Bounty percentage in normal range (5-15%) 5. **Clear scope**: All contracts properly defined [Check Deployment Method](https://docs.battlechain.com/battlechain/how-to/approve-reject-requests#check-deployment-method) --------------------------------------------------------------------------------------------------------------------------- address[] memory contracts = agreement.getBattleChainScopeAddresses(); for (uint i = 0; i < contracts.length; i++) { address deployer = attackRegistry.getContractDeployer(contracts[i]); if (deployer == address(0)) { // NOT via BattleChainDeployer - extra scrutiny needed } } [Timing](https://docs.battlechain.com/battlechain/how-to/approve-reject-requests#timing) ----------------------------------------------------------------------------------------- | Scenario | Action | | --- | --- | | Clear approval | Approve immediately | | Clear rejection | Reject with feedback | | Needs investigation | Decide before 14-day deadline | | Approaching deadline, uncertain | Reject to reset clock | ℹ️ If no action is taken within 14 days, the agreement auto-promotes to `PRODUCTION`. [Batch Processing](https://docs.battlechain.com/battlechain/how-to/approve-reject-requests#batch-processing) ------------------------------------------------------------------------------------------------------------- Process multiple requests efficiently: function batchProcess( address[] calldata toApprove, address[] calldata toReject ) external { for (uint i = 0; i < toApprove.length; i++) { attackRegistry.approveAttack(toApprove[i]); } for (uint i = 0; i < toReject.length; i++) { attackRegistry.rejectAttackRequest(toReject[i]); } } [How to Use Instant Promotion\ \ Handle emergency copycat situations](https://docs.battlechain.com/battlechain/how-to/instant-promotion) --- # How to Use Instant Promotion How to Use Instant Promotion ============================ Emergency promotion for copycat or high-risk situations [Overview](https://docs.battlechain.com/battlechain/how-to/instant-promotion#overview) --------------------------------------------------------------------------------------- The DAO can instantly promote contracts to production, bypassing the 3-day delay. This is an emergency power for protecting the ecosystem. ⚠️ Use instant promotion only for genuine emergencies. [When to Use](https://docs.battlechain.com/battlechain/how-to/instant-promotion#when-to-use) --------------------------------------------------------------------------------------------- ### [Copycat Discovery](https://docs.battlechain.com/battlechain/how-to/instant-promotion#copycat-discovery) A mainnet contract mirrors an attackable BattleChain contract: 1. Whitehat finds vulnerability on BattleChain 2. Someone deploys identical contract to mainnet 3. Mainnet contract is now vulnerable 4. **Action**: Instant promote to stop further disclosure ### [TVL Surge](https://docs.battlechain.com/battlechain/how-to/instant-promotion#tvl-surge) Unexpected liquidity growth creates unreasonable risk: 1. Protocol deployed with $100K TVL 2. TVL grows to $10M unexpectedly 3. Risk/reward ratio changes dramatically 4. **Action**: Consider instant promotion if protocol requests ### [Protocol Emergency](https://docs.battlechain.com/battlechain/how-to/instant-promotion#protocol-emergency) Protocol discovers critical issue and needs to exit attack mode: 1. Protocol finds vulnerability themselves 2. Need to patch without whitehats exploiting 3. **Action**: Instant promote to protect users [Execute Instant Promotion](https://docs.battlechain.com/battlechain/how-to/instant-promotion#execute-instant-promotion) ------------------------------------------------------------------------------------------------------------------------- attackRegistry.instantPromote(agreementAddress); Valid from these states: * `ATTACK_REQUESTED` → skips attack phase entirely * `UNDER_ATTACK` → ends attack immediately * `PROMOTION_REQUESTED` → bypasses 3-day delay [Effects](https://docs.battlechain.com/battlechain/how-to/instant-promotion#effects) ------------------------------------------------------------------------------------- * State immediately becomes `PRODUCTION` * Safe Harbor protection ends * Contracts are no longer attackable [Communication Template](https://docs.battlechain.com/battlechain/how-to/instant-promotion#communication-template) ------------------------------------------------------------------------------------------------------------------- Document and communicate the action: EMERGENCY INSTANT PROMOTION Agreement: 0x1234... Protocol: [Name] Previous State: UNDER_ATTACK New State: PRODUCTION Reason: [Copycat detected / TVL surge / Protocol emergency] Details: [Specific circumstances] Actions taken: - Instant promotion at block [number] - Protocol notified - [Other actions] [Governance Parameters\ \ Understand DAO-controlled parameters](https://docs.battlechain.com/battlechain/reference/governance-parameters) --- # How to Add BattleChain to MetaMask How to Add BattleChain to MetaMask ================================== Connect your wallet to the BattleChain network [Overview](https://docs.battlechain.com/battlechain/how-to/add-battlechain-to-metamask#overview) ------------------------------------------------------------------------------------------------- To interact with contracts on BattleChain, you need to add the network to your wallet. This guide covers MetaMask, but the same details work for any EVM-compatible wallet. Use the **Mainnet / Testnet** toggle in the top bar to choose which network these instructions apply to. [Add the network](https://docs.battlechain.com/battlechain/how-to/add-battlechain-to-metamask#add-the-network) --------------------------------------------------------------------------------------------------------------- Click the button below to add the selected network to MetaMask automatically: ### BattleChain Add to MetaMask | | | | --- | --- | | Network Name | BattleChain | | Chain ID | 626 | | RPC URL | https://mainnet.battlechain.com | | Explorer | [https://explorer.mainnet.battlechain.com/](https://explorer.mainnet.battlechain.com/) | | Currency | ETH | | CAIP-2 ID | eip155:626 | If you prefer to add it manually, open MetaMask, click the network selector at the top, choose **Add Network** → **Add a network manually**, enter the details below, and click **Save**: * **Network Name**: BattleChain * **RPC URL**: `https://mainnet.battlechain.com` * **Chain ID**: `626` * **Currency Symbol**: `ETH` * **Block Explorer URL**: `https://explorer.mainnet.battlechain.com/` * **Network Name**: BattleChain Testnet * **RPC URL**: `https://testnet.battlechain.com` * **Chain ID**: `627` * **Currency Symbol**: `ETH` * **Block Explorer URL**: `https://explorer.testnet.battlechain.com/` ✅ BattleChain is now available in your MetaMask network list. [Troubleshooting](https://docs.battlechain.com/battlechain/how-to/add-battlechain-to-metamask#troubleshooting) --------------------------------------------------------------------------------------------------------------- | Issue | Solution | | --- | --- | | Cannot connect to RPC | Ensure the RPC URL is entered exactly as shown above | | Wrong chain ID | Remove the network and re-add with Chain ID `626` (mainnet) or `627` (testnet) | | Transactions stuck | Try resetting your MetaMask account (Settings → Advanced → Reset Account) | [Next Steps](https://docs.battlechain.com/battlechain/how-to/add-battlechain-to-metamask#next-steps) ----------------------------------------------------------------------------------------------------- [Deploy Your First Contract\ \ Get started deploying contracts on BattleChain](https://docs.battlechain.com/battlechain/quickstart/deploy-your-contract) [Find Attackable Contracts\ \ Discover contracts you can legally attack](https://docs.battlechain.com/battlechain/how-to/find-attackable-contracts) --- # Approving Requests: DAO Member Tutorial Approving Requests: DAO Member Tutorial ======================================= A complete tutorial for DAO members on reviewing, approving, and managing attack requests This tutorial teaches DAO members how to evaluate attack mode requests, make approval decisions, and handle edge cases like copycats and emergencies. ℹ️ **Audience**: AttackRegistry DAO members and registry moderators. **Prerequisites**: You must be the registry moderator or part of the DAO multisig. 💡 The **[Approvals dashboard](https://approvals.battlechain.com/) ** packages the monitoring, review, and decision steps below into one UI: it indexes every request, surfaces protocol details and bounty terms, and — once you connect the moderator Safe — approves or rejects with a click. This tutorial covers the underlying flow so you understand what the dashboard does on your behalf. [Your Role](https://docs.battlechain.com/battlechain/tutorials/approving-requests#your-role) --------------------------------------------------------------------------------------------- As a DAO member, you are the gatekeeper for BattleChain's attack mode. Your primary responsibilities: 1. **Approve legitimate requests** — let real protocols stress-test their contracts 2. **Reject copycats** — prevent mainnet contracts from being copied and exploited 3. **Handle emergencies** — use instant promotion when needed 4. **Act promptly** — if you don't act within 14 days, requests auto-promote to production [Understanding the Review Flow](https://docs.battlechain.com/battlechain/tutorials/approving-requests#understanding-the-review-flow) ------------------------------------------------------------------------------------------------------------------------------------- When a protocol requests attack mode, the agreement state changes to `ATTACK_REQUESTED`. You have three options: | Action | Effect | When to Use | | --- | --- | --- | | `approveAttack()` | → `UNDER_ATTACK` | Request passes all checks | | `rejectAttackRequest()` | → `NOT_DEPLOYED` | Red flags found | | `instantPromote()` | → `PRODUCTION` | Emergency (skip attack phase) | | Do nothing | → `PRODUCTION` after 14 days | **Avoid this** — always act | [Step 1: Monitor for Requests](https://docs.battlechain.com/battlechain/tutorials/approving-requests#step-1-monitor-for-requests) ---------------------------------------------------------------------------------------------------------------------------------- Watch for `AgreementStateChanged` events: event AgreementStateChanged(address indexed agreementAddress, ContractState newState); // newState = 2 (ATTACK_REQUESTED) → needs your review Or query pending requests: IAttackRegistry.ContractState state = attackRegistry.getAgreementState(agreementAddress); if (state == IAttackRegistry.ContractState.ATTACK_REQUESTED) { // Needs review } [Step 2: Gather Information](https://docs.battlechain.com/battlechain/tutorials/approving-requests#step-2-gather-information) ------------------------------------------------------------------------------------------------------------------------------ IAgreement agreement = IAgreement(agreementAddress); AgreementDetails memory details = agreement.getDetails(); // Protocol info string memory name = details.protocolName; Contact[] memory contacts = details.contactDetails; // Bounty terms BountyTerms memory terms = details.bountyTerms; // Contracts in scope address[] memory contracts = agreement.getBattleChainScopeAddresses(); Check deployment method for each contract: for (uint i = 0; i < contracts.length; i++) { address deployer = attackRegistry.getContractDeployer(contracts[i]); if (deployer == address(0)) { // NOT via BattleChainDeployer — extra scrutiny needed } } [Step 3: The Review Checklist](https://docs.battlechain.com/battlechain/tutorials/approving-requests#step-3-the-review-checklist) ---------------------------------------------------------------------------------------------------------------------------------- This is the most important part of your role. Go through each check carefully. ### [Check 1: Is This a Mainnet Copycat?](https://docs.battlechain.com/battlechain/tutorials/approving-requests#check-1-is-this-a-mainnet-copycat) **This is the single most important check.** A copycat is someone who deploys a copy of a mainnet contract on BattleChain to exploit it without consequences. * Compare bytecode to known mainnet contracts * Search for the protocol name on other chains * Check if identical contracts exist elsewhere with TVL * Look for suspiciously generic protocol names ⚠️ If you approve a copycat, whitehats may find vulnerabilities that get exploited on mainnet. This damages the entire ecosystem's trust in BattleChain. ### [Check 2: Is This a Legitimate Protocol?](https://docs.battlechain.com/battlechain/tutorials/approving-requests#check-2-is-this-a-legitimate-protocol) * Does the protocol have a web presence? * Are there social accounts, a team, audit reports? * Are the contact details real and responsive? * Was it deployed via BattleChainDeployer? ### [Check 3: Are Bounty Terms Reasonable?](https://docs.battlechain.com/battlechain/tutorials/approving-requests#check-3-are-bounty-terms-reasonable) * Bounty percentage in normal range (5-15%)? * Cap appropriate for expected TVL? * Identity requirements clearly defined? * If `Named`, are diligence requirements specified? ### [Check 4: Is the Scope Clear?](https://docs.battlechain.com/battlechain/tutorials/approving-requests#check-4-is-the-scope-clear) * All relevant contracts included? * Child contract scope makes sense? * Recovery address is a multisig (not an EOA)? [Step 4: Make Your Decision](https://docs.battlechain.com/battlechain/tutorials/approving-requests#step-4-make-your-decision) ------------------------------------------------------------------------------------------------------------------------------ ### [Approve](https://docs.battlechain.com/battlechain/tutorials/approving-requests#approve) attackRegistry.approveAttack(agreementAddress); ### [Reject](https://docs.battlechain.com/battlechain/tutorials/approving-requests#reject) attackRegistry.rejectAttackRequest(agreementAddress); The protocol can fix issues and resubmit. Rejection is not permanent. 💡 When in doubt, **reject**. The protocol can always resubmit. Approving a bad actor is much harder to undo. [Handling Emergencies](https://docs.battlechain.com/battlechain/tutorials/approving-requests#handling-emergencies) ------------------------------------------------------------------------------------------------------------------- ### [Instant Promotion](https://docs.battlechain.com/battlechain/tutorials/approving-requests#instant-promotion) Use `instantPromote()` for genuine emergencies only: attackRegistry.instantPromote(agreementAddress); Valid scenarios: * **Copycat discovered** after approval * **TVL surge** creating unreasonable risk * **Protocol emergency** — critical issue found See [How to Use Instant Promotion](https://docs.battlechain.com/battlechain/how-to/instant-promotion) for the full process. [Best Practices](https://docs.battlechain.com/battlechain/tutorials/approving-requests#best-practices) ------------------------------------------------------------------------------------------------------- * **Act within days, not weeks** — the 14-day auto-promote is a safety net, not a target * **Reject to buy time** — if you need more time, reject and let the protocol resubmit * **Document every decision** — record what you checked and why you decided * **Use instant promotion sparingly** — it's an emergency power, not a convenience feature * **Coordinate with other DAO members** — discuss borderline cases before acting See [Best Practices for the DAO](https://docs.battlechain.com/battlechain/explanation/best-practices) for more guidelines. [Next Steps](https://docs.battlechain.com/battlechain/tutorials/approving-requests#next-steps) ----------------------------------------------------------------------------------------------- [Review Your First Request\ \ Quick-start walkthrough with code](https://docs.battlechain.com/battlechain/quickstart/review-first-request) [Governance Parameters\ \ All parameters you control](https://docs.battlechain.com/battlechain/reference/governance-parameters) --- # Configure Your AI Tools Configure Your AI Tools ======================= Add BattleChain context to your AI coding tools so they deploy to BattleChain and set up Safe Harbor by default [Why This Matters](https://docs.battlechain.com/battlechain/how-to/configure-ai-tools#why-this-matters) -------------------------------------------------------------------------------------------------------- AI coding agents write your deploy scripts, scaffold your tests, and set up infrastructure. If they don't know about BattleChain, they'll deploy straight to mainnet — skipping the battle-testing step entirely. Adding a short instruction block to your project tells every AI tool to: * Deploy contracts to BattleChain first, not mainnet directly * Create a Safe Harbor agreement as part of project setup * Follow the full BattleChain workflow before promoting to production [The Prompt](https://docs.battlechain.com/battlechain/how-to/configure-ai-tools#the-prompt) -------------------------------------------------------------------------------------------- Add the following to your AI tool's configuration file. It works with any tool that reads project-level instructions: ## BattleChain This project deploys to BattleChain for security battle-testing before mainnet. BattleChain is a pre-mainnet L2 where whitehats legally attack contracts under Safe Harbor protection. Full documentation: https://docs.battlechain.com/llms-full.txt ### Deployment workflow 1. Install `battlechain-lib` (`forge install cyfrin/battlechain-lib`) 2. Deploy contracts via `bcDeployCreate*` helpers — works on BattleChain and 190+ EVM chains 3. Create a Safe Harbor agreement via `createAndAdoptAgreement` — auto-scopes per chain 4. Request attack mode (BattleChain only) — `requestAttackMode(agreement)` 5. After battle-testing, promote to production 6. Deploy to mainnet ### Requirements - Use `battlechain-lib` for all deployment and agreement scripts - All deploy scripts must target BattleChain first — never deploy directly to mainnet - Only `requestAttackMode` is BattleChain-specific — deploy and agreement helpers work on any chain - Read the BattleChain documentation before writing deploy or agreement scripts [Quickstart: Install the Skills (Recommended)](https://docs.battlechain.com/battlechain/how-to/configure-ai-tools#quickstart-install-the-skills-recommended) ------------------------------------------------------------------------------------------------------------------------------------------------------------- The fastest way to give your AI agent BattleChain context is to install the Cyfrin skills package: npx skills add cyfrin/solskill This installs three skills: | Skill | What it does | | --- | --- | | `solidity` | Production-grade Solidity standards: code quality, testing, security, Foundry workflows | | `battlechain` | BattleChain reference: deploying, Safe Harbor, whitehat attacks, contract lifecycle | | `battlechain-tutorial` | Interactive wizard: scans your project, asks guided questions, generates all scripts | After installation, tell your AI agent "Deploy my contracts to BattleChain" and the tutorial skill will walk you through the full process interactively. [Alternative: Download the Pre-Built File](https://docs.battlechain.com/battlechain/how-to/configure-ai-tools#alternative-download-the-pre-built-file) ------------------------------------------------------------------------------------------------------------------------------------------------------- If you prefer a static configuration file, download the ready-made CLAUDE.md that includes the full workflow, contract addresses, `battlechain-lib` helpers, network info, and critical gotchas: curl -o CLAUDE.md https://docs.battlechain.com/CLAUDE.md This works for Claude Code out of the box. For other tools, rename the file to match the table below and drop it in your project root. [Where to Add It](https://docs.battlechain.com/battlechain/how-to/configure-ai-tools#where-to-add-it) ------------------------------------------------------------------------------------------------------ Each AI tool reads instructions from a different file. Add the prompt above to whichever tools your team uses: ### [Claude Code](https://docs.battlechain.com/battlechain/how-to/configure-ai-tools#claude-code) Add to `CLAUDE.md` in your project root. Claude Code loads this file automatically at the start of every session. # Create or append to CLAUDE.md cat >> CLAUDE.md << 'EOF' ## BattleChain ... EOF ### [Cursor](https://docs.battlechain.com/battlechain/how-to/configure-ai-tools#cursor) Add to `.cursor/rules/battlechain.mdc` in your project root. Cursor loads all `.mdc` files from this directory as project rules. mkdir -p .cursor/rules # Create .cursor/rules/battlechain.mdc with the prompt above ### [GitHub Copilot](https://docs.battlechain.com/battlechain/how-to/configure-ai-tools#github-copilot) Add to `.github/copilot-instructions.md`. Copilot reads this file for Chat, code review, and the coding agent. mkdir -p .github # Append to .github/copilot-instructions.md ### [OpenAI Codex](https://docs.battlechain.com/battlechain/how-to/configure-ai-tools#openai-codex) Add to `AGENTS.md` in your project root. Codex CLI loads this file as project-level instructions. # Create or append to AGENTS.md ### [Windsurf](https://docs.battlechain.com/battlechain/how-to/configure-ai-tools#windsurf) Add to `.windsurfrules` in your project root. # Create or append to .windsurfrules ### [OpenClaw](https://docs.battlechain.com/battlechain/how-to/configure-ai-tools#openclaw) Add to your OpenClaw skill configuration or system prompt. Point it at the docs URL so it can fetch full context: https://docs.battlechain.com/llms-full.txt ### [Other Tools](https://docs.battlechain.com/battlechain/how-to/configure-ai-tools#other-tools) The same prompt works with any AI tool that reads project-level instruction files. Common patterns: | Tool | File | | --- | --- | | Claude Code | `CLAUDE.md` | | Cursor | `.cursor/rules/*.mdc` | | GitHub Copilot | `.github/copilot-instructions.md` | | OpenAI Codex | `AGENTS.md` | | Windsurf | `.windsurfrules` | | Gemini | `GEMINI.md` | | JetBrains Junie | `.junie/guidelines.md` | | Aider | `.aider.conf.yml` | 💡 The docs URL `https://docs.battlechain.com/llms-full.txt` is the key piece. Any AI that can fetch a URL will get the full BattleChain documentation in one request (~100 KB, fits in most context windows). --- # How Deployment Works How Deployment Works ==================== The BattleChain deploy stack — how just recipes, battlechain-lib, BattleChainDeployer, and CreateX fit together, plus the Foundry flags you need When you deploy to BattleChain you're using a **layered stack**. Each layer is a thin wrapper over the one below it — so the `just deploy-protocol` you run in the quickstart and the `bcDeployCreate(...)` you write in your own script are the _same path_, just entered at different heights. [The stack](https://docs.battlechain.com/battlechain/explanation/how-deployment-works#the-stack) ------------------------------------------------------------------------------------------------- just recipe → starter-kit convenience wrapper (forge script ... --skip-simulation) forge script → your Solidity deploy script battlechain-lib → BCDeploy / BCSafeHarbor helpers (bcDeployCreate, createAndAdoptAgreement, requestAttackMode) BattleChainDeployer → deploys + auto-registers the contract with the AttackRegistry CreateX → the underlying CREATE/CREATE2/CREATE3 factory | Layer | What it is | When you touch it | | --- | --- | --- | | **`just` recipes** | Convenience aliases in the [starter kit](https://github.com/Cyfrin/battlechain-starter)
that run `forge script` with the right flags | Quickstart / fastest path | | **`battlechain-lib`** | The library you install (`BCDeploy`, `BCSafeHarbor`, `BCScript`) exposing `bcDeployCreate*`, `createAndAdoptAgreement`, `requestAttackMode` | Writing your own deploy + agreement scripts | | **`BattleChainDeployer`** | On-chain deployer that wraps CreateX and **auto-registers each deployment** with the `AttackRegistry` (so contracts are attackable) | Reference / direct calls | | **CreateX** | Standard CREATE/CREATE2/CREATE3 factory used under the hood | Rarely directly | The key reason deployments go through `BattleChainDeployer` rather than a raw `CREATE` is **registration**: it records the deployer of every contract so the `AttackRegistry` can resolve which agreement covers it. Deploy outside this path and your contract won't be linked to its agreement. [Which layer should I use?](https://docs.battlechain.com/battlechain/explanation/how-deployment-works#which-layer-should-i-use) -------------------------------------------------------------------------------------------------------------------------------- * **Just trying it out?** Use the starter kit's `just` recipes — see [Deploy and Battle-Test Your Contract](https://docs.battlechain.com/battlechain/quickstart/deploy-your-contract) . * **Deploying your own contracts?** Install `battlechain-lib` and write a script with `BCScript` / `bcDeployCreate*` — see [Deploying Contracts](https://docs.battlechain.com/battlechain/tutorials/deploying-contracts) . * **Need the raw addresses/ABIs?** See the [Contract API Reference](https://docs.battlechain.com/battlechain/reference/contracts) . `battlechain-lib` works on BattleChain _and_ 190+ other EVM chains (it falls back to CreateX directly off-BattleChain). Only `requestAttackMode` is BattleChain-specific. [Foundry on BattleChain](https://docs.battlechain.com/battlechain/explanation/how-deployment-works#foundry-on-battlechain) --------------------------------------------------------------------------------------------------------------------------- These apply to every `forge script` / `cast` call against BattleChain. The starter kit's `justfile` and `battlechain-lib`'s `battlechain.just` already include them. ### [Always pass `--skip-simulation`](https://docs.battlechain.com/battlechain/explanation/how-deployment-works#always-pass---skip-simulation) Forge's local gas estimation isn't reliable on BattleChain, so simulation can fail before broadcast. Skip it: forge script script/Deploy.s.sol --rpc-url https://testnet.battlechain.com --broadcast --skip-simulation ### [Add `-g 300` if a deploy still fails](https://docs.battlechain.com/battlechain/explanation/how-deployment-works#add--g-300-if-a-deploy-still-fails) Bumps the gas estimate to 3× to clear vague out-of-gas failures: forge script script/Deploy.s.sol --rpc-url https://testnet.battlechain.com --broadcast --skip-simulation -g 300 ### [`--legacy` is **not** needed](https://docs.battlechain.com/battlechain/explanation/how-deployment-works#--legacy-is-not-needed) BattleChain accepts standard EIP-1559 transactions — none of the working deploy scripts use `--legacy`. If a tool or older guide tells you to add it, you can ignore that. ### [Watch the 24 KB contract size limit](https://docs.battlechain.com/battlechain/explanation/how-deployment-works#watch-the-24-kb-contract-size-limit) BattleChain enforces the EVM's 24,576-byte limit. An oversized contract can't be gas-estimated, which surfaces as: AnyTxType(2) transaction can't be built due to missing keys: ["gas_limit"] Fix it by enabling the optimizer, splitting the contract, or compiling with `--via-ir`. Check sizes with `forge build --sizes`. [Deploy and Battle-Test Your Contract\ \ Put the stack to work — deploy a vault and open it for attack](https://docs.battlechain.com/battlechain/quickstart/deploy-your-contract) --- # Vercel Security Checkpoint We're verifying your browser [Website owner? Click here to fix](https://vercel.link/security-checkpoint) --- # Vercel Security Checkpoint We're verifying your browser [Website owner? Click here to fix](https://vercel.link/security-checkpoint) --- # Vercel Security Checkpoint We're verifying your browser [Website owner? Click here to fix](https://vercel.link/security-checkpoint) --- # Vercel Security Checkpoint We're verifying your browser [Website owner? Click here to fix](https://vercel.link/security-checkpoint) --- # Vercel Security Checkpoint We're verifying your browser [Website owner? Click here to fix](https://vercel.link/security-checkpoint) --- # Vercel Security Checkpoint We're verifying your browser [Website owner? Click here to fix](https://vercel.link/security-checkpoint) --- # Vercel Security Checkpoint We're verifying your browser [Website owner? Click here to fix](https://vercel.link/security-checkpoint) --- # Vercel Security Checkpoint We're verifying your browser [Website owner? Click here to fix](https://vercel.link/security-checkpoint) --- # Vercel Security Checkpoint We're verifying your browser [Website owner? Click here to fix](https://vercel.link/security-checkpoint) --- # Vercel Security Checkpoint We're verifying your browser [Website owner? Click here to fix](https://vercel.link/security-checkpoint) --- # Vercel Security Checkpoint We're verifying your browser [Website owner? Click here to fix](https://vercel.link/security-checkpoint) --- # Vercel Security Checkpoint We're verifying your browser [Website owner? Click here to fix](https://vercel.link/security-checkpoint) --- # Vercel Security Checkpoint We're verifying your browser [Website owner? Click here to fix](https://vercel.link/security-checkpoint) --- # Vercel Security Checkpoint We're verifying your browser [Website owner? Click here to fix](https://vercel.link/security-checkpoint) --- # Vercel Security Checkpoint We're verifying your browser [Website owner? Click here to fix](https://vercel.link/security-checkpoint) --- # Vercel Security Checkpoint We're verifying your browser [Website owner? Click here to fix](https://vercel.link/security-checkpoint) --- # Vercel Security Checkpoint We're verifying your browser [Website owner? Click here to fix](https://vercel.link/security-checkpoint) --- # Vercel Security Checkpoint We're verifying your browser [Website owner? Click here to fix](https://vercel.link/security-checkpoint) ---