Override contract state
Write directly to any address’s code, nonce, or storage on your Stagenet. Use it to drop a mock into an existing contract address, force a specific storage layout, or bump a nonce to match a production scenario.
These methods match the semantics of Hardhat’s hardhat_setCode / hardhat_setStorageAt / hardhat_setNonce, Anvil’s equivalents, and Foundry’s vm.etch / vm.store / vm.setNonce. Once written, the values behave like normal EVM state — later transactions can read or modify them.
Prerequisites
- A Stagenet — create one in the dashboard if you don’t have one yet
- The contract.dev CLI installed and configured at your project root (only required for the CLI snippets below):
npm install contract.dev
npx contract.dev init --rpc-url=<YOUR_STAGENET_RPC_URL>Replace bytecode at an address
Drop new bytecode in at an address. Useful for replacing a third-party dependency with a mock without redeploying anything that references it.
From the CLI:
npx contract.dev state set-code 0xContract... 0x6042...
npx contract.dev state set-code 0xContract... 0x # wipeFrom the SDK:
import { createStagenet } from "contract.dev";
const stagenet = createStagenet("<YOUR_STAGENET_RPC_URL>");
await stagenet.setCode("0xContract...", "0x6042...");
await stagenet.setCode("0xContract...", "0x"); // wipeA typical workflow is to compile a mock, then etch its runtime bytecode at the original address:
import { readFileSync } from "node:fs";
const artifact = JSON.parse(
readFileSync("out/MockOracle.sol/MockOracle.json", "utf8"),
);
const runtimeBytecode = artifact.deployedBytecode.object;
await stagenet.setCode(oracle, runtimeBytecode);After this, every call to oracle runs your mock — including inner calls from contracts that depend on it.
Set a storage slot
Write a 32-byte value into a specific slot on a contract. Use this when you need a particular state (e.g. an owner field, a flag, a struct field) without going through whatever setter would normally write to it.
npx contract.dev state set-storage 0xContract... \
--slot 0x0000000000000000000000000000000000000000000000000000000000000000 \
--value 0x000000000000000000000000000000000000000000000000000000000000002aconst toUint = (n: bigint) =>
"0x" + n.toString(16).padStart(64, "0");
await stagenet.setStorageAt(
"0xContract...",
toUint(0n), // slot 0
toUint(42n), // value
);Or with viem’s helpers:
import { pad, toHex } from "viem";
await stagenet.setStorageAt(token, pad(toHex(0)), pad(toHex(42n)));Both slot and value must be exactly 32-byte hex words (0x + 64 hex chars). Short inputs like "0x42" are rejected — encode them explicitly. This is the same convention as Hardhat, Anvil, and Foundry’s vm.store: the caller decides whether the encoding is uint-style (left-padded) or bytes-style (right-padded), so there is no ambiguity.
Set an owner slot
If a contract stores its owner at slot 0, take ownership directly:
const owner = "0x1111111111111111111111111111111111111111";
const ownerAsWord = "0x" + owner.slice(2).padStart(64, "0").toLowerCase();
await stagenet.setStorageAt(vault, toUint(0n), ownerAsWord);Set a packed struct field
Solidity packs multiple variables into one slot. If you don’t know the exact slot, you can find it with Foundry’s forge inspect <Contract> storage-layout or Hardhat’s hardhat-storage-layout plugin, then write the slot directly.
Skip the encoding for ERC20 balances
For ERC20 balanceOf specifically, use the higher-level helpers — they figure out the slot for you:
npx contract.dev erc20-balance set 0x1111... 0xA0b8...eB48 1000000See Fund test wallets.
Set a nonce
Bump an EOA’s nonce to match a production scenario, or reset it for deterministic CREATE-based deployments:
npx contract.dev state set-nonce 0x1111... 42await stagenet.setNonce(alice, 42);Transaction-driven nonce increments after this proceed from the new value.
When to use a function override instead
Storage overrides change real state, so every reader sees them — including functions that do extra computation on top (e.g. a balanceOf that wraps a packed mapping). That’s the right tool when you need a balance change to propagate through transfer and friends.
If you only need a specific function to return a specific value — for one call or for every call — without state changes that anything else can observe, use function overrides instead. They intercept at the call boundary, so the function body never runs.
Next steps
- State SDK reference — full method signatures and return shapes.
stateCLI reference.- Mock a function return value — intercept reads without touching storage.
- Fund test wallets — the storage-write path for native and ERC20 balances.