> ## Documentation Index
> Fetch the complete documentation index at: https://docs.cosmos.network/llms.txt
> Use this file to discover all available pages before exploring further.

# Predeployed Contracts

> Deploying and managing predeployed contracts

<Note>
  **New to predeployed contracts?** Start here:

  * [Predeployed Contracts Concept](/evm/v0.5.0/documentation/concepts/predeployed-contracts) - Understanding predeployed contracts and how they differ from precompiles
  * [Predeployed Contracts Overview](/evm/v0.5.0/documentation/smart-contracts/predeployed-contracts/overview) - Quick reference of available contracts
  * [Building Your Chain Guide](/evm/v0.5.0/documentation/getting-started/build-a-chain/overview#configuring-predeployed-contracts) - Quick start configuration examples

  **Individual Contract Documentation**:

  * [Create2 Factory](/evm/v0.5.0/documentation/smart-contracts/predeployed-contracts/create2) - Deterministic deployment patterns
  * [Multicall3](/evm/v0.5.0/documentation/smart-contracts/predeployed-contracts/multicall3) - Batch operations examples
  * [Permit2](/evm/v0.5.0/documentation/smart-contracts/predeployed-contracts/permit2) - Signature-based approvals
  * [Safe Factory](/evm/v0.5.0/documentation/smart-contracts/predeployed-contracts/safe-factory) - Multisig wallet deployment
</Note>

## Getting Started

There are several methods to deploy preinstalled contracts on a Cosmos EVM chain:

### 1. Genesis Configuration

The most straightforward method for new chains or testnets. Contracts are deployed when the chain is first initialized.

<Tabs>
  <Tab title="Default Configuration">
    If using the reference `evmd` application, your chain automatically includes default preinstalls, however they will not be active by default.

    ```go expandable theme={"theme":{"light":"github-light-high-contrast","dark":"github-dark-high-contrast"}}
    // Source: evmd/genesis.go:28-34
    func NewEVMGenesisState() *evmtypes.GenesisState {
        evmGenState := evmtypes.DefaultGenesisState()
        evmGenState.Params.ActiveStaticPrecompiles = evmtypes.AvailableStaticPrecompiles
        evmGenState.Preinstalls = evmtypes.DefaultPreinstalls  // Defined in x/vm/types/preinstall.go
        return evmGenState
    }
    ```
  </Tab>

  <Tab title="Custom Genesis Configuration">
    To customize which contracts are deployed:

    ```json expandable theme={"theme":{"light":"github-light-high-contrast","dark":"github-dark-high-contrast"}}
    {
      "app_state": {
        "evm": {
          "preinstalls": [
            {
              "name": "Create2",
              "address": "0x4e59b44847b379578588920ca78fbf26c0b4956c",
              "code": "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe03601600081602082378035828234f58015156039578182fd5b8082525050506014600cf3"
            },
            {
              "name": "Multicall3",
              "address": "0xcA11bde05977b3631167028862bE2a173976CA11",
              "code": "0x6080604052..." // Full bytecode
            }
          ]
        }
      }
    }
    ```
  </Tab>
</Tabs>

#### Local Development

`local_node.sh` does not populate preinstalls. The `evmd init` command generates a genesis.json with an empty `preinstalls` array, and the script's `jq` customizations only patch other parameters. To enable preinstalls locally, manually add a `jq` command in your `local_node.sh` (after `evmd init`) to populate `app_state.evm.preinstalls` with the desired entries before starting the node.

### 2. Governance Proposal

For chains already in production, use the `MsgRegisterPreinstalls` governance proposal:

#### Proposal Structure

<Note>
  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.
</Note>

```json expandable theme={"theme":{"light":"github-light-high-contrast","dark":"github-dark-high-contrast"}}
{
  "messages": [
    {
      "@type": "/cosmos.evm.vm.v1.MsgRegisterPreinstalls",
      "authority": "[gov module account address]",
      "preinstalls": [
        {
          "name": "Multicall3",
          "address": "0xcA11bde05977b3631167028862bE2a173976CA11",
          "code": "0x6080604052..."
        }
      ]
    }
  ],
  "metadata": "ipfs://CID",
  "deposit": "10000000stake",
  "title": "Deploy Multicall3 Contract",
  "summary": "Deploy the Multicall3 contract to enable batched calls"
}
```

#### Submission Process

```bash expandable theme={"theme":{"light":"github-light-high-contrast","dark":"github-dark-high-contrast"}}
# Submit proposal
evmd tx gov submit-proposal proposal.json \
  --from mykey \
  --chain-id cosmosevm_9001-1 \
  --gas auto

# Vote on proposal
evmd tx gov vote 1 yes --from mykey
```

### 3. Chain Upgrade Handler

Include predeployed contracts as part of a coordinated chain upgrade:

```go expandable theme={"theme":{"light":"github-light-high-contrast","dark":"github-dark-high-contrast"}}
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

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

### Storage and State

Predeployed contracts are stored in the chain state like regular contracts:

```go expandable theme={"theme":{"light":"github-light-high-contrast","dark":"github-dark-high-contrast"}}
// 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
}
```

## Verification and Testing

### Verify Deployment

After deployment, verify contracts are properly installed:

```bash expandable theme={"theme":{"light":"github-light-high-contrast","dark":"github-dark-high-contrast"}}
# Query contract code via CLI
evmd query evm code 0x4e59b44847b379578588920ca78fbf26c0b4956c

