Skip to content

Commit d28d552

Browse files
authored
Merge pull request #16387 from argotorg/evm_instruction_interpreter_kiss_immutables
EVM instruction interpreter: Add loadimmutable and setimmutable mocks, improve linkersymbol
2 parents fafa321 + 940aa92 commit d28d552

File tree

4 files changed

+51
-0
lines changed

4 files changed

+51
-0
lines changed
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
// yields some value based on the hash of the argument literal
3+
let value := linkersymbol("address")
4+
mstore(0, value)
5+
}
6+
// ----
7+
// Trace:
8+
// Memory dump:
9+
// 0: 421683f821a0574472445355be6d2b769119e8515f8376a1d7878523dfdecf7b
10+
// Storage dump:
11+
// Transient storage dump:
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
// yields some value based on the hash of the argument literal
3+
let value := loadimmutable("address")
4+
mstore(0, value)
5+
}
6+
// ----
7+
// Trace:
8+
// Memory dump:
9+
// 0: 421683f821a0574472445355be6d2b769119e8515f8376a1d7878523dfdecf7b
10+
// Storage dump:
11+
// Transient storage dump:
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
// implemented as no-op
3+
setimmutable(42, "42", 42)
4+
}
5+
// ----
6+
// Trace:
7+
// Memory dump:
8+
// Storage dump:
9+
// Transient storage dump:

test/tools/yulInterpreter/EVMInstructionInterpreter.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -562,6 +562,26 @@ u256 EVMInstructionInterpreter::evalBuiltin(
562562
std::string const placeholder = formatLiteral(std::get<Literal>(_arguments[0]));
563563
h256 const identifier(keccak256(placeholder));
564564
m_linkerSymbols.emplace(identifier, placeholder);
565+
return u256(identifier);
566+
}
567+
568+
if (fun == "loadimmutable")
569+
{
570+
yulAssert(_arguments.size() == 1);
571+
yulAssert(std::holds_alternative<Literal>(_arguments[0]));
572+
std::string const identifier = formatLiteral(std::get<Literal>(_arguments[0]));
573+
// Return a deterministic value based on the identifier.
574+
// This is sufficient for differential fuzzing since the same identifier
575+
// will always return the same value, maintaining trace equivalence.
576+
return u256(h256(keccak256(identifier)));
577+
}
578+
579+
if (fun == "setimmutable")
580+
{
581+
yulAssert(_arguments.size() == 3);
582+
// No-op: The real implementation patches placeholder bytes in memory-loaded runtime code.
583+
// For differential fuzzing, this ensures correct code never fails (no false positives), though some
584+
// bugs in setimmutable handling may not be detected (potential false negatives).
565585
return 0;
566586
}
567587

0 commit comments

Comments
 (0)