-
Notifications
You must be signed in to change notification settings - Fork 1.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(script): add warning for address(this) usage #10295
base: master
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
very supportive, some questions.
wdyt @klkvr @grandizzy
crates/script/src/lib.rs
Outdated
/// An inspector that warns if the `ADDRESS` (0x30) opcode is used during script execution. | ||
#[derive(Debug, Clone, Default)] | ||
pub struct ScriptAddressWarnInspector; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we have this twice now
crates/script/src/lib.rs
Outdated
eprintln!("forge script warning: Usage of `address(this)` detected. Script contracts are ephemeral and their addresses should not be relied upon."); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps we also want a level style setting like "warn", "disallow" which could result in a revert?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah imo this should revert by default
if self.in_inner_context { | ||
return; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not obvious why we need this now
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah this seems wrong
&mut self.fuzzer, | ||
&mut self.tracer, | ||
&mut self.coverage, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why do we need to change this? I would prefer to not change order here without a strong reason
if self.in_inner_context { | ||
return; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah this seems wrong
crates/script/src/lib.rs
Outdated
@@ -629,6 +636,7 @@ impl ScriptConfig { | |||
if let Some((known_contracts, script_wallets, target)) = cheats_data { | |||
builder = builder.inspectors(|stack| { | |||
stack | |||
.address_warn_inspector(true) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
doesn't feel right to have this as a entire separate inspector in the stack given that it pretty much does one simple check
should we move it to Cheatcodes
@grandizzy ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was thinking that would make sense to be in a sepparate one but more generic ScriptExecutionInspector
where we could add more (maybe customizable checks like whitelist/blacklist addresses to call?) if needed?
crates/script/src/lib.rs
Outdated
fn step(&mut self, interp: &mut Interpreter, _data: &mut EvmState<'_>) -> InstructionResult { | ||
let opcode = interp.current_opcode(); | ||
if opcode == opcode::ADDRESS { | ||
// Using eprintln directly might be too noisy or not the standard way Foundry handles warnings. | ||
// Consider integrating with a logger or a dedicated warning mechanism if available. | ||
// For now, printing to stderr demonstrates the concept. | ||
eprintln!("forge script warning: Usage of `address(this)` detected. Script contracts are ephemeral and their addresses should not be relied upon."); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe right now this will emit warnings for any ADDRESS
usage in both tests and scripts
We want to only emit the warning if it's called in the context of script contract
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
guess an ScriptExecutionInspector
attached to script execution would handle this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can you pls add a test too?
Motivation
Closes #10289
Users can accidentally use
address(this)
withinforge script
contracts, often intending to refer to the script contract itself for operations like transferring ownership or sending tokens during deployment. However, theaddress(this)
in a script context refers to a temporary, locally deployed contract instance used for the simulation. This address does not exist on the target network and relying on it leads to deployment errors or incorrect state on-chain.This PR introduces a warning mechanism to alert users when
address(this)
is used during aforge script
execution, helping prevent these common mistakes.Solution
Introduced
ScriptAddressWarnInspector
:revm::Inspector
implementation namedScriptAddressWarnInspector
withincrates/evm/evm/src/inspectors/stack.rs
.step
method, which checks if the currently executing EVM opcode isADDRESS
(0x30).ADDRESS
opcode is detected, it prints a warning message tostderr
:"forge script warning: Usage of \
address(this)` detected. Script contracts are ephemeral and their addresses should not be relied upon."`Integrated into
InspectorStack
:address_warn_inspector
field to theInspectorStackInner
struct.address_warn
boolean flag and a builder method.address_warn_inspector(bool)
toInspectorStackBuilder
.InspectorStackBuilder::build
method to instantiateScriptAddressWarnInspector
if theaddress_warn
flag is true.Inspector
implementation forInspectorStackRefMut
to invoke thestep
method of theaddress_warn_inspector
if it's present.Enabled for
forge script
:crates/script/src/lib.rs
, within the_get_runner
function (which configures theExecutor
for scripts), modified theExecutorBuilder
chain to call.address_warn_inspector(true)
. This ensures the warning inspector is always active duringforge script
runs.This approach leverages the existing
revm
inspector system to passively detect the opcode usage without significantly impacting performance and provides a clear warning directly to the user during script execution.PR Checklist