Skip to content

Commit

Permalink
fix(levm): addmod non-compliance (#1309)
Browse files Browse the repository at this point in the history
Resolves #1292
Resolves #1294
  • Loading branch information
ilitteri authored Nov 27, 2024
1 parent 304cafc commit 3b93170
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 13 deletions.
22 changes: 9 additions & 13 deletions crates/vm/levm/src/opcode_handlers/arithmetic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -169,20 +169,16 @@ impl VM {

let augend = current_call_frame.stack.pop()?;
let addend = current_call_frame.stack.pop()?;
let divisor = current_call_frame.stack.pop()?;
if divisor.is_zero() {
current_call_frame.stack.push(U256::zero())?;
return Ok(OpcodeSuccess::Continue);
}
let (sum, overflow) = augend.overflowing_add(addend);
let mut remainder = sum.checked_rem(divisor).ok_or(VMError::Internal(
InternalError::ArithmeticOperationDividedByZero,
))?; // Cannot be zero bc if above;
if overflow || remainder > divisor {
remainder = remainder.overflowing_sub(divisor).0;
}
let modulus = current_call_frame.stack.pop()?;

current_call_frame.stack.push(remainder)?;
let new_augend = augend.checked_rem(modulus).unwrap_or_default();
let new_addend = addend.checked_rem(modulus).unwrap_or_default();

let (sum, _overflowed) = new_augend.overflowing_add(new_addend);

let sum_mod = sum.checked_rem(modulus).unwrap_or_default();

current_call_frame.stack.push(sum_mod)?;

Ok(OpcodeSuccess::Continue)
}
Expand Down
38 changes: 38 additions & 0 deletions crates/vm/levm/tests/edge_case_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -173,3 +173,41 @@ fn test_non_compliance_calldatacopy_memory_resize() {
U256::from(64)
);
}

#[test]
fn test_non_compliance_addmod() {
let mut vm = new_vm_with_bytecode(Bytes::copy_from_slice(&[
0x60, 0x01, 0x60, 5, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 8,
]))
.unwrap();
let mut current_call_frame = vm.call_frames.pop().unwrap();
vm.execute(&mut current_call_frame);
assert_eq!(
current_call_frame.stack.stack.first().unwrap(),
&U256::zero()
);
}

#[test]
fn test_non_compliance_addmod2() {
let mut vm = new_vm_with_bytecode(Bytes::copy_from_slice(&[
// PUSH20 divisor
0x73, 0x12, 0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56, 0x78,
0x90, 0x12, 0x34, 0x56, 0x78, 0x90, // PUSH1 addend
0x60, 0x08, // PUSH32 augend
0x7F, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xfd, // ADDMOD opcode
0x08, // STOP opcode
0x00,
]))
.unwrap();
let mut current_call_frame = vm.call_frames.pop().unwrap();
vm.execute(&mut current_call_frame);
assert_eq!(
current_call_frame.stack.stack.first().unwrap(),
&U256::from("0xfc7490ee00fc74a0ee00fc7490ee00fc7490ee5")
);
}

0 comments on commit 3b93170

Please sign in to comment.