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

# Contracts

> On-chain contract addresses and EIP-712 signing constants for the Derive v3 mainnet (Ethereum) and testnet (Sepolia) deployments.

The on-chain contracts for the Derive v3 deployments. These are the settlement and custody
contracts your own wallet interacts with for deposits, withdrawals, and the L1 escape hatch.

| Network | Chain | Chain ID |
| - | - | - |
| Mainnet | Ethereum | `1` |
| Testnet | Ethereum Sepolia | `11155111` |

<Note>
  For the per-action **module** addresses and the full signing scheme, see [Action
  signing](/authentication/action-signing). The `ACTION_TYPEHASH` and `DOMAIN_SEPARATOR` are
  under [Signing constants](#signing-constants) below.
</Note>

<Note>
  Token addresses are not listed here — read them from
  `public/get_all_currencies`, under `spot[].erc20.underlying_erc20`. Every
  testnet token is mintable: open
  [testnet.app.derive.xyz](https://testnet.app.derive.xyz/), connect your wallet, and
  click **Deposit** in the top right, then **Mint** a token of your choice.
</Note>

## `ACTION_MANAGER`

<CodeGroup>
  ```text Mainnet theme={null}
  0xE366CcA474968e33b777E13905829A3b800CFAD3
  ```

  ```text Testnet theme={null}
  0xd3625eCf97E5554C62A48Ac1c9284C9dCeFceB68
  ```
</CodeGroup>

Direct L1 calls to the Derive exchange can be made for
[deposits](/getting-started/depositing), or for setting session keys from
[MPC wallets](/authentication/mpc-wallets) and
[multi-sigs or contracts](/authentication/contract-owned-accounts).

## `VAPP`

<CodeGroup>
  ```text Mainnet theme={null}
  0xd330145C17fB6EF2a21ACf1275Ce683A305F58BB
  ```

  ```text Testnet theme={null}
  0x1573bde26338A9E6AA358638679A796c81E33246
  ```
</CodeGroup>

The zk-vApp settlement contract. It anchors the protocol's on-chain state root
and verifies the validity (zero-knowledge) proofs that settle every state
transition — the root of custody and settlement for the deployment.

## `WITHDRAWAL_OUTBOX`

<CodeGroup>
  ```text Mainnet theme={null}
  0x7c743D79C9C595cE332314503d84cBBb4E85FA63
  ```

  ```text Testnet theme={null}
  0xFbB62CE2BbFdFdc8a60DDC22115aC29cf91B4566
  ```
</CodeGroup>

The L1 withdrawal outbox. Finalized withdrawals — and the **escape-hatch** exit
if the operator goes offline — are claimed here; payouts are pulled from the spot
vault through this contract.

## `SPOT_VAULT`

<CodeGroup>
  ```text Mainnet theme={null}
  0x2e7dF4fAf35a1599979C7E764444e112d936ec42
  ```

  ```text Testnet theme={null}
  0x3FB79aafCD401CDD19e3d729241545955DDE0D48
  ```
</CodeGroup>

## `WITHDRAW_FACTORY`

<CodeGroup>
  ```text Mainnet theme={null}
  0xFec48bBC648bd2284520d862Ec67fc68F709915e
  ```

  ```text Testnet theme={null}
  0x6A8566c585903E4558A9BE722FFa55f173c719ef
  ```
</CodeGroup>

Issues the withdraw addresses for [forwarded withdrawals](/trading/transfers-withdrawals#forwarded-withdrawals).
`getWithdrawAddress(bytes32 recipient, uint256 chainId)` returns the address that
`private/register_withdraw_address` gives you.

## Signing constants

Every signed action is an EIP-712 `Action` struct hashed under the action domain. The signer
signs `keccak256(0x1901 || DOMAIN_SEPARATOR || actionHash)`.

### `ACTION_TYPEHASH`

```text theme={null}
0x4d7a9f27c403ff9c0f19bce61d76d82f9aa29f8d6d4b0c5474607d9770d1af17
```

The `keccak256` of the `Action` type string. It is the same on every network:

```text theme={null}
Action(uint256 subaccountId,uint256 nonce,address module,bytes data,uint256 expiry,address owner,address signer)
```

### `DOMAIN_SEPARATOR`

<CodeGroup>
  ```text Mainnet theme={null}
  0xda616dfabb88681b08e1592820a41d55ddc62d68de110e327ae99d734506fe19
  ```

  ```text Testnet theme={null}
  0x24d674cd5f2b9d564691c51e9d88f649b99246a2244dd74ce27b96578d773e85
  ```
</CodeGroup>

The action domain is `name` `Matching`, `version` `1.0`, the network's `chainId`, and a
`verifyingContract` of `0xeB8d770ec18DB98Db922E9D83260A585b9F0DeAD`. That address is the v2
mainnet `Matching` contract, fixed on every network. It is **not** one of the v3 contracts above.

```text theme={null}
DOMAIN_SEPARATOR = keccak256(abi.encode(
    keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"),
    keccak256("Matching"),
    keccak256("1.0"),
    chainId,                                      // 1 mainnet, 11155111 testnet
    0xeB8d770ec18DB98Db922E9D83260A585b9F0DeAD
))
```

The SDKs set both values for each network. See [Action
signing](/authentication/action-signing#domain-separator) for how an action is hashed under them.


## Related topics

- [Smart Contracts & Multi-sigs](/authentication/contract-owned-accounts.md)
- [Gasless Onboarding](/getting-started/gasless-onboarding.md)
- [DevEx improvements](/migrating/v3-improvements.md)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.