From 7d94e81bd10fa263be26e351a76c65965fb8bc28 Mon Sep 17 00:00:00 2001 From: ermvrs Date: Tue, 15 Oct 2024 15:03:44 +0300 Subject: [PATCH 1/3] tests init --- .snfoundry_cache/.prev_tests_failed | 1 + src/accounts/base.cairo | 23 ++++++++++++++++++++--- src/factory.cairo | 4 ++-- tests/factory_tests.cairo | 27 +++++++++++++++++++++++++++ tests/test_data.md | 5 +++++ 5 files changed, 55 insertions(+), 5 deletions(-) create mode 100644 tests/test_data.md diff --git a/.snfoundry_cache/.prev_tests_failed b/.snfoundry_cache/.prev_tests_failed index e69de29..5c7a929 100644 --- a/.snfoundry_cache/.prev_tests_failed +++ b/.snfoundry_cache/.prev_tests_failed @@ -0,0 +1 @@ +rosettacontracts_integrationtest::factory_tests::deploy_check_initials diff --git a/src/accounts/base.cairo b/src/accounts/base.cairo index e2064bf..3124614 100644 --- a/src/accounts/base.cairo +++ b/src/accounts/base.cairo @@ -1,4 +1,5 @@ pub type EthPublicKey = starknet::secp256k1::Secp256k1Point; +use starknet::EthAddress; #[starknet::interface] pub trait IRosettaAccount { fn __execute__(self: @TState, calls: Array) -> Array>; @@ -10,15 +11,17 @@ pub trait IRosettaAccount { self: @TState, class_hash: felt252, contract_address_salt: felt252, public_key: EthPublicKey ) -> felt252; fn get_public_key(self: @TState) -> EthPublicKey; + fn get_ethereum_address(self: @TState) -> EthAddress; fn set_public_key(ref self: TState, new_public_key: EthPublicKey, signature: Span); // Camel case fn isValidSignature(self: @TState, hash: felt252, signature: Array) -> felt252; fn getPublicKey(self: @TState) -> EthPublicKey; + fn getEthereumAddress(self: @TState) -> EthAddress; fn setPublicKey(ref self: TState, newPublicKey: EthPublicKey, signature: Span); } #[starknet::contract(account)] -mod RosettaAccount { +pub mod RosettaAccount { use super::EthPublicKey; use core::num::traits::Zero; use starknet::{ @@ -45,17 +48,23 @@ mod RosettaAccount { fn constructor(ref self: ContractState, eth_account: EthAddress) { self.ethereum_address.write(eth_account); } - + // TODO: Raw transaction tx.signature da, __execute__ parametresindede bit locationlar mı olacak?? #[abi(embed_v0)] impl AccountImpl of super::IRosettaAccount { // Instead of Array we use Array since we pass different values to the // parameter + // It is EOA execution so multiple calls are not possible + // calls params can include raw signed tx or can include the abi parsing bit locations for calldata fn __execute__(self: @ContractState, calls: Array) -> Array> { let sender = get_caller_address(); assert(sender.is_zero(), Errors::INVALID_CALLER); // TODO: Check tx version - // TODO: Exec calls + // TODO: Exec call + + // 1) Deserialize tx data from signature to get calldata and target contract. + // 2) Match the entrypoint and call contract with calldata parsed according this function bit size param + array![array!['todo'].span()] } fn __validate__(self: @ContractState, calls: Array) -> felt252 { @@ -96,6 +105,10 @@ mod RosettaAccount { self.ethereum_public_key.read() } + fn get_ethereum_address(self: @ContractState) -> EthAddress { + self.ethereum_address.read() + } + // We dont need that function fn set_public_key( ref self: ContractState, new_public_key: EthPublicKey, signature: Span @@ -111,6 +124,10 @@ mod RosettaAccount { self.get_public_key() } + fn getEthereumAddress(self: @ContractState) -> EthAddress { + self.get_ethereum_address() + } + // We dont need that function fn setPublicKey( ref self: ContractState, newPublicKey: EthPublicKey, signature: Span diff --git a/src/factory.cairo b/src/factory.cairo index 3ebc174..4b34acc 100644 --- a/src/factory.cairo +++ b/src/factory.cairo @@ -1,7 +1,7 @@ use starknet::{ContractAddress, ClassHash, EthAddress}; #[starknet::interface] -trait IFactory { +pub trait IFactory { fn lens(self: @TContractState) -> ContractAddress; fn current_account_class(self: @TContractState) -> ClassHash; fn precalculate_starknet_address(self: @TContractState, address: EthAddress) -> ContractAddress; @@ -9,7 +9,7 @@ trait IFactory { } #[starknet::contract] -mod Factory { +pub mod Factory { use core::option::OptionTrait; use starknet::{ContractAddress, ClassHash, EthAddress}; use starknet::syscalls::{deploy_syscall}; diff --git a/tests/factory_tests.cairo b/tests/factory_tests.cairo index 8b13789..b2b915b 100644 --- a/tests/factory_tests.cairo +++ b/tests/factory_tests.cairo @@ -1 +1,28 @@ +use openzeppelin_utils::serde::SerializedAppend; +use rosettacontracts::accounts::base::{RosettaAccount, IRosettaAccountDispatcher, IRosettaAccountDispatcherTrait}; +use rosettacontracts::factory::{Factory, IFactoryDispatcher, IFactoryDispatcherTrait}; +use snforge_std::{declare, get_class_hash, ContractClassTrait, DeclareResultTrait}; +#[test] +fn deploy_check_initials() { + let account_contract_class = declare("RosettaAccount").unwrap().contract_class(); + + let (account_contract_address, _) = account_contract_class.deploy(@array!['0']).unwrap(); + + let account_class_hash = get_class_hash(account_contract_address); + + let factory_contract_class = declare("Factory").unwrap().contract_class(); + + let mut factory_calldata = array![]; + + factory_calldata.append_serde(account_class_hash); + factory_calldata.append_serde('0'); + + let (factory_contract_address, _) = factory_contract_class.deploy(@factory_calldata).unwrap(); + + let factory_dispatcher = IFactoryDispatcher { contract_address: factory_contract_address }; + factory_dispatcher.current_account_class().print(); + account_class_hash.print(); + assert(factory_dispatcher.current_account_class() == account_class_hash, 'account class wrong'); + // TODO: burayı fixle neden hata dönüyor ve debug print ekle +} \ No newline at end of file diff --git a/tests/test_data.md b/tests/test_data.md new file mode 100644 index 0000000..bb703dc --- /dev/null +++ b/tests/test_data.md @@ -0,0 +1,5 @@ +### Eth Account used in tests +0x11655f4Ee2A5B66F9DCbe758e9FcdCd3eBF95eE5 +### Test transaction +[ ] Transfer or approve of standard erc20 in starknet +[ ] Account contruction etc. \ No newline at end of file From 5f3e890c6bd24863ca8b0a9f069f0a6a21b1118a Mon Sep 17 00:00:00 2001 From: ermvrs Date: Tue, 15 Oct 2024 20:31:30 +0300 Subject: [PATCH 2/3] test inits --- src/accounts/base.cairo | 2 +- src/factory.cairo | 2 ++ src/lens/lens_dev.cairo | 8 ++++---- tests/factory_tests.cairo | 18 ++++++++++-------- 4 files changed, 17 insertions(+), 13 deletions(-) diff --git a/src/accounts/base.cairo b/src/accounts/base.cairo index 3124614..7d0ec89 100644 --- a/src/accounts/base.cairo +++ b/src/accounts/base.cairo @@ -25,7 +25,7 @@ pub mod RosettaAccount { use super::EthPublicKey; use core::num::traits::Zero; use starknet::{ - EthAddress, get_execution_info, get_contract_address, get_caller_address, get_tx_info + EthAddress, get_contract_address, get_caller_address, get_tx_info }; use starknet::storage::{StoragePointerReadAccess, StoragePointerWriteAccess}; use rosettacontracts::accounts::utils::{is_valid_eth_signature, Secp256k1PointStorePacking}; diff --git a/src/factory.cairo b/src/factory.cairo index 4b34acc..14e0824 100644 --- a/src/factory.cairo +++ b/src/factory.cairo @@ -15,6 +15,7 @@ pub mod Factory { use starknet::syscalls::{deploy_syscall}; use core::traits::{Into, TryInto}; use openzeppelin::utils::deployments::{calculate_contract_address_from_deploy_syscall}; + use starknet::storage::{StoragePointerReadAccess, StoragePointerWriteAccess}; #[storage] struct Storage { @@ -60,6 +61,7 @@ pub mod Factory { ) } + // TODO: this funcation can be removed /// Deploys new rosettanet account. Fails if account already deployed /// # Params /// `address` - Ethereum Address that will be used to deploy starknet account. diff --git a/src/lens/lens_dev.cairo b/src/lens/lens_dev.cairo index 8da11ca..240b306 100644 --- a/src/lens/lens_dev.cairo +++ b/src/lens/lens_dev.cairo @@ -14,15 +14,15 @@ mod LensDev { use super::ILensDev; use starknet::{ContractAddress, EthAddress}; use core::poseidon::PoseidonTrait; - use core::hash::{HashStateTrait, HashStateExTrait}; + use core::hash::{HashStateTrait}; use core::traits::{Into, TryInto}; use core::num::traits::{Zero}; - + use starknet::storage::{Map}; #[storage] struct Storage { - eth_address_to_sn_address: LegacyMap::, - sn_address_to_eth_address: LegacyMap::, + eth_address_to_sn_address: Map, + sn_address_to_eth_address: Map, } #[constructor] diff --git a/tests/factory_tests.cairo b/tests/factory_tests.cairo index b2b915b..2816d72 100644 --- a/tests/factory_tests.cairo +++ b/tests/factory_tests.cairo @@ -2,27 +2,29 @@ use openzeppelin_utils::serde::SerializedAppend; use rosettacontracts::accounts::base::{RosettaAccount, IRosettaAccountDispatcher, IRosettaAccountDispatcherTrait}; use rosettacontracts::factory::{Factory, IFactoryDispatcher, IFactoryDispatcherTrait}; use snforge_std::{declare, get_class_hash, ContractClassTrait, DeclareResultTrait}; +use starknet::{EthAddress}; #[test] fn deploy_check_initials() { let account_contract_class = declare("RosettaAccount").unwrap().contract_class(); - let (account_contract_address, _) = account_contract_class.deploy(@array!['0']).unwrap(); - - let account_class_hash = get_class_hash(account_contract_address); - let factory_contract_class = declare("Factory").unwrap().contract_class(); let mut factory_calldata = array![]; - factory_calldata.append_serde(account_class_hash); + factory_calldata.append_serde('123123'); factory_calldata.append_serde('0'); let (factory_contract_address, _) = factory_contract_class.deploy(@factory_calldata).unwrap(); let factory_dispatcher = IFactoryDispatcher { contract_address: factory_contract_address }; - factory_dispatcher.current_account_class().print(); - account_class_hash.print(); - assert(factory_dispatcher.current_account_class() == account_class_hash, 'account class wrong'); + + let ethereum_address: EthAddress = 0x11655f4Ee2A5B66F9DCbe758e9FcdCd3eBF95eE5.try_into().unwrap(); + + let precalculated_address = factory_dispatcher.precalculate_starknet_address(ethereum_address); + + let (account_contract_address, _) = account_contract_class.deploy(@array![ethereum_address.into()]).unwrap(); + + assert(precalculated_address == account_contract_address, 'precalculated address wrong'); // TODO: burayı fixle neden hata dönüyor ve debug print ekle } \ No newline at end of file From 9d4f334a76aa1dca5c80a3c0c95f9054cd2a00b8 Mon Sep 17 00:00:00 2001 From: Erim Date: Wed, 16 Oct 2024 12:53:12 +0300 Subject: [PATCH 3/3] dev functions --- .gitignore | 4 +++- src/factory.cairo | 26 ++++++++++++++++++++++---- 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/.gitignore b/.gitignore index 6186287..4a84f7e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ target dev_signer -dev_account \ No newline at end of file +dev_account +sepolia +sepolia_account \ No newline at end of file diff --git a/src/factory.cairo b/src/factory.cairo index 14e0824..3bc8a99 100644 --- a/src/factory.cairo +++ b/src/factory.cairo @@ -6,13 +6,15 @@ pub trait IFactory { fn current_account_class(self: @TContractState) -> ClassHash; fn precalculate_starknet_address(self: @TContractState, address: EthAddress) -> ContractAddress; fn deploy_account(self: @TContractState, address: EthAddress) -> ContractAddress; + fn upgrade_contract(self: @TContractState, new_class: ClassHash); + fn change_account_class(ref self: TContractState, new_class: ClassHash); } #[starknet::contract] pub mod Factory { use core::option::OptionTrait; - use starknet::{ContractAddress, ClassHash, EthAddress}; - use starknet::syscalls::{deploy_syscall}; + use starknet::{ContractAddress, ClassHash, EthAddress, get_caller_address}; + use starknet::syscalls::{deploy_syscall, replace_class_syscall}; use core::traits::{Into, TryInto}; use openzeppelin::utils::deployments::{calculate_contract_address_from_deploy_syscall}; use starknet::storage::{StoragePointerReadAccess, StoragePointerWriteAccess}; @@ -20,13 +22,15 @@ pub mod Factory { #[storage] struct Storage { account_class: ClassHash, - lens: ContractAddress + lens: ContractAddress, + dev: ContractAddress } #[constructor] - fn constructor(ref self: ContractState, lens: ContractAddress, account_class: ClassHash) { + fn constructor(ref self: ContractState, lens: ContractAddress, account_class: ClassHash, dev: ContractAddress) { self.account_class.write(account_class); self.lens.write(lens); + self.dev.write(dev); } #[abi(embed_v0)] @@ -79,5 +83,19 @@ pub mod Factory { // Todo: register lens if needed ?? Or we can use precalculate account } + + // REMOVE THIS FUNCTION AFTER DEVELOPMENT + fn upgrade_contract(self: @ContractState, new_class: ClassHash) { + assert(get_caller_address() == self.dev.read(), 'only dev'); + + replace_class_syscall(new_class).unwrap(); + } + + // REMOVE THIS FUNCTION AFTER DEVELOPMENT + fn change_account_class(ref self: ContractState, new_class: ClassHash) { + assert(get_caller_address() == self.dev.read(), 'only dev'); + + self.account_class.write(new_class); + } } }