From 40b1bda35c3ff588eb5ce5aad146e037b24d4fa5 Mon Sep 17 00:00:00 2001 From: SantiagoPittella Date: Tue, 4 Jul 2023 15:59:02 -0300 Subject: [PATCH 01/15] add erc20 --- src/testing/erc20.rs | 278 +++++++++++++++++++++++++++ src/testing/mod.rs | 1 + starknet_programs/cairo2/erc20.cairo | 188 ++++++++++++++++++ 3 files changed, 467 insertions(+) create mode 100644 src/testing/erc20.rs create mode 100644 starknet_programs/cairo2/erc20.cairo diff --git a/src/testing/erc20.rs b/src/testing/erc20.rs new file mode 100644 index 000000000..a93b0f233 --- /dev/null +++ b/src/testing/erc20.rs @@ -0,0 +1,278 @@ +#![allow(unused_imports)] +use std::{collections::HashMap, vec, io::Bytes}; + +use cairo_lang_starknet::casm_contract_class::CasmContractClass; +use cairo_vm::felt::felt_str; +use lazy_static::lazy_static; +use num_traits::Zero; +use starknet_contract_class::EntryPointType; +use crate::{ + definitions::{block_context::{BlockContext, StarknetChainId}, constants::CONSTRUCTOR_ENTRY_POINT_SELECTOR}, + state::{ + cached_state::CachedState, in_memory_state_reader::InMemoryStateReader, ExecutionResourcesManager, state_api::{State, StateReader}, + }, Felt252, transaction::{InvokeFunction, DeployAccount, error::TransactionError}, execution::{TransactionExecutionContext, execution_entry_point::ExecutionEntryPoint, CallType}, utils::calculate_sn_keccak, +}; +pub const ERC20_CONTRACT_PATH: &str = "starknet_programs/cairo2/ERC20.casm"; +use crate::{ + state::state_cache::StorageEntry, + utils::{felt_to_hash, Address, ClassHash}, +}; + +use super::{ + get_contract_class, new_starknet_block_context_for_testing, ACCOUNT_CONTRACT_PATH, ACTUAL_FEE, + TEST_ACCOUNT_CONTRACT_ADDRESS, TEST_ACCOUNT_CONTRACT_CLASS_HASH, TEST_CLASS_HASH, + TEST_CONTRACT_ADDRESS, TEST_CONTRACT_PATH, TEST_ERC20_ACCOUNT_BALANCE_KEY, + TEST_ERC20_CONTRACT_CLASS_HASH, +}; + +pub fn call_contract( + contract_address: Felt252, + entrypoint_selector: Felt252, + calldata: Vec, + state: &mut T, + block_context: BlockContext, + caller_address: Address, +) -> Result, TransactionError> { + let contract_address = Address(contract_address); + let class_hash = state.get_class_hash_at(&contract_address)?; + let nonce = state.get_nonce_at(&contract_address)?; + + // TODO: Revisit these parameters + let transaction_hash = 0.into(); + let signature = vec![]; + let max_fee = 1000000000; + let initial_gas = 1000000000; + let caller_address = caller_address; + let version = 0; + + let execution_entrypoint = ExecutionEntryPoint::new( + contract_address.clone(), + calldata, + entrypoint_selector, + caller_address, + EntryPointType::External, + Some(CallType::Delegate), + Some(class_hash), + initial_gas, + ); + + let mut tx_execution_context = TransactionExecutionContext::new( + contract_address, + transaction_hash, + signature, + max_fee, + nonce, + block_context.invoke_tx_max_n_steps(), + version.into(), + ); + + let call_info = execution_entrypoint.execute( + state, + &block_context, + &mut ExecutionResourcesManager::default(), + &mut tx_execution_context, + false, + )?; + + Ok(call_info.retdata) +} + +#[test] +fn deploy_erc20_cairo2_without_constructor() { + // INSERT ERC20 IN MEMORY + let program_data = include_bytes!("../../starknet_programs/cairo2/erc20.casm"); + let contract_class: CasmContractClass = serde_json::from_slice(program_data).unwrap(); + + let mut contract_class_cache = HashMap::new(); + + let address = Address(1111.into()); + let class_hash: ClassHash = [1; 32]; + let nonce = Felt252::zero(); + + contract_class_cache.insert(class_hash, contract_class); + let mut state_reader = InMemoryStateReader::default(); + state_reader + .address_to_class_hash_mut() + .insert(address.clone(), class_hash); + state_reader + .address_to_nonce_mut() + .insert(address.clone(), nonce); + + let mut state = CachedState::new(state_reader, None, Some(contract_class_cache)); + + // ACCOUNT 1 + let program_data_account = include_bytes!("../../starknet_programs/cairo2/hello_world_account.casm"); + let contract_class_account: CasmContractClass = serde_json::from_slice(program_data_account).unwrap(); + + state + .set_compiled_class( + &felt_str!("1"), + contract_class_account, + ) + .unwrap(); + + let contract_address_salt = + felt_str!("2669425616857739096022668060305620640217901643963991674344872184515580705509"); + + let internal_deploy_account = DeployAccount::new( + felt_str!("1") + .clone() + .to_be_bytes(), + 0, + 1.into(), + Felt252::zero(), + vec![2.into()], + vec![ + felt_str!( + "3233776396904427614006684968846859029149676045084089832563834729503047027074" + ), + felt_str!( + "707039245213420890976709143988743108543645298941971188668773816813012281203" + ), + ], + contract_address_salt, + StarknetChainId::TestNet.to_felt(), + None, + ) + .unwrap(); + + let account_address_1 = internal_deploy_account + .execute(&mut state, &Default::default()) + .unwrap().validate_info.unwrap().contract_address; + + println!("account_address_1: {:?}", account_address_1.clone()); + + // ACCOUNT 2 + let program_data_account = include_bytes!("../../starknet_programs/cairo2/hello_world_account.casm"); + let contract_class_account: CasmContractClass = serde_json::from_slice(program_data_account).unwrap(); + + state + .set_compiled_class( + &felt_str!("1"), + contract_class_account, + ) + .unwrap(); + + let contract_address_salt = + felt_str!("123123123123123"); + + let internal_deploy_account = DeployAccount::new( + felt_str!("1") + .clone() + .to_be_bytes(), + 0, + 1.into(), + Felt252::zero(), + vec![2.into()], + vec![ + felt_str!( + "3233776396904427614006684968846859029149676045084089832563834729503047027074" + ), + felt_str!( + "707039245213420890976709143988743108543645298941971188668773816813012281203" + ), + ], + contract_address_salt, + StarknetChainId::TestNet.to_felt(), + None, + ) + .unwrap(); + + let account_address_2 = internal_deploy_account + .execute(&mut state, &Default::default()) + .unwrap().validate_info.unwrap().contract_address; + + // END OF ACCOUNTS + + // CONSTRUCTOR CALLDATA FOR ERC20 + let name_ = Felt252::from_bytes_be(b"some-token"); + let symbol_ = Felt252::from_bytes_be(b"my-super-awesome-token"); + let decimals_ = Felt252::from(24); + let initial_supply = Felt252::from(1000); + let recipient = account_address_1.clone().0; + let calldata = vec![name_, symbol_, decimals_, initial_supply, recipient]; + + // CONSTRUCTOR + let _internal_deploy_account = DeployAccount::new( + class_hash + .clone(), + 0, + 1.into(), + Felt252::zero(), + calldata.clone(), + vec![ + felt_str!( + "3233776396904427614006684968846859029149676045084089832563834729503047027074" + ), + felt_str!( + "707039245213420890976709143988743108543645298941971188668773816813012281203" + ), + ], + felt_str!("123123123123123"), + StarknetChainId::TestNet.to_felt(), + None, + ) + .unwrap(); + + println!("deploying contract: {:?}", _internal_deploy_account); + + // let entrypoint_selector = Felt252::from_bytes_be(&calculate_sn_keccak(b"fake_constructor")); + // let _retdata = call_contract( + // address.0.clone(), + // entrypoint_selector.clone().into(), + // calldata, + // &mut state, + // BlockContext::default(), + // account_address_1.clone().into(), + // ) + // .unwrap(); + // println!("constructor retadata: {:?}", _retdata); + // println!("message: {:?}", std::str::from_utf8(&Felt252::to_be_bytes(&_retdata[0]))); + + // TRANSFER + let entrypoint_selector = Felt252::from_bytes_be(&calculate_sn_keccak(b"transfer")); + let calldata = vec![account_address_2.clone().0, Felt252::from(100)]; + + let _retdata = call_contract( + address.clone().0, + entrypoint_selector.clone().into(), + calldata, + &mut state, + BlockContext::default(), + account_address_1.clone().into(), + ) + .unwrap(); + + println!("transfer retadata: {:?}", _retdata); + println!("message: {:?}", std::str::from_utf8(&Felt252::to_be_bytes(&_retdata[0]))); + + // GET BALANCE ACCOUNT 1 + let entrypoint_selector = Felt252::from_bytes_be(&calculate_sn_keccak(b"balance_of")); + let retdata = call_contract( + address.clone().0, + entrypoint_selector.clone().into(), + vec![account_address_1.clone().0], + &mut state, + BlockContext::default(), + account_address_1.clone().into(), + ) + .unwrap(); + + println!("balance account 1: {:?}", retdata); + // GET BALANCE ACCOUNT 2 + let entrypoint_selector = Felt252::from_bytes_be(&calculate_sn_keccak(b"balance_of")); + let retdata = call_contract( + address.0, + entrypoint_selector.clone().into(), + vec![account_address_2.clone().0], + &mut state, + BlockContext::default(), + account_address_1.clone().into(), + ) + .unwrap(); + + println!("balance account 2: {:?}", retdata); + + println!("message: {:?}", std::str::from_utf8(&Felt252::to_be_bytes(&retdata[0]))); + assert_eq!(retdata, vec![89.into()]); +} diff --git a/src/testing/mod.rs b/src/testing/mod.rs index 60bda230d..5ff6f49b7 100644 --- a/src/testing/mod.rs +++ b/src/testing/mod.rs @@ -1,3 +1,4 @@ +pub mod erc20; pub mod state; pub mod state_error; pub mod type_utils; diff --git a/starknet_programs/cairo2/erc20.cairo b/starknet_programs/cairo2/erc20.cairo new file mode 100644 index 000000000..07bc77a9d --- /dev/null +++ b/starknet_programs/cairo2/erc20.cairo @@ -0,0 +1,188 @@ +use starknet::ContractAddress; + +#[starknet::interface] +trait IERC20 { + fn get_name(self: @TContractState) -> felt252; + fn get_symbol(self: @TContractState) -> felt252; + fn get_decimals(self: @TContractState) -> u8; + fn get_total_supply(self: @TContractState) -> u256; + fn balance_of(self: @TContractState, account: ContractAddress) -> u256; + fn allowance(self: @TContractState, owner: ContractAddress, spender: ContractAddress) -> u256; + fn transfer(ref self: TContractState, recipient: ContractAddress, amount: u256); + fn transfer_from( + ref self: TContractState, sender: ContractAddress, recipient: ContractAddress, amount: u256 + ); + fn approve(ref self: TContractState, spender: ContractAddress, amount: u256); + fn increase_allowance(ref self: TContractState, spender: ContractAddress, added_value: u256); + fn decrease_allowance( + ref self: TContractState, spender: ContractAddress, subtracted_value: u256 + ); +} + +#[starknet::contract] +mod erc_20 { + use zeroable::Zeroable; + use starknet::get_caller_address; + use starknet::contract_address_const; + use starknet::ContractAddress; + + #[storage] + struct Storage { + name: felt252, + symbol: felt252, + decimals: u8, + total_supply: u256, + balances: LegacyMap::, + allowances: LegacyMap::<(ContractAddress, ContractAddress), u256>, + } + + #[event] + #[derive(Drop, starknet::Event)] + enum Event { + Transfer: Transfer, + Approval: Approval, + } + #[derive(Drop, starknet::Event)] + struct Transfer { + from: ContractAddress, + to: ContractAddress, + value: u256, + } + #[derive(Drop, starknet::Event)] + struct Approval { + owner: ContractAddress, + spender: ContractAddress, + value: u256, + } + + #[constructor] + fn constructor( + ref self: ContractState, + name_: felt252, + symbol_: felt252, + decimals_: u8, + initial_supply: u256, + recipient: ContractAddress + ) { + self.name.write(name_); + self.symbol.write(symbol_); + self.decimals.write(decimals_); + assert(!recipient.is_zero(), 'ERC20: mint to the 0 address'); + self.total_supply.write(initial_supply); + self.balances.write(recipient, initial_supply); + self + .emit( + Event::Transfer( + Transfer { + from: contract_address_const::<0>(), to: recipient, value: initial_supply + } + ) + ); + } + + #[external(v0)] + impl IERC20Impl of super::IERC20 { + fn get_name(self: @ContractState) -> felt252 { + self.name.read() + } + + fn get_symbol(self: @ContractState) -> felt252 { + self.symbol.read() + } + + fn get_decimals(self: @ContractState) -> u8 { + self.decimals.read() + } + + fn get_total_supply(self: @ContractState) -> u256 { + self.total_supply.read() + } + + fn balance_of(self: @ContractState, account: ContractAddress) -> u256 { + self.balances.read(account) + } + + fn allowance( + self: @ContractState, owner: ContractAddress, spender: ContractAddress + ) -> u256 { + self.allowances.read((owner, spender)) + } + + fn transfer(ref self: ContractState, recipient: ContractAddress, amount: u256) { + let sender = get_caller_address(); + self.transfer_helper(sender, recipient, amount); + } + + fn transfer_from( + ref self: ContractState, + sender: ContractAddress, + recipient: ContractAddress, + amount: u256 + ) { + let caller = get_caller_address(); + self.spend_allowance(sender, caller, amount); + self.transfer_helper(sender, recipient, amount); + } + + fn approve(ref self: ContractState, spender: ContractAddress, amount: u256) { + let caller = get_caller_address(); + self.approve_helper(caller, spender, amount); + } + + fn increase_allowance( + ref self: ContractState, spender: ContractAddress, added_value: u256 + ) { + let caller = get_caller_address(); + self + .approve_helper( + caller, spender, self.allowances.read((caller, spender)) + added_value + ); + } + + fn decrease_allowance( + ref self: ContractState, spender: ContractAddress, subtracted_value: u256 + ) { + let caller = get_caller_address(); + self + .approve_helper( + caller, spender, self.allowances.read((caller, spender)) - subtracted_value + ); + } + } + + #[generate_trait] + impl StorageImpl of StorageTrait { + fn transfer_helper( + ref self: ContractState, + sender: ContractAddress, + recipient: ContractAddress, + amount: u256 + ) { + assert(!sender.is_zero(), 'ERC20: transfer from 0'); + assert(!recipient.is_zero(), 'ERC20: transfer to 0'); + self.balances.write(sender, self.balances.read(sender) - amount); + self.balances.write(recipient, self.balances.read(recipient) + amount); + self.emit(Transfer { from: sender, to: recipient, value: amount }); + } + + fn spend_allowance( + ref self: ContractState, owner: ContractAddress, spender: ContractAddress, amount: u256 + ) { + let current_allowance = self.allowances.read((owner, spender)); + let ONES_MASK = 0xffffffffffffffffffffffffffffffff_u128; + let is_unlimited_allowance = current_allowance.low == ONES_MASK + && current_allowance.high == ONES_MASK; + if !is_unlimited_allowance { + self.approve_helper(owner, spender, current_allowance - amount); + } + } + + fn approve_helper( + ref self: ContractState, owner: ContractAddress, spender: ContractAddress, amount: u256 + ) { + assert(!spender.is_zero(), 'ERC20: approve from 0'); + self.allowances.write((owner, spender), amount); + self.emit(Approval { owner, spender, value: amount }); + } + } +} From bcead42bebec045f6116f0139d5711114c806606 Mon Sep 17 00:00:00 2001 From: SantiagoPittella Date: Tue, 4 Jul 2023 16:10:39 -0300 Subject: [PATCH 02/15] use exec --- src/testing/erc20.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/testing/erc20.rs b/src/testing/erc20.rs index a93b0f233..210ccfefa 100644 --- a/src/testing/erc20.rs +++ b/src/testing/erc20.rs @@ -212,7 +212,7 @@ fn deploy_erc20_cairo2_without_constructor() { StarknetChainId::TestNet.to_felt(), None, ) - .unwrap(); + .unwrap().execute(&mut state, &Default::default()); println!("deploying contract: {:?}", _internal_deploy_account); From a50488080b21f5dd15e87fc5dc6e221a6356a329 Mon Sep 17 00:00:00 2001 From: SantiagoPittella Date: Tue, 4 Jul 2023 16:46:24 -0300 Subject: [PATCH 03/15] use deploy syscall --- src/testing/erc20.rs | 39 ++++++++----------- .../cairo2/hello_world_account.cairo | 16 ++++++++ 2 files changed, 33 insertions(+), 22 deletions(-) diff --git a/src/testing/erc20.rs b/src/testing/erc20.rs index 210ccfefa..6ac5db0f9 100644 --- a/src/testing/erc20.rs +++ b/src/testing/erc20.rs @@ -181,6 +181,8 @@ fn deploy_erc20_cairo2_without_constructor() { let account_address_2 = internal_deploy_account .execute(&mut state, &Default::default()) .unwrap().validate_info.unwrap().contract_address; + + println!("Account address 2: {:?}", account_address_2); // END OF ACCOUNTS @@ -190,32 +192,25 @@ fn deploy_erc20_cairo2_without_constructor() { let decimals_ = Felt252::from(24); let initial_supply = Felt252::from(1000); let recipient = account_address_1.clone().0; - let calldata = vec![name_, symbol_, decimals_, initial_supply, recipient]; + // let calldata = vec![name_, symbol_, decimals_, initial_supply, recipient]; // CONSTRUCTOR - let _internal_deploy_account = DeployAccount::new( - class_hash - .clone(), - 0, - 1.into(), - Felt252::zero(), - calldata.clone(), - vec![ - felt_str!( - "3233776396904427614006684968846859029149676045084089832563834729503047027074" - ), - felt_str!( - "707039245213420890976709143988743108543645298941971188668773816813012281203" - ), - ], - felt_str!("123123123123123"), - StarknetChainId::TestNet.to_felt(), - None, + let entrypoint_selector = Felt252::from_bytes_be(&calculate_sn_keccak(b"deploy")); + let erc20_salt = felt_str!("1234"); + let calldata = vec![Felt252::from_bytes_be(&class_hash), erc20_salt.clone(), name_.clone(), symbol_.clone(), decimals_.clone(), initial_supply.clone(), recipient.clone()]; + let erc20_account_address = call_contract( + account_address_1.clone().0, + entrypoint_selector.clone().into(), + calldata, + &mut state, + BlockContext::default(), + account_address_1.clone().into(), ) - .unwrap().execute(&mut state, &Default::default()); - - println!("deploying contract: {:?}", _internal_deploy_account); + .unwrap(); + + println!("erc20 contract address: {:?}", erc20_account_address); + println!("message: {:?}", std::str::from_utf8(&Felt252::to_be_bytes(&erc20_account_address[0]))); // let entrypoint_selector = Felt252::from_bytes_be(&calculate_sn_keccak(b"fake_constructor")); // let _retdata = call_contract( // address.0.clone(), diff --git a/starknet_programs/cairo2/hello_world_account.cairo b/starknet_programs/cairo2/hello_world_account.cairo index 117181cd0..b0c0392fe 100644 --- a/starknet_programs/cairo2/hello_world_account.cairo +++ b/starknet_programs/cairo2/hello_world_account.cairo @@ -19,6 +19,7 @@ trait IAccount { fn __validate_declare__(self: @TContractState, class_hash: felt252) -> felt252; fn __validate__(self: @TContractState, contract_address: ContractAddress, entry_point_selector: felt252, calldata: Array) -> felt252; fn __execute__(ref self: TContractState, calls: Array) -> Span; + fn deploy(self: @TContractState, class_hash: felt252, contract_address_salt: felt252, name_: felt252, symbol_: felt252, decimals: felt252, initial_supply: felt252, recipient: felt252) -> ContractAddress; } // Define the Account contract @@ -32,6 +33,11 @@ mod Account { use super::Call; use starknet::ContractAddress; use zeroable::Zeroable; + use starknet::syscalls::deploy_syscall; + use core::result::ResultTrait; + use starknet::class_hash::ClassHash; + use starknet::class_hash::Felt252TryIntoClassHash; + use traits::TryInto; // Define the contract's storage variables #[storage] @@ -58,6 +64,16 @@ mod Account { #[external(v0)] impl Account of super::IAccount { + fn deploy(self: @ContractState, class_hash: felt252, contract_address_salt: felt252, name_: felt252, symbol_: felt252, decimals: felt252, initial_supply: felt252, recipient: felt252) -> ContractAddress { + let mut calldata = ArrayTrait::new(); + calldata.append(name_); + calldata.append(symbol_); + calldata.append(decimals); + calldata.append(initial_supply); + calldata.append(recipient); + let (address0, _) = deploy_syscall(class_hash.try_into().unwrap(), contract_address_salt, calldata.span(), false).unwrap(); + address0 + } // Validate contract deployment fn __validate_deploy__( self: @ContractState, class_hash: felt252, contract_address_salt: felt252, public_key_: felt252 From ce09774dad0424192d8e5fdf9cb29e2880f8e307 Mon Sep 17 00:00:00 2001 From: SantiagoPittella Date: Tue, 4 Jul 2023 17:35:34 -0300 Subject: [PATCH 04/15] use proxy contract --- src/testing/erc20.rs | 139 +++++++++++++----- starknet_programs/cairo2/deploy_erc20.cairo | 36 +++++ .../cairo2/hello_world_account.cairo | 8 +- 3 files changed, 144 insertions(+), 39 deletions(-) create mode 100644 starknet_programs/cairo2/deploy_erc20.cairo diff --git a/src/testing/erc20.rs b/src/testing/erc20.rs index 6ac5db0f9..97d8e10b7 100644 --- a/src/testing/erc20.rs +++ b/src/testing/erc20.rs @@ -1,5 +1,5 @@ #![allow(unused_imports)] -use std::{collections::HashMap, vec, io::Bytes}; +use std::{collections::HashMap, vec, io::Bytes, path::Path}; use cairo_lang_starknet::casm_contract_class::CasmContractClass; use cairo_vm::felt::felt_str; @@ -10,7 +10,7 @@ use crate::{ definitions::{block_context::{BlockContext, StarknetChainId}, constants::CONSTRUCTOR_ENTRY_POINT_SELECTOR}, state::{ cached_state::CachedState, in_memory_state_reader::InMemoryStateReader, ExecutionResourcesManager, state_api::{State, StateReader}, - }, Felt252, transaction::{InvokeFunction, DeployAccount, error::TransactionError}, execution::{TransactionExecutionContext, execution_entry_point::ExecutionEntryPoint, CallType}, utils::calculate_sn_keccak, + }, Felt252, transaction::{InvokeFunction, DeployAccount, error::TransactionError}, execution::{TransactionExecutionContext, execution_entry_point::ExecutionEntryPoint, CallType}, utils::calculate_sn_keccak, services::api::contract_classes::deprecated_contract_class::ContractClass, }; pub const ERC20_CONTRACT_PATH: &str = "starknet_programs/cairo2/ERC20.casm"; use crate::{ @@ -79,26 +79,109 @@ pub fn call_contract( #[test] fn deploy_erc20_cairo2_without_constructor() { - // INSERT ERC20 IN MEMORY - let program_data = include_bytes!("../../starknet_programs/cairo2/erc20.casm"); - let contract_class: CasmContractClass = serde_json::from_slice(program_data).unwrap(); + // data to deploy + let erc20_class_hash: ClassHash = [2; 32]; + let test_data = include_bytes!("../../starknet_programs/cairo2/erc20.casm"); + let test_contract_class: CasmContractClass = serde_json::from_slice(test_data).unwrap(); - let mut contract_class_cache = HashMap::new(); + // Create the deploy contract class + let program_data = include_bytes!("../../starknet_programs/cairo2/deploy_erc20.casm"); + let contract_class: CasmContractClass = serde_json::from_slice(program_data).unwrap(); + let entrypoints = contract_class.clone().entry_points_by_type; + let entrypoint_selector = &entrypoints.external.get(0).unwrap().selector; + + // Create state reader with class hash data + let mut contract_class_cache = HashMap::new(); + + let address = Address(1111.into()); + let class_hash: ClassHash = [1; 32]; + let nonce = Felt252::zero(); + + contract_class_cache.insert(class_hash, contract_class); + contract_class_cache.insert(erc20_class_hash, test_contract_class.clone()); + + let mut state_reader = InMemoryStateReader::default(); + state_reader + .address_to_class_hash_mut() + .insert(address.clone(), class_hash); + state_reader + .address_to_nonce_mut() + .insert(address.clone(), nonce); + + // Create state from the state_reader and contract cache. + let mut state = CachedState::new(state_reader, None, Some(contract_class_cache)); + + let name_ = Felt252::from_bytes_be(b"some-token"); + let symbol_ = Felt252::from_bytes_be(b"my-super-awesome-token"); + let decimals_ = Felt252::from(24); + let initial_supply = Felt252::from(1000); + let recipient = felt_str!("397149464972449753182583229366244826403270781177748543857889179957856017275"); + let erc20_salt = felt_str!("1234"); + // arguments of deploy contract + let calldata = vec![Felt252::from_bytes_be(&class_hash), erc20_salt.clone(), name_.clone(), symbol_.clone(), decimals_.clone(), initial_supply.clone(), recipient.clone()]; + + // set up remaining structures + + let caller_address = Address(0000.into()); + let entry_point_type = EntryPointType::External; + + let exec_entry_point = ExecutionEntryPoint::new( + address, + calldata, + Felt252::new(entrypoint_selector.clone()), + caller_address, + entry_point_type, + Some(CallType::Delegate), + Some(class_hash), + 100_000_000, + ); + + // Execute the entrypoint + let block_context = BlockContext::default(); + let mut tx_execution_context = TransactionExecutionContext::new( + Address(0.into()), + Felt252::zero(), + Vec::new(), + 0, + 10.into(), + block_context.invoke_tx_max_n_steps(), + 1.into(), + ); + let mut resources_manager = ExecutionResourcesManager::default(); + + let call_info = exec_entry_point.execute( + &mut state, + &block_context, + &mut resources_manager, + &mut tx_execution_context, + false, + ).unwrap(); + let erc20_address = call_info.clone().retdata.get(0).unwrap().clone(); + println!("deploy erc20 call_info: {:?}", call_info); + println!("message: {:?}", std::str::from_utf8(&Felt252::to_be_bytes(&erc20_address))); + + + + // // INSERT ERC20 IN MEMORY + // let program_data = include_bytes!("../../starknet_programs/cairo2/erc20.casm"); + // let contract_class: CasmContractClass = serde_json::from_slice(program_data).unwrap(); + + // let mut contract_class_cache = HashMap::new(); - let address = Address(1111.into()); - let class_hash: ClassHash = [1; 32]; - let nonce = Felt252::zero(); + // let address = Address(1111.into()); + // let class_hash: ClassHash = [1; 32]; + // let nonce = Felt252::zero(); - contract_class_cache.insert(class_hash, contract_class); - let mut state_reader = InMemoryStateReader::default(); - state_reader - .address_to_class_hash_mut() - .insert(address.clone(), class_hash); - state_reader - .address_to_nonce_mut() - .insert(address.clone(), nonce); + // contract_class_cache.insert(class_hash, contract_class); + // let mut state_reader = InMemoryStateReader::default(); + // state_reader + // .address_to_class_hash_mut() + // .insert(address.clone(), class_hash); + // state_reader + // .address_to_nonce_mut() + // .insert(address.clone(), nonce); - let mut state = CachedState::new(state_reader, None, Some(contract_class_cache)); + // let mut state = CachedState::new(state_reader, None, Some(contract_class_cache)); // ACCOUNT 1 let program_data_account = include_bytes!("../../starknet_programs/cairo2/hello_world_account.casm"); @@ -183,8 +266,6 @@ fn deploy_erc20_cairo2_without_constructor() { .unwrap().validate_info.unwrap().contract_address; println!("Account address 2: {:?}", account_address_2); - - // END OF ACCOUNTS // CONSTRUCTOR CALLDATA FOR ERC20 let name_ = Felt252::from_bytes_be(b"some-token"); @@ -211,25 +292,13 @@ fn deploy_erc20_cairo2_without_constructor() { println!("erc20 contract address: {:?}", erc20_account_address); println!("message: {:?}", std::str::from_utf8(&Felt252::to_be_bytes(&erc20_account_address[0]))); - // let entrypoint_selector = Felt252::from_bytes_be(&calculate_sn_keccak(b"fake_constructor")); - // let _retdata = call_contract( - // address.0.clone(), - // entrypoint_selector.clone().into(), - // calldata, - // &mut state, - // BlockContext::default(), - // account_address_1.clone().into(), - // ) - // .unwrap(); - // println!("constructor retadata: {:?}", _retdata); - // println!("message: {:?}", std::str::from_utf8(&Felt252::to_be_bytes(&_retdata[0]))); // TRANSFER let entrypoint_selector = Felt252::from_bytes_be(&calculate_sn_keccak(b"transfer")); let calldata = vec![account_address_2.clone().0, Felt252::from(100)]; let _retdata = call_contract( - address.clone().0, + erc20_address.clone(), entrypoint_selector.clone().into(), calldata, &mut state, @@ -244,7 +313,7 @@ fn deploy_erc20_cairo2_without_constructor() { // GET BALANCE ACCOUNT 1 let entrypoint_selector = Felt252::from_bytes_be(&calculate_sn_keccak(b"balance_of")); let retdata = call_contract( - address.clone().0, + erc20_address.clone(), entrypoint_selector.clone().into(), vec![account_address_1.clone().0], &mut state, @@ -257,7 +326,7 @@ fn deploy_erc20_cairo2_without_constructor() { // GET BALANCE ACCOUNT 2 let entrypoint_selector = Felt252::from_bytes_be(&calculate_sn_keccak(b"balance_of")); let retdata = call_contract( - address.0, + erc20_address.clone(), entrypoint_selector.clone().into(), vec![account_address_2.clone().0], &mut state, diff --git a/starknet_programs/cairo2/deploy_erc20.cairo b/starknet_programs/cairo2/deploy_erc20.cairo new file mode 100644 index 000000000..ef9cb89da --- /dev/null +++ b/starknet_programs/cairo2/deploy_erc20.cairo @@ -0,0 +1,36 @@ +use starknet::contract_address::ContractAddress; +#[starknet::interface] +trait IDeployTest { + fn deploy_test(self: @TContractState, class_hash: felt252, contract_address_salt: felt252, name_: felt252, symbol_: felt252, decimals: felt252, initial_supply: felt252, recipient: felt252) -> ContractAddress; +} + +#[starknet::contract] +mod DeployTest { + use core::result::ResultTrait; + use starknet::syscalls::deploy_syscall; + use starknet::class_hash::ClassHash; + use starknet::contract_address::ContractAddress; + use starknet::class_hash::Felt252TryIntoClassHash; + use option::OptionTrait; + use traits::TryInto; + use array::ArrayTrait; + + + #[storage] + struct Storage { + } + + #[external(v0)] + impl DeployTest of super::IDeployTest { + fn deploy_test(self: @ContractState, class_hash: felt252, contract_address_salt: felt252, name_: felt252, symbol_: felt252, decimals: felt252, initial_supply: felt252, recipient: felt252) -> ContractAddress { + let mut calldata = ArrayTrait::new(); + calldata.append(name_); + calldata.append(symbol_); + calldata.append(decimals); + calldata.append(initial_supply); + calldata.append(recipient); + let (address0, _) = deploy_syscall(class_hash.try_into().unwrap(), contract_address_salt, calldata.span(), false).unwrap(); + address0 + } + } +} diff --git a/starknet_programs/cairo2/hello_world_account.cairo b/starknet_programs/cairo2/hello_world_account.cairo index b0c0392fe..c87651795 100644 --- a/starknet_programs/cairo2/hello_world_account.cairo +++ b/starknet_programs/cairo2/hello_world_account.cairo @@ -19,7 +19,7 @@ trait IAccount { fn __validate_declare__(self: @TContractState, class_hash: felt252) -> felt252; fn __validate__(self: @TContractState, contract_address: ContractAddress, entry_point_selector: felt252, calldata: Array) -> felt252; fn __execute__(ref self: TContractState, calls: Array) -> Span; - fn deploy(self: @TContractState, class_hash: felt252, contract_address_salt: felt252, name_: felt252, symbol_: felt252, decimals: felt252, initial_supply: felt252, recipient: felt252) -> ContractAddress; + fn deploy(self: @TContractState, class_hash: felt252, contract_address_salt: felt252, name_: felt252, symbol_: felt252, decimals: felt252, initial_supply: felt252, recipient: felt252) -> (ContractAddress, core::array::Span::); } // Define the Account contract @@ -64,15 +64,15 @@ mod Account { #[external(v0)] impl Account of super::IAccount { - fn deploy(self: @ContractState, class_hash: felt252, contract_address_salt: felt252, name_: felt252, symbol_: felt252, decimals: felt252, initial_supply: felt252, recipient: felt252) -> ContractAddress { + fn deploy(self: @ContractState, class_hash: felt252, contract_address_salt: felt252, name_: felt252, symbol_: felt252, decimals: felt252, initial_supply: felt252, recipient: felt252) -> (ContractAddress, core::array::Span::) { let mut calldata = ArrayTrait::new(); calldata.append(name_); calldata.append(symbol_); calldata.append(decimals); calldata.append(initial_supply); calldata.append(recipient); - let (address0, _) = deploy_syscall(class_hash.try_into().unwrap(), contract_address_salt, calldata.span(), false).unwrap(); - address0 + let (address0, something_else) = deploy_syscall(class_hash.try_into().unwrap(), contract_address_salt, calldata.span(), false).unwrap(); + (address0, something_else) } // Validate contract deployment fn __validate_deploy__( From 9189648f37f4a7e0cad8677f5e958eb32704f7ad Mon Sep 17 00:00:00 2001 From: SantiagoPittella Date: Tue, 4 Jul 2023 17:48:35 -0300 Subject: [PATCH 05/15] use erc class hash --- src/testing/erc20.rs | 4 ++-- starknet_programs/cairo2/deploy_erc20.cairo | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/testing/erc20.rs b/src/testing/erc20.rs index 97d8e10b7..677d22e8f 100644 --- a/src/testing/erc20.rs +++ b/src/testing/erc20.rs @@ -118,11 +118,11 @@ fn deploy_erc20_cairo2_without_constructor() { let recipient = felt_str!("397149464972449753182583229366244826403270781177748543857889179957856017275"); let erc20_salt = felt_str!("1234"); // arguments of deploy contract - let calldata = vec![Felt252::from_bytes_be(&class_hash), erc20_salt.clone(), name_.clone(), symbol_.clone(), decimals_.clone(), initial_supply.clone(), recipient.clone()]; + let calldata = vec![Felt252::from_bytes_be(&erc20_class_hash), erc20_salt.clone(), name_.clone(), symbol_.clone(), decimals_.clone(), initial_supply.clone(), recipient.clone()]; // set up remaining structures - let caller_address = Address(0000.into()); + let caller_address = Address(recipient.clone()); let entry_point_type = EntryPointType::External; let exec_entry_point = ExecutionEntryPoint::new( diff --git a/starknet_programs/cairo2/deploy_erc20.cairo b/starknet_programs/cairo2/deploy_erc20.cairo index ef9cb89da..403f2a038 100644 --- a/starknet_programs/cairo2/deploy_erc20.cairo +++ b/starknet_programs/cairo2/deploy_erc20.cairo @@ -29,6 +29,7 @@ mod DeployTest { calldata.append(decimals); calldata.append(initial_supply); calldata.append(recipient); + assert(calldata.len() == 5, 'Wrong calldata length'); let (address0, _) = deploy_syscall(class_hash.try_into().unwrap(), contract_address_salt, calldata.span(), false).unwrap(); address0 } From d5709d51c9a7ab9a1542e5b40e015d16ba369207 Mon Sep 17 00:00:00 2001 From: SantiagoPittella Date: Tue, 4 Jul 2023 18:36:50 -0300 Subject: [PATCH 06/15] fix test --- src/testing/erc20.rs | 49 +++++++------- starknet_programs/cairo2/deploy_erc20.cairo | 18 ++--- starknet_programs/cairo2/erc20.cairo | 74 ++++++++++----------- 3 files changed, 71 insertions(+), 70 deletions(-) diff --git a/src/testing/erc20.rs b/src/testing/erc20.rs index 677d22e8f..50181fb3f 100644 --- a/src/testing/erc20.rs +++ b/src/testing/erc20.rs @@ -118,11 +118,12 @@ fn deploy_erc20_cairo2_without_constructor() { let recipient = felt_str!("397149464972449753182583229366244826403270781177748543857889179957856017275"); let erc20_salt = felt_str!("1234"); // arguments of deploy contract - let calldata = vec![Felt252::from_bytes_be(&erc20_class_hash), erc20_salt.clone(), name_.clone(), symbol_.clone(), decimals_.clone(), initial_supply.clone(), recipient.clone()]; - + //let calldata = vec![Felt252::from_bytes_be(&erc20_class_hash), erc20_salt.clone(), name_.clone(), symbol_.clone(), decimals_.clone(), initial_supply.clone(), recipient.clone()]; + let calldata = vec![Felt252::from_bytes_be(&erc20_class_hash), erc20_salt.clone(), recipient.clone(), name_.clone(), decimals_.clone(), initial_supply.clone(), symbol_.clone()]; + //let calldata = vec![Felt252::from_bytes_be(&erc20_class_hash), erc20_salt.clone(), felt_str!("1")]; // set up remaining structures - let caller_address = Address(recipient.clone()); + let caller_address = Address(0000.into()); let entry_point_type = EntryPointType::External; let exec_entry_point = ExecutionEntryPoint::new( @@ -133,7 +134,7 @@ fn deploy_erc20_cairo2_without_constructor() { entry_point_type, Some(CallType::Delegate), Some(class_hash), - 100_000_000, + 100_000_000_000, ); // Execute the entrypoint @@ -268,30 +269,30 @@ fn deploy_erc20_cairo2_without_constructor() { println!("Account address 2: {:?}", account_address_2); // CONSTRUCTOR CALLDATA FOR ERC20 - let name_ = Felt252::from_bytes_be(b"some-token"); - let symbol_ = Felt252::from_bytes_be(b"my-super-awesome-token"); - let decimals_ = Felt252::from(24); - let initial_supply = Felt252::from(1000); - let recipient = account_address_1.clone().0; + // let name_ = Felt252::from_bytes_be(b"some-token"); + // let symbol_ = Felt252::from_bytes_be(b"my-super-awesome-token"); + // let decimals_ = Felt252::from(24); + // let initial_supply = Felt252::from(1000); + // let recipient = account_address_1.clone().0; // let calldata = vec![name_, symbol_, decimals_, initial_supply, recipient]; // CONSTRUCTOR - let entrypoint_selector = Felt252::from_bytes_be(&calculate_sn_keccak(b"deploy")); - let erc20_salt = felt_str!("1234"); - let calldata = vec![Felt252::from_bytes_be(&class_hash), erc20_salt.clone(), name_.clone(), symbol_.clone(), decimals_.clone(), initial_supply.clone(), recipient.clone()]; - let erc20_account_address = call_contract( - account_address_1.clone().0, - entrypoint_selector.clone().into(), - calldata, - &mut state, - BlockContext::default(), - account_address_1.clone().into(), - ) - .unwrap(); + // let entrypoint_selector = Felt252::from_bytes_be(&calculate_sn_keccak(b"deploy")); + // let erc20_salt = felt_str!("1234"); + // let calldata = vec![Felt252::from_bytes_be(&class_hash), erc20_salt.clone(), name_.clone(), symbol_.clone(), decimals_.clone(), initial_supply.clone(), recipient.clone()]; + // let erc20_account_address = call_contract( + // account_address_1.clone().0, + // entrypoint_selector.clone().into(), + // calldata, + // &mut state, + // BlockContext::default(), + // account_address_1.clone().into(), + // ) + // .unwrap(); - println!("erc20 contract address: {:?}", erc20_account_address); - println!("message: {:?}", std::str::from_utf8(&Felt252::to_be_bytes(&erc20_account_address[0]))); + println!("erc20 contract address: {:?}", erc20_address); + println!("message: {:?}", std::str::from_utf8(&Felt252::to_be_bytes(&erc20_address))); // TRANSFER let entrypoint_selector = Felt252::from_bytes_be(&calculate_sn_keccak(b"transfer")); @@ -308,7 +309,7 @@ fn deploy_erc20_cairo2_without_constructor() { .unwrap(); println!("transfer retadata: {:?}", _retdata); - println!("message: {:?}", std::str::from_utf8(&Felt252::to_be_bytes(&_retdata[0]))); + // println!("message: {:?}", std::str::from_utf8(&Felt252::to_be_bytes(&_retdata[0]))); // GET BALANCE ACCOUNT 1 let entrypoint_selector = Felt252::from_bytes_be(&calculate_sn_keccak(b"balance_of")); diff --git a/starknet_programs/cairo2/deploy_erc20.cairo b/starknet_programs/cairo2/deploy_erc20.cairo index 403f2a038..71e91ecd8 100644 --- a/starknet_programs/cairo2/deploy_erc20.cairo +++ b/starknet_programs/cairo2/deploy_erc20.cairo @@ -1,7 +1,8 @@ use starknet::contract_address::ContractAddress; +use starknet::class_hash::ClassHash; #[starknet::interface] trait IDeployTest { - fn deploy_test(self: @TContractState, class_hash: felt252, contract_address_salt: felt252, name_: felt252, symbol_: felt252, decimals: felt252, initial_supply: felt252, recipient: felt252) -> ContractAddress; + fn deploy_test(self: @TContractState, class_hash: ClassHash, contract_address_salt: felt252, recipient: felt252, name: felt252, decimals: felt252, initial_supply: felt252, symbol: felt252) -> (core::starknet::contract_address::ContractAddress, core::array::Span::); } #[starknet::contract] @@ -15,23 +16,22 @@ mod DeployTest { use traits::TryInto; use array::ArrayTrait; - #[storage] struct Storage { } #[external(v0)] impl DeployTest of super::IDeployTest { - fn deploy_test(self: @ContractState, class_hash: felt252, contract_address_salt: felt252, name_: felt252, symbol_: felt252, decimals: felt252, initial_supply: felt252, recipient: felt252) -> ContractAddress { + // fn deploy_test(self: @ContractState, class_hash: ClassHash, contract_address_salt: felt252, name_: felt252, symbol_: felt252, decimals: felt252, initial_supply: felt252, recipient: felt252) -> ContractAddress { + fn deploy_test(self: @ContractState, class_hash: ClassHash, contract_address_salt: felt252, recipient: felt252, name: felt252, decimals: felt252, initial_supply: felt252, symbol: felt252) -> (core::starknet::contract_address::ContractAddress, core::array::Span::) { let mut calldata = ArrayTrait::new(); - calldata.append(name_); - calldata.append(symbol_); + calldata.append(recipient); + calldata.append(name); calldata.append(decimals); calldata.append(initial_supply); - calldata.append(recipient); - assert(calldata.len() == 5, 'Wrong calldata length'); - let (address0, _) = deploy_syscall(class_hash.try_into().unwrap(), contract_address_salt, calldata.span(), false).unwrap(); - address0 + calldata.append(symbol); + // assert(calldata.len() == 5, 'Wrong calldata length'); + deploy_syscall(class_hash, contract_address_salt, calldata.span(), false).unwrap() } } } diff --git a/starknet_programs/cairo2/erc20.cairo b/starknet_programs/cairo2/erc20.cairo index 07bc77a9d..c17e9b2f3 100644 --- a/starknet_programs/cairo2/erc20.cairo +++ b/starknet_programs/cairo2/erc20.cairo @@ -5,17 +5,17 @@ trait IERC20 { fn get_name(self: @TContractState) -> felt252; fn get_symbol(self: @TContractState) -> felt252; fn get_decimals(self: @TContractState) -> u8; - fn get_total_supply(self: @TContractState) -> u256; - fn balance_of(self: @TContractState, account: ContractAddress) -> u256; - fn allowance(self: @TContractState, owner: ContractAddress, spender: ContractAddress) -> u256; - fn transfer(ref self: TContractState, recipient: ContractAddress, amount: u256); + fn get_total_supply(self: @TContractState) -> felt252; + fn balance_of(self: @TContractState, account: ContractAddress) -> felt252; + fn allowance(self: @TContractState, owner: ContractAddress, spender: ContractAddress) -> felt252; + fn transfer(ref self: TContractState, recipient: ContractAddress, amount: felt252); fn transfer_from( - ref self: TContractState, sender: ContractAddress, recipient: ContractAddress, amount: u256 + ref self: TContractState, sender: ContractAddress, recipient: ContractAddress, amount: felt252 ); - fn approve(ref self: TContractState, spender: ContractAddress, amount: u256); - fn increase_allowance(ref self: TContractState, spender: ContractAddress, added_value: u256); + fn approve(ref self: TContractState, spender: ContractAddress, amount: felt252); + fn increase_allowance(ref self: TContractState, spender: ContractAddress, added_value: felt252); fn decrease_allowance( - ref self: TContractState, spender: ContractAddress, subtracted_value: u256 + ref self: TContractState, spender: ContractAddress, subtracted_value: felt252 ); } @@ -31,9 +31,9 @@ mod erc_20 { name: felt252, symbol: felt252, decimals: u8, - total_supply: u256, - balances: LegacyMap::, - allowances: LegacyMap::<(ContractAddress, ContractAddress), u256>, + total_supply: felt252, + balances: LegacyMap::, + allowances: LegacyMap::<(ContractAddress, ContractAddress), felt252>, } #[event] @@ -46,27 +46,27 @@ mod erc_20 { struct Transfer { from: ContractAddress, to: ContractAddress, - value: u256, + value: felt252, } #[derive(Drop, starknet::Event)] struct Approval { owner: ContractAddress, spender: ContractAddress, - value: u256, + value: felt252, } #[constructor] fn constructor( ref self: ContractState, - name_: felt252, - symbol_: felt252, - decimals_: u8, - initial_supply: u256, - recipient: ContractAddress + recipient: ContractAddress, + name: felt252, + decimals: u8, + initial_supply: felt252, + symbol: felt252 ) { - self.name.write(name_); - self.symbol.write(symbol_); - self.decimals.write(decimals_); + self.name.write(name); + self.symbol.write(symbol); + self.decimals.write(decimals); assert(!recipient.is_zero(), 'ERC20: mint to the 0 address'); self.total_supply.write(initial_supply); self.balances.write(recipient, initial_supply); @@ -94,21 +94,21 @@ mod erc_20 { self.decimals.read() } - fn get_total_supply(self: @ContractState) -> u256 { + fn get_total_supply(self: @ContractState) -> felt252 { self.total_supply.read() } - fn balance_of(self: @ContractState, account: ContractAddress) -> u256 { + fn balance_of(self: @ContractState, account: ContractAddress) -> felt252 { self.balances.read(account) } fn allowance( self: @ContractState, owner: ContractAddress, spender: ContractAddress - ) -> u256 { + ) -> felt252 { self.allowances.read((owner, spender)) } - fn transfer(ref self: ContractState, recipient: ContractAddress, amount: u256) { + fn transfer(ref self: ContractState, recipient: ContractAddress, amount: felt252) { let sender = get_caller_address(); self.transfer_helper(sender, recipient, amount); } @@ -117,20 +117,20 @@ mod erc_20 { ref self: ContractState, sender: ContractAddress, recipient: ContractAddress, - amount: u256 + amount: felt252 ) { let caller = get_caller_address(); self.spend_allowance(sender, caller, amount); self.transfer_helper(sender, recipient, amount); } - fn approve(ref self: ContractState, spender: ContractAddress, amount: u256) { + fn approve(ref self: ContractState, spender: ContractAddress, amount: felt252) { let caller = get_caller_address(); self.approve_helper(caller, spender, amount); } fn increase_allowance( - ref self: ContractState, spender: ContractAddress, added_value: u256 + ref self: ContractState, spender: ContractAddress, added_value: felt252 ) { let caller = get_caller_address(); self @@ -140,7 +140,7 @@ mod erc_20 { } fn decrease_allowance( - ref self: ContractState, spender: ContractAddress, subtracted_value: u256 + ref self: ContractState, spender: ContractAddress, subtracted_value: felt252 ) { let caller = get_caller_address(); self @@ -156,7 +156,7 @@ mod erc_20 { ref self: ContractState, sender: ContractAddress, recipient: ContractAddress, - amount: u256 + amount: felt252 ) { assert(!sender.is_zero(), 'ERC20: transfer from 0'); assert(!recipient.is_zero(), 'ERC20: transfer to 0'); @@ -166,19 +166,19 @@ mod erc_20 { } fn spend_allowance( - ref self: ContractState, owner: ContractAddress, spender: ContractAddress, amount: u256 + ref self: ContractState, owner: ContractAddress, spender: ContractAddress, amount: felt252 ) { let current_allowance = self.allowances.read((owner, spender)); let ONES_MASK = 0xffffffffffffffffffffffffffffffff_u128; - let is_unlimited_allowance = current_allowance.low == ONES_MASK - && current_allowance.high == ONES_MASK; - if !is_unlimited_allowance { - self.approve_helper(owner, spender, current_allowance - amount); - } + // let is_unlimited_allowance = current_allowance.low == ONES_MASK + // && current_allowance.high == ONES_MASK; + // if !is_unlimited_allowance { + // self.approve_helper(owner, spender, current_allowance - amount); + // } } fn approve_helper( - ref self: ContractState, owner: ContractAddress, spender: ContractAddress, amount: u256 + ref self: ContractState, owner: ContractAddress, spender: ContractAddress, amount: felt252 ) { assert(!spender.is_zero(), 'ERC20: approve from 0'); self.allowances.write((owner, spender), amount); From 503220973ef0f282e29ad9f70efefc12466cea10 Mon Sep 17 00:00:00 2001 From: SantiagoPittella Date: Tue, 4 Jul 2023 20:02:52 -0300 Subject: [PATCH 07/15] add asserts --- src/testing/erc20.rs | 301 +++++++++++++++++++------------------------ 1 file changed, 133 insertions(+), 168 deletions(-) diff --git a/src/testing/erc20.rs b/src/testing/erc20.rs index 50181fb3f..9eef1840f 100644 --- a/src/testing/erc20.rs +++ b/src/testing/erc20.rs @@ -1,17 +1,30 @@ #![allow(unused_imports)] -use std::{collections::HashMap, vec, io::Bytes, path::Path}; +use std::{collections::HashMap, io::Bytes, path::Path, vec}; +use crate::{ + definitions::{ + block_context::{BlockContext, StarknetChainId}, + constants::CONSTRUCTOR_ENTRY_POINT_SELECTOR, + }, + execution::{ + execution_entry_point::ExecutionEntryPoint, CallType, TransactionExecutionContext, + }, + services::api::contract_classes::deprecated_contract_class::ContractClass, + state::{ + cached_state::CachedState, + in_memory_state_reader::InMemoryStateReader, + state_api::{State, StateReader}, + ExecutionResourcesManager, + }, + transaction::{error::TransactionError, DeployAccount, InvokeFunction}, + utils::calculate_sn_keccak, + Felt252, +}; use cairo_lang_starknet::casm_contract_class::CasmContractClass; use cairo_vm::felt::felt_str; use lazy_static::lazy_static; use num_traits::Zero; use starknet_contract_class::EntryPointType; -use crate::{ - definitions::{block_context::{BlockContext, StarknetChainId}, constants::CONSTRUCTOR_ENTRY_POINT_SELECTOR}, - state::{ - cached_state::CachedState, in_memory_state_reader::InMemoryStateReader, ExecutionResourcesManager, state_api::{State, StateReader}, - }, Felt252, transaction::{InvokeFunction, DeployAccount, error::TransactionError}, execution::{TransactionExecutionContext, execution_entry_point::ExecutionEntryPoint, CallType}, utils::calculate_sn_keccak, services::api::contract_classes::deprecated_contract_class::ContractClass, -}; pub const ERC20_CONTRACT_PATH: &str = "starknet_programs/cairo2/ERC20.casm"; use crate::{ state::state_cache::StorageEntry, @@ -78,130 +91,113 @@ pub fn call_contract( } #[test] -fn deploy_erc20_cairo2_without_constructor() { - // data to deploy - let erc20_class_hash: ClassHash = [2; 32]; - let test_data = include_bytes!("../../starknet_programs/cairo2/erc20.casm"); - let test_contract_class: CasmContractClass = serde_json::from_slice(test_data).unwrap(); - - // Create the deploy contract class - let program_data = include_bytes!("../../starknet_programs/cairo2/deploy_erc20.casm"); - let contract_class: CasmContractClass = serde_json::from_slice(program_data).unwrap(); - let entrypoints = contract_class.clone().entry_points_by_type; - let entrypoint_selector = &entrypoints.external.get(0).unwrap().selector; - - // Create state reader with class hash data - let mut contract_class_cache = HashMap::new(); - - let address = Address(1111.into()); - let class_hash: ClassHash = [1; 32]; - let nonce = Felt252::zero(); - - contract_class_cache.insert(class_hash, contract_class); - contract_class_cache.insert(erc20_class_hash, test_contract_class.clone()); - - let mut state_reader = InMemoryStateReader::default(); - state_reader - .address_to_class_hash_mut() - .insert(address.clone(), class_hash); - state_reader - .address_to_nonce_mut() - .insert(address.clone(), nonce); - - // Create state from the state_reader and contract cache. - let mut state = CachedState::new(state_reader, None, Some(contract_class_cache)); - - let name_ = Felt252::from_bytes_be(b"some-token"); - let symbol_ = Felt252::from_bytes_be(b"my-super-awesome-token"); - let decimals_ = Felt252::from(24); - let initial_supply = Felt252::from(1000); - let recipient = felt_str!("397149464972449753182583229366244826403270781177748543857889179957856017275"); - let erc20_salt = felt_str!("1234"); - // arguments of deploy contract - //let calldata = vec![Felt252::from_bytes_be(&erc20_class_hash), erc20_salt.clone(), name_.clone(), symbol_.clone(), decimals_.clone(), initial_supply.clone(), recipient.clone()]; - let calldata = vec![Felt252::from_bytes_be(&erc20_class_hash), erc20_salt.clone(), recipient.clone(), name_.clone(), decimals_.clone(), initial_supply.clone(), symbol_.clone()]; - //let calldata = vec![Felt252::from_bytes_be(&erc20_class_hash), erc20_salt.clone(), felt_str!("1")]; - // set up remaining structures - - let caller_address = Address(0000.into()); - let entry_point_type = EntryPointType::External; - - let exec_entry_point = ExecutionEntryPoint::new( - address, - calldata, - Felt252::new(entrypoint_selector.clone()), - caller_address, - entry_point_type, - Some(CallType::Delegate), - Some(class_hash), - 100_000_000_000, - ); - - // Execute the entrypoint - let block_context = BlockContext::default(); - let mut tx_execution_context = TransactionExecutionContext::new( - Address(0.into()), - Felt252::zero(), - Vec::new(), - 0, - 10.into(), - block_context.invoke_tx_max_n_steps(), - 1.into(), - ); - let mut resources_manager = ExecutionResourcesManager::default(); - - let call_info = exec_entry_point.execute( +fn test_erc20_cairo2() { + // data to deploy + let erc20_class_hash: ClassHash = [2; 32]; + let test_data = include_bytes!("../../starknet_programs/cairo2/erc20.casm"); + let test_contract_class: CasmContractClass = serde_json::from_slice(test_data).unwrap(); + + // Create the deploy contract class + let program_data = include_bytes!("../../starknet_programs/cairo2/deploy_erc20.casm"); + let contract_class: CasmContractClass = serde_json::from_slice(program_data).unwrap(); + let entrypoints = contract_class.clone().entry_points_by_type; + let entrypoint_selector = &entrypoints.external.get(0).unwrap().selector; + + // Create state reader with class hash data + let mut contract_class_cache = HashMap::new(); + + let address = Address(1111.into()); + let class_hash: ClassHash = [1; 32]; + let nonce = Felt252::zero(); + + contract_class_cache.insert(class_hash, contract_class); + contract_class_cache.insert(erc20_class_hash, test_contract_class.clone()); + + let mut state_reader = InMemoryStateReader::default(); + state_reader + .address_to_class_hash_mut() + .insert(address.clone(), class_hash); + state_reader + .address_to_nonce_mut() + .insert(address.clone(), nonce); + + // Create state from the state_reader and contract cache. + let mut state = CachedState::new(state_reader, None, Some(contract_class_cache)); + + let name_ = Felt252::from_bytes_be(b"some-token"); + let symbol_ = Felt252::from_bytes_be(b"my-super-awesome-token"); + let decimals_ = Felt252::from(24); + let initial_supply = Felt252::from(1000); + let recipient = + felt_str!("397149464972449753182583229366244826403270781177748543857889179957856017275"); + let erc20_salt = felt_str!("1234"); + // arguments of deploy contract + //let calldata = vec![Felt252::from_bytes_be(&erc20_class_hash), erc20_salt.clone(), name_.clone(), symbol_.clone(), decimals_.clone(), initial_supply.clone(), recipient.clone()]; + let calldata = vec![ + Felt252::from_bytes_be(&erc20_class_hash), + erc20_salt.clone(), + recipient.clone(), + name_.clone(), + decimals_.clone(), + initial_supply.clone(), + symbol_.clone(), + ]; + //let calldata = vec![Felt252::from_bytes_be(&erc20_class_hash), erc20_salt.clone(), felt_str!("1")]; + // set up remaining structures + + let caller_address = Address(0000.into()); + let entry_point_type = EntryPointType::External; + + let exec_entry_point = ExecutionEntryPoint::new( + address, + calldata, + Felt252::new(entrypoint_selector.clone()), + caller_address, + entry_point_type, + Some(CallType::Delegate), + Some(class_hash), + 100_000_000_000, + ); + + // Execute the entrypoint + let block_context = BlockContext::default(); + let mut tx_execution_context = TransactionExecutionContext::new( + Address(0.into()), + Felt252::zero(), + Vec::new(), + 0, + 10.into(), + block_context.invoke_tx_max_n_steps(), + 1.into(), + ); + let mut resources_manager = ExecutionResourcesManager::default(); + + let call_info = exec_entry_point + .execute( &mut state, &block_context, &mut resources_manager, &mut tx_execution_context, false, - ).unwrap(); - let erc20_address = call_info.clone().retdata.get(0).unwrap().clone(); - println!("deploy erc20 call_info: {:?}", call_info); - println!("message: {:?}", std::str::from_utf8(&Felt252::to_be_bytes(&erc20_address))); - - - - // // INSERT ERC20 IN MEMORY - // let program_data = include_bytes!("../../starknet_programs/cairo2/erc20.casm"); - // let contract_class: CasmContractClass = serde_json::from_slice(program_data).unwrap(); - - // let mut contract_class_cache = HashMap::new(); - - // let address = Address(1111.into()); - // let class_hash: ClassHash = [1; 32]; - // let nonce = Felt252::zero(); - - // contract_class_cache.insert(class_hash, contract_class); - // let mut state_reader = InMemoryStateReader::default(); - // state_reader - // .address_to_class_hash_mut() - // .insert(address.clone(), class_hash); - // state_reader - // .address_to_nonce_mut() - // .insert(address.clone(), nonce); - - // let mut state = CachedState::new(state_reader, None, Some(contract_class_cache)); + ) + .unwrap(); + let erc20_address = call_info.clone().retdata.get(0).unwrap().clone(); // ACCOUNT 1 - let program_data_account = include_bytes!("../../starknet_programs/cairo2/hello_world_account.casm"); - let contract_class_account: CasmContractClass = serde_json::from_slice(program_data_account).unwrap(); + let program_data_account = + include_bytes!("../../starknet_programs/cairo2/hello_world_account.casm"); + let contract_class_account: CasmContractClass = + serde_json::from_slice(program_data_account).unwrap(); state - .set_compiled_class( - &felt_str!("1"), - contract_class_account, - ) + .set_compiled_class(&felt_str!("1"), contract_class_account) .unwrap(); let contract_address_salt = felt_str!("2669425616857739096022668060305620640217901643963991674344872184515580705509"); let internal_deploy_account = DeployAccount::new( - felt_str!("1") - .clone() - .to_be_bytes(), + felt_str!("1").clone().to_be_bytes(), 0, 1.into(), Felt252::zero(), @@ -222,28 +218,25 @@ fn deploy_erc20_cairo2_without_constructor() { let account_address_1 = internal_deploy_account .execute(&mut state, &Default::default()) - .unwrap().validate_info.unwrap().contract_address; + .unwrap() + .validate_info + .unwrap() + .contract_address; - println!("account_address_1: {:?}", account_address_1.clone()); - // ACCOUNT 2 - let program_data_account = include_bytes!("../../starknet_programs/cairo2/hello_world_account.casm"); - let contract_class_account: CasmContractClass = serde_json::from_slice(program_data_account).unwrap(); + let program_data_account = + include_bytes!("../../starknet_programs/cairo2/hello_world_account.casm"); + let contract_class_account: CasmContractClass = + serde_json::from_slice(program_data_account).unwrap(); state - .set_compiled_class( - &felt_str!("1"), - contract_class_account, - ) + .set_compiled_class(&felt_str!("1"), contract_class_account) .unwrap(); - let contract_address_salt = - felt_str!("123123123123123"); + let contract_address_salt = felt_str!("123123123123123"); let internal_deploy_account = DeployAccount::new( - felt_str!("1") - .clone() - .to_be_bytes(), + felt_str!("1").clone().to_be_bytes(), 0, 1.into(), Felt252::zero(), @@ -264,39 +257,14 @@ fn deploy_erc20_cairo2_without_constructor() { let account_address_2 = internal_deploy_account .execute(&mut state, &Default::default()) - .unwrap().validate_info.unwrap().contract_address; - - println!("Account address 2: {:?}", account_address_2); - - // CONSTRUCTOR CALLDATA FOR ERC20 - // let name_ = Felt252::from_bytes_be(b"some-token"); - // let symbol_ = Felt252::from_bytes_be(b"my-super-awesome-token"); - // let decimals_ = Felt252::from(24); - // let initial_supply = Felt252::from(1000); - // let recipient = account_address_1.clone().0; - // let calldata = vec![name_, symbol_, decimals_, initial_supply, recipient]; - - // CONSTRUCTOR - // let entrypoint_selector = Felt252::from_bytes_be(&calculate_sn_keccak(b"deploy")); - // let erc20_salt = felt_str!("1234"); - // let calldata = vec![Felt252::from_bytes_be(&class_hash), erc20_salt.clone(), name_.clone(), symbol_.clone(), decimals_.clone(), initial_supply.clone(), recipient.clone()]; - // let erc20_account_address = call_contract( - // account_address_1.clone().0, - // entrypoint_selector.clone().into(), - // calldata, - // &mut state, - // BlockContext::default(), - // account_address_1.clone().into(), - // ) - // .unwrap(); - - - println!("erc20 contract address: {:?}", erc20_address); - println!("message: {:?}", std::str::from_utf8(&Felt252::to_be_bytes(&erc20_address))); + .unwrap() + .validate_info + .unwrap() + .contract_address; // TRANSFER let entrypoint_selector = Felt252::from_bytes_be(&calculate_sn_keccak(b"transfer")); - let calldata = vec![account_address_2.clone().0, Felt252::from(100)]; + let calldata = vec![account_address_2.clone().0, Felt252::from(123)]; let _retdata = call_contract( erc20_address.clone(), @@ -307,9 +275,8 @@ fn deploy_erc20_cairo2_without_constructor() { account_address_1.clone().into(), ) .unwrap(); - - println!("transfer retadata: {:?}", _retdata); - // println!("message: {:?}", std::str::from_utf8(&Felt252::to_be_bytes(&_retdata[0]))); + + assert_eq!(_retdata, []); // GET BALANCE ACCOUNT 1 let entrypoint_selector = Felt252::from_bytes_be(&calculate_sn_keccak(b"balance_of")); @@ -323,7 +290,8 @@ fn deploy_erc20_cairo2_without_constructor() { ) .unwrap(); - println!("balance account 1: {:?}", retdata); + assert_eq!(retdata, vec![877.into()]); + // GET BALANCE ACCOUNT 2 let entrypoint_selector = Felt252::from_bytes_be(&calculate_sn_keccak(b"balance_of")); let retdata = call_contract( @@ -336,8 +304,5 @@ fn deploy_erc20_cairo2_without_constructor() { ) .unwrap(); - println!("balance account 2: {:?}", retdata); - - println!("message: {:?}", std::str::from_utf8(&Felt252::to_be_bytes(&retdata[0]))); - assert_eq!(retdata, vec![89.into()]); + assert_eq!(retdata, vec![123.into()]); } From 7cb280ca3e2b5a6eaa1d5827cffc6cc882e4424e Mon Sep 17 00:00:00 2001 From: SantiagoPittella Date: Tue, 4 Jul 2023 20:09:00 -0300 Subject: [PATCH 08/15] clippy --- src/testing/erc20.rs | 38 ++++++++++++++++++-------------------- 1 file changed, 18 insertions(+), 20 deletions(-) diff --git a/src/testing/erc20.rs b/src/testing/erc20.rs index 9eef1840f..d05495716 100644 --- a/src/testing/erc20.rs +++ b/src/testing/erc20.rs @@ -111,7 +111,7 @@ fn test_erc20_cairo2() { let nonce = Felt252::zero(); contract_class_cache.insert(class_hash, contract_class); - contract_class_cache.insert(erc20_class_hash, test_contract_class.clone()); + contract_class_cache.insert(erc20_class_hash, test_contract_class); let mut state_reader = InMemoryStateReader::default(); state_reader @@ -132,17 +132,15 @@ fn test_erc20_cairo2() { felt_str!("397149464972449753182583229366244826403270781177748543857889179957856017275"); let erc20_salt = felt_str!("1234"); // arguments of deploy contract - //let calldata = vec![Felt252::from_bytes_be(&erc20_class_hash), erc20_salt.clone(), name_.clone(), symbol_.clone(), decimals_.clone(), initial_supply.clone(), recipient.clone()]; let calldata = vec![ Felt252::from_bytes_be(&erc20_class_hash), - erc20_salt.clone(), - recipient.clone(), - name_.clone(), - decimals_.clone(), - initial_supply.clone(), - symbol_.clone(), + erc20_salt, + recipient, + name_, + decimals_, + initial_supply, + symbol_, ]; - //let calldata = vec![Felt252::from_bytes_be(&erc20_class_hash), erc20_salt.clone(), felt_str!("1")]; // set up remaining structures let caller_address = Address(0000.into()); @@ -181,7 +179,7 @@ fn test_erc20_cairo2() { false, ) .unwrap(); - let erc20_address = call_info.clone().retdata.get(0).unwrap().clone(); + let erc20_address = call_info.retdata.get(0).unwrap().clone(); // ACCOUNT 1 let program_data_account = @@ -197,7 +195,7 @@ fn test_erc20_cairo2() { felt_str!("2669425616857739096022668060305620640217901643963991674344872184515580705509"); let internal_deploy_account = DeployAccount::new( - felt_str!("1").clone().to_be_bytes(), + felt_str!("1").to_be_bytes(), 0, 1.into(), Felt252::zero(), @@ -236,7 +234,7 @@ fn test_erc20_cairo2() { let contract_address_salt = felt_str!("123123123123123"); let internal_deploy_account = DeployAccount::new( - felt_str!("1").clone().to_be_bytes(), + felt_str!("1").to_be_bytes(), 0, 1.into(), Felt252::zero(), @@ -268,11 +266,11 @@ fn test_erc20_cairo2() { let _retdata = call_contract( erc20_address.clone(), - entrypoint_selector.clone().into(), + entrypoint_selector, calldata, &mut state, BlockContext::default(), - account_address_1.clone().into(), + account_address_1.clone(), ) .unwrap(); @@ -282,11 +280,11 @@ fn test_erc20_cairo2() { let entrypoint_selector = Felt252::from_bytes_be(&calculate_sn_keccak(b"balance_of")); let retdata = call_contract( erc20_address.clone(), - entrypoint_selector.clone().into(), + entrypoint_selector, vec![account_address_1.clone().0], &mut state, BlockContext::default(), - account_address_1.clone().into(), + account_address_1.clone(), ) .unwrap(); @@ -295,12 +293,12 @@ fn test_erc20_cairo2() { // GET BALANCE ACCOUNT 2 let entrypoint_selector = Felt252::from_bytes_be(&calculate_sn_keccak(b"balance_of")); let retdata = call_contract( - erc20_address.clone(), - entrypoint_selector.clone().into(), - vec![account_address_2.clone().0], + erc20_address, + entrypoint_selector, + vec![account_address_2.0], &mut state, BlockContext::default(), - account_address_1.clone().into(), + account_address_1, ) .unwrap(); From b13dd10ca17834831ee5aee8b51f68a81945863c Mon Sep 17 00:00:00 2001 From: SantiagoPittella Date: Wed, 5 Jul 2023 10:57:44 -0300 Subject: [PATCH 09/15] remove old crate dep --- src/testing/erc20.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/testing/erc20.rs b/src/testing/erc20.rs index d05495716..75e4b6755 100644 --- a/src/testing/erc20.rs +++ b/src/testing/erc20.rs @@ -18,13 +18,12 @@ use crate::{ }, transaction::{error::TransactionError, DeployAccount, InvokeFunction}, utils::calculate_sn_keccak, - Felt252, + EntryPointType, Felt252, }; use cairo_lang_starknet::casm_contract_class::CasmContractClass; use cairo_vm::felt::felt_str; use lazy_static::lazy_static; use num_traits::Zero; -use starknet_contract_class::EntryPointType; pub const ERC20_CONTRACT_PATH: &str = "starknet_programs/cairo2/ERC20.casm"; use crate::{ state::state_cache::StorageEntry, From c2e1ef4818f02298cc720a7eea078daecb80b6df Mon Sep 17 00:00:00 2001 From: Santiago Pittella <87827390+SantiagoPittella@users.noreply.github.com> Date: Wed, 5 Jul 2023 14:42:16 -0300 Subject: [PATCH 10/15] Update starknet_programs/cairo2/deploy_erc20.cairo MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Matías Ignacio González --- starknet_programs/cairo2/deploy_erc20.cairo | 1 - 1 file changed, 1 deletion(-) diff --git a/starknet_programs/cairo2/deploy_erc20.cairo b/starknet_programs/cairo2/deploy_erc20.cairo index 71e91ecd8..dc88a3c74 100644 --- a/starknet_programs/cairo2/deploy_erc20.cairo +++ b/starknet_programs/cairo2/deploy_erc20.cairo @@ -30,7 +30,6 @@ mod DeployTest { calldata.append(decimals); calldata.append(initial_supply); calldata.append(symbol); - // assert(calldata.len() == 5, 'Wrong calldata length'); deploy_syscall(class_hash, contract_address_salt, calldata.span(), false).unwrap() } } From 7f3ad159d02dc4a7c6c56d534e3b74cf03d0adc4 Mon Sep 17 00:00:00 2001 From: Santiago Pittella <87827390+SantiagoPittella@users.noreply.github.com> Date: Wed, 5 Jul 2023 14:42:26 -0300 Subject: [PATCH 11/15] Update starknet_programs/cairo2/deploy_erc20.cairo MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Matías Ignacio González --- starknet_programs/cairo2/deploy_erc20.cairo | 1 - 1 file changed, 1 deletion(-) diff --git a/starknet_programs/cairo2/deploy_erc20.cairo b/starknet_programs/cairo2/deploy_erc20.cairo index dc88a3c74..d62455c2c 100644 --- a/starknet_programs/cairo2/deploy_erc20.cairo +++ b/starknet_programs/cairo2/deploy_erc20.cairo @@ -22,7 +22,6 @@ mod DeployTest { #[external(v0)] impl DeployTest of super::IDeployTest { - // fn deploy_test(self: @ContractState, class_hash: ClassHash, contract_address_salt: felt252, name_: felt252, symbol_: felt252, decimals: felt252, initial_supply: felt252, recipient: felt252) -> ContractAddress { fn deploy_test(self: @ContractState, class_hash: ClassHash, contract_address_salt: felt252, recipient: felt252, name: felt252, decimals: felt252, initial_supply: felt252, symbol: felt252) -> (core::starknet::contract_address::ContractAddress, core::array::Span::) { let mut calldata = ArrayTrait::new(); calldata.append(recipient); From f8e8431afa6c6f1cc94f321e16eb1d78071c35ad Mon Sep 17 00:00:00 2001 From: Santiago Pittella <87827390+SantiagoPittella@users.noreply.github.com> Date: Wed, 5 Jul 2023 14:43:10 -0300 Subject: [PATCH 12/15] Update src/testing/erc20.rs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Matías Ignacio González --- src/testing/erc20.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/testing/erc20.rs b/src/testing/erc20.rs index 75e4b6755..c031f1abb 100644 --- a/src/testing/erc20.rs +++ b/src/testing/erc20.rs @@ -273,7 +273,7 @@ fn test_erc20_cairo2() { ) .unwrap(); - assert_eq!(_retdata, []); + assert!(retdata.is_empty()); // GET BALANCE ACCOUNT 1 let entrypoint_selector = Felt252::from_bytes_be(&calculate_sn_keccak(b"balance_of")); From e0ffa4e5bc30b7edfe85111472235db99428d716 Mon Sep 17 00:00:00 2001 From: Santiago Pittella <87827390+SantiagoPittella@users.noreply.github.com> Date: Wed, 5 Jul 2023 14:43:17 -0300 Subject: [PATCH 13/15] Update src/testing/erc20.rs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Matías Ignacio González --- src/testing/erc20.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/testing/erc20.rs b/src/testing/erc20.rs index c031f1abb..7744677f4 100644 --- a/src/testing/erc20.rs +++ b/src/testing/erc20.rs @@ -54,7 +54,6 @@ pub fn call_contract( let signature = vec![]; let max_fee = 1000000000; let initial_gas = 1000000000; - let caller_address = caller_address; let version = 0; let execution_entrypoint = ExecutionEntryPoint::new( From ff4b3bbe2386644de6c5ce8641c4bbf8bdc2ce62 Mon Sep 17 00:00:00 2001 From: Santiago Pittella <87827390+SantiagoPittella@users.noreply.github.com> Date: Wed, 5 Jul 2023 14:43:31 -0300 Subject: [PATCH 14/15] Update src/testing/erc20.rs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Matías Ignacio González --- src/testing/erc20.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/testing/erc20.rs b/src/testing/erc20.rs index 7744677f4..e728f6e6a 100644 --- a/src/testing/erc20.rs +++ b/src/testing/erc20.rs @@ -262,7 +262,7 @@ fn test_erc20_cairo2() { let entrypoint_selector = Felt252::from_bytes_be(&calculate_sn_keccak(b"transfer")); let calldata = vec![account_address_2.clone().0, Felt252::from(123)]; - let _retdata = call_contract( + let retdata = call_contract( erc20_address.clone(), entrypoint_selector, calldata, From efda09e714e11f1ef69b4d272ce2121e62260912 Mon Sep 17 00:00:00 2001 From: SantiagoPittella Date: Wed, 5 Jul 2023 14:49:45 -0300 Subject: [PATCH 15/15] remove duplicated function --- src/lib.rs | 3 ++- src/testing/erc20.rs | 52 +------------------------------------------- 2 files changed, 3 insertions(+), 52 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 6b0fc94f6..5bf63855b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -108,6 +108,7 @@ pub fn call_contract( calldata: Vec, state: &mut T, block_context: BlockContext, + caller_address: Address, ) -> Result, TransactionError> { let contract_address = Address(contract_address); let class_hash = state.get_class_hash_at(&contract_address)?; @@ -118,7 +119,6 @@ pub fn call_contract( let signature = vec![]; let max_fee = 1000000000; let initial_gas = 1000000000; - let caller_address = Address(0.into()); let version = 0; let execution_entrypoint = ExecutionEntryPoint::new( @@ -319,6 +319,7 @@ mod test { calldata, &mut state, BlockContext::default(), + Address(0.into()), ) .unwrap(); diff --git a/src/testing/erc20.rs b/src/testing/erc20.rs index e728f6e6a..60f8e4e8d 100644 --- a/src/testing/erc20.rs +++ b/src/testing/erc20.rs @@ -2,6 +2,7 @@ use std::{collections::HashMap, io::Bytes, path::Path, vec}; use crate::{ + call_contract, definitions::{ block_context::{BlockContext, StarknetChainId}, constants::CONSTRUCTOR_ENTRY_POINT_SELECTOR, @@ -37,57 +38,6 @@ use super::{ TEST_ERC20_CONTRACT_CLASS_HASH, }; -pub fn call_contract( - contract_address: Felt252, - entrypoint_selector: Felt252, - calldata: Vec, - state: &mut T, - block_context: BlockContext, - caller_address: Address, -) -> Result, TransactionError> { - let contract_address = Address(contract_address); - let class_hash = state.get_class_hash_at(&contract_address)?; - let nonce = state.get_nonce_at(&contract_address)?; - - // TODO: Revisit these parameters - let transaction_hash = 0.into(); - let signature = vec![]; - let max_fee = 1000000000; - let initial_gas = 1000000000; - let version = 0; - - let execution_entrypoint = ExecutionEntryPoint::new( - contract_address.clone(), - calldata, - entrypoint_selector, - caller_address, - EntryPointType::External, - Some(CallType::Delegate), - Some(class_hash), - initial_gas, - ); - - let mut tx_execution_context = TransactionExecutionContext::new( - contract_address, - transaction_hash, - signature, - max_fee, - nonce, - block_context.invoke_tx_max_n_steps(), - version.into(), - ); - - let call_info = execution_entrypoint.execute( - state, - &block_context, - &mut ExecutionResourcesManager::default(), - &mut tx_execution_context, - false, - )?; - - Ok(call_info.retdata) -} - #[test] fn test_erc20_cairo2() { // data to deploy