-
Notifications
You must be signed in to change notification settings - Fork 48
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Chore] - opcode tester contracts (#447)
* 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 <[email protected]> Signed-off-by: The Dark Jester <[email protected]> * Update contracts/contracts/test-contracts/LondonEvmCodes.yul Co-authored-by: kyzooghost <[email protected]> Signed-off-by: The Dark Jester <[email protected]> * deduplicate rollingBlockDetailComputations * add missing bytecode and cleanup * order functions by usage order * correct loops --------- Signed-off-by: The Dark Jester <[email protected]> Co-authored-by: kyzooghost <[email protected]>
- Loading branch information
1 parent
29a8d19
commit edca267
Showing
8 changed files
with
597 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
12 changes: 12 additions & 0 deletions
12
contracts/contracts/test-contracts/ErrorAndDestructionTesting.sol
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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))); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) | ||
} | ||
} | ||
} | ||
} |
Oops, something went wrong.