"count()(uint256)" --rpc-url http://localhost:8545
+```
-## Advanced Configuration
+## Configuration
-For specialized customization beyond the core configuration:
+### Basic Chain Configuration
-## Advanced Configuration
+The following are some examples of basic configuration options for the `evmd` chain.
-For specialized customization beyond the core configuration:
+| Setting | Default | How to change | Reference |
+|---------|---------|---------------|-----------|
+| **Cosmos Chain ID** | `cosmos_262144-1` | Pass `--chain-id` at node start | — |
+| **EVM Chain ID** | `262144` | Pass `--evm-chain-id` at node start | [`x/vm/types/params.go`](https://github.com/cosmos/evm/blob/main/x/vm/types/params.go) |
+| **Bech32 Prefix** | `cosmos` | Change `Bech32Prefix` constant | [`evmd/config/bech32.go`](https://github.com/cosmos/evm/blob/main/evmd/config/bech32.go) |
+| **Token Denomination** | `aatom` | Update `ExampleAttoDenom`, used by `NewMintGenesisState()` | [`testutil/constants/constants.go`](https://github.com/cosmos/evm/blob/main/testutil/constants/constants.go) |
+| **EVM Permissioning** | Permissionless | Set `AccessType` in `DefaultAccessControl` | [`x/vm/types/params.go`](https://github.com/cosmos/evm/blob/main/x/vm/types/params.go) |
+| **Precompiles** | All (9 enabled) | Replace `AvailableStaticPrecompiles` in `NewEVMGenesisState()` | [`evmd/genesis.go`](https://github.com/cosmos/evm/blob/main/evmd/genesis.go) |
+| **Modules** | Standard SDK set | Register, set the pre-begin-, begin-, and endblockers, genesis module order, and keeper initialization | [`evmd/app.go`](https://github.com/cosmos/evm/blob/main/evmd/app.go) |
+| **Binary name** | `evmd` | Rename directory and run `find . -type f -name "*.go" -exec sed -i 's/evmd/yourchain/g' {} \;`, then update `go.mod` | — |
-
-
-Configure the EVM mempool for nonce gap handling and transaction prioritization
-
-
-
-
-Deploy standard contracts at genesis for Create2, Multicall3, Permit2, and Safe
-
-
+### Advanced Configuration
-### Recommended Reading
+`evmd` works out of the box with sensible defaults. The following are optional configurations for chains that need to go further.
-
-
-EVM execution and parameter configuration
-
+| Configuration | Description | Reference |
+|---------------|-------------|-----------|
+| **Mempool** | Custom transaction prioritization, nonce gap handling, pool size limits | [Mempool Configuration](/evm/next/documentation/getting-started/build-a-chain/additional-configuration/mempool-integration) |
+| **Fee Market** | Disable base fee, set min gas price, tune base fee adjustment rate | [Fee Market Module](/evm/next/documentation/cosmos-sdk/modules/feemarket) |
+| **EVM Access Control** | Restrict contract deployment/calls to whitelisted addresses | [VM Module](/evm/next/documentation/cosmos-sdk/modules/vm) |
+| **JSON-RPC** | Enable/disable namespaces, set resource caps, configure WebSocket origins | [Node Configuration](/evm/next/documentation/getting-started/network-operators/node-configuration) |
+| **Predeployed Contracts** | Deploy Create2, Multicall3, Permit2, Safe at genesis | [Predeployed Contracts](/evm/next/documentation/getting-started/build-a-chain/additional-configuration/predeployed-contracts) |
-
-Precompiled contracts and integration
-
-
For additional support and community resources, visit the [Cosmos EVM GitHub repository](https://github.com/cosmos/evm) or join the Cosmos developer community.
\ No newline at end of file
From f8ed2f9b4a272cdd14e1360677afbfe631bfa840 Mon Sep 17 00:00:00 2001
From: Evan <87997759+evanorti@users.noreply.github.com>
Date: Wed, 18 Feb 2026 18:07:20 -0500
Subject: [PATCH 11/32] Update docs.json
---
docs.json | 35 ++++++++++++++++++++++++-----------
1 file changed, 24 insertions(+), 11 deletions(-)
diff --git a/docs.json b/docs.json
index 01691a61..987ab80f 100644
--- a/docs.json
+++ b/docs.json
@@ -42,6 +42,30 @@
"source": "/sdk/v0.53/build/spec/addresses/addresses",
"destination": "/sdk/v0.53/build/spec/addresses/bech32"
},
+ {
+ "source": "/evm/next/documentation/concepts/predeployed-contracts",
+ "destination": "/evm/next/documentation/getting-started/build-a-chain/additional-configuration/predeployed-contracts"
+ },
+ {
+ "source": "/evm/next/documentation/smart-contracts/predeployed-contracts/overview",
+ "destination": "/evm/next/documentation/getting-started/build-a-chain/additional-configuration/predeployed-contracts"
+ },
+ {
+ "source": "/evm/next/documentation/smart-contracts/predeployed-contracts/create2",
+ "destination": "/evm/next/documentation/getting-started/build-a-chain/additional-configuration/predeployed-contracts"
+ },
+ {
+ "source": "/evm/next/documentation/smart-contracts/predeployed-contracts/multicall3",
+ "destination": "/evm/next/documentation/getting-started/build-a-chain/additional-configuration/predeployed-contracts"
+ },
+ {
+ "source": "/evm/next/documentation/smart-contracts/predeployed-contracts/permit2",
+ "destination": "/evm/next/documentation/getting-started/build-a-chain/additional-configuration/predeployed-contracts"
+ },
+ {
+ "source": "/evm/next/documentation/smart-contracts/predeployed-contracts/safe-factory",
+ "destination": "/evm/next/documentation/getting-started/build-a-chain/additional-configuration/predeployed-contracts"
+ },
{
"source": "/evm/next/documentation/evm-compatibility/overview",
"destination": "/evm/next/documentation/evm-compatibility"
@@ -1553,7 +1577,6 @@
"evm/next/documentation/concepts/single-token-representation",
"evm/next/documentation/concepts/tokens",
"evm/next/documentation/concepts/transactions",
- "evm/next/documentation/concepts/predeployed-contracts",
"evm/next/documentation/concepts/eip-1559-feemarket",
"evm/next/documentation/concepts/precision-handling"
]
@@ -1579,16 +1602,6 @@
"evm/next/documentation/smart-contracts/precompiles/staking",
"evm/next/documentation/smart-contracts/precompiles/werc20"
]
- },
- {
- "group": "Predeployed Contracts",
- "pages": [
- "evm/next/documentation/smart-contracts/predeployed-contracts/overview",
- "evm/next/documentation/smart-contracts/predeployed-contracts/create2",
- "evm/next/documentation/smart-contracts/predeployed-contracts/multicall3",
- "evm/next/documentation/smart-contracts/predeployed-contracts/permit2",
- "evm/next/documentation/smart-contracts/predeployed-contracts/safe-factory"
- ]
}
]
},
From d37c46e1885a5335da50f181370690887ca5ef52 Mon Sep 17 00:00:00 2001
From: Evan <87997759+evanorti@users.noreply.github.com>
Date: Wed, 18 Feb 2026 18:07:22 -0500
Subject: [PATCH 12/32] Delete predeployed-contracts.mdx
---
.../concepts/predeployed-contracts.mdx | 115 ------------------
1 file changed, 115 deletions(-)
delete mode 100644 evm/next/documentation/concepts/predeployed-contracts.mdx
diff --git a/evm/next/documentation/concepts/predeployed-contracts.mdx b/evm/next/documentation/concepts/predeployed-contracts.mdx
deleted file mode 100644
index 4e41f675..00000000
--- a/evm/next/documentation/concepts/predeployed-contracts.mdx
+++ /dev/null
@@ -1,115 +0,0 @@
----
-title: "Predeployed Contracts"
-description: "Understanding predeployed contracts - what they are, why they're used, and how they differ from precompiles"
-icon: "package"
-keywords: ['predeployed', 'preinstalls', 'theory', 'concept', 'comparison', 'precompiles']
----
-
-## What Are Predeployed Contracts?
-
-Predeployed contracts (also called preinstalls) are regular EVM smart contracts with their bytecode deployed at predetermined addresses, either at chain genesis or through governance mechanisms. Unlike precompiles which are native Go implementations built into the chain binary, predeployed contracts:
-
-- Contain actual EVM bytecode that can be executed by the EVM
-- Consume gas like any regular smart contract
-- Can be verified on block explorers
-- Are immutable once deployed (no upgrades possible)
-
-## Why Use Predeployed Contracts?
-
-Predeployed contracts represent a fundamental pattern in EVM-based chains that provides several key advantages:
-
-### Standardization
-By deploying essential contracts at known addresses, chains ensure compatibility with existing Ethereum tooling and libraries that expect these contracts at specific locations.
-
-### Developer Experience
-Developers don't need to deploy their own versions of common utilities, saving deployment costs and reducing complexity.
-
-### Cross-chain Consistency
-Using the same addresses across different chains enables easier multi-chain development and deployment strategies.
-
-### Ecosystem Alignment
-Many tools, wallets, and dApps in the Ethereum ecosystem expect certain contracts (like Multicall3) at specific addresses.
-
-## Comparison with Precompiles
-
-Understanding the distinction between predeployed contracts and precompiles is crucial for choosing the right approach for your implementation:
-
-| Aspect | Predeployed Contracts | Precompiles |
-|--------|----------------------|-------------|
-| **Implementation** | EVM bytecode stored on-chain | Native Go code in chain binary |
-| **Gas Costs** | Standard EVM gas pricing | Custom, typically lower gas costs |
-| **Deployment** | Must be explicitly deployed | Always available when enabled |
-| **Upgradeability** | Immutable once deployed | Can be modified via chain upgrades |
-| **Verification** | Verifiable on block explorers | Source not visible on-chain |
-| **Address Range** | Any valid address | Special range (0x1-0x9FF) |
-| **Storage** | Uses regular contract storage | Can access native Cosmos state |
-
-## When to Choose Predeployed Contracts
-
-Use predeployed contracts when:
-- You need standard Ethereum contracts at expected addresses
-- Full EVM compatibility is required
-- Contract source verification is important
-- The functionality doesn't require native chain integration
-
-Use precompiles when:
-- You need optimized gas costs for frequently used operations
-- Direct access to Cosmos SDK state is required
-- The functionality requires native chain features
-- Upgradeability through chain upgrades is needed
-
-## Configuration
-
-### Genesis Configuration
-
-Predeployed contracts are configured during chain genesis through the `preinstalls` parameter in the VM module. This defines which contracts are deployed at specific addresses during network initialization.
-
-```json "Genesis Preinstalls Configuration" expandable
-{
- "app_state": {
- "vm": {
- "preinstalls": [
- {
- "address": "0x4e59b44847b379578588920ca78fbf26c0b4956c",
- "code": "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe03601600081602082378035828234f58015156039578182fd5b8082525050506014600cf3",
- "name": "Create2"
- },
- {
- "address": "0xcA11bde05977b3631167028862bE2a173976CA11",
- "code": "0x6080604052...", // Full Multicall3 bytecode
- "name": "Multicall3"
- }
- ]
- }
- }
-}
-```
-
-
-The default preinstalls are defined in the codebase at [`x/vm/types/preinstall.go:13-39`](https://github.com/cosmos/evm/blob/main/x/vm/types/preinstall.go#L13-L39). For complete guidance on customizing preinstalls, see:
-- [Building Your Chain Guide](/evm/next/documentation/getting-started/build-a-chain/overview#configuring-predeployed-contracts) - Quick start configuration
-- [Predeployed Contracts Integration](/evm/next/documentation/getting-started/build-a-chain/additional-configuration/predeployed-contracts) - Detailed implementation guide
-
-
-## Common Examples
-
-The Cosmos EVM includes several default predeployed contracts (defined in [`evmtypes.DefaultPreinstalls`](https://github.com/cosmos/evm/blob/main/x/vm/types/preinstall.go#L13-L39)):
-
-- **Create2** (`0x4e59b44847b379578588920ca78fbf26c0b4956c`): Deterministic contract deployment - [Documentation](/evm/next/documentation/smart-contracts/predeployed-contracts/create2)
-- **Multicall3** (`0xcA11bde05977b3631167028862bE2a173976CA11`): Batch multiple calls in one transaction - [Documentation](/evm/next/documentation/smart-contracts/predeployed-contracts/multicall3)
-- **Permit2** (`0x000000000022D473030F116dDEE9F6B43aC78BA3`): Universal token approval system - [Documentation](/evm/next/documentation/smart-contracts/predeployed-contracts/permit2)
-- **Safe Factory** (`0x914d7Fec6aaC8cd542e72Bca78B30650d45643d7`): Deploy Safe multisig wallets - [Documentation](/evm/next/documentation/smart-contracts/predeployed-contracts/safe-factory)
-- **EIP-2935** (`0x0b`): Historical block hash storage (system contract)
-
-For comprehensive information on each contract including usage examples and integration patterns, see the [Predeployed Contracts Overview](/evm/next/documentation/smart-contracts/predeployed-contracts/overview).
-
-## Related Concepts
-
-- [Precompiles](/evm/next/documentation/smart-contracts/precompiles/overview) - Native chain implementations exposed as smart contracts
-- [VM Module](evm/next/documentation/cosmos-sdk/modules/vm) - Core EVM module configuration including preinstalls
-- [Building Your Chain](/evm/next/documentation/getting-started/build-a-chain/overview) - Complete guide to chain setup
-
-## Implementation Guides
-
-- [Predeployed Contracts Integration](/evm/next/documentation/getting-started/build-a-chain/additional-configuration/predeployed-contracts) - Detailed technical guide for deploying and managing preinstalled contracts
-- [Individual Contract Documentation](/evm/next/documentation/smart-contracts/predeployed-contracts/overview) - Usage examples and integration patterns for each contract
\ No newline at end of file
From 392b64906215691d60806d654162311663de4fe4 Mon Sep 17 00:00:00 2001
From: Evan <87997759+evanorti@users.noreply.github.com>
Date: Wed, 18 Feb 2026 18:07:24 -0500
Subject: [PATCH 13/32] Update predeployed-contracts.mdx
---
.../predeployed-contracts.mdx | 310 ++++--------------
1 file changed, 67 insertions(+), 243 deletions(-)
diff --git a/evm/next/documentation/getting-started/build-a-chain/additional-configuration/predeployed-contracts.mdx b/evm/next/documentation/getting-started/build-a-chain/additional-configuration/predeployed-contracts.mdx
index e1efe69b..928ebc27 100644
--- a/evm/next/documentation/getting-started/build-a-chain/additional-configuration/predeployed-contracts.mdx
+++ b/evm/next/documentation/getting-started/build-a-chain/additional-configuration/predeployed-contracts.mdx
@@ -1,48 +1,51 @@
---
title: "Predeployed Contracts"
-description: "Deploying and managing predeployed contracts"
+description: "Deploy standard EVM contracts at fixed addresses on your Cosmos EVM chain."
---
-
-**New to predeployed contracts?** Start here:
-- [Predeployed Contracts Concept](/evm/next/documentation/concepts/predeployed-contracts) - Understanding predeployed contracts and how they differ from precompiles
-- [Predeployed Contracts Overview](/evm/next/documentation/smart-contracts/predeployed-contracts/overview) - Quick reference of available contracts
-- [Building Your Chain Guide](/evm/next/documentation/getting-started/build-a-chain/overview#configuring-predeployed-contracts) - Quick start configuration examples
+Predeployed contracts (also called preinstalls) are EVM contracts that exist in chain state at a specific address from genesis. Because the address is fixed and known in advance, the same contract can exist at the same address across every chain that includes it, making them useful for infrastructure that needs to be reliably reachable everywhere.
-**Individual Contract Documentation**:
-- [Create2 Factory](/evm/next/documentation/smart-contracts/predeployed-contracts/create2) - Deterministic deployment patterns
-- [Multicall3](/evm/next/documentation/smart-contracts/predeployed-contracts/multicall3) - Batch operations examples
-- [Permit2](/evm/next/documentation/smart-contracts/predeployed-contracts/permit2) - Signature-based approvals
-- [Safe Factory](/evm/next/documentation/smart-contracts/predeployed-contracts/safe-factory) - Multisig wallet deployment
-
+## Default Contracts
-## Getting Started
+Cosmos EVM includes five default preinstalls ([`x/vm/types/preinstall.go`](https://github.com/cosmos/evm/blob/main/x/vm/types/preinstall.go)):
-There are several methods to deploy preinstalled contracts on a Cosmos EVM chain:
+| Contract | Address | Purpose | Docs |
+|----------|---------|---------|------|
+| **Create2** | `0x4e59b44847b379578588920ca78fbf26c0b4956c` | Deterministic contract deployment using CREATE2 | [EIP-1014](https://eips.ethereum.org/EIPS/eip-1014) |
+| **Multicall3** | `0xcA11bde05977b3631167028862bE2a173976CA11` | Batch multiple contract calls in one transaction | [Repo](https://github.com/mds1/multicall) · [Site](https://www.multicall3.com/) |
+| **Permit2** | `0x000000000022D473030F116dDEE9F6B43aC78BA3` | Signature-based token approvals for any ERC20 | [Repo](https://github.com/Uniswap/permit2) · [Docs](https://docs.uniswap.org/contracts/permit2/overview) |
+| **Safe Singleton Factory** | `0x914d7Fec6aaC8cd542e72Bca78B30650d45643d7` | Deploy Safe multisig wallets at deterministic addresses | [Repo](https://github.com/safe-global/safe-singleton-factory) · [Docs](https://docs.safe.global/) |
+| **EIP-2935** | `0x0000F90827F1C53a10cb7A02335B175320002935` | Historical block hash storage | [EIP-2935](https://eips.ethereum.org/EIPS/eip-2935) |
-### 1. Genesis Configuration
-The most straightforward method for new chains or testnets. Contracts are deployed when the chain is first initialized.
+## Enabling at Genesis
-
-
-If using the reference `evmd` application, your chain automatically includes default preinstalls, however they will not be active by default.
+Preinstalls are deployed when the chain first starts, based on the `preinstalls` array in `genesis.json`. If the array is empty, no contracts are deployed.
-```go expandable
-// Source: evmd/genesis.go:28-34
+### App-level configuration
+
+In your chain's application code, define which preinstalls to include in `NewEVMGenesisState`. The `evmd` reference chain includes all five defaults:
+
+```go title="evmd/genesis.go"
func NewEVMGenesisState() *evmtypes.GenesisState {
evmGenState := evmtypes.DefaultGenesisState()
evmGenState.Params.ActiveStaticPrecompiles = evmtypes.AvailableStaticPrecompiles
- evmGenState.Preinstalls = evmtypes.DefaultPreinstalls // Defined in x/vm/types/preinstall.go
+ evmGenState.Preinstalls = evmtypes.DefaultPreinstalls
return evmGenState
}
```
-
-
-To customize which contracts are deployed:
+This function is called by your app's `DefaultGenesis()`, which is used when generating genesis state programmatically (e.g. `evmd testnet`).
+
+### Populating genesis.json
-```json expandable
+
+`evmd init` generates a genesis.json with an empty `preinstalls` array. The app-level preinstall configuration is **not** automatically written to the genesis file by the init command.
+
+
+To enable preinstalls on a chain started from a genesis file (including `local_node.sh`), populate the `preinstalls` array in `genesis.json` before starting the node. Each entry requires the contract name, address, and compiled bytecode:
+
+```json title="genesis.json"
{
"app_state": {
"evm": {
@@ -55,283 +58,104 @@ To customize which contracts are deployed:
{
"name": "Multicall3",
"address": "0xcA11bde05977b3631167028862bE2a173976CA11",
- "code": "0x6080604052..." // Full bytecode
+ "code": "0x..."
}
]
}
}
}
```
-
-
-
-#### Local Development
-
-The `local_node.sh` script automatically configures default preinstalls:
-
-```bash expandable
-./local_node.sh
-# Automatically deploys all default preinstalls
-```
-### 2. Governance Proposal
+The full bytecode for each default preinstall is defined in [`x/vm/types/preinstall.go`](https://github.com/cosmos/evm/blob/main/x/vm/types/preinstall.go).
-For chains already in production, use the `MsgRegisterPreinstalls` governance proposal:
+## Adding Contracts After Launch
-#### Proposal Structure
+### Governance Proposal
-
-The `authority` field must be set to the governance module account address, which is typically derived from the gov module name. This is usually something like `cosmos10d07y265gmmuvt4z0w9aw880jnsr700j6zn9kn` for the standard gov module.
-
+Use `MsgRegisterPreinstalls` to deploy contracts on a running chain via governance:
-```json expandable
+```json title="proposal.json"
{
"messages": [
{
"@type": "/cosmos.evm.vm.v1.MsgRegisterPreinstalls",
- "authority": "[gov module account address]",
+ "authority": "",
"preinstalls": [
{
"name": "Multicall3",
"address": "0xcA11bde05977b3631167028862bE2a173976CA11",
- "code": "0x6080604052..."
+ "code": "0x..."
}
]
}
],
- "metadata": "ipfs://CID",
"deposit": "10000000stake",
- "title": "Deploy Multicall3 Contract",
- "summary": "Deploy the Multicall3 contract to enable batched calls"
+ "title": "Deploy Multicall3",
+ "summary": "Deploy Multicall3 to enable batched contract calls"
}
```
-#### Submission Process
-
-```bash expandable
-# Submit proposal
-evmd tx gov submit-proposal proposal.json \
- --from mykey \
- --chain-id cosmosevm_9001-1 \
- --gas auto
-
-# Vote on proposal
+```bash
+evmd tx gov submit-proposal proposal.json --from mykey --chain-id --gas auto
evmd tx gov vote 1 yes --from mykey
```
-### 3. Chain Upgrade Handler
+### Chain Upgrade Handler
-Include predeployed contracts as part of a coordinated chain upgrade:
+Include preinstalls in a coordinated chain upgrade:
-```go expandable
+```go title="app/upgrades/v2/upgrades.go"
func CreateUpgradeHandler(
mm *module.Manager,
configurator module.Configurator,
evmKeeper *evmkeeper.Keeper,
) upgradetypes.UpgradeHandler {
return func(ctx sdk.Context, plan upgradetypes.Plan, fromVM module.VersionMap) (module.VersionMap, error) {
- // Add preinstalls during upgrade
if err := evmKeeper.AddPreinstalls(ctx, evmtypes.DefaultPreinstalls); err != nil {
return nil, err
}
-
return mm.RunMigrations(ctx, configurator, fromVM)
}
}
```
-## Implementation Details
-
-### Validation Process
-
-All preinstall deployments undergo strict validation:
-
-1. **Address Validation**
- - Must be valid Ethereum address format (40 hex characters)
- - Cannot conflict with existing contracts
- - Should not overlap with precompile reserved addresses (typically 0x1-0x9FF)
-
-2. **Code Validation**
- - Must be valid EVM bytecode (hex encoded)
- - Cannot have empty code hash
- - Must pass bytecode verification
+## Adding Custom Contracts
-3. **Conflict Prevention**
- - Checks for existing contracts at target address
- - Validates against account keeper for existing accounts
- - Ensures no code hash conflicts with different bytecode
+To deploy a contract beyond the defaults, add it to your preinstalls list:
-### Storage and State
-
-Predeployed contracts are stored in the chain state like regular contracts:
-
-```go expandable
-// Actual deployment process from x/vm/keeper/preinstalls.go
-func (k *Keeper) AddPreinstalls(ctx sdk.Context, preinstalls []types.Preinstall) error {
- for _, preinstall := range preinstalls {
- address := common.HexToAddress(preinstall.Address)
- accAddress := sdk.AccAddress(address.Bytes())
-
- if len(preinstall.Code) == 0 {
- return errorsmod.Wrapf(types.ErrInvalidPreinstall,
- "preinstall %s has no code", preinstall.Address)
- }
-
- codeHash := crypto.Keccak256Hash(common.FromHex(preinstall.Code)).Bytes()
- if types.IsEmptyCodeHash(codeHash) {
- return errorsmod.Wrapf(types.ErrInvalidPreinstall,
- "preinstall %s has empty code hash", preinstall.Address)
- }
-
- // Check for existing code hash conflicts
- existingCodeHash := k.GetCodeHash(ctx, address)
- if !types.IsEmptyCodeHash(existingCodeHash.Bytes()) &&
- !bytes.Equal(existingCodeHash.Bytes(), codeHash) {
- return errorsmod.Wrapf(types.ErrInvalidPreinstall,
- "preinstall %s already has a different code hash", preinstall.Address)
- }
-
- // Check that the account is not already set
- if acc := k.accountKeeper.GetAccount(ctx, accAddress); acc != nil {
- return errorsmod.Wrapf(types.ErrInvalidPreinstall,
- "preinstall %s already has an account in account keeper", preinstall.Address)
- }
-
- // Create account and store code
- account := k.accountKeeper.NewAccountWithAddress(ctx, accAddress)
- k.accountKeeper.SetAccount(ctx, account)
- k.SetCodeHash(ctx, address.Bytes(), codeHash)
- k.SetCode(ctx, codeHash, common.FromHex(preinstall.Code))
- }
- return nil
+```go title="evmd/genesis.go"
+customPreinstall := evmtypes.Preinstall{
+ Name: "MyContract",
+ Address: "0xYourChosenAddress",
+ Code: "0xCompiledBytecode",
}
+evmGenState.Preinstalls = append(evmtypes.DefaultPreinstalls, customPreinstall)
```
-## Verification and Testing
+Requirements for a valid preinstall:
+- Valid Ethereum address (0x prefix, 40 hex characters)
+- Must not conflict with existing contracts or precompile addresses (0x1–0x9FF)
+- Non-empty, valid EVM bytecode (hex encoded)
-### Verify Deployment
+## Verification
-After deployment, verify contracts are properly installed:
+After the chain starts with preinstalls in genesis.json, confirm the contracts are installed:
-```bash expandable
-# Query contract code via CLI
+```bash
+# Check contract code is present
evmd query evm code 0x4e59b44847b379578588920ca78fbf26c0b4956c
# Check account exists
evmd query evm account 0x4e59b44847b379578588920ca78fbf26c0b4956c
```
-```javascript expandable
-// Verify via Web3
-const code = await provider.getCode("0x4e59b44847b379578588920ca78fbf26c0b4956c");
-console.log("Deployed:", code !== "0x");
-```
-
-## Known Issues
-
-
-**Critical - Safe Factory Bytecode Error**
-
-The Safe Singleton Factory bytecode in `DefaultPreinstalls` ([`x/vm/types/preinstall.go:30-32`](https://github.com/cosmos/evm/blob/main/x/vm/types/preinstall.go#L30-L32)) is **identical to the Create2 factory bytecode**, which is incorrect and will not function for deploying Safe wallets.
-
-**Verification**:
-```bash expandable
-# Create2 bytecode
-0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe03601600081602082378035828234f58015156039578182fd5b8082525050506014600cf3
-
-# Safe Factory bytecode (INCORRECT - same as Create2)
-0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe03601600081602082378035828234f58015156039578182fd5b8082525050506014600cf3
-```
-
-**Before deploying to production**:
-1. Get the correct Safe Singleton Factory bytecode from the [official repository](https://github.com/safe-global/safe-singleton-factory)
-2. Update your genesis `preinstalls` configuration with the correct bytecode
-3. Test thoroughly on a testnet
-4. See the [Safe Factory documentation](/evm/next/documentation/smart-contracts/predeployed-contracts/safe-factory) for more details
-
-**Temporary workaround**: If you need Safe functionality immediately, manually update the bytecode in your genesis.json or use a governance proposal to deploy the correct contract.
-
-
-## Adding Custom Preinstalls
-
-To add custom contracts beyond the defaults:
-
-```go expandable
-// Define custom preinstall
-customPreinstall := types.Preinstall{
- Name: "MyCustomContract",
- Address: "0xYourChosenAddress",
- Code: "0xCompiledBytecode",
-}
-
-// Validate before deployment
-if err := customPreinstall.Validate(); err != nil {
- return err
-}
-
-// Add via appropriate method (genesis, governance, or upgrade)
-preinstalls := append(evmtypes.DefaultPreinstalls, customPreinstall)
-```
+Both commands should return non-empty results. If `code` returns `null`, the preinstall was not included in genesis.json when the chain was initialized.
## Troubleshooting
-### Common Issues
-
-| Issue | Cause | Solution |
-|-|-|-|
-| "preinstall already has an account in account keeper" | Address collision | Choose different address |
-| "preinstall has empty code hash" | Invalid or empty bytecode | Verify bytecode hex string is valid |
-| "preinstall address is not a valid hex address" | Malformed address | Ensure 0x prefix and 40 hex chars |
-| "invalid authority" | Wrong governance address | Use correct gov module account address |
-| Contract not found after deployment | Wrong network | Verify chain ID and RPC endpoint |
-
-### Debugging Steps
-
-1. Check chain genesis configuration
-2. Verify proposal passed and executed
-3. Query contract code directly
-4. Test with simple contract interaction
-5. Review chain logs for errors
-
-## Quick Reference
-
-### Default Preinstalls
-
-| Contract | Address | Bytecode Field | Status |
-|-|||--|
-| Create2 | `0x4e59b44847b379578588920ca78fbf26c0b4956c` | `preinstall.Code` | ✓ Verified |
-| Multicall3 | `0xcA11bde05977b3631167028862bE2a173976CA11` | `preinstall.Code` | ✓ Verified |
-| Permit2 | `0x000000000022D473030F116dDEE9F6B43aC78BA3` | `preinstall.Code` | ✓ Verified |
-| Safe Factory | `0x914d7Fec6aaC8cd542e72Bca78B30650d45643d7` | `preinstall.Code` | ⚠️ Bytecode Issue |
-| EIP-2935 | `0x0b` | `params.HistoryStorageCode` | ✓ System Contract |
-
-**Source**: [`x/vm/types/preinstall.go:13-39`](https://github.com/cosmos/evm/blob/main/x/vm/types/preinstall.go#L13-L39)
-
-### Genesis Configuration Paths
-
-```json expandable
-{
- "app_state": {
- "vm": {
- "preinstalls": [...], // Configure predeployed contracts
- "params": {
- "active_static_precompiles": [...] // Configure precompiles (different!)
- }
- }
- }
-}
-```
-
-## Further Resources
-
-### Official Specifications
-- [EIP-1014: CREATE2 Specification](https://eips.ethereum.org/EIPS/eip-1014) - Understanding deterministic deployment
-- [EIP-2935: Historical Block Hashes](https://eips.ethereum.org/EIPS/eip-2935) - Block hash storage specification
-
-### Contract Documentation
-- [Multicall3 Documentation](https://github.com/mds1/multicall) - Official Multicall3 repository
-- [Permit2 Introduction](https://blog.uniswap.org/permit2-and-universal-router) - Uniswap's Permit2 design
-- [Safe Contracts](https://github.com/safe-global/safe-contracts) - Safe multisig implementation
-
-### Cosmos EVM Resources
-- [VM Module Reference](evm/next/documentation/cosmos-sdk/modules/vm) - Complete VM module configuration
\ No newline at end of file
+| Error | Cause | Fix |
+|-------|-------|-----|
+| `preinstall already has an account in account keeper` | Address already has a contract | Choose a different address |
+| `preinstall has empty code hash` | Invalid or empty bytecode | Verify bytecode hex string is valid and non-empty |
+| `preinstall address is not a valid hex address` | Malformed address | Ensure 0x prefix and 40 hex characters |
+| `invalid authority` | Wrong governance address | Use the correct gov module account address |
From 5a5ad271622ffe6c46c702f489600ce6245182c8 Mon Sep 17 00:00:00 2001
From: Evan <87997759+evanorti@users.noreply.github.com>
Date: Wed, 18 Feb 2026 18:07:26 -0500
Subject: [PATCH 14/32] Update overview.mdx
---
.../documentation/getting-started/build-a-chain/overview.mdx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/evm/next/documentation/getting-started/build-a-chain/overview.mdx b/evm/next/documentation/getting-started/build-a-chain/overview.mdx
index 29a875ca..5c80f496 100644
--- a/evm/next/documentation/getting-started/build-a-chain/overview.mdx
+++ b/evm/next/documentation/getting-started/build-a-chain/overview.mdx
@@ -31,7 +31,7 @@ Configure the EVM mempool for nonce gap handling and transaction prioritization
-
+
Deploy standard contracts at genesis for Create2, Multicall3, Permit2, and Safe
From cf1bf78524794b2aee2201b56d498a0aec1de38b Mon Sep 17 00:00:00 2001
From: Evan <87997759+evanorti@users.noreply.github.com>
Date: Wed, 18 Feb 2026 18:07:40 -0500
Subject: [PATCH 15/32] remove unneeded pages
---
.../predeployed-contracts/create2.mdx | 303 -------------
.../predeployed-contracts/multicall3.mdx | 330 --------------
.../predeployed-contracts/overview.mdx | 33 --
.../predeployed-contracts/permit2.mdx | 415 -----------------
.../predeployed-contracts/safe-factory.mdx | 419 ------------------
5 files changed, 1500 deletions(-)
delete mode 100644 evm/next/documentation/smart-contracts/predeployed-contracts/create2.mdx
delete mode 100644 evm/next/documentation/smart-contracts/predeployed-contracts/multicall3.mdx
delete mode 100644 evm/next/documentation/smart-contracts/predeployed-contracts/overview.mdx
delete mode 100644 evm/next/documentation/smart-contracts/predeployed-contracts/permit2.mdx
delete mode 100644 evm/next/documentation/smart-contracts/predeployed-contracts/safe-factory.mdx
diff --git a/evm/next/documentation/smart-contracts/predeployed-contracts/create2.mdx b/evm/next/documentation/smart-contracts/predeployed-contracts/create2.mdx
deleted file mode 100644
index eb98b146..00000000
--- a/evm/next/documentation/smart-contracts/predeployed-contracts/create2.mdx
+++ /dev/null
@@ -1,303 +0,0 @@
----
-title: "Create2 Factory"
-description: "Deterministic contract deployment factory using the CREATE2 opcode"
-icon: "factory"
-keywords: ['create2', 'deterministic', 'deployment', 'factory', 'salt', 'address', 'prediction', 'bytecode']
----
-
-The Create2 Factory is a minimal proxy contract that enables deterministic contract deployment using the CREATE2 opcode. This allows developers to deploy contracts to addresses that can be computed in advance, regardless of the deployer's nonce or transaction order.
-
-**Contract Address**: `0x4e59b44847b379578588920ca78fbf26c0b4956c`
-**Deployment Status**: Default preinstall
-**Gas Cost**: Deployment cost + ~32,000 gas overhead
-
-## Key Features
-
-- **Deterministic Addresses**: Compute contract addresses before deployment
-- **Cross-chain Consistency**: Same address on all chains with the same bytecode and salt
-- **Minimal Implementation**: Only 45 bytes of optimized assembly code
-- **No Storage or State**: Pure function contract with no storage variables
-
-## How It Works
-
-The CREATE2 opcode computes addresses using:
-```
-address = keccak256(0xff ++ deployerAddress ++ salt ++ keccak256(bytecode))[12:]
-```
-
-This formula ensures that the same inputs always produce the same address, enabling:
-- Pre-funding of contract addresses before deployment
-- Cross-chain address consistency
-- Gasless contract deployment patterns
-
-## Usage
-
-### Deploy a Contract
-
-
-```javascript "Ethers.js Create2 Contract Deployment" expandable
-import { ethers } from "ethers";
-
-const provider = new ethers.JsonRpcProvider("YOUR_RPC_URL");
-const signer = new ethers.Wallet("YOUR_PRIVATE_KEY", provider);
-
-// Create2 Factory address
-const CREATE2_FACTORY = "0x4e59b44847b379578588920ca78fbf26c0b4956c";
-
-// Your contract bytecode (including constructor args)
-const bytecode = "0x608060405234801561001057600080fd5b50..."; // Your compiled bytecode
-
-// Choose a salt (32 bytes)
-const salt = ethers.id("my-unique-salt-v1"); // Or use ethers.randomBytes(32)
-
-// Deploy using Create2
-async function deployWithCreate2() {
- // Compute the deployment address
- const deployAddress = ethers.getCreate2Address(
- CREATE2_FACTORY,
- salt,
- ethers.keccak256(bytecode)
- );
-
- console.log("Contract will be deployed to:", deployAddress);
-
- // Send deployment transaction
- const tx = await signer.sendTransaction({
- to: CREATE2_FACTORY,
- data: salt + bytecode.slice(2), // Concatenate salt and bytecode
- gasLimit: 3000000, // Adjust based on your contract
- });
-
- console.log("Deployment tx:", tx.hash);
- await tx.wait();
-
- console.log("Contract deployed to:", deployAddress);
- return deployAddress;
-}
-
-deployWithCreate2();
-```
-
-```solidity "Solidity Create2 Deployer Contract" expandable
-// SPDX-License-Identifier: MIT
-pragma solidity ^0.8.0;
-
-contract Create2Deployer {
- address constant CREATE2_FACTORY = 0x4e59b44847b379578588920ca78fbf26c0b4956c;
-
- function deployContract(
- bytes32 salt,
- bytes memory bytecode
- ) external returns (address) {
- // Prepare deployment data
- bytes memory deploymentData = abi.encodePacked(salt, bytecode);
-
- // Deploy via Create2 factory
- (bool success, bytes memory result) = CREATE2_FACTORY.call(deploymentData);
- require(success, "Create2 deployment failed");
-
- // Extract deployed address from return data
- address deployed = abi.decode(result, (address));
- return deployed;
- }
-
- function computeAddress(
- bytes32 salt,
- bytes memory bytecode
- ) external pure returns (address) {
- bytes32 hash = keccak256(
- abi.encodePacked(
- bytes1(0xff),
- CREATE2_FACTORY,
- salt,
- keccak256(bytecode)
- )
- );
- return address(uint160(uint256(hash)));
- }
-}
-```
-
-
-### Compute Deployment Address
-
-You can calculate the deployment address without actually deploying:
-
-```javascript
-import { ethers } from "ethers";
-
-function computeCreate2Address(salt, bytecode) {
- const factoryAddress = "0x4e59b44847b379578588920ca78fbf26c0b4956c";
-
- const address = ethers.getCreate2Address(
- factoryAddress,
- salt,
- ethers.keccak256(bytecode)
- );
-
- return address;
-}
-
-// Example usage
-const salt = ethers.id("my-deployment-v1");
-const bytecode = "0x608060405234801561001057600080fd5b50...";
-const futureAddress = computeCreate2Address(salt, bytecode);
-console.log("Contract will deploy to:", futureAddress);
-```
-
-## Common Use Cases
-
-
-
- Deploy contracts to the same address across multiple chains:
- ```javascript
- const salt = ethers.id("myapp-v1.0.0");
- // Same salt + bytecode = same address on all chains
- ```
-
-
-
- Interact with contracts before they're deployed:
- 1. Compute the future address
- 2. Send funds or tokens to that address
- 3. Deploy the contract later when needed
-
-
-
- Predictable upgrade addresses using versioned salts:
- ```javascript
- const v1Salt = ethers.id("mycontract-v1");
- const v2Salt = ethers.id("mycontract-v2");
- ```
-
-
-
- Build factory contracts with deterministic child addresses:
- ```solidity
- function deployChild(uint256 nonce) external {
- bytes32 salt = keccak256(abi.encode(msg.sender, nonce));
- // Deploy with predictable address
- }
- ```
-
-
-
-## Implementation Details
-
-The Create2 factory contract is extremely minimal:
-
-```assembly
-// Entire contract bytecode (45 bytes)
-0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe03601600081602082378035828234f58015156039578182fd5b8082525050506014600cf3
-```
-
-This assembly code:
-1. Reads the salt (32 bytes) and bytecode from calldata
-2. Uses the CREATE2 opcode to deploy the contract
-3. Returns the deployed contract address
-
-## Best Practices
-
-
- **Security Considerations**:
- - Always verify bytecode integrity before deployment
- - Be aware that anyone can deploy to a CREATE2 address if they have the bytecode and salt
- - Consider using access controls in your factory contracts
-
-
-### Salt Selection
-
-Choose salts carefully for your use case:
-
-```javascript "Salt Selection Strategies" expandable
-// Sequential salts for multiple instances
-const salt1 = ethers.solidityPacked(["uint256"], [1]);
-const salt2 = ethers.solidityPacked(["uint256"], [2]);
-
-// User-specific salts
-const userSalt = ethers.solidityPacked(["address", "uint256"], [userAddress, nonce]);
-
-// Version-based salts
-const versionSalt = ethers.id("v1.2.3");
-
-// Random salts for uniqueness
-const randomSalt = ethers.randomBytes(32);
-```
-
-### Gas Optimization
-
-- The Create2 factory adds ~32,000 gas overhead
-- Batch deployments in a single transaction when possible
-- Pre-compute addresses to avoid on-chain calculations
-
-## Comparison with CREATE
-
-| Aspect | CREATE | CREATE2 |
-|--------|--------|---------|
-| Address Calculation | Based on deployer + nonce | Based on deployer + salt + bytecode |
-| Predictability | Requires knowing nonce | Fully deterministic |
-| Cross-chain | Different addresses | Same address possible |
-| Gas Cost | Baseline | ~32,000 gas overhead |
-| Use Case | Standard deployments | Deterministic deployments |
-
-## Troubleshooting
-
-Common issues and solutions:
-
-| Issue | Solution |
-|-------|----------|
-| "Create2 deployment failed" | Ensure sufficient gas and correct bytecode format |
-| Address mismatch | Verify salt and bytecode are identical to computation |
-| Contract already deployed | CREATE2 can't deploy to the same address twice |
-| Invalid bytecode | Ensure bytecode includes constructor arguments if needed |
-
-## Example: Multi-chain Token Deployment
-
-Deploy an ERC20 token to the same address across multiple chains:
-
-```javascript "Multi-chain Token Deployment" expandable
-import { ethers } from "ethers";
-
-async function deployTokenMultichain(chains) {
- const bytecode = "0x..."; // ERC20 bytecode with constructor args
- const salt = ethers.id("MyToken-v1.0.0");
-
- // Compute address (same on all chains)
- const tokenAddress = ethers.getCreate2Address(
- "0x4e59b44847b379578588920ca78fbf26c0b4956c",
- salt,
- ethers.keccak256(bytecode)
- );
-
- console.log("Token will deploy to:", tokenAddress);
-
- // Deploy on each chain
- for (const chain of chains) {
- const provider = new ethers.JsonRpcProvider(chain.rpc);
- const signer = new ethers.Wallet(privateKey, provider);
-
- // Check if already deployed
- const code = await provider.getCode(tokenAddress);
- if (code !== "0x") {
- console.log(`Already deployed on ${chain.name}`);
- continue;
- }
-
- // Deploy
- const tx = await signer.sendTransaction({
- to: "0x4e59b44847b379578588920ca78fbf26c0b4956c",
- data: salt + bytecode.slice(2),
- gasLimit: 3000000,
- });
-
- await tx.wait();
- console.log(`Deployed on ${chain.name}`);
- }
-}
-```
-
-## Further Reading
-
-- [EIP-1014: CREATE2 Specification](https://eips.ethereum.org/EIPS/eip-1014)
-- [Ethereum Yellowpaper: CREATE2 Definition](https://ethereum.github.io/yellowpaper/paper.pdf)
-- [OpenZeppelin Create2 Library](https://docs.openzeppelin.com/contracts/4.x/api/utils#Create2)
\ No newline at end of file
diff --git a/evm/next/documentation/smart-contracts/predeployed-contracts/multicall3.mdx b/evm/next/documentation/smart-contracts/predeployed-contracts/multicall3.mdx
deleted file mode 100644
index c0f712a2..00000000
--- a/evm/next/documentation/smart-contracts/predeployed-contracts/multicall3.mdx
+++ /dev/null
@@ -1,330 +0,0 @@
----
-title: "Multicall3"
-description: "Batch multiple contract calls in a single transaction for gas efficiency and atomicity"
-icon: "layers"
-keywords: ['multicall', 'batch', 'aggregate', 'optimization', 'gas', 'efficiency', 'atomic']
----
-
-Multicall3 is a utility contract that enables batching multiple contract calls into a single transaction. This provides gas savings, atomic execution, and simplified interaction patterns for complex multi-step operations.
-
-**Contract Address**: `0xcA11bde05977b3631167028862bE2a173976CA11`
-**Deployment Status**: Default preinstall
-**Repository**: [github.com/mds1/multicall](https://github.com/mds1/multicall)
-
-## Key Features
-
-- **Gas Efficiency**: Save on base transaction costs by batching calls
-- **Atomic Execution**: All calls succeed or all revert together (optional)
-- **State Consistency**: Read multiple values from the same block
-- **Flexible Error Handling**: Choose between strict or permissive execution
-- **Value Forwarding**: Send ETH/native tokens with calls
-
-## Core Methods
-
-### `aggregate`
-Execute multiple calls and revert if any fail.
-
-```solidity
-function aggregate(Call[] calldata calls)
- returns (uint256 blockNumber, bytes[] memory returnData)
-```
-
-### `tryAggregate`
-Execute multiple calls, returning success status for each.
-
-```solidity
-function tryAggregate(bool requireSuccess, Call[] calldata calls)
- returns (Result[] memory returnData)
-```
-
-### `aggregate3`
-Most flexible method with per-call configuration.
-
-```solidity
-function aggregate3(Call3[] calldata calls)
- returns (Result[] memory returnData)
-```
-
-### `aggregate3Value`
-Like aggregate3 but allows sending value with each call.
-
-```solidity
-function aggregate3Value(Call3Value[] calldata calls)
- payable returns (Result[] memory returnData)
-```
-
-## Usage Examples
-
-### Basic Batch Calls
-
-
-```javascript "Ethers.js Multiple Token Balance Query" expandable
-import { ethers } from "ethers";
-
-const provider = new ethers.JsonRpcProvider("YOUR_RPC_URL");
-const MULTICALL3 = "0xcA11bde05977b3631167028862bE2a173976CA11";
-
-// Multicall3 ABI
-const multicallAbi = [
- "function aggregate3(tuple(address target, bool allowFailure, bytes callData)[] calls) returns (tuple(bool success, bytes returnData)[] returnData)"
-];
-
-const multicall = new ethers.Contract(MULTICALL3, multicallAbi, provider);
-
-// Example: Read multiple token balances
-async function getMultipleBalances(tokenAddress, accounts) {
- const erc20Abi = ["function balanceOf(address) view returns (uint256)"];
- const iface = new ethers.Interface(erc20Abi);
-
- // Prepare calls
- const calls = accounts.map(account => ({
- target: tokenAddress,
- allowFailure: false,
- callData: iface.encodeFunctionData("balanceOf", [account])
- }));
-
- // Execute multicall
- const results = await multicall.aggregate3(calls);
-
- // Decode results
- const balances = results.map((result, i) => {
- if (result.success) {
- return {
- account: accounts[i],
- balance: iface.decodeFunctionResult("balanceOf", result.returnData)[0]
- };
- }
- return { account: accounts[i], balance: null };
- });
-
- return balances;
-}
-```
-
-```solidity "Solidity Multi-Token Balance Reader" expandable
-// SPDX-License-Identifier: MIT
-pragma solidity ^0.8.0;
-
-interface IMulticall3 {
- struct Call3 {
- address target;
- bool allowFailure;
- bytes callData;
- }
-
- struct Result {
- bool success;
- bytes returnData;
- }
-
- function aggregate3(Call3[] calldata calls)
- external returns (Result[] memory returnData);
-}
-
-contract MultiTokenReader {
- IMulticall3 constant multicall = IMulticall3(0xcA11bde05977b3631167028862bE2a173976CA11);
-
- function getTokenBalances(
- address[] calldata tokens,
- address account
- ) external returns (uint256[] memory balances) {
- IMulticall3.Call3[] memory calls = new IMulticall3.Call3[](tokens.length);
-
- for (uint i = 0; i < tokens.length; i++) {
- calls[i] = IMulticall3.Call3({
- target: tokens[i],
- allowFailure: true,
- callData: abi.encodeWithSignature("balanceOf(address)", account)
- });
- }
-
- IMulticall3.Result[] memory results = multicall.aggregate3(calls);
- balances = new uint256[](results.length);
-
- for (uint i = 0; i < results.length; i++) {
- if (results[i].success) {
- balances[i] = abi.decode(results[i].returnData, (uint256));
- }
- }
- }
-}
-```
-
-
-### Complex DeFi Operations
-
-Combine multiple DeFi operations atomically:
-
-```javascript "Complex DeFi Swap and Stake Operation" expandable
-// Swap and stake in one transaction
-async function swapAndStake(tokenIn, tokenOut, amountIn, poolAddress) {
- const calls = [
- // 1. Approve router
- {
- target: tokenIn,
- allowFailure: false,
- callData: iface.encodeFunctionData("approve", [router, amountIn])
- },
- // 2. Perform swap
- {
- target: router,
- allowFailure: false,
- callData: iface.encodeFunctionData("swap", [tokenIn, tokenOut, amountIn])
- },
- // 3. Approve staking
- {
- target: tokenOut,
- allowFailure: false,
- callData: iface.encodeFunctionData("approve", [poolAddress, amountOut])
- },
- // 4. Stake tokens
- {
- target: poolAddress,
- allowFailure: false,
- callData: iface.encodeFunctionData("stake", [amountOut])
- }
- ];
-
- return await multicall.aggregate3(calls);
-}
-```
-
-### Reading Protocol State
-
-Get consistent protocol state in one call:
-
-```javascript
-async function getProtocolState(protocol) {
- const calls = [
- { target: protocol, callData: "0x18160ddd", allowFailure: false }, // totalSupply()
- { target: protocol, callData: "0x313ce567", allowFailure: false }, // decimals()
- { target: protocol, callData: "0x06fdde03", allowFailure: false }, // name()
- { target: protocol, callData: "0x95d89b41", allowFailure: false }, // symbol()
- ];
-
- const results = await multicall.aggregate3(calls);
- // All values from the same block
- return decodeResults(results);
-}
-```
-
-## Advanced Features
-
-### Value Forwarding
-
-Send native tokens with calls using `aggregate3Value`:
-
-```javascript "Native Token Forwarding with Multicall3" expandable
-const calls = [
- {
- target: weth,
- allowFailure: false,
- value: ethers.parseEther("1.0"),
- callData: iface.encodeFunctionData("deposit")
- },
- {
- target: contract2,
- allowFailure: false,
- value: ethers.parseEther("0.5"),
- callData: iface.encodeFunctionData("buyTokens")
- }
-];
-
-await multicall.aggregate3Value(calls, {
- value: ethers.parseEther("1.5") // Total ETH to send
-});
-```
-
-### Error Handling Strategies
-
-```javascript "Error Handling Strategies" expandable
-// Strict mode - revert if any call fails
-const strictCalls = calls.map(call => ({
- ...call,
- allowFailure: false
-}));
-
-// Permissive mode - continue even if some fail
-const permissiveCalls = calls.map(call => ({
- ...call,
- allowFailure: true
-}));
-
-// Mixed mode - critical calls must succeed
-const mixedCalls = [
- { ...criticalCall, allowFailure: false },
- { ...optionalCall, allowFailure: true }
-];
-```
-
-## Common Use Cases
-
-
-
- Query multiple token balances for multiple users efficiently.
-
-
- Fetch prices from multiple DEXs in a single call for best execution.
-
-
- Cast votes on multiple proposals in one transaction.
-
-
- Claim rewards, compound, and rebalance positions atomically.
-
-
- Mint, transfer, or approve multiple NFTs efficiently.
-
-
-
-## Gas Optimization
-
-Multicall3 saves gas through:
-
-1. **Base Fee Savings**: Pay the 21,000 gas base fee only once
-2. **Storage Optimization**: Warm storage slots across calls
-3. **Reduced State Changes**: Fewer transaction state transitions
-
-Typical savings: 20-40% for batching 5+ calls
-
-## Best Practices
-
-- **Batch Size**: Optimal batch size is 10-50 calls depending on complexity
-- **Gas Limits**: Set appropriate gas limits for complex batches
-- **Error Handling**: Use `allowFailure` wisely based on criticality
-- **Return Data**: Decode return data carefully, checking success flags
-- **Reentrancy**: Be aware of potential reentrancy in batched calls
-
-## Comparison with Alternatives
-
-| Feature | Multicall3 | Multicall2 | Manual Batching |
-|---------|-----------|-----------|-----------------|
-| Gas Efficiency | Excellent | Good | Poor |
-| Error Handling | Flexible | Basic | N/A |
-| Value Support | Yes | No | Yes |
-| Deployment | Standard address | Varies | N/A |
-| Block Consistency | Yes | Yes | No |
-
-## Integration Libraries
-
-Popular libraries with Multicall3 support:
-
-- **ethers-rs**: Rust implementation
-- **web3.py**: Python Web3 library
-- **viem**: TypeScript alternative to ethers
-- **wagmi**: React hooks for Ethereum
-
-## Troubleshooting
-
-| Issue | Solution |
-|-------|----------|
-| "Multicall3: call failed" | Check individual call success flags |
-| Gas estimation failure | Increase gas limit or reduce batch size |
-| Unexpected revert | One of the calls with `allowFailure: false` failed |
-| Value mismatch | Ensure total value sent matches sum of individual values |
-
-## Further Reading
-
-- [Multicall3 GitHub Repository](https://github.com/mds1/multicall)
-- [Multicall3 Deployments](https://www.multicall3.com/)
-- [Original Multicall by MakerDAO](https://github.com/makerdao/multicall)
\ No newline at end of file
diff --git a/evm/next/documentation/smart-contracts/predeployed-contracts/overview.mdx b/evm/next/documentation/smart-contracts/predeployed-contracts/overview.mdx
deleted file mode 100644
index b4106ed7..00000000
--- a/evm/next/documentation/smart-contracts/predeployed-contracts/overview.mdx
+++ /dev/null
@@ -1,33 +0,0 @@
----
-title: "Overview"
-description: "Ready-to-use smart contracts deployed at predefined addresses"
-icon: "package"
-keywords: ['predeployed', 'preinstalls', 'create2', 'multicall', 'permit2', 'safe', 'factory']
----
-
-## "Pre-deployed" Contracts
-
-### Default Preinstalls
-
-These contracts are included in `evmtypes.DefaultPreinstalls` (defined in [`x/vm/types/preinstall.go:13-39`](https://github.com/cosmos/evm/blob/main/x/vm/types/preinstall.go#L13-L39)) and can be deployed at genesis or via governance:
-
-| Contract | Address | Purpose | Documentation |
-|----------|---------|---------|---------------|
-| **Create2** | `0x4e59b44847b379578588920ca78fbf26c0b4956c` | Deterministic contract deployment using CREATE2 opcode | [Details](./create2) |
-| **Multicall3** | `0xcA11bde05977b3631167028862bE2a173976CA11` | Batch multiple contract calls in a single transaction | [Details](./multicall3) |
-| **Permit2** | `0x000000000022D473030F116dDEE9F6B43aC78BA3` | Token approval and transfer management with signatures | [Details](./permit2) |
-| **Safe Singleton Factory** | `0x914d7Fec6aaC8cd542e72Bca78B30650d45643d7` | Deploy Safe multisig wallets at deterministic addresses | [Details](./safe-factory) |
-| **EIP-2935** | `0x0b` | Historical block hash storage (system contract) | N/A |
-
-
-Additional pre-deployable contracts can be incorporated into your project in a similar way, given that any dependencies are met. See the [Predeployed Contracts Integration](/evm/next/documentation/getting-started/build-a-chain/additional-configuration/predeployed-contracts) guide for instructions.
-
-
-
-## Learn More
-
-- [Implementation](/evm/next/documentation/getting-started/build-a-chain/additional-configuration/predeployed-contracts) - Activate these contracts for your project
-- [Create2](./create2) - Deterministic deployment factory documentation
-- [Multicall3](./multicall3) - Batch operations contract documentation
-- [Permit2](./permit2) - Advanced token approvals documentation
-- [Safe Factory](./safe-factory) - Multisig wallet factory documentation
\ No newline at end of file
diff --git a/evm/next/documentation/smart-contracts/predeployed-contracts/permit2.mdx b/evm/next/documentation/smart-contracts/predeployed-contracts/permit2.mdx
deleted file mode 100644
index dd3c28b9..00000000
--- a/evm/next/documentation/smart-contracts/predeployed-contracts/permit2.mdx
+++ /dev/null
@@ -1,415 +0,0 @@
----
-title: "Permit2"
-description: "Universal token approval and transfer management system with signature-based permissions"
-icon: "key-round"
-keywords: ['permit2', 'approval', 'signature', 'eip-2612', 'token', 'transfer', 'allowance', 'gasless']
----
-
-Permit2 is a universal token approval contract that enables signature-based approvals and transfers. Developed by Uniswap Labs, it improves upon EIP-2612 by providing a single contract for managing token permissions across all ERC20 tokens, even those that don't natively support permits.
-
-**Contract Address**: `0x000000000022D473030F116dDEE9F6B43aC78BA3`
-**Deployment Status**: Default preinstall
-**Audit Reports**: [Multiple audits available](https://github.com/Uniswap/permit2/tree/main/audits)
-
-## Key Benefits
-
-- **Universal Compatibility**: Works with any ERC20 token
-- **Gas Savings**: One-time approval to Permit2, then signature-based transfers
-- **Enhanced Security**: Granular permissions with expiration times
-- **Better UX**: Gasless approvals via signatures
-- **Batching Support**: Multiple token operations in one transaction
-
-## Core Concepts
-
-### Two-Step Process
-
-1. **One-time Approval**: User approves Permit2 to spend their tokens
-2. **Signature Permits**: User signs messages for specific transfers
-
-### Permission Types
-
-- **AllowanceTransfer**: Traditional allowance model with signatures
-- **SignatureTransfer**: Direct transfers using only signatures
-
-## Core Methods
-
-### Allowance Transfer
-
-```solidity
-// Grant permission via signature
-function permit(
- address owner,
- PermitSingle memory permitSingle,
- bytes calldata signature
-) external
-
-// Transfer with existing permission
-function transferFrom(
- address from,
- address to,
- uint160 amount,
- address token
-) external
-```
-
-### Signature Transfer
-
-```solidity
-// One-time transfer via signature
-function permitTransferFrom(
- PermitTransferFrom memory permit,
- SignatureTransferDetails calldata transferDetails,
- address owner,
- bytes calldata signature
-) external
-```
-
-## Usage Examples
-
-### Basic Permit2 Integration
-
-
-```javascript "Ethers.js Complete Permit2 Integration" expandable
-import { ethers } from "ethers";
-import { AllowanceProvider, AllowanceTransfer } from "@uniswap/permit2-sdk";
-
-const PERMIT2_ADDRESS = "0x000000000022D473030F116dDEE9F6B43aC78BA3";
-
-// Step 1: User approves Permit2 for token (one-time)
-async function approvePermit2(tokenContract, signer) {
- const tx = await tokenContract.approve(
- PERMIT2_ADDRESS,
- ethers.MaxUint256
- );
- await tx.wait();
- console.log("Permit2 approved for token");
-}
-
-// Step 2: Create and sign permit
-async function createPermit(token, spender, amount, deadline, signer) {
- const permit = {
- details: {
- token: token,
- amount: amount,
- expiration: deadline,
- nonce: 0, // Get current nonce from contract
- },
- spender: spender,
- sigDeadline: deadline,
- };
-
- // Create permit data
- const { domain, types, values } = AllowanceTransfer.getPermitData(
- permit,
- PERMIT2_ADDRESS,
- await signer.provider.getNetwork().then(n => n.chainId)
- );
-
- // Sign permit
- const signature = await signer._signTypedData(domain, types, values);
-
- return { permit, signature };
-}
-
-// Step 3: Execute transfer with permit
-async function transferWithPermit(permit, signature, transferDetails) {
- const permit2 = new ethers.Contract(
- PERMIT2_ADDRESS,
- ["function transferFrom(address,address,uint160,address)"],
- signer
- );
-
- // First, submit the permit
- await permit2.permit(
- signer.address,
- permit,
- signature
- );
-
- // Then transfer
- await permit2.transferFrom(
- transferDetails.from,
- transferDetails.to,
- transferDetails.amount,
- transferDetails.token
- );
-}
-```
-
-```solidity "Solidity Permit2 Integration Contract" expandable
-// SPDX-License-Identifier: MIT
-pragma solidity ^0.8.0;
-
-interface IPermit2 {
- struct PermitDetails {
- address token;
- uint160 amount;
- uint48 expiration;
- uint48 nonce;
- }
-
- struct PermitSingle {
- PermitDetails details;
- address spender;
- uint256 sigDeadline;
- }
-
- struct SignatureTransferDetails {
- address to;
- uint256 requestedAmount;
- }
-
- function permit(
- address owner,
- PermitSingle memory permitSingle,
- bytes calldata signature
- ) external;
-
- function transferFrom(
- address from,
- address to,
- uint160 amount,
- address token
- ) external;
-}
-
-contract Permit2Integration {
- IPermit2 constant permit2 = IPermit2(0x000000000022D473030F116dDEE9F6B43aC78BA3);
-
- function executeTransferWithPermit(
- address token,
- address from,
- address to,
- uint160 amount,
- IPermit2.PermitSingle calldata permit,
- bytes calldata signature
- ) external {
- // Submit permit
- permit2.permit(from, permit, signature);
-
- // Execute transfer
- permit2.transferFrom(from, to, amount, token);
- }
-}
-```
-
-
-### Batch Operations
-
-Handle multiple tokens in one transaction:
-
-```javascript "Batch Token Transfers with Permit2" expandable
-async function batchTransferWithPermit2(transfers, owner, signer) {
- const permits = [];
- const signatures = [];
-
- // Prepare batch permits
- for (const transfer of transfers) {
- const permit = {
- details: {
- token: transfer.token,
- amount: transfer.amount,
- expiration: transfer.expiration,
- nonce: await getNonce(transfer.token, owner),
- },
- spender: transfer.spender,
- sigDeadline: transfer.deadline,
- };
-
- const signature = await signPermit(permit, signer);
- permits.push(permit);
- signatures.push(signature);
- }
-
- // Execute batch
- const permit2 = new ethers.Contract(PERMIT2_ADDRESS, abi, signer);
- await permit2.permitBatch(owner, permits, signatures);
-}
-```
-
-### Gasless Approvals
-
-Enable gasless token approvals using meta-transactions:
-
-```javascript "Gasless Approval via Meta-transactions" expandable
-// User signs permit off-chain
-async function createGaslessPermit(token, spender, amount, signer) {
- const deadline = Math.floor(Date.now() / 1000) + 3600; // 1 hour
-
- const permit = {
- details: {
- token: token,
- amount: amount,
- expiration: deadline,
- nonce: 0,
- },
- spender: spender,
- sigDeadline: deadline,
- };
-
- const signature = await signPermit(permit, signer);
-
- // Return data for relayer
- return {
- permit,
- signature,
- owner: signer.address,
- };
-}
-
-// Relayer submits transaction
-async function relayPermit(permitData, relayerSigner) {
- const permit2 = new ethers.Contract(PERMIT2_ADDRESS, abi, relayerSigner);
-
- const tx = await permit2.permit(
- permitData.owner,
- permitData.permit,
- permitData.signature
- );
-
- return tx.wait();
-}
-```
-
-## Advanced Features
-
-### Witness Data
-
-Include additional data in permits for complex protocols:
-
-```solidity
-struct PermitWitnessTransferFrom {
- TokenPermissions permitted;
- address spender;
- uint256 nonce;
- uint256 deadline;
- bytes32 witness; // Custom data hash
-}
-```
-
-### Nonce Management
-
-Permit2 uses unordered nonces for flexibility:
-
-```javascript
-// Invalidate specific nonces
-await permit2.invalidateNonces(token, spender, newNonce);
-
-// Invalidate nonce range
-await permit2.invalidateUnorderedNonces(wordPos, mask);
-```
-
-### Expiration Handling
-
-Set appropriate expiration times:
-
-```javascript
-const expirations = {
- shortTerm: Math.floor(Date.now() / 1000) + 300, // 5 minutes
- standard: Math.floor(Date.now() / 1000) + 3600, // 1 hour
- longTerm: Math.floor(Date.now() / 1000) + 86400, // 1 day
- maximum: 2n ** 48n - 1n, // Max allowed
-};
-```
-
-## Security Considerations
-
-### Best Practices
-
-1. **Validate Signatures**: Always verify signature validity
-2. **Check Expiration**: Ensure permits haven't expired
-3. **Nonce Tracking**: Prevent replay attacks
-4. **Amount Limits**: Set reasonable amount limits
-5. **Deadline Checks**: Validate signature deadlines
-
-### Common Attack Vectors
-
-- **Signature Replay**: Mitigated by nonces
-- **Front-running**: Use commit-reveal or deadlines
-- **Phishing**: Educate users about signing
-- **Unlimited Approvals**: Set specific amounts
-
-## Integration Patterns
-
-### DEX Integration
-
-```solidity "DEX Integration with Permit2" expandable
-contract DEXWithPermit2 {
- function swapWithPermit(
- SwapParams calldata params,
- PermitSingle calldata permit,
- bytes calldata signature
- ) external {
- // Get tokens via permit
- permit2.permit(msg.sender, permit, signature);
- permit2.transferFrom(
- msg.sender,
- address(this),
- permit.details.amount,
- permit.details.token
- );
-
- // Execute swap
- _performSwap(params);
- }
-}
-```
-
-### Payment Processor
-
-```javascript "Payment Processor with Permit2" expandable
-class PaymentProcessor {
- async processPayment(order, permit, signature) {
- // Verify order details
- if (!this.verifyOrder(order)) {
- throw new Error("Invalid order");
- }
-
- // Process payment via Permit2
- await this.permit2.permitTransferFrom(
- permit,
- {
- to: this.treasury,
- requestedAmount: order.amount,
- },
- order.buyer,
- signature
- );
-
- // Fulfill order
- await this.fulfillOrder(order);
- }
-}
-```
-
-## Comparison with Alternatives
-
-| Feature | Permit2 | EIP-2612 | Traditional Approve |
-|---------|---------|----------|-------------------|
-| Universal Support | Yes | No (per-token) | Yes |
-| Gas for Approval | Once per token | None (signature) | Every time |
-| Granular Control | Excellent | Limited | Basic |
-| Batch Operations | Yes | No | No |
-| Signature Required | Yes | Yes | No |
-
-## Common Issues
-
-| Issue | Solution |
-|-------|----------|
-| "PERMIT_EXPIRED" | Increase deadline or request new signature |
-| "INVALID_SIGNATURE" | Verify signer address and signature data |
-| "INSUFFICIENT_ALLOWANCE" | Ensure Permit2 is approved for token |
-| "NONCE_ALREADY_USED" | Use a new nonce for the permit |
-
-## Libraries and SDKs
-
-- [Permit2 SDK](https://github.com/Uniswap/permit2-sdk) - Official TypeScript SDK
-- [Permit2 Universal Router](https://github.com/Uniswap/universal-router) - Integration example
-- [Uniswap v2 Periphery](https://github.com/Uniswap/v2-periphery) - Helper contracts
-
-## Further Reading
-
-- [Permit2 Introduction Blog](https://blog.uniswap.org/permit2-and-universal-router)
-- [Permit2 GitHub Repository](https://github.com/Uniswap/permit2)
-- [EIP-2612: Permit Extension](https://eips.ethereum.org/EIPS/eip-2612)
-- [Permit2 Documentation](https://github.com/Uniswap/permit2/blob/main/README.md)
\ No newline at end of file
diff --git a/evm/next/documentation/smart-contracts/predeployed-contracts/safe-factory.mdx b/evm/next/documentation/smart-contracts/predeployed-contracts/safe-factory.mdx
deleted file mode 100644
index 3478d69b..00000000
--- a/evm/next/documentation/smart-contracts/predeployed-contracts/safe-factory.mdx
+++ /dev/null
@@ -1,419 +0,0 @@
----
-title: "Safe Singleton Factory"
-description: "Factory contract for deploying Safe multisig wallets at deterministic addresses"
-icon: "shield-check"
-keywords: ['safe', 'multisig', 'factory', 'gnosis', 'deterministic', 'wallet', 'singleton']
----
-
-The Safe Singleton Factory is a minimal proxy factory that enables deterministic deployment of Safe (formerly Gnosis Safe) multisig wallets and related contracts. It uses CREATE2 to ensure the same wallet addresses across all EVM chains.
-
-**Contract Address**: `0x914d7Fec6aaC8cd542e72Bca78B30650d45643d7`
-**Deployment Status**: Default preinstall
-**Repository**: [github.com/safe-global/safe-singleton-factory](https://github.com/safe-global/safe-singleton-factory)
-
-
-**Known Issue - Bytecode Verification Required**
-
-The Safe Singleton Factory bytecode in the current `DefaultPreinstalls` ([x/vm/types/preinstall.go:30-32](https://github.com/cosmos/evm/blob/main/x/vm/types/preinstall.go#L30-L32)) is currently **identical to the Create2 factory bytecode**, which is incorrect.
-
-Before deploying this contract in production:
-1. Verify the correct Safe Singleton Factory bytecode from the [official repository](https://github.com/safe-global/safe-singleton-factory)
-2. Update your genesis configuration with the correct bytecode
-3. Test the deployment on a testnet first
-
-This issue is tracked and will be addressed in a future release. For now, you should manually verify and update the bytecode if you need Safe Factory functionality.
-
-
-## Key Features
-
-- **Deterministic Deployment**: Same Safe addresses across all chains
-- **Minimal Implementation**: Simple factory pattern using CREATE2
-- **Version Agnostic**: Deploy any version of Safe contracts
-- **Gas Efficient**: Optimized proxy deployment pattern
-- **Ecosystem Standard**: Used by Safe infrastructure globally
-
-## How It Works
-
-The factory uses a two-step deployment process:
-
-1. **Deploy Singleton**: Deploy the Safe master copy (implementation)
-2. **Deploy Proxy**: Deploy minimal proxies pointing to the singleton
-
-This pattern enables gas-efficient deployment of multiple Safe wallets sharing the same implementation.
-
-## Core Method
-
-```solidity
-function deploy(bytes memory data, bytes32 salt)
- returns (address deploymentAddress)
-```
-
-The factory has a single method that deploys contracts using CREATE2.
-
-## Usage Examples
-
-### Deploy a Safe Wallet
-
-
-```javascript "Ethers.js Safe SDK Implementation" expandable
-import { ethers } from "ethers";
-import { SafeFactory } from "@safe-global/safe-core-sdk";
-
-const FACTORY_ADDRESS = "0x914d7Fec6aaC8cd542e72Bca78B30650d45643d7";
-
-// Using Safe SDK
-async function deploySafeWallet(owners, threshold, signer) {
- const safeFactory = await SafeFactory.create({
- ethAdapter: new EthersAdapter({ ethers, signer }),
- safeVersion: '1.4.1'
- });
-
- const safeAccountConfig = {
- owners: owners,
- threshold: threshold,
- // Optional parameters
- fallbackHandler: "0x...", // Fallback handler address
- paymentToken: ethers.ZeroAddress,
- payment: 0,
- paymentReceiver: ethers.ZeroAddress
- };
-
- // Predict address before deployment
- const predictedAddress = await safeFactory.predictSafeAddress(safeAccountConfig);
- console.log("Safe will be deployed to:", predictedAddress);
-
- // Deploy the Safe
- const safeSdk = await safeFactory.deploySafe({ safeAccountConfig });
- const safeAddress = await safeSdk.getAddress();
-
- console.log("Safe deployed to:", safeAddress);
- return safeSdk;
-}
-
-// Manual deployment without SDK
-async function deployManually(signer) {
- const factory = new ethers.Contract(
- FACTORY_ADDRESS,
- ["function deploy(bytes,bytes32) returns (address)"],
- signer
- );
-
- // Prepare Safe proxy bytecode with initialization
- const proxyBytecode = "0x..."; // Safe proxy bytecode
- const salt = ethers.id("my-safe-v1");
-
- // Deploy
- const tx = await factory.deploy(proxyBytecode, salt);
- const receipt = await tx.wait();
-
- // Get deployed address from events
- const deployedAddress = receipt.logs[0].address;
- return deployedAddress;
-}
-```
-
-```solidity "Solidity Safe Deployer Contract" expandable
-// SPDX-License-Identifier: MIT
-pragma solidity ^0.8.0;
-
-interface ISafeFactory {
- function deploy(bytes memory code, bytes32 salt)
- external returns (address);
-}
-
-contract SafeDeployer {
- ISafeFactory constant factory = ISafeFactory(
- 0x914d7Fec6aaC8cd542e72Bca78B30650d45643d7
- );
-
- function deploySafe(
- address safeSingleton,
- bytes memory initializer,
- uint256 saltNonce
- ) external returns (address safe) {
- // Prepare proxy creation code
- bytes memory deploymentData = abi.encodePacked(
- getProxyCreationCode(),
- uint256(uint160(safeSingleton))
- );
-
- // Calculate salt
- bytes32 salt = keccak256(abi.encodePacked(
- keccak256(initializer),
- saltNonce
- ));
-
- // Deploy via factory
- safe = factory.deploy(deploymentData, salt);
-
- // Initialize the Safe
- (bool success,) = safe.call(initializer);
- require(success, "Safe initialization failed");
- }
-
- function getProxyCreationCode() pure returns (bytes memory) {
- // Safe proxy bytecode
- return hex"608060405234801561001057600080fd5b50...";
- }
-}
-```
-
-
-### Predict Safe Address
-
-Calculate the deployment address before deploying:
-
-```javascript
-function predictSafeAddress(owners, threshold, saltNonce) {
- const initializer = encodeSafeSetup(owners, threshold);
- const salt = ethers.solidityPackedKeccak256(
- ["bytes32", "uint256"],
- [ethers.keccak256(initializer), saltNonce]
- );
-
- const initCode = ethers.concat([
- PROXY_CREATION_CODE,
- ethers.AbiCoder.defaultAbiCoder().encode(["address"], [SAFE_SINGLETON])
- ]);
-
- const deploymentAddress = ethers.getCreate2Address(
- FACTORY_ADDRESS,
- salt,
- ethers.keccak256(initCode)
- );
-
- return deploymentAddress;
-}
-```
-
-### Deploy with Custom Configuration
-
-```javascript "Deploy Safe with Custom Configuration" expandable
-async function deployCustomSafe(config, signer) {
- const {
- owners,
- threshold,
- modules = [],
- guards = [],
- fallbackHandler
- } = config;
-
- // Encode initialization data
- const setupData = safeSingleton.interface.encodeFunctionData("setup", [
- owners,
- threshold,
- ethers.ZeroAddress, // to
- "0x", // data
- fallbackHandler,
- ethers.ZeroAddress, // paymentToken
- 0, // payment
- ethers.ZeroAddress // paymentReceiver
- ]);
-
- // Deploy proxy pointing to singleton
- const proxyFactory = new ethers.Contract(
- PROXY_FACTORY_ADDRESS,
- proxyFactoryAbi,
- signer
- );
-
- const tx = await proxyFactory.createProxyWithNonce(
- SAFE_SINGLETON_ADDRESS,
- setupData,
- Date.now() // saltNonce
- );
-
- const receipt = await tx.wait();
- const safeAddress = getSafeAddressFromReceipt(receipt);
-
- // Enable modules if specified
- for (const module of modules) {
- await enableModule(safeAddress, module, signer);
- }
-
- return safeAddress;
-}
-```
-
-## Deployment Patterns
-
-### Organization Wallets
-
-Deploy consistent treasury addresses across chains:
-
-```javascript "Deploy Organization Treasury Across Chains" expandable
-async function deployOrgTreasury(orgId, chains) {
- const salt = ethers.id(`org-treasury-${orgId}`);
- const results = {};
-
- for (const chain of chains) {
- const provider = new ethers.JsonRpcProvider(chain.rpc);
- const signer = new ethers.Wallet(deployerKey, provider);
-
- // Same salt = same address on all chains
- const address = await deploySafeWithSalt(salt, signer);
- results[chain.name] = address;
- }
-
- return results;
-}
-```
-
-### Counterfactual Wallets
-
-Create wallets that can receive funds before deployment:
-
-```javascript "Counterfactual Safe Class Implementation" expandable
-class CounterfactualSafe {
- constructor(owners, threshold) {
- this.owners = owners;
- this.threshold = threshold;
- this.address = this.predictAddress();
- }
-
- predictAddress() {
- // Calculate address without deploying
- return predictSafeAddress(
- this.owners,
- this.threshold,
- 0 // saltNonce
- );
- }
-
- async deploy(signer) {
- // Only deploy when needed
- const code = await signer.provider.getCode(this.address);
- if (code !== "0x") {
- console.log("Already deployed");
- return this.address;
- }
-
- return deploySafeWallet(
- this.owners,
- this.threshold,
- signer
- );
- }
-}
-```
-
-## Integration with Safe Ecosystem
-
-### Safe Modules
-
-Deploy and enable Safe modules:
-
-```javascript "Safe Module Deployment and Configuration" expandable
-// Deploy module via factory
-async function deployModule(moduleCode, salt) {
- const tx = await factory.deploy(moduleCode, salt);
- const receipt = await tx.wait();
- return receipt.contractAddress;
-}
-
-// Enable module on Safe
-async function enableModule(safeAddress, moduleAddress, signer) {
- const safe = new ethers.Contract(safeAddress, safeAbi, signer);
- const tx = await safe.enableModule(moduleAddress);
- await tx.wait();
-}
-```
-
-### Safe Guards
-
-Deploy transaction guards for additional security:
-
-```javascript "Deploy and Set Safe Transaction Guard" expandable
-async function deployAndSetGuard(safeAddress, guardCode, signer) {
- // Deploy guard
- const salt = ethers.id(`guard-${safeAddress}`);
- const guardAddress = await factory.deploy(guardCode, salt);
-
- // Set as Safe guard
- const safe = new ethers.Contract(safeAddress, safeAbi, signer);
- const tx = await safe.setGuard(guardAddress);
- await tx.wait();
-
- return guardAddress;
-}
-```
-
-## Best Practices
-
-### Salt Management
-
-```javascript "Structured Salt Generation Patterns" expandable
-// Structured salt generation
-function generateSalt(context, nonce) {
- return ethers.solidityPackedKeccak256(
- ["string", "uint256"],
- [context, nonce]
- );
-}
-
-// Examples
-const userSalt = generateSalt(`user-${userId}`, 0);
-const orgSalt = generateSalt(`org-${orgId}`, iteration);
-const appSalt = generateSalt(`app-${appId}-${version}`, 0);
-```
-
-### Version Control
-
-```javascript "Safe Version Management" expandable
-const SAFE_VERSIONS = {
- "1.3.0": "0xd9Db270c1B5E3Bd161E8c8503c55cEABeE709552",
- "1.4.0": "0x41675C099F32341bf84BFc5382aF534df5C7461a",
- "1.4.1": "0x29fcB43b46531BcA003ddC8FCB67FFE91900C762"
-};
-
-async function deploySafeVersion(version, owners, threshold) {
- const singleton = SAFE_VERSIONS[version];
- if (!singleton) throw new Error(`Unknown version: ${version}`);
-
- return deployWithSingleton(singleton, owners, threshold);
-}
-```
-
-### Gas Optimization
-
-- Deploy singleton once per chain
-- Reuse proxy bytecode
-- Batch deployments when possible
-- Use minimal initializers
-
-## Security Considerations
-
-- **Initialization**: Ensure Safes are properly initialized after deployment
-- **Salt Uniqueness**: Use unique salts to prevent address collisions
-- **Singleton Verification**: Verify singleton contract before deployment
-- **Access Control**: The factory itself has no access control - anyone can deploy
-
-## Troubleshooting
-
-| Issue | Solution |
-|-------|----------|
-| Address mismatch | Verify salt and bytecode are identical |
-| Deployment fails | Check sufficient gas and valid bytecode |
-| Safe not working | Ensure proper initialization after deployment |
-| Cross-chain inconsistency | Verify same singleton and salt used |
-
-## Related Contracts
-
-### Safe Infrastructure
-
-```javascript
-const SAFE_CONTRACTS = {
- factory: "0x914d7Fec6aaC8cd542e72Bca78B30650d45643d7",
- singleton_1_4_1: "0x29fcB43b46531BcA003ddC8FCB67FFE91900C762",
- proxyFactory: "0x4e1DCf7AD4e460CfD30791CCC4F9c8a4f820ec67",
- multiSend: "0x38869bf66a61cF6bDB996A6aE40D5853Fd43B526",
- fallbackHandler: "0xfd0732Dc9E303f09fCEf3a7388Ad10A83459Ec99"
-};
-```
-
-## Further Reading
-
-- [Safe Documentation](https://docs.safe.global/)
-- [Safe Singleton Factory](https://github.com/safe-global/safe-singleton-factory)
-- [Safe Contracts](https://github.com/safe-global/safe-contracts)
-- [Safe SDK](https://github.com/safe-global/safe-core-sdk)
\ No newline at end of file
From 8a36bc3a5d1f6d25fe37227982ec8cc015d4d190 Mon Sep 17 00:00:00 2001
From: Evan <87997759+evanorti@users.noreply.github.com>
Date: Thu, 19 Feb 2026 12:44:11 -0500
Subject: [PATCH 16/32] update tools page
---
docs.json | 46 +++-
evm/next/documentation/evm-compatibility.mdx | 16 +-
.../getting-started/tooling-and-resources.mdx | 58 +++++
.../tooling-and-resources/block-explorers.mdx | 21 --
.../development-environment.mdx | 121 ---------
.../tooling-and-resources/foundry.mdx | 180 -------------
.../tooling-and-resources/hardhat.mdx | 237 ------------------
.../tooling-and-resources/overview.mdx | 54 ----
.../tooling-and-resources/remix.mdx | 49 ----
.../testing-and-fuzzing.mdx | 181 -------------
.../wallet-integration.mdx | 47 ----
.../smart-contracts/introduction.mdx | 4 +-
.../smart-contracts/precompiles/overview.mdx | 237 ++----------------
13 files changed, 124 insertions(+), 1127 deletions(-)
create mode 100644 evm/next/documentation/getting-started/tooling-and-resources.mdx
delete mode 100644 evm/next/documentation/getting-started/tooling-and-resources/block-explorers.mdx
delete mode 100644 evm/next/documentation/getting-started/tooling-and-resources/development-environment.mdx
delete mode 100644 evm/next/documentation/getting-started/tooling-and-resources/foundry.mdx
delete mode 100644 evm/next/documentation/getting-started/tooling-and-resources/hardhat.mdx
delete mode 100644 evm/next/documentation/getting-started/tooling-and-resources/overview.mdx
delete mode 100644 evm/next/documentation/getting-started/tooling-and-resources/remix.mdx
delete mode 100644 evm/next/documentation/getting-started/tooling-and-resources/testing-and-fuzzing.mdx
delete mode 100644 evm/next/documentation/getting-started/tooling-and-resources/wallet-integration.mdx
diff --git a/docs.json b/docs.json
index 987ab80f..931ab3df 100644
--- a/docs.json
+++ b/docs.json
@@ -81,6 +81,38 @@
{
"source": "/evm/next/documentation/evm-compatibility/eip-7702",
"destination": "/evm/next/documentation/evm-compatibility"
+ },
+ {
+ "source": "/evm/next/documentation/getting-started/tooling-and-resources/overview",
+ "destination": "/evm/next/documentation/getting-started/tooling-and-resources"
+ },
+ {
+ "source": "/evm/next/documentation/getting-started/tooling-and-resources/hardhat",
+ "destination": "/evm/next/documentation/getting-started/tooling-and-resources"
+ },
+ {
+ "source": "/evm/next/documentation/getting-started/tooling-and-resources/foundry",
+ "destination": "/evm/next/documentation/getting-started/tooling-and-resources"
+ },
+ {
+ "source": "/evm/next/documentation/getting-started/tooling-and-resources/remix",
+ "destination": "/evm/next/documentation/getting-started/tooling-and-resources"
+ },
+ {
+ "source": "/evm/next/documentation/getting-started/tooling-and-resources/testing-and-fuzzing",
+ "destination": "/evm/next/documentation/getting-started/tooling-and-resources"
+ },
+ {
+ "source": "/evm/next/documentation/getting-started/tooling-and-resources/wallet-integration",
+ "destination": "/evm/next/documentation/getting-started/tooling-and-resources"
+ },
+ {
+ "source": "/evm/next/documentation/getting-started/tooling-and-resources/block-explorers",
+ "destination": "/evm/next/documentation/getting-started/tooling-and-resources"
+ },
+ {
+ "source": "/evm/next/documentation/getting-started/tooling-and-resources/development-environment",
+ "destination": "/evm/next/documentation/getting-started/tooling-and-resources"
}
],
"integrations": {
@@ -1536,19 +1568,7 @@
"evm/next/documentation/getting-started/faq"
]
},
- {
- "group": "Tooling and Resources",
- "pages": [
- "evm/next/documentation/getting-started/tooling-and-resources/overview",
- "evm/next/documentation/getting-started/tooling-and-resources/development-environment",
- "evm/next/documentation/getting-started/tooling-and-resources/block-explorers",
- "evm/next/documentation/getting-started/tooling-and-resources/foundry",
- "evm/next/documentation/getting-started/tooling-and-resources/hardhat",
- "evm/next/documentation/getting-started/tooling-and-resources/remix",
- "evm/next/documentation/getting-started/tooling-and-resources/testing-and-fuzzing",
- "evm/next/documentation/getting-started/tooling-and-resources/wallet-integration"
- ]
- },
+ "evm/next/documentation/getting-started/tooling-and-resources",
{
"group": "Migrations",
"pages": [
diff --git a/evm/next/documentation/evm-compatibility.mdx b/evm/next/documentation/evm-compatibility.mdx
index 2bee94d3..18545270 100644
--- a/evm/next/documentation/evm-compatibility.mdx
+++ b/evm/next/documentation/evm-compatibility.mdx
@@ -66,14 +66,14 @@ The following are **not supported**:
You can build on Cosmos EVM exactly as you would on Ethereum. Solidity contracts compile and deploy unchanged, and the full standard toolchain is supported without any custom configuration.
-| Tool | Category | Docs |
-|------|----------|------|
-| Hardhat, Foundry, Remix | Contract development | [Tooling guides](/evm/next/documentation/getting-started/tooling-and-resources/overview) |
-| OpenZeppelin | Smart contract libraries | [Tooling guides](/evm/next/documentation/getting-started/tooling-and-resources/overview) |
-| Forge, Hardhat test | Testing & fuzzing | [Testing guide](/evm/next/documentation/getting-started/tooling-and-resources/testing-and-fuzzing) |
-| MetaMask, WalletConnect, Rabby | Wallets | [Wallet integration](/evm/next/documentation/getting-started/tooling-and-resources/wallet-integration) |
-| ethers.js, viem, web3.js, wagmi | JavaScript libraries | [Tooling guides](/evm/next/documentation/getting-started/tooling-and-resources/overview) |
-| Blockscout | Block explorer | [Block explorers](/evm/next/documentation/getting-started/tooling-and-resources/block-explorers) |
+| Tool | Category |
+|------|----------|
+| [Hardhat](https://hardhat.org), [Foundry](https://book.getfoundry.sh), [Remix](https://remix.ethereum.org) | Contract development |
+| [OpenZeppelin Contracts](https://docs.openzeppelin.com/contracts) | Smart contract libraries |
+| [Forge](https://book.getfoundry.sh/forge/), [Hardhat](https://hardhat.org) | Testing & fuzzing |
+| [MetaMask](https://metamask.io), [WalletConnect](https://walletconnect.com), [Rabby](https://rabby.io) | Wallets |
+| [ethers.js](https://docs.ethers.org/v6/), [viem](https://viem.sh), [web3.js](https://web3js.org), [wagmi](https://wagmi.sh) | JavaScript libraries |
+| [Blockscout](https://github.com/blockscout/blockscout) | Block explorer |
Any tool that connects to a standard Ethereum JSON-RPC endpoint is compatible with Cosmos EVM.
diff --git a/evm/next/documentation/getting-started/tooling-and-resources.mdx b/evm/next/documentation/getting-started/tooling-and-resources.mdx
new file mode 100644
index 00000000..3a14721a
--- /dev/null
+++ b/evm/next/documentation/getting-started/tooling-and-resources.mdx
@@ -0,0 +1,58 @@
+---
+title: Tooling & Resources
+description: Tools, libraries, wallets, and explorers for building on Cosmos EVM.
+---
+
+Cosmos EVM implements a complete Ethereum execution environment, so the standard development toolchain carries over without modification. You can use any of the EVM tools you already know; just point them at your chain's RPC endpoint and chain ID.
+
+## Development Tools
+
+The following tools are a few examples of the many tools that are available for development on Cosmos EVM:
+
+| Tool | Description |
+|------|-------------|
+| [Hardhat](https://hardhat.org) | JavaScript/TypeScript-based framework with a flexible plugin system and Ethers.js integration. |
+| [Foundry](https://book.getfoundry.sh) | Rust-based toolkit with Solidity-native tests and fast execution. Includes `forge`, `cast`, `anvil`, and `chisel`. |
+| [OpenZeppelin Contracts](https://docs.openzeppelin.com/contracts) | Audited implementations of common standards — ERC-20, ERC-721, access control, and more. |
+
+## Client Libraries
+
+| Library | Description |
+|---------|-------------|
+| [Ethers.js](https://docs.ethers.org/v6/) | JS/TS library for contract interaction, transaction signing, and provider management. |
+| [Viem](https://viem.sh) | TypeScript-first, tree-shakeable library for RPC calls, ABI encoding, and contract access. Used by Wagmi. |
+| [Wagmi](https://wagmi.sh) | React hooks for wallet connection, chain state, and contract reads/writes. Built on Viem. |
+| [RainbowKit](https://www.rainbowkit.com) | React component library for wallet connection UI. Integrates with Wagmi. |
+## Wallets
+
+See the [quick-start guide](/evm/next/documentation/getting-started/build-a-chain/quick-start#connect-a-wallet) for a walkthrough of connecting MetaMask to a local chain. The following are a few examples of the many wallets that are available for development on Cosmos EVM:
+
+| Wallet | Notes |
+|--------|-------|
+| [MetaMask](https://metamask.io) | Add network via Settings → Networks |
+| [Rabby](https://rabby.io) | Add network via Settings → Networks |
+| [WalletConnect](https://walletconnect.com) | Standard WalletConnect integration |
+| [Keplr](https://www.keplr.app) | Supports both Cosmos and Ethereum transaction formats |
+| [Leap](https://www.leapwallet.io) | Supports both Cosmos and Ethereum transaction formats |
+| Ledger | Compatible via MetaMask or other wallet interfaces |
+
+To add a chain manually, you'll need: the network name, RPC URL (port 8545), chain ID, and currency symbol.
+
+## Block Explorers
+
+Cosmos EVM chains support two types of explorer: EVM explorers for Ethereum-formatted data and Cosmos explorers for Cosmos and IBC data. [Mintscan](https://mintscan.io) supports both but requires a custom integration.
+
+| Explorer | Type | Link |
+|----------|------|------|
+| Blockscout | EVM | [GitHub](https://github.com/blockscout/blockscout) |
+| Ping.pub | Cosmos | [GitHub](https://github.com/ping-pub/explorer) |
+| BigDipper | Cosmos | [GitHub](https://github.com/forbole/big-dipper-2.0-cosmos) |
+
+## Testing & Analysis
+
+| Tool | Purpose |
+|------|---------|
+| [Slither](https://github.com/crytic/slither) | Static analysis — detects common vulnerability patterns in Solidity. |
+| [solidity-coverage](https://github.com/sc-forks/solidity-coverage) | Reports untested code branches. Works with Hardhat and Foundry. |
+| [Echidna](https://github.com/crytic/echidna) | Property-based fuzzer for Solidity contracts. |
+| [OpenZeppelin Test Helpers](https://github.com/OpenZeppelin/openzeppelin-test-helpers) | Time manipulation, event assertions, and revert testing for Hardhat/Mocha. |
diff --git a/evm/next/documentation/getting-started/tooling-and-resources/block-explorers.mdx b/evm/next/documentation/getting-started/tooling-and-resources/block-explorers.mdx
deleted file mode 100644
index 21d5d86e..00000000
--- a/evm/next/documentation/getting-started/tooling-and-resources/block-explorers.mdx
+++ /dev/null
@@ -1,21 +0,0 @@
----
-title: "Block Explorers"
-description: "Blockchain explorers allow users to query the blockchain for data. Explorers are often compared to search engines for the blockchain. By using an explorer, users can search and track balances, transactions, contracts, and other broadcast data to the blockchain."
----
-
-Cosmos EVM chains can use two types block explorers: an EVM explorer and a Cosmos explorer. Each explorer queries data respective to their environment with the EVM explorers querying Ethereum-formatted data (blocks, transactions, accounts, smart contracts, etc) and the Cosmos explorers querying Cosmos-formatted data (Cosmos and IBC transactions, blocks, accounts, module data, etc).
-
-## List of Block Explorers[](#list-of-block-explorers "Direct link to List of Block Explorers")
-
-Below is a list of open source explorers that you can use:
-
-| Service | Support | URL |
-| ---------- | ---------- | --------------------------------------------------------------- |
-| Ping.Pub | `cosmos` | [Github Repo](https://github.com/ping-pub/explorer) |
-| BigDipper | `cosmos` | [Github Repo](https://github.com/forbole/big-dipper-2.0-cosmos) |
-| Blockscout | `ethereum` | [Github Repo](https://github.com/blockscout/blockscout) |
-
-## Cosmos & EVM Compatible explorers[](#cosmos--evm-compatible-explorers "Direct link to Cosmos & EVM Compatible explorers")
-
-As of yet, there is no open source explorer that supports both EVM and Cosmos transactions. [Mintscan](https://mintscan.io/) does support this but requires an integration.
-
diff --git a/evm/next/documentation/getting-started/tooling-and-resources/development-environment.mdx b/evm/next/documentation/getting-started/tooling-and-resources/development-environment.mdx
deleted file mode 100644
index 0183dfd6..00000000
--- a/evm/next/documentation/getting-started/tooling-and-resources/development-environment.mdx
+++ /dev/null
@@ -1,121 +0,0 @@
----
-title: "Development Environment Setup"
-description: "A guide to setting up a local environment for Cosmos EVM development."
----
-
-Taking the time to set up the overall development environment is often overlooked, yet is one of the most important tasks.
-Each person has their own preference and different tasks or scopes of work may call for vastly different setups, so this section will cover just enough to get you started, and pointed in the right direction.
-
-## IDE Setup
-
-
-[Remix](https://remix.ethereum.org) is a full-feature IDE in a web-app supporting all EVM compatible networks out of the box. A convenient option For quick testing, or as a self-contained smart contract depoyment interface.
-[Read more..](/evm/next/documentation/getting-started/tooling-and-resources/remix.mdx)
-
-
-
-### Visual Studio / Visual Studio Code
-
-"VSCode" is widely used and has unparalelled extension support.
-
-#### Essential Extensions
-
-- **Solidity by Nomic Foundation**: Syntax highlighting, code completion, and linting.
-- **Go by Google**: Required for Cosmos SDK development.
-- **Prettier - Code formatter**: For automated code formatting.
-- **ESLint**: For JavaScript/TypeScript error detection.
-
-#### VS Code Configuration
-
-Create a `.vscode/settings.json` file in your project root:
-
-```json
-{
- "go.testFlags": ["-v"],
- "go.testTimeout": "60s",
- "go.lintTool": "golangci-lint",
- "solidity.defaultCompiler": "remote",
- "solidity.compileUsingRemoteVersion": "v0.8.20+commit.a1b79de6"
-}
-```
-
-## Core Tooling
-
-### Node.js
-
-Most smart contract frameworks require Node.js. Install using Node Version Manager (nvm):
-
-```bash
-# Install nvm
-curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.3/install.sh | bash
-
-# Install latest LTS Node.js
-nvm install --lts
-
-# Install yarn (recommended over npm)
-npm install -g yarn
-```
-
-### Go
-
-Required for Cosmos SDK development:
-
-```bash
-# Install Go from https://go.dev/doc/install
-# Verify installation
-go version
-```
-
-## Environment Configuration
-
-Configure your shell environment variables in `~/.bashrc` or `~/.zshrc`:
-
-```bash
-# Set Go paths
-export GOPATH=$HOME/go
-export PATH=$PATH:$GOPATH/bin
-
-# Useful aliases
-alias evm-build='make build'
-alias evm-test='make test'
-```
-
-## Development Workflow
-
-
-Always use the provided `make` targets for consistency with core developers and CI/CD pipelines.
-
-
-### Common Commands
-
-```bash
-make build # Build binaries
-make test # Run tests
-make lint # Check code style
-make format # Format code
-```
-
-### Project Structure
-
-```
-cosmos-evm/
-├── app/ # Application configuration
-├── x/ # Custom modules
-│ ├── evm/ # EVM module
-│ └── feemarket/ # Fee market module
-├── tests/ # Integration tests
-└── Makefile # Build automation
-```
-
-## Next Steps
-
-With your environment configured, explore the development tools:
-
-
-
- Fast, efficient smart contract development and testing
-
-
- Flexible environment for compiling, deploying, and debugging
-
-
diff --git a/evm/next/documentation/getting-started/tooling-and-resources/foundry.mdx b/evm/next/documentation/getting-started/tooling-and-resources/foundry.mdx
deleted file mode 100644
index a54d4627..00000000
--- a/evm/next/documentation/getting-started/tooling-and-resources/foundry.mdx
+++ /dev/null
@@ -1,180 +0,0 @@
----
-title: "Foundry Guide - Setup & Walkthrough"
-description: "An introduction to Foundry and using the `cast` function, replacing complex scripts that may otherwise require multiple rpc calls and other functions in between with a single command."
----
-
-Foundry is a fast and modular toolkit for Ethereum application development written in Rust. It provides four main command-line tools—`forge`, `cast`, `anvil`, and `chisel`—to streamline everything from project setup to live-chain interactions.
-
-Among these, `cast` serves as your "Swiss-army knife" for JSON-RPC calls, letting you execute tedious day-to-day tasks (like sending raw transactions, querying balances, fetching blocks, and looking up chain metadata) with simple, consistent commands instead of verbose `curl` scripts.
-
-This guide walks you through installing Foundry, configuring your environment, and using the most common `cast` commands to accelerate your development workflow.
-
-## Installation & Setup
-
-### Install Foundry
-
-Run the following command to install `foundryup`, the Foundry toolchain installer. This will give you the four main binaries.
-
-```bash lines
-curl -L https://foundry.paradigm.xyz | bash
-foundryup
-```
-
-After installation, you can switch to the nightly builds for the latest features, though this is optional.
-
-```bash lines
-foundryup -i nightly
-```
-
-### Verify Installation
-
-Check that each binary was installed correctly by running:
-
-```bash lines expandable
-foundryup --version
-cast --version
-forge --version
-anvil --version
-```
-
-You should see version outputs for each tool (e.g., `cast 0.2.0`).
-
-## Configuration
-
-To avoid passing the `--rpc-url` flag with every command, you can set defaults in a `foundry.toml` file. This file can be placed in your project's root directory for project-specific settings, or you can create a global configuration at `~/.foundry/foundry.toml` for settings you use across all projects.
-
-Here is an example of a global configuration for connecting to a local Cosmos EVM node:
-
-```toml title="~/.foundry/foundry.toml" lines expandable
-# ~/.foundry/foundry.toml
-
-# Declare your named endpoints (optional; for forge test / forking)
-[rpc_endpoints]
-cosmos = ""
-
-# Configure the default profile for cast/forge/anvil
-[profile.default]
-# Tell Foundry which chain you're targeting:
-chain_id = 4321
-# Directly tell cast to use your endpoint:
-eth_rpc_url = ""
-# Set EVM version for Solidity compilation
-evm_version = "istanbul"
-```
-
-With this global configuration, Foundry tools will automatically connect to your local node without needing additional flags.
-
-## Basic Usage of `cast`
-
-`cast` replaces the need for custom shell scripts and verbose `curl` commands by offering first-class RPC commands.
-
-### Chain Metadata
-
-- **Get Chain ID**
- ```bash lines
- cast chain-id --rpc-url local
- ```
- Returns the chain ID in decimal format.
-
-- **Get Client Version**
- ```bash lines
- cast client --rpc-url local
- ```
- Displays the client implementation and version (e.g., `reth/v1.0.0`).
-
-## `cast` Command Reference
-
-### Chain Commands
-
-| Command | Purpose |
-| :--- | :--- |
-| `cast chain` | Show the symbolic name of the current chain. |
-| `cast chain-id` | Fetch the numeric chain ID. |
-| `cast client` | Get the JSON-RPC client version. |
-
-**Example**:
-```bash lines
-# Assuming FOUNDRY_RPC_URL is set or using a configured alias
-cast chain
-cast chain-id
-cast client
-```
-
-### Transaction Commands
-
-| Command | Purpose |
-| :--- | :--- |
-| `cast send` | Sign and publish a transaction. |
-| `cast publish` | Publish a raw, signed transaction. |
-| `cast receipt` | Fetch the receipt for a transaction hash. |
-| `cast tx` | Query transaction details (status, logs, etc.). |
-| `cast rpc` | Invoke any raw JSON-RPC method. |
-
-- **Sign and Send** (using a private key or local keystore):
- ```bash lines
- cast send 0xRecipientAddress "transfer(address,uint256)" "0xSomeOtherAddress,100" --private-key $YOUR_PK
- ```
-
-- **Publish Raw Transaction** (hex-encoded):
- ```bash lines
- cast publish 0xf86b808504a817c80082520894...
- ```
-
-- **Generic RPC Call**:
- ```bash lines
- cast rpc eth_sendRawTransaction 0xf86b8085...
- ```
-
-### Account & Block Commands
-
-| Command | Purpose |
-| :--- | :--- |
-| `cast balance` | Get an account's balance (supports ENS and units). |
-| `cast block` | Fetch block information by number or hash. |
-| `cast block-number`| Get the latest block number. |
-| `cast logs` | Query event logs. |
-
-- **Get Balance** (with unit flag):
- ```bash lines
- # Using an ENS name on Ethereum mainnet
- cast balance vitalik.eth --ether --rpc-url https://eth.merkle.io
- ```
-
-- **Get Block Details**:
- ```bash lines
- cast block latest
- ```
-
-### Utility & Conversion Commands
-
-| Command | Purpose |
-| :--- | :--- |
-| `cast estimate` | Estimate gas for a call or deployment. |
-| `cast find-block` | Find a block by its timestamp. |
-| `cast compute-address`| Calculate a CREATE2 address. |
-| `cast from-bin` | Decode binary data to hex. |
-| `cast from-wei` | Convert wei to a more readable unit (e.g., ether). |
-| `cast to-wei` | Convert a unit (e.g., ether) to wei. |
-| `cast abi-encode` | Encode function arguments. |
-| `cast keccak` | Hash data with Keccak-256. |
-
-These commands allow you to drop one-off scripts for common conversions and estimations.
-
-## Streamlining Repetative / Tedious tasks
-
-When performing testing or development roles you may find yourself doing one or more small but very
-tedious tasks frequently.
-In your shell's configuration file (`~/.bashrc`, `~/.zshrc`), you can alias `cast` with your default RPC URL
-(or multiple on various chains) to save time.
-
-```bash lines expandable
-# Set your default RPC endpoint
-export CDEV_RPC=""
-# Create an alias
-alias ccast='cast --rpc-url $CDEV_RPC'
-
-# Now you can run commands like:
-ccast balance 0x...
-```
-
-This is an extremely basic example of how you can improve your workflows by building upon the heavy lifting Foundry already does out of the box.
\ No newline at end of file
diff --git a/evm/next/documentation/getting-started/tooling-and-resources/hardhat.mdx b/evm/next/documentation/getting-started/tooling-and-resources/hardhat.mdx
deleted file mode 100644
index 73961ba9..00000000
--- a/evm/next/documentation/getting-started/tooling-and-resources/hardhat.mdx
+++ /dev/null
@@ -1,237 +0,0 @@
----
-title: "Hardhat Guide: Setup & Workflows"
-description: "A guide to setting up and using the Hardhat development environment for building, testing, and deploying on Cosmos EVM."
----
-
-Hardhat is a flexible and extensible Ethereum development environment that is fully compatible with Cosmos EVM. It's an excellent choice for teams with JavaScript/TypeScript expertise or those who need complex deployment and testing workflows.
-
-## Project Setup and Configuration
-
-Initialize and configure a new Hardhat project for Cosmos EVM development.
-
-### 1. Installation
-
-```bash lines expandable
-mkdir cosmos-evm-hardhat
-cd cosmos-evm-hardhat
-npm init -y
-npm install --save-dev hardhat @nomicfoundation/hardhat-toolbox @openzeppelin/contracts
-npx hardhat init # Select "Create a TypeScript project"
-```
-
-### 2. Configuration
-
-Modify `hardhat.config.ts` to include networks and settings for Cosmos EVM.
-
-```typescript title="hardhat.config.ts" lines expandable
-import { HardhatUserConfig } from "hardhat/config";
-import "@nomicfoundation/hardhat-toolbox";
-import "dotenv/config";
-
-const config: HardhatUserConfig = {
- solidity: {
- version: "0.8.24",
- settings: {
- optimizer: {
- enabled: true,
- runs: 200,
- },
- evmVersion: "istanbul"
- },
- },
- networks: {
- local: {
- url: "http://127.0.0.1:8545",
- chainId: 4321, // Your EVM chain ID
- accounts: process.env.PRIVATE_KEY ? [process.env.PRIVATE_KEY] : [],
- gasPrice: 20000000000,
- },
- testnet: {
- url: "",
- chainId: 4321, // Your EVM chain ID
- accounts: process.env.PRIVATE_KEY ? [process.env.PRIVATE_KEY] : [],
- }
- },
- gasReporter: {
- enabled: process.env.REPORT_GAS !== undefined,
- currency: "USD",
- },
- etherscan: {
- apiKey: {
- cosmosEvmTestnet: process.env.ETHERSCAN_API_KEY || "dummy_key"
- },
- customChains: [
- {
- network: "cosmosEvmTestnet",
- chainId: 4321, // Your EVM chain ID
- urls: {
- apiURL: "",
- browserURL: ""
- }
- }
- ]
- }
-};
-
-export default config;
-```
-
-## TypeScript Integration
-
-Hardhat's first-class TypeScript support enables type-safe contract interactions and tests.
-
-### 1. Writing a Contract
-
-Create a contract in the `contracts/` directory. For this example, we'll use a simple `LiquidStakingVault`.
-
-```solidity title="contracts/LiquidStakingVault.sol" lines expandable
-// contracts/LiquidStakingVault.sol
-// SPDX-License-Identifier: MIT
-pragma solidity ^0.8.24;
-
-import "@openzeppelin/contracts/access/Ownable.sol";
-
-// Interface for the staking precompile
-interface IStaking {
- function delegate(address validator, uint256 amount) external returns (bool);
- function undelegate(address validator, uint256 amount) external returns (bool, uint64);
-}
-
-contract LiquidStakingVault is Ownable {
- IStaking constant STAKING = IStaking(0x0000000000000000000000000000000000000800);
-
- mapping(address => uint256) public stakedBalance;
- address public primaryValidator;
- uint256 public totalStaked;
-
- event Staked(address indexed user, uint256 amount);
-
- constructor(address _primaryValidator) Ownable(msg.sender) {
- primaryValidator = _primaryValidator;
- }
-
- function stake() external payable {
- require(msg.value > 0, "Must stake positive amount");
- bool success = STAKING.delegate(primaryValidator, msg.value);
- require(success, "Delegation failed");
- stakedBalance[msg.sender] += msg.value;
- totalStaked += msg.value;
- emit Staked(msg.sender, msg.value);
- }
-}
-```
-
-### 2. Writing Tests
-
-Create type-safe tests in the `test/` directory.
-
-```typescript title="test/LiquidStakingVault.test.ts" lines expandable
-// test/LiquidStakingVault.test.ts
-import { expect } from "chai";
-import { ethers } from "hardhat";
-import { LiquidStakingVault } from "../typechain-types";
-import { SignerWithAddress } from "@nomicfoundation/hardhat-ethers/signers";
-
-describe("LiquidStakingVault", function () {
- let vault: LiquidStakingVault;
- let owner: SignerWithAddress;
- let user1: SignerWithAddress;
-
- const STAKING_PRECOMPILE = "0x0000000000000000000000000000000000000800";
- const VALIDATOR_ADDRESS = "0x1234567890123456789012345678901234567890";
-
- beforeEach(async function () {
- [owner, user1] = await ethers.getSigners();
-
- const VaultFactory = await ethers.getContractFactory("LiquidStakingVault");
- vault = await VaultFactory.deploy(VALIDATOR_ADDRESS);
- await vault.waitForDeployment();
-
- // Mock the staking precompile's delegate function to always return true
- // This bytecode is a minimal contract that returns true for any call
- const successBytecode = "0x6080604052348015600f57600080fd5b50600160005560016000f3";
- await ethers.provider.send("hardhat_setCode", [
- STAKING_PRECOMPILE,
- successBytecode,
- ]);
- });
-
- it("Should allow a user to stake tokens", async function () {
- const stakeAmount = ethers.parseEther("1.0");
-
- await expect(vault.connect(user1).stake({ value: stakeAmount }))
- .to.emit(vault, "Staked")
- .withArgs(user1.address, stakeAmount);
-
- expect(await vault.stakedBalance(user1.address)).to.equal(stakeAmount);
- expect(await vault.totalStaked()).to.equal(stakeAmount);
- });
-});
-```
-
-Run your tests:
-```bash lines
-npx hardhat test
-```
-
-## Deployment Scripts
-
-Create a deployment script in the `scripts/` directory to deploy your contract to a live network.
-
-```typescript title="scripts/deploy.ts" lines expandable
-// scripts/deploy.ts
-import { ethers, network } from "hardhat";
-import { writeFileSync } from "fs";
-
-async function main() {
- const [deployer] = await ethers.getSigners();
-
- console.log("Deploying contracts with the account:", deployer.address);
-
- const validatorAddress = process.env.VALIDATOR_ADDRESS || "0x0000000000000000000000000000000000000000";
-
- const VaultFactory = await ethers.getContractFactory("LiquidStakingVault");
- const vault = await VaultFactory.deploy(validatorAddress);
- await vault.waitForDeployment();
-
- const vaultAddress = await vault.getAddress();
- console.log("LiquidStakingVault deployed to:", vaultAddress);
-
- // Save deployment information
- const deploymentInfo = {
- contractAddress: vaultAddress,
- deployer: deployer.address,
- network: network.name,
- chainId: network.config.chainId,
- };
-
- writeFileSync(
- `deployments/${network.name}-deployment.json`,
- JSON.stringify(deploymentInfo, null, 2)
- );
-
- // Optional: Verify contract on Etherscan-compatible explorer
- if (network.name !== "local" && process.env.ETHERSCAN_API_KEY) {
- console.log("Waiting for block confirmations before verification...");
- // await vault.deploymentTransaction()?.wait(5); // Wait for 5 blocks
- await new Promise(resolve => setTimeout(resolve, 30000)); // Or wait 30 seconds
-
- await hre.run("verify:verify", {
- address: vaultAddress,
- constructorArguments: [validatorAddress],
- });
- }
-}
-
-main()
- .then(() => process.exit(0))
- .catch((error) => {
- console.error(error);
- process.exit(1);
- });
-```
-
-Run the deployment script:
-```bash lines
-npx hardhat run scripts/deploy.ts --network testnet
-```
\ No newline at end of file
diff --git a/evm/next/documentation/getting-started/tooling-and-resources/overview.mdx b/evm/next/documentation/getting-started/tooling-and-resources/overview.mdx
deleted file mode 100644
index 2bac0f3c..00000000
--- a/evm/next/documentation/getting-started/tooling-and-resources/overview.mdx
+++ /dev/null
@@ -1,54 +0,0 @@
----
-title: Overview
-description: "Tooling and resources to 10x your development workflows."
----
-
-## Client Integrations
-
-Client libraries play a crucial role indevelopment by making it easier for developers interact with the underlying protocols.
-Well-made libraries abstract away complexities and provide optimized methods to allow developers to focus on their project rather than the network itself."
-
-EthersJS and Web3JS are two most commonly used libraries in dApp development. Developer uses these libraries to interact with blockchain and query JSON-RPC data, for example. Additionally, both of these libraries contain utilities to aid in task like converting large numbers (BigNumber).
-
-* [Ethers.js](https://docs.ethers.org/v6/) is the latest JS library that aims to be a complete and compact library for interacting with the Ethereum Blockchain and its ecosystem.
-
-
-## Development & Testing Toolkits
-
-
-
- Fast, modular toolkit for Solidity and Forge-based development, testing, and
- deployment workflows.
-
-
-
- Flexible, plug-in-rich environment for building, testing, and deploying
- smart contracts with TypeScript support.
-
-
-
- Libraries, fuzzers, and best practices to ensure contract correctness,
- safety, and edge-case coverage.
-
-
-
- Browser-based integrated development environment for rapid prototyping,
- debugging, and interactive contract deployment.
-
-
diff --git a/evm/next/documentation/getting-started/tooling-and-resources/remix.mdx b/evm/next/documentation/getting-started/tooling-and-resources/remix.mdx
deleted file mode 100644
index 427616f3..00000000
--- a/evm/next/documentation/getting-started/tooling-and-resources/remix.mdx
+++ /dev/null
@@ -1,49 +0,0 @@
----
-title: "Remix IDE"
-description: "Deploy and test smart contracts on Cosmos EVM chains using the Remix browser-based IDE"
----
-
-# Remix IDE
-
-[Remix](https://remix.ethereum.org) is a powerful browser-based IDE that allows you to write, compile, deploy, and test smart contracts directly from your web browser. It's an excellent tool for rapid prototyping and testing smart contracts on Cosmos EVM chains without needing to set up a local development environment.
-
-## Connecting to Cosmos EVM Chains
-
-To deploy contracts to a Cosmos EVM chain through Remix, you'll need to use the **Injected Provider** option with MetaMask.
-
-
- Remix cannot connect directly to custom RPC endpoints. You must use MetaMask as an intermediary to connect to Cosmos EVM chains.
-
-
-### Step-by-Step Guide
-
-1. **Configure MetaMask**: First, add your Cosmos EVM chain to MetaMask with the correct RPC endpoint, Chain ID, and currency symbol.
-
-2. **Select Network in MetaMask**: Make sure the Cosmos EVM network you want to use is currently selected in MetaMask.
-
-3. **Open Remix**: Navigate to [https://remix.ethereum.org](https://remix.ethereum.org)
-
-4. **Deploy Your Contract**:
- - Go to the "Deploy & Run Transactions" tab (the Ethereum icon in the sidebar)
- - In the "Environment" dropdown, select **"Injected Provider - MetaMask"**
- - Remix will automatically connect to the network currently selected in MetaMask
-
-
-
-5. **Confirm Connection**: MetaMask will prompt you to connect to Remix. Approve the connection to proceed.
-
-6. **Deploy and Interact**: You can now compile, deploy, and interact with your contracts on the Cosmos EVM chain through Remix.
-
-## Important Considerations
-
-- **Network Selection**: Always verify that MetaMask is connected to the correct network before deploying contracts
-- **Gas Fees**: Ensure you have sufficient native tokens in your MetaMask wallet to pay for transaction fees
-- **Chain Compatibility**: Your smart contracts should be compatible with the EVM version supported by the Cosmos chain
-
-## Additional Resources
-
-For more detailed information about using Remix IDE, including advanced features and troubleshooting, refer to the [official Remix documentation](https://remix-ide.readthedocs.io/en/latest/run.html).
-
-
- **Quick Tip**: You can save your Remix workspace to GitHub or IPFS to preserve your contracts and deployment configurations across sessions.
-
\ No newline at end of file
diff --git a/evm/next/documentation/getting-started/tooling-and-resources/testing-and-fuzzing.mdx b/evm/next/documentation/getting-started/tooling-and-resources/testing-and-fuzzing.mdx
deleted file mode 100644
index 5749a95c..00000000
--- a/evm/next/documentation/getting-started/tooling-and-resources/testing-and-fuzzing.mdx
+++ /dev/null
@@ -1,181 +0,0 @@
----
-title: "Popular Libraries for Development, Testing & Fuzzing"
-description: "Key frameworks, libraries, and practices for frontend development, wallet integration, smart contracts, testing and more."
-mode: "wide"
----
-
-
-## Common Libraries & Tooling
-
-These libraries are used across the stack to write tests, simulate transactions, connect wallets, and interface with the blockchain in both scripting and frontend contexts.
-
-| Library | Purpose | Key Features |
-|---------------|------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------|
-| **Ethers.js** | Contract interaction, transaction signing, provider management in JS/TS environments | Provides `Contract`, `Provider`, `Wallet`, and `Interface` abstractions. Deep Hardhat integration. ABI coder, calldata utilities, and ENS support. |
-| **Viem** | Modular TypeScript-first library for RPC, contract access, encoding, and data formatting | Tree-shakeable. Supports batching, client-side caching, EIP-1559 fees, multicalls, typed reads/writes. Used by Wagmi. |
-| **Wagmi** | React hooks for wallet connection, chain state, and contract calls in frontend apps | Built on Viem. Includes `useAccount`, `useConnect`, `useContractRead`, and event subscriptions. Enables seamless integration with wallet modals. |
-| **Web3.js** | Legacy Ethereum contract and RPC library | One of the earliest libraries. Now largely unmaintained. Lacks EIP-1559 support and modern modularity. |
-| **RainbowKit** | React component library for wallet connection UI and chain management | Pre-built wallet connect buttons, chain switch UI, and custom themes. Integrates with Wagmi for wallet state management and tx handling. |
-
-> Ethers and Viem serve similar purposes, but Viem is optimized for frontend apps. Wagmi builds on Viem. Web3.js is no longer recommended for new projects.
-
----
-
-
-## Testing Frameworks
-
-> **Note**
-> Smart contract quality and security depend on a comprehensive testing strategy including but not limited to:
->
-> - **Unit Tests**: Verify individual functions and components
-> - **Property-Based Fuzzing**: Test invariants with random inputs
-> - **Code Coverage**: Ensure all code paths are tested
-> - **Static Analysis**: Detect common vulnerabilities and anti-patterns
->
-> The tools and frameworks below provide a foundation for each of these testing layers.
-
-
-### Foundry — Solidity-Native
-
-- Tests written directly in Solidity.
-- Very fast runner (`forge test`) and rich cheatcodes for state manipulation.
-- Built-in, configurable fuzzing (`forge test --fuzz-runs=N`).
-- Includes tools like `forge script`, `forge coverage`, and `forge snapshot`.
-
-### Hardhat — JavaScript / TypeScript
-
-- Mocha + Chai test runner for JS/TS-based tests.
-- Flexible task system (`hardhat.config.js`), plugin support, and network forking.
-- Integrates with Ethers.js and Solidity tooling for deployments, gas tracking, and test orchestration.
-
-## v0.5.0 Compatibility Testing Framework
-
-Cosmos EVM v0.5.0 introduces comprehensive compatibility testing to ensure seamless integration with major Ethereum development tools.
-
-### EVM Tools Compatibility Testing
-
-**Automated Testing Suites:** Five comprehensive test suites validate compatibility with popular Ethereum tools:
-
-| Tool | Test Coverage | GitHub Workflow |
-|------|---------------|-----------------|
-| **Foundry** | Contract deployment, testing, gas estimation | `.github/workflows/tests-compatibility-foundry.yml` |
-| **Hardhat** | Contract deployment, ethers.js integration | `.github/workflows/tests-compatibility-hardhat.yml` |
-| **Viem** | TypeScript client compatibility, RPC methods | `.github/workflows/tests-compatibility-viem.yml` |
-| **Web3.js** | Legacy client compatibility, transaction handling | `.github/workflows/tests-compatibility-web3js.yml` |
-| **Foundry + UniswapV3** | Complex DeFi protocol deployment | `.github/workflows/tests-compatibility-foundry-uniswap-v3.yml` |
-
-### Running Compatibility Tests
-
-**Local Testing:**
-```bash
-# Run JSON-RPC compatibility tests
-cd /path/to/cosmos-evm
-make test-rpc-compat # Makefile:373
-
-# Test specific tool
-./scripts/tests_compatibility_foundry.sh
-./scripts/tests_compatibility_hardhat.sh
-./scripts/tests_compatibility_viem.sh
-./scripts/tests_compatibility_web3js.sh
-./scripts/tests_compatibility_foundry_uniswap_v3.sh
-```
-
-**Test Structure:**
-```
-tests/evm-tools-compatibility/
-├── foundry/ # Foundry compatibility tests
-├── hardhat/ # Hardhat + Ethers.js tests
-├── viem/ # Viem TypeScript tests
-├── web3.js/ # Web3.js legacy tests
-└── foundry-uniswap-v3/ # Complex DeFi protocol tests
-```
-
-### JSON-RPC Compatibility Testing
-
-**Comprehensive RPC Validation:** New framework compares Cosmos EVM responses against geth for accuracy.
-
-**Setup:**
-```bash
-# Start comparison testing environment
-cd tests/jsonrpc
-
-# Build required Docker images
-make localnet-build-env
-
-# Start both evmd and geth for comparison
-./scripts/start-networks.sh
-
-# Run compatibility test suite
-cd simulator && go build . && ./simulator
-
-# Stop testing environment
-./scripts/stop-networks.sh
-```
-
-**Test Coverage:**
-- **Transaction Processing:** Compare transaction execution results
-- **Block Queries:** Validate block structure and data
-- **Account Queries:** Verify balance and nonce handling
-- **Event Logs:** Ensure log filtering and retrieval accuracy
-- **Gas Estimation:** Compare gas estimation algorithms
-
-**Configuration:**
-```go
-// tests/jsonrpc/simulator/config/config.go:27-36
-type Config struct {
- EvmdHttpEndpoint string // Default: "http://localhost:8545"
- EvmdWsEndpoint string // Default: "ws://localhost:8546"
- GethHttpEndpoint string // Default: "http://localhost:8547"
- GethWsEndpoint string // Default: "ws://localhost:8548"
- RichPrivKey string
- Timeout string
-}
-```
-
-## Fuzz (Property-Based) Testing
-
-Fuzz testing generates random inputs to find edge cases that violate expected properties.
-
-```solidity title="test/MyContract.t.sol (Foundry)" lines expandable
-// test/MyContract.t.sol (Foundry)
-function test_myFunction_fuzz(uint256 amount) public {
- vm.assume(amount > 0 && amount < 1e18); // constrain input
- myContract.myFunction(amount);
- assertEq(myContract.someState(), expectedValue);
-}
-```
-
-| Tool | Notes |
-| ----------- | ------------------------------------------------------------------- |
-| **Foundry** | Built-in fuzzing; enabled by default when running `forge test`. |
-| **Echidna** | External, property-based fuzzer. Supports invariants and campaigns. |
-
-Use fuzzing to test against invariants such as:
-
-* balance never exceeds total supply
-* no overflow or underflow under bounded inputs
-* access control is consistently enforced
-
-## Supplementary Tools
-
-Tools that enhance test coverage, assert correctness, or catch common vulnerabilities.
-
-| Tool | Purpose | Typical Command |
-| ----------------------------- | --------------------------------------- | ----------------------------------------- |
-| **OpenZeppelin Test Helpers** | Time travel, event assertions, reverts | JS/TS only. Works with Hardhat + Mocha. |
-| **solidity-coverage** | Reports untested branches in Solidity | `npx hardhat coverage` · `forge coverage` |
-| **Slither** | Static analysis for known vuln patterns | `slither .` |
-
-### Example — OpenZeppelin Test Helpers
-
-```js lines expandable
-const { time, expectRevert } = require('@openzeppelin/test-helpers');
-
-// advance clock by one day
-await time.increase(time.duration.days(1));
-
-// expect revert with specific reason
-await expectRevert(contract.someFunction(), "Ownable: caller is not the owner");
-```
-
----
diff --git a/evm/next/documentation/getting-started/tooling-and-resources/wallet-integration.mdx b/evm/next/documentation/getting-started/tooling-and-resources/wallet-integration.mdx
deleted file mode 100644
index 002825ae..00000000
--- a/evm/next/documentation/getting-started/tooling-and-resources/wallet-integration.mdx
+++ /dev/null
@@ -1,47 +0,0 @@
----
-title: "Wallet Integration"
-description: "Wallet integration is an essential aspect of dApp development that allows users to securely interact with blockchain-based applications."
----
-
-## EVM Wallet Compatibility[](#evm-wallet-compatibility "Direct link to EVM Wallet Compatibility")
-
-**Any standard EVM wallet works out of the box with Cosmos EVM chains.** This includes popular wallets like MetaMask, Rabby, WalletConnect, and any other wallet that supports Ethereum and EVM-compatible chains. No special configuration or custom integration is required - simply add your chain's RPC endpoint and chain ID to any EVM wallet.
-
-### Key Integration Points[](#key-integration-points "Direct link to Key Integration Points")
-
-* **Standard EVM RPC**: Cosmos EVM exposes the standard Ethereum JSON-RPC API, ensuring compatibility with all EVM wallets
-* **EIP-1559 Support**: Full support for EIP-1559 dynamic fee transactions, enabling automatic gas estimation
-* **Address Format**: Uses standard Ethereum addresses (0x format) for EVM transactions
-* **Transaction Types**: Supports all standard Ethereum transaction types including legacy and EIP-1559 transactions
-
-## Wallet Support[](#wallet-support "Direct link to Wallet Support")
-
-| Wallet | Type | Notes |
-| ------------- | ------------ | ----------------------------------------------------- |
-| MetaMask | EVM | Works out of the box - just add network RPC |
-| Rabby | EVM | Works out of the box - just add network RPC |
-| WalletConnect | EVM | Standard WalletConnect integration works |
-| Keplr | Cosmos + EVM | Supports both Cosmos and Ethereum transaction formats |
-| Leap | Cosmos + EVM | Supports both Cosmos and Ethereum transaction formats |
-| Ledger | Hardware | Compatible via MetaMask or other wallet interfaces |
-
-## Client Libraries[](#client-libraries "Direct link to Client Libraries")
-
-For programmatic wallet integration, use standard Ethereum client libraries like ethers.js, web3.js, or viem which are fully compatible with Cosmos EVM chains.
-
-## Quick Start[](#quick-start "Direct link to Quick Start")
-
-To add a Cosmos EVM chain to MetaMask or any EVM wallet:
-
-1. Open your wallet and navigate to "Add Network"
-
-2. Enter the following details:
-
- * **Network Name**: Your chain name
- * **RPC URL**: Your chain's JSON-RPC endpoint (port 8545)
- * **Chain ID**: Your EVM chain ID (integer)
- * **Currency Symbol**: Your native token symbol
- * **Block Explorer URL**: (optional) Your chain's block explorer
-
-That's it! Your wallet is now ready to interact with the Cosmos EVM chain.
-
diff --git a/evm/next/documentation/smart-contracts/introduction.mdx b/evm/next/documentation/smart-contracts/introduction.mdx
index 96c17c3e..df6c1400 100644
--- a/evm/next/documentation/smart-contracts/introduction.mdx
+++ b/evm/next/documentation/smart-contracts/introduction.mdx
@@ -35,7 +35,7 @@ Cosmos EVM supports the full [Ethereum JSON-RPC](/evm/next/api-reference/ethereu
* Deploy and interact with smart contracts using familiar web3 tools
* Connect existing Ethereum tooling without modifications
-* Use [block explorers](/evm/next/documentation/getting-started/tooling-and-resources/block-explorers) to debug and monitor your contracts
+* Use [block explorers](/evm/next/documentation/getting-started/tooling-and-resources) to debug and monitor your contracts
### Leverage Cosmos EVM Precompiles
@@ -58,7 +58,7 @@ These precompiles open up functionality that would be impossible or prohibitivel
## Resources
-* **Documentation:** [Cosmos EVM Precompiles](/evm/next/documentation/smart-contracts/precompiles) | [Tooling Guide](/evm/next/documentation/getting-started/tooling-and-resources/overview)
+* **Documentation:** [Cosmos EVM Precompiles](/evm/next/documentation/smart-contracts/precompiles) | [Tooling Guide](/evm/next/documentation/getting-started/tooling-and-resources)
* **Community:** [Discord](https://discord.gg/interchain) | [Cosmos Forum](https://forum.cosmos.network)
* **Examples:** Browse sample contracts and integration patterns in our guides
diff --git a/evm/next/documentation/smart-contracts/precompiles/overview.mdx b/evm/next/documentation/smart-contracts/precompiles/overview.mdx
index 3d812bfc..00a3226f 100644
--- a/evm/next/documentation/smart-contracts/precompiles/overview.mdx
+++ b/evm/next/documentation/smart-contracts/precompiles/overview.mdx
@@ -5,226 +5,35 @@ icon: "code"
keywords: ['precompiles', 'precompiled contracts', 'cosmos sdk', 'evm', 'smart contracts', 'staking', 'governance', 'ibc', 'bank', 'distribution', 'slashing', 'evidence', 'bech32', 'p256', 'erc20', 'werc20', 'callbacks']
---
-## Available Precompiles
-
-| Precompile | Address | Purpose | Reference |
-| ---------------- | -------------------------------------------- | ---------------------------------------------------------------- | ------------------------- |
-| **P256** | `0x0000000000000000000000000000000000000100` | P-256 elliptic curve cryptographic operations | [Details](./p256) |
-| **Bech32** | `0x0000000000000000000000000000000000000400` | Address format conversion between Ethereum hex and Cosmos bech32 | [Details](./bech32) |
-| **Staking** | `0x0000000000000000000000000000000000000800` | Validator operations, delegation, and staking rewards | [Details](./staking) |
-| **Distribution** | `0x0000000000000000000000000000000000000801` | Staking rewards and community pool management | [Details](./distribution) |
-| **ICS20** | `0x0000000000000000000000000000000000000802` | Cross-chain token transfers via IBC | [Details](./ics20) |
-| **Vesting** | `0x0000000000000000000000000000000000000803` | Vesting account creation and management | Coming Soon |
-| **Bank** | `0x0000000000000000000000000000000000000804` | ERC20-style access to native Cosmos SDK tokens | [Details](./bank) |
-| **Governance** | `0x0000000000000000000000000000000000000805` | On-chain governance proposals and voting | [Details](./governance) |
-| **Slashing** | `0x0000000000000000000000000000000000000806` | Validator slashing and jail management | [Details](./slashing) |
-| **ERC20** | Dynamic per token | Standard ERC20 functionality for native Cosmos tokens | [Details](./erc20) |
-| **WERC20** | Dynamic per token | Wrapped native token functionality | [Details](./werc20) |
+Precompiles are smart contract interfaces deployed at fixed addresses where the implementation runs as native Go code rather than EVM bytecode. In standard Ethereum, precompiles are stateless and handle things like signature verification and hashing. In Cosmos EVM, they can also be stateful — reading from and writing to Cosmos SDK module state outside the EVM.
-## Configuration
+This is what makes them powerful: a smart contract can call the staking precompile to delegate tokens, the governance precompile to submit a proposal, or the IBC precompile to send tokens cross-chain — all using a standard Solidity interface, all within a single transaction.
-Precompiled contracts provide direct, gas-efficient access to native Cosmos SDK functionality from within the EVM. Build powerful hybrid applications that leverage the best of both worlds. This page provides an overview of the available precompiled contracts, each with detailed documentation on its usage, Solidity interface, and ABI.
+Calls are bidirectional. EVM contracts can call precompiles, and precompiles can call back into EVM contracts. When a precompile is invoked, execution routes from the EVM through the corresponding Cosmos SDK module and returns the result to the EVM for continued execution. Gas is metered across both environments.
- **Critical: Understanding Token Decimals in Precompiles**
-
- All Cosmos EVM precompile contracts use the **native chain's decimal precision**, not Ethereum's standard 18 decimals (wei).
-
- **Why this matters:**
- - Cosmos chains typically use 6 decimals, while Ethereum uses 18
- - Passing values while assuming conventional Ethereum exponents could cause significant miscalculations
- - Example: On a 6-decimal chain, passing `1000000000000000000` (1 token in wei) will be interpreted as **1 trillion tokens**
-
- **Before using any precompile:**
- 1. Check your chain's native token decimal precision
- 2. Convert amounts to match the native token's format
- 3. Never assume 18-decimal precision
-
- ```solidity
- // WRONG: Assuming Ethereum's 18 decimals
- uint256 amount = 1 ether; // 1000000000000000000
- staking.delegate(validator, amount); // Delegates 1 trillion tokens!
-
- // CORRECT: Using chain's native 6 decimals
- uint256 amount = 1000000; // 1 token with 6 decimals
- staking.delegate(validator, amount); // Delegates 1 token
- ```
-
-
-### Genesis Configuration
+ All precompile contracts use the native chain's decimal precision, not Ethereum's standard 18 decimals.
-Precompiles must be enabled in the genesis file to be available on the network. The `active_static_precompiles` parameter controls which precompiles are activated at network launch.
+ Cosmos chains typically use 6 decimals. Passing a value like `1000000000000000000` (1 ETH in wei) to a precompile on a 6-decimal chain will be interpreted as 1 trillion tokens.
-```json
-{
- "app_state": {
- "vm": {
- "params": {
- "active_static_precompiles": [
- "0x0000000000000000000000000000000000000100", // P256
- "0x0000000000000000000000000000000000000400", // Bech32
- "0x0000000000000000000000000000000000000800", // Staking
- "0x0000000000000000000000000000000000000801", // Distribution
- "0x0000000000000000000000000000000000000802", // ICS20
- "0x0000000000000000000000000000000000000803", // Vesting
- "0x0000000000000000000000000000000000000804", // Bank
- "0x0000000000000000000000000000000000000805", // Governance
- "0x0000000000000000000000000000000000000806" // Slashing
- ]
- }
- }
- }
-}
-```
-
-
-For complete genesis configuration including EVM and fee market parameters, see the [Node Configuration](/evm/next/documentation/getting-started/network-operators/node-configuration) reference.
-
-
-## v0.5.0 Breaking Changes
-
-
-**Precompile Constructor Interface Changes**
-
-All precompile constructors in v0.5.0 now require keeper interfaces instead of concrete keeper implementations. This improves decoupling and testability but requires updates to custom precompile implementations.
+ Always check your chain's decimal precision before interacting with a precompile, and convert amounts accordingly.
-### Interface Requirements
-
-**Before (v0.4.x):**
-```go
-// Concrete keeper types required
-bankPrecompile, err := bankprecompile.NewPrecompile(
- bankKeeper, // bankkeeper.Keeper concrete type
- stakingKeeper, // stakingkeeper.Keeper concrete type
- // ... other keepers
-)
-```
-
-**After (v0.5.0):**
-```go
-// Keeper interfaces required (parameters accept interfaces directly)
-bankPrecompile, err := bankprecompile.NewPrecompile(
- bankKeeper, // common.BankKeeper interface
- erc20Keeper, // erc20keeper.Keeper interface
-)
-```
-
-**Source:** [`evmd/precompiles.go:122`](https://github.com/cosmos/evm/blob/main/evmd/precompiles.go#L122)
-
-### Required Interfaces
-
-The following keeper interfaces are defined in [`precompiles/common/interfaces.go`](https://github.com/cosmos/evm/blob/main/precompiles/common/interfaces.go):
-
-- `BankKeeper`: Account balances, token transfers, metadata
-- `StakingKeeper`: Validator operations, delegations, bond denom
-- `DistributionKeeper`: Reward withdrawals and distribution
-- `SlashingKeeper`: Validator slashing information
-- `TransferKeeper`: IBC transfer operations
-- `ChannelKeeper`: IBC channel and connection queries
-- `ERC20Keeper`: Token pair mappings and conversions
-
-### Migration Example
-
-**Custom Precompile Migration:**
-```go
-// Before (v0.4.x)
-func NewCustomPrecompile(
- bankKeeper bankkeeper.Keeper,
- stakingKeeper stakingkeeper.Keeper,
-) (*CustomPrecompile, error) {
- return &CustomPrecompile{
- bankKeeper: bankKeeper,
- stakingKeeper: stakingKeeper,
- }, nil
-}
-
-// After (v0.5.0)
-func NewCustomPrecompile(
- bankKeeper common.BankKeeper, // Interface instead of concrete type
- stakingKeeper common.StakingKeeper, // Interface instead of concrete type
-) (*CustomPrecompile, error) {
- return &CustomPrecompile{
- bankKeeper: bankKeeper,
- stakingKeeper: stakingKeeper,
- }, nil
-}
-```
-
-**Assembly Updates:**
-```go
-// In your precompile assembly function (based on evmd/precompiles.go)
-func NewAvailableStaticPrecompiles(
- stakingKeeper stakingkeeper.Keeper,
- distributionKeeper distributionkeeper.Keeper,
- bankKeeper cmn.BankKeeper, // Already interface type
- erc20Keeper erc20keeper.Keeper,
- // ... other keeper interfaces
- opts ...Option,
-) map[common.Address]vm.PrecompiledContract {
- precompiles := make(map[common.Address]vm.PrecompiledContract)
-
- // No casting needed - parameters are already interface types
- bankPrecompile, err := bankprecompile.NewPrecompile(bankKeeper, erc20Keeper)
- if err != nil {
- panic(fmt.Errorf("failed to instantiate bank precompile: %w", err))
- }
- precompiles[bankPrecompile.Address()] = bankPrecompile
-)
-if err != nil {
- return nil, err
-}
-precompiles[bankAddress] = bankPrecompile
-```
-
-## Integration Guide
-
-### Activation
-
-Precompiles must be explicitly activated via the `active_static_precompiles` parameter:
-
-```bash
-# Via genesis configuration
-{
- "active_static_precompiles": [
- "0x0000000000000000000000000000000000000804", // Bank
- "0x0000000000000000000000000000000000000800" // Staking
- ]
-}
-
-# Via governance proposal
-evmd tx gov submit-proposal param-change-proposal.json --from validator
-```
-
-### Usage in Smart Contracts
-
-```solidity
-// Import precompile interfaces
-import "./IBank.sol";
-import "./IStaking.sol";
-
-contract MyDApp {
- IBank constant bank = IBank(0x0000000000000000000000000000000000000804);
- IStaking constant staking = IStaking(0x0000000000000000000000000000000000000800);
-
- function getBalance(string memory denom) external view returns (uint256) {
- return bank.balances(msg.sender, denom);
- }
-
- function delegateTokens(string memory validatorAddr, uint256 amount) external {
- staking.delegate(msg.sender, validatorAddr, amount);
- }
-}
-```
-
-### Testing
-
-All precompiles include comprehensive Solidity test suites for validation:
-
-```bash
-# Run precompile tests
-cd tests && npm test
+## Available Precompiles
-# Test specific precompile
-npx hardhat test test/Bank.test.js
-```
+| Precompile | Address | Purpose | Reference |
+| ---------------- | -------------------------------------------- | ---------------------------------------------------------------- | ------------------------- |
+| P256 | `0x0000000000000000000000000000000000000100` | P-256 elliptic curve signature verification | [Details](./p256) |
+| Bech32 | `0x0000000000000000000000000000000000000400` | Address format conversion between Ethereum hex and Cosmos bech32 | [Details](./bech32) |
+| Staking | `0x0000000000000000000000000000000000000800` | Validator operations, delegation, and staking rewards | [Details](./staking) |
+| Distribution | `0x0000000000000000000000000000000000000801` | Staking rewards and community pool management | [Details](./distribution) |
+| ICS20 | `0x0000000000000000000000000000000000000802` | Cross-chain token transfers via IBC | [Details](./ics20) |
+| Vesting | `0x0000000000000000000000000000000000000803` | Vesting account creation and management | Coming Soon |
+| Bank | `0x0000000000000000000000000000000000000804` | ERC20-style access to native Cosmos SDK tokens | [Details](./bank) |
+| Governance | `0x0000000000000000000000000000000000000805` | On-chain governance proposals and voting | [Details](./governance) |
+| Slashing | `0x0000000000000000000000000000000000000806` | Validator slashing and jail management | [Details](./slashing) |
+| ICS02 | `0x0000000000000000000000000000000000000807` | IBC light client queries | Coming Soon |
+| ERC20 | Dynamic per token | Standard ERC20 interface for native Cosmos tokens | [Details](./erc20) |
+| WERC20 | Dynamic per token | Wrapped native token functionality | [Details](./werc20) |
+
+Chain builders can control which precompiles are active and add their own. See [Precompile Configuration](/evm/next/documentation/getting-started/build-a-chain/additional-configuration/precompiles) for details.
From f9efb459b15c31e268807b5628ab48ef9502b00a Mon Sep 17 00:00:00 2001
From: Evan <87997759+evanorti@users.noreply.github.com>
Date: Thu, 19 Feb 2026 14:51:26 -0500
Subject: [PATCH 17/32] Update evm-compatibility.mdx
---
evm/next/documentation/evm-compatibility.mdx | 70 +++++++++++---------
1 file changed, 38 insertions(+), 32 deletions(-)
diff --git a/evm/next/documentation/evm-compatibility.mdx b/evm/next/documentation/evm-compatibility.mdx
index 18545270..51ba0358 100644
--- a/evm/next/documentation/evm-compatibility.mdx
+++ b/evm/next/documentation/evm-compatibility.mdx
@@ -5,29 +5,26 @@ keywords: ['differences', 'ethereum', 'evm', 'cosmos', 'CometBFT', 'consensus',
Cosmos EVM provides full Ethereum compatibility for Cosmos SDK chains. Existing contracts, tools, and workflows run without modification: deploy Solidity contracts, connect MetaMask, and use the same libraries and frameworks you already know.
-## Key Compatibility Areas
-
-Cosmos EVM maintains all critical EVM behaviors that developers expect. The table below shows how we've addressed each compatibility requirement.
-
-| Feature | Ethereum Behavior | Cosmos EVM Implementation | Compatible? |
-|---------|------------------|---------------------------|---------------|
-| **Transaction Ordering** | Gas price + nonce ordering | Fee priority + nonce ordering with configurable MinTip | Yes |
-| **Multiple Txs per Block** | Multiple per account | Multiple per account | Yes |
-| **Mempool Behavior** | Pending pool for transactions | ExperimentalEVMMempool with unified EVM/Cosmos pools | Yes |
-| **Nonce Management** | Sequential nonce enforcement | Sequential nonce enforcement with gap queuing | Yes |
-| **EIP-1559 (Dynamic Fees)** | Base fee + priority fee | Base fee + priority fee (distributed, not burned) | Yes |
-| **EIP-7702 (Set Code)** | Account code delegation | Full support with authorization lists | Yes |
-| **Address Format** | 0x addresses | 0x addresses (+ cosmos1 alias) | Yes |
-| **Smart Contracts** | EVM bytecode execution | Full EVM bytecode execution | Yes |
-| **Gas Metering** | Standard gas costs | Standard gas costs | Yes |
-| **Event Logs** | Ethereum event system | Full event compatibility | Yes |
-| **JSON-RPC API** | Standard Ethereum RPC | Full RPC implementation | Yes |
-| **Block Time** | 12 seconds | 1-2 seconds | Faster |
-| **Finality** | 12+ blocks (~3min) | 1 block (~2s) | Instant |
-| **Reorganizations** | Possible | Not possible | More secure |
-| **Cross-chain** | Bridge protocols | Native IBC | Enhanced |
-
-**You can build on Cosmos EVM exactly like you would on Ethereum.** Every essential feature works identically, from deploying contracts to managing transactions. The enhancements (faster blocks, instant finality, IBC) are pure additions that don't break any existing patterns or workflows.
+## Solidity Smart Contracts
+
+The Cosmos EVM smart contract development flow is identical to the flow on Ethereum. Contracts that work on Ethereum work on Cosmos EVM without code changes. The same tools, the same Solidity, the same patterns.
+
+### Development
+
+Write Solidity using [Hardhat](https://hardhat.org), [Foundry](https://book.getfoundry.sh), or [Remix](https://remix.ethereum.org) with no custom configuration needed. Point your tooling at your chain's JSON-RPC endpoint and chain ID and you're set. See the [tooling overview](/evm/next/documentation/getting-started/tooling-and-resources) for a full list of supported tools, and the [quick-start guide](/evm/next/documentation/getting-started/build-a-chain/quick-start#deploy-a-solidity-contract-with-forge) for a step-by-step contract deployment walkthrough.
+
+### Deployment
+
+Deploy using standard Ethereum tools by pointing them at your chain's RPC endpoint. Deployment transactions go through the JSON-RPC or Cosmos gRPC interface and are processed by the EVM module. Once deployed, contract bytecode is stored in chain state and callable at its Ethereum address like any other chain.
+
+### Upgrading
+
+Cosmos EVM supports all standard EVM upgrade patterns:
+
+- **Proxy patterns (EIP-1967, Transparent Proxy, UUPS)** — Delegate calls to an implementation contract. Upgrading means swapping the implementation address in the proxy without touching the proxy's storage or address.
+- **Diamond pattern (EIP-2535)** — Modular contracts split into "facets" that can be added, replaced, or removed independently. The diamond routes calls to the appropriate facet, enabling granular upgrades without redeploying the whole contract.
+
+Any upgrade architecture that works on Ethereum works on Cosmos EVM.
## Supported EIPs
@@ -125,24 +122,33 @@ Cosmos EVM uses two independent chain IDs: a Cosmos Chain ID (string, e.g. `cosm
### JSON-RPC API
+The JSON-RPC interface is compatible with the full Ethereum tooling ecosystem without modification. Any tool that speaks standard Ethereum JSON-RPC works by pointing it at your chain's RPC endpoint.
+
Most standard Ethereum JSON-RPC methods are supported, with some returning stub values for compatibility. View the complete reference.
-**Core functionality for developers:**
-- All standard transaction methods (`eth_sendRawTransaction`, `eth_call`, `eth_estimateGas`)
-- Block and receipt queries
-- Account balances and nonces
-- Event logs and filters
-- Web3 utilities and net info
-- Debug namespace (partial - tracing and profiling methods available)
-- Websocket subscription support
+**Compatible tools include:**
+
+| Category | Tools |
+|----------|-------|
+| Development frameworks | Foundry (Forge, Cast), Hardhat, Truffle, Remix IDE |
+| Wallets | MetaMask, WalletConnect, Ledger |
+| Libraries | ethers.js, web3.js, viem, wagmi |
+| Block explorers | Etherscan-compatible, Blockscout |
+
+**Core functionality:**
+- All standard transaction methods (`eth_sendRawTransaction`, `eth_call`, `eth_estimateGas`)
+- Block and receipt queries
+- Account balances and nonces
+- Event logs and filters
+- WebSocket subscription support
+- Debug namespace (tracing and profiling)
**Implementation notes:**
- Some methods return stub values for compatibility (e.g., `eth_gasPrice` returns 0)
- Mining-related methods are not applicable (Cosmos uses CometBFT consensus)
- `txpool` methods require experimental mempool configuration
-- Debug namespace includes functional tracing and profiling tools
### Performance
From e84c194d99f05f3f0188442e3746c08681d91444 Mon Sep 17 00:00:00 2001
From: Evan <87997759+evanorti@users.noreply.github.com>
Date: Thu, 19 Feb 2026 14:51:28 -0500
Subject: [PATCH 18/32] Update overview.mdx
---
.../smart-contracts/precompiles/overview.mdx | 29 +++++++++----------
1 file changed, 14 insertions(+), 15 deletions(-)
diff --git a/evm/next/documentation/smart-contracts/precompiles/overview.mdx b/evm/next/documentation/smart-contracts/precompiles/overview.mdx
index 00a3226f..967c134e 100644
--- a/evm/next/documentation/smart-contracts/precompiles/overview.mdx
+++ b/evm/next/documentation/smart-contracts/precompiles/overview.mdx
@@ -19,21 +19,20 @@ Calls are bidirectional. EVM contracts can call precompiles, and precompiles can
Always check your chain's decimal precision before interacting with a precompile, and convert amounts accordingly.