Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 22 additions & 24 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -444,12 +444,12 @@ rexpect = { git = "https://github.com/rust-cli/rexpect", rev = "2ed0b1898d7edaf6
## alloy-evm
# alloy-evm = { git = "https://github.com/haythemsellami/evm", branch = "main" }
# alloy-op-evm = { git = "https://github.com/haythemsellami/evm", branch = "main" }
# alloy-monad-evm = { git = "https://github.com/category-labs/alloy-monad-evm", branch = "main" }
alloy-monad-evm = { git = "https://github.com/category-labs/alloy-monad-evm", branch = "feat/staking-write-functions" }

## revm
# revm = { git = "https://github.com/haythemsellami/revm", branch = "main" }
# op-revm = { git = "https://github.com/haythemsellami/revm", branch = "main" }
# monad-revm = { git = "https://github.com/category-labs/monad-revm", branch = "main" }
monad-revm = { git = "https://github.com/category-labs/monad-revm", branch = "feat/staking-write-functions" }
revm-inspectors = { git = "https://github.com/haythemsellami/revm-inspectors", branch = "main" }

## foundry
Expand Down
14 changes: 13 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,22 @@ Monad is a Layer-1 blockchain delivering high performance, true decentralization
- Monad-specific [opcode and precompile gas costs](https://docs.monad.xyz/developer-essentials/opcode-pricing), no gas refunds, increased bytecode limits (128KB code, 256KB initcode), and no EIP-4844 blob transactions. See [Monad EVM differences](https://docs.monad.xyz/developer-essentials/differences) for full details.

### Staking Precompile (address `0x1000`)
- Full support for all staking [view functions](https://docs.monad.xyz/developer-essentials/staking/staking-precompile): `getEpoch`, `getProposerValId`, `getValidator`, `getDelegator`, `getWithdrawalRequest`, `getConsensusValidatorSet`, `getSnapshotValidatorSet`, `getExecutionValidatorSet`, `getDelegations`, `getDelegators`.
- Full support for Monad staking precompile execution in tests/scripts via the Monad EVM stack.
- Support for staking view functions (`getEpoch`, `getProposerValId`, `getValidator`, `getDelegator`, `getWithdrawalRequest`, `getConsensusValidatorSet`, `getSnapshotValidatorSet`, `getExecutionValidatorSet`, `getDelegations`, `getDelegators`) and state-changing functions (`addValidator`, `delegate`, `undelegate`, `withdraw`, `compound`, `claimRewards`, `changeCommission`, `externalReward`).
- Full staking behavior is implemented in [`monad-revm`](https://github.com/category-labs/monad-revm) and consumed through [`alloy-monad-evm`](https://github.com/category-labs/alloy-monad-evm). See the monad-revm README for design/lifecycle details.
- Human-readable ABI decoding in `forge test -vvvv` traces for all staking functions and events.
- Address `0x1000` labeled as "Staking" in trace output.

### Monad Staking Cheatcodes
- Monad staking cheatcodes are exposed from a separate cheatcode address:
- `0xc0FFeeCD43A10e1C2b0De63c6CDCFe5B7d0e0CEA`
- Current implemented cheatcodes:
- Direct state controls: `setEpoch(uint64,bool)`, `setProposer(uint64)`, `setAccumulator(uint64,uint256)`
- Syscall wrappers: `blockReward(address,uint256)`, `epochSnapshot()`, `epochChange(uint64)`, `epochBoundary(uint64)`
- These cheatcodes are helper controls around lifecycle/state setup. Core staking operations (delegate/undelegate/claim/withdraw/etc.) still execute through the real staking precompile at `0x1000`.
- Solidity interface path in this repository: `testdata/utils/MonadVm.sol`
- End-to-end tests for current coverage: `testdata/default/cheats/MonadStaking.t.sol`

### Forge
- `forge test` and `forge script` execute with Monad EVM by default.
- `forge verify-contract` uses Monad-specific compilation settings.
Expand Down
35 changes: 35 additions & 0 deletions crates/cheatcodes/src/inspector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -761,6 +761,41 @@ impl Cheatcodes {
};
}

if call.target_address == crate::monad::MONAD_CHEATCODE_ADDRESS {
let input = call.input.bytes(ecx);
let result = crate::monad::apply_monad_cheatcode(
&mut CheatsCtxt {
state: self,
ecx,
gas_limit: call.gas_limit,
caller: call.caller,
},
&input,
);
return match result {
Ok(retdata) => Some(CallOutcome {
result: InterpreterResult {
result: InstructionResult::Return,
output: retdata.into(),
gas,
},
memory_offset: call.return_memory_offset.clone(),
was_precompile_called: true,
precompile_call_logs: vec![],
}),
Err(err) => Some(CallOutcome {
result: InterpreterResult {
result: InstructionResult::Revert,
output: err.abi_encode().into(),
gas,
},
memory_offset: call.return_memory_offset.clone(),
was_precompile_called: false,
precompile_call_logs: vec![],
}),
};
}

if call.target_address == HARDHAT_CONSOLE_ADDRESS {
return None;
}
Expand Down
2 changes: 2 additions & 0 deletions crates/cheatcodes/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ mod toml;

mod utils;

pub mod monad;

/// Cheatcode implementation.
pub(crate) trait Cheatcode: CheatcodeDef + DynCheatcode {
/// Applies this cheatcode to the given state.
Expand Down
Loading
Loading