Skip to content

Commit

Permalink
[Chore] - opcode tester contracts (#447)
Browse files Browse the repository at this point in the history
* initial commit of all opcode testing

* linting

* use better names - refactored + no optimizer

* store timestamp on verbatim execution

* Update contracts/contracts/test-contracts/OpcodeTester.sol

Co-authored-by: kyzooghost <73516204+kyzooghost@users.noreply.github.com>
Signed-off-by: The Dark Jester <thedarkjester@users.noreply.github.com>

* Update contracts/contracts/test-contracts/LondonEvmCodes.yul

Co-authored-by: kyzooghost <73516204+kyzooghost@users.noreply.github.com>
Signed-off-by: The Dark Jester <thedarkjester@users.noreply.github.com>

* deduplicate rollingBlockDetailComputations

* add missing bytecode and cleanup

* order functions by usage order

* correct loops

---------

Signed-off-by: The Dark Jester <thedarkjester@users.noreply.github.com>
Co-authored-by: kyzooghost <73516204+kyzooghost@users.noreply.github.com>
  • Loading branch information
thedarkjester and kyzooghost authored Dec 17, 2024
1 parent 29a8d19 commit edca267
Show file tree
Hide file tree
Showing 8 changed files with 597 additions and 0 deletions.
16 changes: 16 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,22 @@ deploy-l2-test-erc20:
TEST_ERC20_INITIAL_SUPPLY=100000 \
npx ts-node local-deployments-artifacts/deployTestERC20.ts

deploy-l2-evm-opcode-tester:
# WARNING: FOR LOCAL DEV ONLY - DO NOT REUSE THESE KEYS ELSEWHERE
cd contracts/; \
PRIVATE_KEY=0x1dd171cec7e2995408b5513004e8207fe88d6820aeff0d82463b3e41df251aae \
RPC_URL=http:\\localhost:8545/ \
npx ts-node local-deployments-artifacts/deployLondonEvmTestingFramework.ts

execute-all-opcodes:
# WARNING: FOR LOCAL DEV ONLY - DO NOT REUSE THESE KEYS ELSEWHERE
cd contracts/; \
OPCODE_TEST_CONTRACT_ADDRESS=0x997FC3aF1F193Cbdc013060076c67A13e218980e \
NUMBER_OF_RUNS=3 \
PRIVATE_KEY=0x1dd171cec7e2995408b5513004e8207fe88d6820aeff0d82463b3e41df251aae \
RPC_URL=http:\\localhost:8545/ \
npx ts-node local-deployments-artifacts/executeAllOpcodes.ts

fresh-start-l2-blockchain-only:
make clean-environment
make start-l2-blockchain-only
Expand Down
12 changes: 12 additions & 0 deletions contracts/contracts/test-contracts/ErrorAndDestructionTesting.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// SPDX-License-Identifier: AGPL-3.0
pragma solidity 0.8.19;

contract ErrorAndDestructionTesting {
function externalRevert() external pure {
revert("OPCODE FD");
}

function callmeToSelfDestruct() external {
selfdestruct(payable(address(0)));
}
}
100 changes: 100 additions & 0 deletions contracts/contracts/test-contracts/LondonEvmCodes.yul
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
// This has been compiled on REMIX without the optimization and stored as contracts/local-deployments-artifacts/static-artifacts/LondonEvmCodes.json
// If you copy the bytecode from the verbatim_0i_0o section and open in https://evm.codes you can step through the entire execution.
// Compiler: 0.8.19, no optimizations and London EVM Version

object "DynamicBytecode" {
code {
datacopy(0x00, dataoffset("runtime"), datasize("runtime"))
return(0x00, datasize("runtime"))
}

object "runtime" {
code {
switch selector()
case 0xa378ff3e // executeAll()
{
doExternalCallsAndMStore8()
executeOpcodes()
}

default {
// if the function signature sent does not match any
revert(0, 0)
}

function doExternalCallsAndMStore8(){

// Using a random function on an EOA for all calls other than the embedded staticcall in the verbatim code to the precompile
// - should be a successful call for all.

let callSelector := 0xfed44325

// Load the free memory pointer
let ptr := mload(0x40)

// Store the selector in memory at the pointer location
mstore(ptr, callSelector)

// Perform the call
let success := call(
gas(), // Forward all available gas
0x55, // Random address
0, // No Ether to transfer
ptr, // Pointer to input data (selector)
0x04, // Input size (4 bytes for the selector)
0, // No output data
0 // No output size
)

// Handle the call result
if iszero(success) {
revert(0, 0) // Revert with no message if the call fails
}

success := callcode(
gas(), // Forward all available gas
0x55, // Random address
0, // No Ether to transfer
ptr, // Pointer to input data (selector)
0x04, // Input size (4 bytes for the selector)
0, // No output data
0 // No output size
)

// Handle the call result
if iszero(success) {
revert(0, 0) // Revert with no message if the call fails
}

success := delegatecall(
gas(), // Forward all available gas
0x55, // Random address
ptr, // Pointer to input data (selector)
0x04, // Input size (4 bytes for the selector)
0, // No output data
0 // No output size
)

// Handle the call result
if iszero(success) {
revert(0, 0) // Revert with no message if the call fails
}

ptr := add(ptr,0x4)

// Make sure MSTORE8 opcode is called
mstore8(ptr,0x1234567812345678)
}

function executeOpcodes() {
// Verbatim bytecode to do most of London including the precompile and control flow opcodes:
verbatim_0i_0o(hex"602060206001601f600263ffffffffFA5060006000600042F550600060006000F050600060006000600060006000A460006000600060006000A36000600060006000A2600060006000A160006000A0585059505A50426000556000545060004050415042504350445045504650475048507300000000000000000000000000000000000000003F506000600060003E6000600060007300000000000000000000000000000000000000003C3D507300000000000000000000000000000000000000003B5060016001016001026003036001046001056001066001076001600108600160010960020160030A60010B600810600A11600112600113600114156001166001176001181960161A60011B60011C60011D506000600020303132333450505050503635600060003738604051600081016000600083393A50505050607e50617e0150627e012350637e01234550647e0123456750657e012345678950667e0123456789AB50677e0123456789ABCD50687e0123456789ABCDEF50697e0123456789ABCDEF01506a7e0123456789ABCDEF0123506b7e0123456789ABCDEF012345506c7e0123456789ABCDEF01234567506d7e0123456789ABCDEF0123456789506e7e0123456789ABCDEF0123456789AB506f7e0123456789ABCDEF0123456789ABCD50707e0123456789ABCDEF0123456789ABCDEF50717e0123456789ABCDEF0123456789ABCDEF0150727e0123456789ABCDEF0123456789ABCDEF012350737e0123456789ABCDEF0123456789ABCDEF01234550747e0123456789ABCDEF0123456789ABCDEF0123456750757e0123456789ABCDEF0123456789ABCDEF012345678950767e0123456789ABCDEF0123456789ABCDEF0123456789AB50777e0123456789ABCDEF0123456789ABCDEF0123456789ABCD50787e0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF50797e0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF01507a7e0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123507b7e0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF012345507c7e0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF01234567507d7e0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789507e0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCD507f0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f5050505050505050505050505050505050")
}

// Return the function selector: the first 4 bytes of the call data
function selector() -> s {
s := div(calldataload(0), 0x100000000000000000000000000000000000000000000000000000000)
}
}
}
}
Loading

0 comments on commit edca267

Please sign in to comment.