Skip to content

Commit

Permalink
feat: add testing for call_helpers
Browse files Browse the repository at this point in the history
  • Loading branch information
Harsh Bajpai authored and Harsh Bajpai committed Nov 29, 2023
1 parent 430d8c2 commit 81a5114
Show file tree
Hide file tree
Showing 7 changed files with 312 additions and 3 deletions.
1 change: 0 additions & 1 deletion crates/contracts/src/tests/test_eoa.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ mod test_external_owned_account {
use core::array::SpanTrait;
use core::starknet::account::{Call, AccountContractDispatcher, AccountContractDispatcherTrait};


use evm::model::{Address, AddressTrait, ContractAccountTrait};
use evm::tests::test_utils::{
kakarot_address, evm_address, other_evm_address, other_starknet_address, eoa_address,
Expand Down
3 changes: 2 additions & 1 deletion crates/evm/src/call_helpers.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
use cmp::min;
use contracts::kakarot_core::KakarotCore;
use contracts::kakarot_core::interface::IKakarotCore;

use evm::context::{
ExecutionContext, Status, CallContext, CallContextTrait, ExecutionContextType,
ExecutionContextTrait
Expand All @@ -19,7 +20,7 @@ use utils::traits::{BoolIntoNumeric, U256TryIntoResult};

/// CallArgs is a subset of CallContext
/// Created in order to simplify setting up the call opcodes
#[derive(Drop)]
#[derive(Drop, PartialEq)]
struct CallArgs {
caller: Address,
code_address: Address,
Expand Down
7 changes: 7 additions & 0 deletions crates/evm/src/model/account.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use contracts::contract_account::{
use contracts::kakarot_core::kakarot::KakarotCore::KakarotCoreInternal;
use contracts::kakarot_core::kakarot::StoredAccountType;
use contracts::kakarot_core::{KakarotCore, IKakarotCore};

use evm::errors::{EVMError, CONTRACT_SYSCALL_FAILED};
use evm::model::contract_account::{ContractAccountTrait};
use evm::model::{Address, AddressTrait, AccountType};
Expand Down Expand Up @@ -72,6 +73,12 @@ impl AccountBuilderImpl of AccountBuilderTrait {
self
}

#[inline(always)]
fn set_balance(mut self: AccountBuilder, balance: u256) -> AccountBuilder {
self.account.balance = balance;
self
}

/// Loads the bytecode of a ContractAccount from Kakarot Core's contract storage into a Span<u8>.
/// # Arguments
/// * `self` - The address of the Contract Account to load the bytecode from
Expand Down
2 changes: 2 additions & 0 deletions crates/evm/src/state.cairo
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use contracts::kakarot_core::{IKakarotCore, KakarotCore};

use evm::errors::{
EVMError, WRITE_SYSCALL_FAILED, READ_SYSCALL_FAILED, INSUFFICIENT_BALANCE, BALANCE_OVERFLOW
};
Expand Down Expand Up @@ -222,6 +223,7 @@ impl StateImpl of StateTrait {
#[inline(always)]
fn set_account(ref self: State, account: Account) {
let evm_address = account.evm_address();

self.accounts.write(evm_address.into(), account)
}

Expand Down
1 change: 1 addition & 0 deletions crates/evm/src/tests.cairo
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
mod test_call_helpers;
mod test_create_helpers;

mod test_execution;
Expand Down
297 changes: 297 additions & 0 deletions crates/evm/src/tests/test_call_helpers.cairo
Original file line number Diff line number Diff line change
@@ -0,0 +1,297 @@
use contracts::kakarot_core::interface::IExtendedKakarotCoreDispatcherTrait;

use contracts::tests::test_utils::setup_contracts_for_testing;
use core::box::BoxTrait;
use core::nullable::NullableTrait;
use core::result::ResultTrait;
use core::traits::Destruct;
use core::traits::TryInto;

use evm::call_helpers::{MachineCallHelpers, CallType, CallArgs};
use evm::machine::MachineTrait;
use evm::model::{Address, account::{AccountBuilderTrait}};
use evm::stack::StackTrait;
use evm::state::StateTrait;
use evm::tests::test_utils::{MachineBuilderTestTrait, test_address, other_evm_address};
use starknet::testing::set_contract_address;
use starknet::{contract_address_const, EthAddress};

#[test]
#[available_gas(20000000)]
fn test_prepare_call_type_call() {
let (_, kakarot_core) = setup_contracts_for_testing();

set_contract_address(kakarot_core.contract_address);

let caller_address = EthAddress { address: 0xabde2 };
let caller_address = Address {
evm: caller_address, starknet: kakarot_core.compute_starknet_address(caller_address)
};

let mut machine = MachineBuilderTestTrait::new_with_presets()
.with_caller(caller_address)
.build();

let gas: u128 = 1000;
let address = other_evm_address();
let value = 100;
let args_offset = 5;
let args_size = 1;
let ret_offset: usize = 15;
let ret_size: usize = 20;

machine.stack.push(ret_size.into());
machine.stack.push(ret_offset.into());
machine.stack.push(args_size);
machine.stack.push(args_offset);
machine.stack.push(value);
machine.stack.push(address.address.into());
machine.stack.push(gas.into());

let expected_call_args = CallArgs {
caller: test_address(),
code_address: Address {
evm: address, starknet: kakarot_core.compute_starknet_address(address)
},
to: Address { evm: address, starknet: kakarot_core.compute_starknet_address(address) },
gas,
value,
calldata: array![0x0].span(),
ret_offset,
ret_size,
should_transfer: true
};

let call_args = machine.prepare_call(@CallType::Call).unwrap();

assert(call_args == expected_call_args, 'wrong calls_args prepared');
}

#[test]
#[available_gas(20000000)]
fn test_prepare_call_type_delegate_call() {
let (_, kakarot_core) = setup_contracts_for_testing();

let caller_address = EthAddress { address: 0xabde2 };
let caller_address = Address {
evm: caller_address, starknet: kakarot_core.compute_starknet_address(caller_address)
};

set_contract_address(kakarot_core.contract_address);

let mut machine = MachineBuilderTestTrait::new_with_presets()
.with_caller(caller_address)
.build();

let gas: u128 = 1000;
let address = other_evm_address();
let args_offset = 5;
let args_size = 1;
let ret_offset: usize = 15;
let ret_size: usize = 20;

machine.stack.push(ret_size.into());
machine.stack.push(ret_offset.into());
machine.stack.push(args_size);
machine.stack.push(args_offset);
machine.stack.push(address.address.into());
machine.stack.push(gas.into());

let expected_call_args = CallArgs {
caller: caller_address,
code_address: Address {
evm: address, starknet: kakarot_core.compute_starknet_address(address)
},
to: Address {
evm: test_address().evm,
starknet: kakarot_core.compute_starknet_address(test_address().evm)
},
gas,
value: machine.call_ctx().value,
calldata: array![0x0].span(),
ret_offset,
ret_size,
should_transfer: false
};

let call_args = machine.prepare_call(@CallType::DelegateCall).unwrap();

assert(call_args == expected_call_args, 'wrong calls_args prepared');
}

#[test]
#[available_gas(20000000)]
fn test_prepare_call_type_call_code() {
let (_, kakarot_core) = setup_contracts_for_testing();

let caller_address = EthAddress { address: 0xabde2 };
let caller_address = Address {
evm: caller_address, starknet: kakarot_core.compute_starknet_address(caller_address)
};

set_contract_address(kakarot_core.contract_address);

let mut machine = MachineBuilderTestTrait::new_with_presets()
.with_caller(caller_address)
.build();

let gas: u128 = 1000;
let address = other_evm_address();
let value = 100;
let args_offset = 5;
let args_size = 1;
let ret_offset: usize = 15;
let ret_size: usize = 20;

machine.stack.push(ret_size.into());
machine.stack.push(ret_offset.into());
machine.stack.push(args_size);
machine.stack.push(args_offset);
machine.stack.push(value);
machine.stack.push(address.address.into());
machine.stack.push(gas.into());

let expected_call_args = CallArgs {
caller: test_address(),
code_address: Address {
evm: address, starknet: kakarot_core.compute_starknet_address(address)
},
to: Address {
evm: test_address().evm,
starknet: kakarot_core.compute_starknet_address(test_address().evm)
},
gas,
value: 100,
calldata: array![0x0].span(),
ret_offset,
ret_size,
should_transfer: false
};

let call_args = machine.prepare_call(@CallType::CallCode).unwrap();

assert(call_args == expected_call_args, 'wrong calls_args prepared');
}

#[test]
#[available_gas(20000000)]
fn test_prepare_call_type_static_call() {
let (_, kakarot_core) = setup_contracts_for_testing();

let caller_address = EthAddress { address: 0xabde2 };
let caller_address = Address {
evm: caller_address, starknet: kakarot_core.compute_starknet_address(caller_address)
};

set_contract_address(kakarot_core.contract_address);

let mut machine = MachineBuilderTestTrait::new_with_presets()
.with_caller(caller_address)
.build();

let gas: u128 = 1000;
let address = other_evm_address();
let args_offset = 5;
let args_size = 1;
let ret_offset: usize = 15;
let ret_size: usize = 20;

machine.stack.push(ret_size.into());
machine.stack.push(ret_offset.into());
machine.stack.push(args_size);
machine.stack.push(args_offset);
machine.stack.push(address.address.into());
machine.stack.push(gas.into());

let expected_call_args = CallArgs {
caller: test_address(),
code_address: Address {
evm: address, starknet: kakarot_core.compute_starknet_address(address)
},
to: Address {
evm: other_evm_address(),
starknet: kakarot_core.compute_starknet_address(other_evm_address())
},
gas,
value: 0,
calldata: array![0x0].span(),
ret_offset,
ret_size,
should_transfer: false
};

let call_args = machine.prepare_call(@CallType::StaticCall).unwrap();

assert(call_args == expected_call_args, 'wrong calls_args prepared');
}


#[test]
#[available_gas(20000000)]
fn test_init_call_sub_ctx() {
let (_, kakarot_core) = setup_contracts_for_testing();

set_contract_address(kakarot_core.contract_address);

let caller_address = EthAddress { address: 0xabde2 };
let caller_address = Address {
evm: caller_address, starknet: kakarot_core.compute_starknet_address(caller_address)
};

let mut machine = MachineBuilderTestTrait::new_with_presets()
.with_caller(caller_address)
.build();

let gas: u128 = 1000;
let address = other_evm_address();
let value = 100;
let args_offset = 5;
let args_size = 1;
let ret_offset: usize = 15;
let ret_size: usize = 20;

let call_args = CallArgs {
caller: test_address(),
code_address: Address {
evm: address, starknet: kakarot_core.compute_starknet_address(address)
},
to: Address { evm: address, starknet: kakarot_core.compute_starknet_address(address) },
gas,
value,
calldata: array![0x0].span(),
ret_offset,
ret_size,
should_transfer: true
};

let account = AccountBuilderTrait::new(machine.address()).set_balance(1000).build();
machine.state.set_account(account);

let sender_address = machine.address().evm;

let current_ctx_prev = machine.current_ctx.as_snapshot().unbox();
let ctx_count_prev = machine.ctx_count;

let sender_balance_prev = machine.state.get_account(sender_address).balance;
let reciver_balance_prev = machine.state.get_account(address).balance;

machine.init_call_sub_ctx(call_args, machine.call_ctx().read_only).unwrap();

let ctx_count_after = machine.ctx_count;

let sender_balance_after = machine.state.get_account(sender_address).balance;
let reciver_balance_after = machine.state.get_account(address).balance;

assert(
machine
.address() == Address {
evm: address, starknet: kakarot_core.compute_starknet_address(address)
},
'wrong execution context address'
);

assert(sender_balance_prev - sender_balance_after == 100, 'wrong sender balance');
assert(reciver_balance_after - reciver_balance_prev == 100, 'wrong reciever balance');

assert!(ctx_count_after - ctx_count_prev == 1, "ctx count increased by wrong value");
}
4 changes: 3 additions & 1 deletion crates/evm/src/tests/test_model.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ use contracts::tests::test_utils::{
setup_contracts_for_testing, fund_account_with_native_token, deploy_contract_account
};
use evm::model::account::AccountTrait;
use evm::model::{Address, Account, ContractAccountTrait, AccountType, EOATrait, AddressTrait};
use evm::model::{
Address, Account, ContractAccountTrait, AccountType, eoa::{EOATrait}, AddressTrait
};
use evm::tests::test_utils::{evm_address};
use openzeppelin::token::erc20::interface::IERC20CamelDispatcherTrait;
use starknet::testing::set_contract_address;
Expand Down

0 comments on commit 81a5114

Please sign in to comment.