# Check account exists
evmd query evm account 0x4e59b44847b379578588920ca78fbf26c0b4956c
```

```javascript expandable theme={"theme":{"light":"github-light-high-contrast","dark":"github-dark-high-contrast"}}
// Verify via Web3
const code = await provider.getCode("0x4e59b44847b379578588920ca78fbf26c0b4956c");
console.log("Deployed:", code !== "0x");
```

### Testing Strategy

1. **Local Testing**: Deploy on local node first
2. **Testnet Validation**: Test governance proposal process
3. **Integration Testing**: Verify interactions with other contracts
4. **Gas Analysis**: Monitor gas consumption patterns
5. **Security Audit**: Review bytecode before mainnet deployment

## Best Practices

### Security Considerations

* **Bytecode Verification**: Always verify that bytecode matches official releases
* **Address Selection**: Ensure addresses don't conflict with future plans
* **Audit Requirements**: Even well-known contracts should be reviewed
* **Immutability**: Remember that predeployed contracts cannot be upgraded

### Deployment Recommendations

1. **Start with Defaults**: Use `evmtypes.DefaultPreinstalls` unless you have specific requirements
2. **Test Thoroughly**: Validate on testnet before mainnet deployment
3. **Document Changes**: Clearly communicate any non-standard deployments to developers
4. **Monitor Usage**: Track contract interactions to understand adoption

### Common Pitfalls to Avoid

* Don't deploy to addresses that could conflict with precompiles (typically 0x1-0x9FF)
* Don't assume contracts are deployed - always check first
* Don't modify standard contract addresses without strong justification
* Don't deploy untested or unaudited bytecode

## Known Issues

<Warning>
  **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 theme={"theme":{"light":"github-light-high-contrast","dark":"github-dark-high-contrast"}}
  # 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/v0.5.0/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.
</Warning>

## Adding Custom Preinstalls

To add custom contracts beyond the defaults:

```go expandable theme={"theme":{"light":"github-light-high-contrast","dark":"github-dark-high-contrast"}}
// 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)
```

## 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 | `0x0000F90827F1C53a10cb7A02335B175320002935` | `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 theme={"theme":{"light":"github-light-high-contrast","dark":"github-dark-high-contrast"}}
{
  "app_state": {
    "evm": {
      "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/v0.5.0/documentation/cosmos-sdk/modules/vm) - Complete VM module configuration
* [Chain Customization Checklist](/evm/v0.5.0/documentation/getting-started/build-a-chain/quick-start) - Step-by-step setup guide
* [Configuration Parameters](/evm/v0.5.0/documentation/getting-started/build-a-chain/quick-start) - All genesis parameters explained
