Skip to content

Commit

Permalink
chore: move staticcall checks to builtins
Browse files Browse the repository at this point in the history
  • Loading branch information
DaniPopes committed Jul 18, 2024
1 parent 3018390 commit be78b9f
Show file tree
Hide file tree
Showing 4 changed files with 20 additions and 17 deletions.
2 changes: 1 addition & 1 deletion crates/revmc-builtins/src/ir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,7 @@ builtins! {
Sload = __revmc_builtin_sload(@[ecx] ptr, @[sp] ptr, u8) Some(u8),
Sstore = __revmc_builtin_sstore(@[ecx] ptr, @[sp] ptr, u8) Some(u8),
Msize = __revmc_builtin_msize(@[ecx] ptr) Some(usize),
Tstore = __revmc_builtin_tstore(@[ecx] ptr, @[sp] ptr) None,
Tstore = __revmc_builtin_tstore(@[ecx] ptr, @[sp] ptr) Some(u8),
Tload = __revmc_builtin_tload(@[ecx] ptr, @[sp] ptr) None,
Mcopy = __revmc_builtin_mcopy(@[ecx] ptr, @[sp] ptr) Some(u8),
Log = __revmc_builtin_log(@[ecx] ptr, @[sp_dyn] ptr, u8) Some(u8),
Expand Down
11 changes: 10 additions & 1 deletion crates/revmc-builtins/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,8 @@ pub unsafe extern "C" fn __revmc_builtin_sstore(
rev![index, value]: &mut [EvmWord; 2],
spec_id: SpecId,
) -> InstructionResult {
ensure_non_staticcall!(ecx);

let SStoreResult { original_value: original, present_value: old, new_value: new, is_cold } =
try_opt!(ecx.host.sstore(ecx.contract.target_address, index.to_u256(), value.to_u256()));

Expand All @@ -353,8 +355,10 @@ pub unsafe extern "C" fn __revmc_builtin_msize(ecx: &mut EvmContext<'_>) -> usiz
pub unsafe extern "C" fn __revmc_builtin_tstore(
ecx: &mut EvmContext<'_>,
rev![key, value]: &mut [EvmWord; 2],
) {
) -> InstructionResult {
ensure_non_staticcall!(ecx);
ecx.host.tstore(ecx.contract.target_address, key.to_u256(), value.to_u256());
InstructionResult::Continue
}

#[no_mangle]
Expand Down Expand Up @@ -384,6 +388,7 @@ pub unsafe extern "C" fn __revmc_builtin_log(
sp: *mut EvmWord,
n: u8,
) -> InstructionResult {
ensure_non_staticcall!(ecx);
assume!(n <= 4, "invalid log topic count: {n}");
let sp = sp.add(n as usize);
read_words!(sp, offset, len);
Expand Down Expand Up @@ -418,6 +423,8 @@ pub unsafe extern "C" fn __revmc_builtin_create(
spec_id: SpecId,
create_kind: CreateKind,
) -> InstructionResult {
ensure_non_staticcall!(ecx);

let len = match create_kind {
CreateKind::Create => 3,
CreateKind::Create2 => 4,
Expand Down Expand Up @@ -612,6 +619,8 @@ pub unsafe extern "C" fn __revmc_builtin_selfdestruct(
target: &mut EvmWord,
spec_id: SpecId,
) -> InstructionResult {
ensure_non_staticcall!(ecx);

let res = try_host!(ecx.host.selfdestruct(ecx.contract.target_address, target.to_address()));

// EIP-3529: Reduction in refunds
Expand Down
8 changes: 8 additions & 0 deletions crates/revmc-builtins/src/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,14 @@ macro_rules! gas_opt {
};
}

macro_rules! ensure_non_staticcall {
($ecx:expr) => {
if $ecx.is_static {
return InstructionResult::StateChangeDuringStaticCall;
}
};
}

macro_rules! ensure_memory {
($ecx:expr, $offset:expr, $len:expr) => {
match ensure_memory($ecx, $offset, $len) {
Expand Down
16 changes: 1 addition & 15 deletions crates/revmc/src/compiler/translate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -883,7 +883,6 @@ impl<'a, B: Backend> FunctionCx<'a, B> {
self.call_fallible_builtin(Builtin::Sload, &[self.ecx, sp, spec_id]);
}
op::SSTORE => {
self.fail_if_staticcall(InstructionResult::StateChangeDuringStaticCall);
let sp = self.sp_after_inputs();
let spec_id = self.const_spec_id();
self.call_fallible_builtin(Builtin::Sstore, &[self.ecx, sp, spec_id]);
Expand Down Expand Up @@ -955,9 +954,8 @@ impl<'a, B: Backend> FunctionCx<'a, B> {
let _ = self.call_builtin(Builtin::Tload, &[self.ecx, sp]);
}
op::TSTORE => {
self.fail_if_staticcall(InstructionResult::StateChangeDuringStaticCall);
let sp = self.sp_after_inputs();
let _ = self.call_builtin(Builtin::Tstore, &[self.ecx, sp]);
self.call_fallible_builtin(Builtin::Tstore, &[self.ecx, sp]);
}
op::MCOPY => {
let sp = self.sp_after_inputs();
Expand All @@ -981,7 +979,6 @@ impl<'a, B: Backend> FunctionCx<'a, B> {
op::SWAP1..=op::SWAP16 => self.swap(opcode - op::SWAP1 + 1),

op::LOG0..=op::LOG4 => {
self.fail_if_staticcall(InstructionResult::StateChangeDuringStaticCall);
let n = opcode - op::LOG0;
let sp = self.sp_after_inputs();
let n = self.bcx.iconst(self.i8_type, n as i64);
Expand Down Expand Up @@ -1024,7 +1021,6 @@ impl<'a, B: Backend> FunctionCx<'a, B> {
}
op::INVALID => goto_return!(fail InstructionResult::InvalidFEOpcode),
op::SELFDESTRUCT => {
self.fail_if_staticcall(InstructionResult::StateChangeDuringStaticCall);
let sp = self.sp_after_inputs();
let spec_id = self.const_spec_id();
self.call_fallible_builtin(Builtin::SelfDestruct, &[self.ecx, sp, spec_id]);
Expand Down Expand Up @@ -1082,15 +1078,6 @@ impl<'a, B: Backend> FunctionCx<'a, B> {
})
}

/// Returns an error if the current context is a static call.
fn fail_if_staticcall(&mut self, ret: InstructionResult) {
let ptr =
self.get_field(self.ecx, mem::offset_of!(EvmContext<'_>, is_static), "ecx.is_static");
let bool = self.bcx.type_int(1);
let is_static = self.bcx.load(bool, ptr, "is_static");
self.build_check(is_static, ret)
}

/// Duplicates the `n`th value from the top of the stack.
/// `n` cannot be `0`.
fn dup(&mut self, n: u8) {
Expand Down Expand Up @@ -1127,7 +1114,6 @@ impl<'a, B: Backend> FunctionCx<'a, B> {

/// `CREATE` or `CREATE2` instruction.
fn create_common(&mut self, create_kind: CreateKind) {
self.fail_if_staticcall(InstructionResult::StateChangeDuringStaticCall);
let sp = self.sp_after_inputs();
let spec_id = self.const_spec_id();
let create_kind = self.bcx.iconst(self.i8_type, create_kind as i64);
Expand Down

0 comments on commit be78b9f

Please sign in to comment.