From f11b720479b9a35c88b753ebe8cc9e7675641739 Mon Sep 17 00:00:00 2001 From: enitrat Date: Fri, 13 Sep 2024 16:23:02 +0200 Subject: [PATCH] fix: mcopy opcode --- crates/evm/src/instructions/memory_operations.cairo | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/crates/evm/src/instructions/memory_operations.cairo b/crates/evm/src/instructions/memory_operations.cairo index 659297291..09badfbcd 100644 --- a/crates/evm/src/instructions/memory_operations.cairo +++ b/crates/evm/src/instructions/memory_operations.cairo @@ -7,6 +7,7 @@ use evm::memory::MemoryTrait; use evm::model::vm::{VM, VMTrait}; use evm::stack::StackTrait; use evm::state::StateTrait; +use utils::helpers::ceil32; use utils::set::SetTrait; #[inline(always)] @@ -281,15 +282,17 @@ pub impl MemoryOperation of MemoryOperationTrait { /// Copy memory from one location to another. /// # Specification: https://www.evm.codes/#5e?fork=cancun fn exec_mcopy(ref self: VM) -> Result<(), EVMError> { - let size = self.stack.pop_usize()?; - let source_offset = self.stack.pop_usize()?; let dest_offset = self.stack.pop_usize()?; + let source_offset = self.stack.pop_usize()?; + let size = self.stack.pop_usize()?; + let words_size = (ceil32(size) / 32).into(); + let copy_gas_cost = gas::COPY * words_size; let memory_expansion = gas::memory_expansion( self.memory.size(), [(max(dest_offset, source_offset), size)].span() ); self.memory.ensure_length(memory_expansion.new_size); - self.charge_gas(gas::VERYLOW + memory_expansion.expansion_cost)?; + self.charge_gas(gas::VERYLOW + copy_gas_cost + memory_expansion.expansion_cost)?; if size == 0 { return Result::Ok(()); @@ -1039,9 +1042,9 @@ mod tests { vm.memory.store_with_expansion((*element).into(), source_offset + 0x20 * i); i += 1; }; - vm.stack.push(dest_offset.into()).expect('push failed'); - vm.stack.push(source_offset.into()).expect('push failed'); vm.stack.push(size.into()).expect('push failed'); + vm.stack.push(source_offset.into()).expect('push failed'); + vm.stack.push(dest_offset.into()).expect('push failed'); // When let expected_gas = gas::VERYLOW