igneum/tools/exec-attacks/contracts/RegistryAbuse.sol
igneum-josh 1d58fd8726 exec-attacks: execution-layer attack suite (tools + bench log)
Adversarial robustness and conformance tests of the execution layer against a
throwaway 3-node simnet on ports 27600+. Six scenarios, each a runnable command
with a design-derived pass criterion and a measured result: malformed/boundary
txs, nonce games across parallel blocks, RPC fuzz, pgas exhaustion, reorgs under
execution, and developer-registry abuse. 98 checks, 0 failures, 0 node panics.

Two findings filed in the bench-log entry: the mempool admits txs with gas_limit
above B_e (low), and an over-pgas-budget tx is executed natively in full before
being skipped for no fee (medium, griefing).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-03 22:57:19 +00:00

41 lines
1.7 KiB
Solidity

// SPDX-License-Identifier: ISC
pragma solidity ^0.8.20;
// Contracts for scenario 4 (developer-registry abuse, design 4.5): a Worker whose calls spend gas (so a tip is
// attributable to its code), and a Factory that deploys Workers via CREATE and CREATE2 and exercises the registry's
// register rules, including a same-transaction override by the creator.
interface IReg {
function register(address account, address payee) external;
function payeeOf(address account) external view returns (address);
function creatorOf(address account) external view returns (address);
}
contract Worker {
uint256 public acc;
function work(uint256 n) external returns (uint256) {
for (uint256 i = 0; i < n; i++) acc += i + 1;
return acc;
}
}
contract Factory {
address constant REG = 0x0000000000000000000000000000000000000210;
event Created(address child);
// The factory registers itself (allowed: msg.sender == account).
function registerSelf(address payee) external { IReg(REG).register(address(this), payee); }
// CREATE: child inherits the factory's payee by the executor's rule.
function createChild() external returns (address c) { c = address(new Worker()); emit Created(c); }
// CREATE2: same inheritance.
function createChild2(bytes32 salt) external returns (address c) { c = address(new Worker{salt: salt}()); emit Created(c); }
// The creating transaction overrides the child's payee in the same tx (allowed: factory is the recorded creator).
function createAndOverride(address payee) external returns (address c) {
c = address(new Worker());
IReg(REG).register(c, payee);
emit Created(c);
}
}