diff --git a/.github/workflows/test_contracts.yml b/.github/workflows/test_contracts.yml index 7559459..d698951 100644 --- a/.github/workflows/test_contracts.yml +++ b/.github/workflows/test_contracts.yml @@ -11,6 +11,6 @@ jobs: - uses: software-mansion/setup-scarb@v1 - uses: foundry-rs/setup-snfoundry@v3 with: - starknet-foundry-version: 0.19.0 + starknet-foundry-version: 0.20.1 - name: Run cairo tests run: snforge test \ No newline at end of file diff --git a/.tool-versions b/.tool-versions index b5cb918..ea9156d 100644 --- a/.tool-versions +++ b/.tool-versions @@ -1,2 +1,2 @@ scarb 2.6.0 -starknet-foundry 0.19.0 \ No newline at end of file +starknet-foundry 0.20.1 \ No newline at end of file diff --git a/Scarb.lock b/Scarb.lock index 09d8c2d..e4d841e 100644 --- a/Scarb.lock +++ b/Scarb.lock @@ -3,8 +3,8 @@ version = 1 [[package]] name = "snforge_std" -version = "0.19.0" -source = "git+https://github.com/foundry-rs/starknet-foundry.git?tag=v0.19.0#a3391dce5bdda51c63237032e6cfc64fb7a346d4" +version = "0.20.1" +source = "git+https://github.com/foundry-rs/starknet-foundry.git?tag=v0.20.1#fea2db8f2b20148cc15ee34b08de12028eb42942" [[package]] name = "token_bound_accounts" diff --git a/Scarb.toml b/Scarb.toml index 9967a65..baeb484 100644 --- a/Scarb.toml +++ b/Scarb.toml @@ -1,6 +1,7 @@ [package] name = "token_bound_accounts" version = "0.3.0" +edition = "2023_10" # See more keys and their definitions at https://docs.swmansion.com/scarb/docs/reference/manifest @@ -10,7 +11,7 @@ casm = true [dependencies] starknet = "2.6.0" -snforge_std = { git = "https://github.com/foundry-rs/starknet-foundry.git", tag = "v0.19.0" } +snforge_std = { git = "https://github.com/foundry-rs/starknet-foundry.git", tag = "v0.20.1" } [tool.snforge] # exit_first = true \ No newline at end of file diff --git a/src/account/account.cairo b/src/account/account.cairo index 0a56edf..8f117ac 100644 --- a/src/account/account.cairo +++ b/src/account/account.cairo @@ -3,24 +3,21 @@ //////////////////////////////// #[starknet::component] mod AccountComponent { + use core::num::traits::zero::Zero; use starknet::{ get_tx_info, get_caller_address, get_contract_address, get_block_timestamp, ContractAddress, account::Call, call_contract_syscall, replace_class_syscall, ClassHash, SyscallResultTrait }; - use ecdsa::check_ecdsa_signature; - use array::{SpanTrait, ArrayTrait}; - use box::BoxTrait; - use option::OptionTrait; - use zeroable::Zeroable; use token_bound_accounts::interfaces::IERC721::{IERC721DispatcherTrait, IERC721Dispatcher}; - use token_bound_accounts::interfaces::IAccount::IAccount; - use token_bound_accounts::interfaces::IAccount::{TBA_INTERFACE_ID}; + use token_bound_accounts::interfaces::IAccount::{ + IAccount, IAccountDispatcherTrait, IAccountDispatcher, TBA_INTERFACE_ID + }; #[storage] struct Storage { - Account_token_contract: ContractAddress, // contract address of NFT - Account_token_id: u256, // token ID of NFT - Account_unlock_timestamp: u64, // time to unlock account when locked + account_token_contract: ContractAddress, // contract address of NFT + account_token_id: u256, // token ID of NFT + account_unlock_timestamp: u64, // time to unlock account when locked } #[event] @@ -82,6 +79,18 @@ mod AccountComponent { self._is_valid_signature(hash, signature) } + /// @notice used to validate signer + /// @param signer address to be validated + fn is_valid_signer( + self: @ComponentState, signer: ContractAddress + ) -> felt252 { + if self._is_valid_signer(signer) { + return starknet::VALIDATED; + } else { + return 0; + } + } + fn __validate_deploy__( self: @ComponentState, class_hash: felt252, @@ -109,7 +118,9 @@ mod AccountComponent { fn __execute__( ref self: ComponentState, mut calls: Array ) -> Array> { - self._assert_only_owner(); + let caller = get_caller_address(); + assert(self._is_valid_signer(caller), Errors::UNAUTHORIZED); + let (lock_status, _) = self._is_locked(); assert(!lock_status, Errors::LOCKED_ACCOUNT); @@ -123,16 +134,16 @@ mod AccountComponent { retdata } - /// @notice gets the token bound NFT owner + /// @notice gets the NFT owner /// @param token_contract the contract address of the NFT /// @param token_id the token ID of the NFT - fn owner( - self: @ComponentState, token_contract: ContractAddress, token_id: u256 - ) -> ContractAddress { + fn owner(self: @ComponentState) -> ContractAddress { + let token_contract = self.account_token_contract.read(); + let token_id = self.account_token_id.read(); self._get_owner(token_contract, token_id) } - /// @notice returns the contract address and token ID of the NFT + /// @notice returns the contract address and token ID of the associated NFT fn token(self: @ComponentState) -> (ContractAddress, u256) { self._get_token() } @@ -140,12 +151,15 @@ mod AccountComponent { // @notice protection mechanism for selling token bound accounts. can't execute when account is locked // @param duration for which to lock account fn lock(ref self: ComponentState, duration: u64) { - self._assert_only_owner(); + let caller = get_caller_address(); + assert(self._is_valid_signer(caller), Errors::UNAUTHORIZED); + let (lock_status, _) = self._is_locked(); assert(!lock_status, Errors::LOCKED_ACCOUNT); + let current_timestamp = get_block_timestamp(); let unlock_time = current_timestamp + duration; - self.Account_unlock_timestamp.write(unlock_time); + self.account_unlock_timestamp.write(unlock_time); self .emit( AccountLocked { @@ -176,27 +190,20 @@ mod AccountComponent { impl InternalImpl< TContractState, +HasComponent, +Drop > of InternalTrait { - /// @notice initializes the account by setting the initial token conrtact and token id + /// @notice initializes the account by setting the initial token contract and token id fn initializer( ref self: ComponentState, token_contract: ContractAddress, token_id: u256 ) { - self.Account_token_contract.write(token_contract); - self.Account_token_id.write(token_id); - let owner = self._get_owner(token_contract, token_id); + assert(owner.is_non_zero(), Errors::UNAUTHORIZED); + // initialize account + self.account_token_contract.write(token_contract); + self.account_token_id.write(token_id); self.emit(AccountCreated { owner }); } - /// @notice check that caller is the token bound account - fn _assert_only_owner(ref self: ComponentState) { - let caller = get_caller_address(); - let owner = self - ._get_owner(self.Account_token_contract.read(), self.Account_token_id.read()); - assert(caller == owner, Errors::UNAUTHORIZED); - } - /// @notice internal function for getting NFT owner /// @param token_contract contract address of NFT // @param token_id token ID of NFT @@ -218,14 +225,14 @@ mod AccountComponent { /// @notice internal transaction for returning the contract address and token ID of the NFT fn _get_token(self: @ComponentState) -> (ContractAddress, u256) { - let contract = self.Account_token_contract.read(); - let tokenId = self.Account_token_id.read(); + let contract = self.account_token_contract.read(); + let tokenId = self.account_token_id.read(); (contract, tokenId) } // @notice protection mechanism for TBA trading. Returns the lock-status (true or false), and the remaning time till account unlocks. fn _is_locked(self: @ComponentState) -> (bool, u64) { - let unlock_timestamp = self.Account_unlock_timestamp.read(); + let unlock_timestamp = self.account_unlock_timestamp.read(); let current_time = get_block_timestamp(); if (current_time < unlock_timestamp) { let time_until_unlocks = unlock_timestamp - current_time; @@ -235,16 +242,17 @@ mod AccountComponent { } } - /// @notice internal function for tx validation - fn _validate_transaction(self: @ComponentState) -> felt252 { - let tx_info = get_tx_info().unbox(); - let tx_hash = tx_info.transaction_hash; - let signature = tx_info.signature; - assert( - self._is_valid_signature(tx_hash, signature) == starknet::VALIDATED, - Errors::INV_SIGNATURE - ); - starknet::VALIDATED + // @notice internal function for validating signer + fn _is_valid_signer( + self: @ComponentState, signer: ContractAddress + ) -> bool { + let owner = self + ._get_owner(self.account_token_contract.read(), self.account_token_id.read()); + if (signer == owner) { + return true; + } else { + return false; + } } /// @notice internal function for signature validation @@ -254,16 +262,28 @@ mod AccountComponent { let signature_length = signature.len(); assert(signature_length == 2_u32, Errors::INV_SIG_LEN); - let caller = get_caller_address(); let owner = self - ._get_owner(self.Account_token_contract.read(), self.Account_token_id.read()); - if (caller == owner) { + ._get_owner(self.account_token_contract.read(), self.account_token_id.read()); + let account = IAccountDispatcher { contract_address: owner }; + if (account.is_valid_signature(hash, signature) == starknet::VALIDATED) { return starknet::VALIDATED; } else { return 0; } } + /// @notice internal function for tx validation + fn _validate_transaction(self: @ComponentState) -> felt252 { + let tx_info = get_tx_info().unbox(); + let tx_hash = tx_info.transaction_hash; + let signature = tx_info.signature; + assert( + self._is_valid_signature(tx_hash, signature) == starknet::VALIDATED, + Errors::INV_SIGNATURE + ); + starknet::VALIDATED + } + /// @notice internal function for executing transactions /// @param calls An array of transactions to be executed fn _execute_calls( @@ -277,7 +297,7 @@ mod AccountComponent { Option::Some(call) => { match call_contract_syscall(call.to, call.selector, call.calldata) { Result::Ok(mut retdata) => { result.append(retdata); }, - Result::Err(_) => { panic_with_felt252('multicall_failed'); } + Result::Err(_) => { panic(array!['multicall_failed']); } } }, Option::None(_) => { break (); } diff --git a/src/interfaces/IAccount.cairo b/src/interfaces/IAccount.cairo index 0e8645e..efc4335 100644 --- a/src/interfaces/IAccount.cairo +++ b/src/interfaces/IAccount.cairo @@ -3,13 +3,14 @@ use starknet::ClassHash; use starknet::account::Call; // SRC5 interface for token bound accounts -const TBA_INTERFACE_ID: felt252 = 0x539036932a2ab9c4734fbfd9872a1f7791a3f577e45477336ae0fd0a00c9ff; +const TBA_INTERFACE_ID: felt252 = 0xd050d1042482f6e9a28d0c039d0a8428266bf4fd59fe95cee66d8e0e8b3b2e; #[starknet::interface] trait IAccount { fn is_valid_signature( self: @TContractState, hash: felt252, signature: Span ) -> felt252; + fn is_valid_signer(self: @TContractState, signer: ContractAddress) -> felt252; fn __validate__(ref self: TContractState, calls: Array) -> felt252; fn __validate_declare__(self: @TContractState, class_hash: felt252) -> felt252; fn __validate_deploy__( @@ -17,9 +18,7 @@ trait IAccount { ) -> felt252; fn __execute__(ref self: TContractState, calls: Array) -> Array>; fn token(self: @TContractState) -> (ContractAddress, u256); - fn owner( - self: @TContractState, token_contract: ContractAddress, token_id: u256 - ) -> ContractAddress; + fn owner(self: @TContractState) -> ContractAddress; fn lock(ref self: TContractState, duration: u64); fn is_locked(self: @TContractState) -> (bool, u64); fn supports_interface(self: @TContractState, interface_id: felt252) -> bool; diff --git a/src/presets/account.cairo b/src/presets/account.cairo index 07edf3f..4f31e41 100644 --- a/src/presets/account.cairo +++ b/src/presets/account.cairo @@ -3,7 +3,7 @@ //////////////////////////////// #[starknet::contract(account)] mod Account { - use starknet::ContractAddress; + use starknet::{ContractAddress, get_caller_address}; use starknet::ClassHash; use token_bound_accounts::account::AccountComponent; use token_bound_accounts::upgradeable::UpgradeableComponent; @@ -45,7 +45,8 @@ mod Account { #[abi(embed_v0)] impl UpgradeableImpl of IUpgradeable { fn upgrade(ref self: ContractState, new_class_hash: ClassHash) { - self.account._assert_only_owner(); + let caller = get_caller_address(); + assert(self.account._is_valid_signer(caller), AccountComponent::Errors::UNAUTHORIZED); let (lock_status, _) = self.account._is_locked(); assert(!lock_status, AccountComponent::Errors::LOCKED_ACCOUNT); self.upgradeable._upgrade(new_class_hash); diff --git a/src/registry/registry.cairo b/src/registry/registry.cairo index 0426253..c579da8 100644 --- a/src/registry/registry.cairo +++ b/src/registry/registry.cairo @@ -5,22 +5,17 @@ mod Registry { use core::result::ResultTrait; use core::hash::HashStateTrait; + use core::pedersen::PedersenTrait; use starknet::{ ContractAddress, get_caller_address, syscalls::call_contract_syscall, class_hash::ClassHash, class_hash::Felt252TryIntoClassHash, syscalls::deploy_syscall, SyscallResultTrait }; - use zeroable::Zeroable; - use traits::{Into, TryInto}; - use option::OptionTrait; - use array::{ArrayTrait, SpanTrait}; - use pedersen::PedersenTrait; - use token_bound_accounts::interfaces::IERC721::{IERC721DispatcherTrait, IERC721Dispatcher}; use token_bound_accounts::interfaces::IRegistry::IRegistry; #[storage] struct Storage { - Registry_deployed_accounts: LegacyMap< + registry_deployed_accounts: LegacyMap< (ContractAddress, u256), u8 >, // tracks no. of deployed accounts by registry for an NFT } @@ -72,10 +67,10 @@ mod Registry { let (account_address, _) = result.unwrap_syscall(); let new_deployment_index: u8 = self - .Registry_deployed_accounts + .registry_deployed_accounts .read((token_contract, token_id)) + 1_u8; - self.Registry_deployed_accounts.write((token_contract, token_id), new_deployment_index); + self.registry_deployed_accounts.write((token_contract, token_id), new_deployment_index); self.emit(AccountCreated { account_address, token_contract, token_id, }); @@ -120,7 +115,7 @@ mod Registry { fn total_deployed_accounts( self: @ContractState, token_contract: ContractAddress, token_id: u256 ) -> u8 { - self.Registry_deployed_accounts.read((token_contract, token_id)) + self.registry_deployed_accounts.read((token_contract, token_id)) } } diff --git a/src/test_helper.cairo b/src/test_helper.cairo index 57f17fb..a560453 100644 --- a/src/test_helper.cairo +++ b/src/test_helper.cairo @@ -1,3 +1,4 @@ mod hello_starknet; mod account_upgrade; mod erc721_helper; +mod simple_account; diff --git a/src/test_helper/account_upgrade.cairo b/src/test_helper/account_upgrade.cairo index 8e86a50..9d90a6a 100644 --- a/src/test_helper/account_upgrade.cairo +++ b/src/test_helper/account_upgrade.cairo @@ -1,4 +1,3 @@ -use array::{ArrayTrait, SpanTrait}; use starknet::{account::Call, ContractAddress, ClassHash}; #[starknet::interface] @@ -55,11 +54,8 @@ mod UpgradedAccount { get_tx_info, get_caller_address, get_contract_address, ContractAddress, account::Call, call_contract_syscall, replace_class_syscall, ClassHash, SyscallResultTrait }; - use ecdsa::check_ecdsa_signature; - use array::{SpanTrait, ArrayTrait}; - use box::BoxTrait; - use option::OptionTrait; - use zeroable::Zeroable; + use core::ecdsa::check_ecdsa_signature; + use core::zeroable::Zeroable; use super::{IERC721DispatcherTrait, IERC721Dispatcher}; #[storage] @@ -211,7 +207,7 @@ mod UpgradedAccount { Option::Some(call) => { match call_contract_syscall(call.to, call.selector, call.calldata) { Result::Ok(mut retdata) => { result.append(retdata); }, - Result::Err(_) => { panic_with_felt252('multicall_failed'); } + Result::Err(_) => { panic(array!['multicall_failed']); } } }, Option::None(_) => { break (); } diff --git a/src/test_helper/erc721_helper.cairo b/src/test_helper/erc721_helper.cairo index 20036e6..cb88290 100644 --- a/src/test_helper/erc721_helper.cairo +++ b/src/test_helper/erc721_helper.cairo @@ -26,11 +26,8 @@ trait IERC721 { mod ERC721 { use starknet::ContractAddress; use starknet::get_caller_address; - use zeroable::Zeroable; + use core::zeroable::Zeroable; use starknet::contract_address_to_felt252; - use traits::Into; - use traits::TryInto; - use option::OptionTrait; #[storage] struct Storage { diff --git a/src/test_helper/simple_account.cairo b/src/test_helper/simple_account.cairo new file mode 100644 index 0000000..3e0476c --- /dev/null +++ b/src/test_helper/simple_account.cairo @@ -0,0 +1,140 @@ +use starknet::{account::Call, ContractAddress, ClassHash}; + +#[starknet::interface] +trait ISimpleAccount { + fn get_public_key(self: @TContractState) -> felt252; + fn set_public_key(ref self: TContractState, new_public_key: felt252); + fn is_valid_signature( + self: @TContractState, hash: felt252, signature: Span + ) -> felt252; + fn __validate__(ref self: TContractState, calls: Array) -> felt252; + fn __validate_declare__(self: @TContractState, class_hash: felt252) -> felt252; + fn __validate_deploy__( + self: @TContractState, + class_hash: felt252, + contract_address_salt: felt252, + public_key: felt252 + ) -> felt252; + fn __execute__(ref self: TContractState, calls: Array) -> Array>; +} + +#[starknet::contract(account)] +mod SimpleAccount { + use starknet::{ + get_tx_info, get_caller_address, get_contract_address, ContractAddress, account::Call, + call_contract_syscall, replace_class_syscall, ClassHash, SyscallResultTrait + }; + use core::ecdsa::check_ecdsa_signature; + use core::zeroable::Zeroable; + + #[storage] + struct Storage { + _public_key: felt252, + } + + #[constructor] + fn constructor(ref self: ContractState, _public_key: felt252) { + self._public_key.write(_public_key); + } + + #[abi(embed_v0)] + impl IAccountImpl of super::ISimpleAccount { + fn get_public_key(self: @ContractState) -> felt252 { + self._public_key.read() + } + + fn set_public_key(ref self: ContractState, new_public_key: felt252) { + self.assert_only_self(); + self._public_key.write(new_public_key); + } + + fn is_valid_signature( + self: @ContractState, hash: felt252, signature: Span + ) -> felt252 { + self._is_valid_signature(hash, signature) + } + + fn __validate_deploy__( + self: @ContractState, + class_hash: felt252, + contract_address_salt: felt252, + public_key: felt252 + ) -> felt252 { + self.validate_transaction() + } + + fn __validate_declare__(self: @ContractState, class_hash: felt252) -> felt252 { + self.validate_transaction() + } + + fn __validate__(ref self: ContractState, mut calls: Array) -> felt252 { + self.validate_transaction() + } + + fn __execute__(ref self: ContractState, mut calls: Array) -> Array> { + let caller = get_caller_address(); + assert(caller.is_zero(), 'invalid caller'); + + let tx_info = get_tx_info().unbox(); + assert(tx_info.version != 0, 'invalid tx version'); + + self._execute_calls(calls) + } + } + + #[generate_trait] + impl internalImpl of InternalTrait { + fn assert_only_self(ref self: ContractState) { + let caller = get_caller_address(); + let self = get_contract_address(); + assert(self == caller, 'Account: unathorized'); + } + + fn validate_transaction(self: @ContractState) -> felt252 { + let tx_info = get_tx_info().unbox(); + let tx_hash = tx_info.transaction_hash; + let signature = tx_info.signature; + assert( + self._is_valid_signature(tx_hash, signature) == starknet::VALIDATED, + 'Account: invalid signature' + ); + starknet::VALIDATED + } + + fn _is_valid_signature( + self: @ContractState, hash: felt252, signature: Span + ) -> felt252 { + assert(signature.len() == 2_u32, 'invalid signature'); + let public_key = self._public_key.read(); + + if check_ecdsa_signature( + message_hash: hash, + public_key: public_key, + signature_r: *signature[0_u32], + signature_s: *signature[1_u32], + ) { + return starknet::VALIDATED; + } else { + return 0; + } + } + + fn _execute_calls(ref self: ContractState, mut calls: Array) -> Array> { + let mut result: Array> = ArrayTrait::new(); + let mut calls = calls; + + loop { + match calls.pop_front() { + Option::Some(call) => { + match call_contract_syscall(call.to, call.selector, call.calldata) { + Result::Ok(mut retdata) => { result.append(retdata); }, + Result::Err(_) => { panic(array!['multicall_failed']); } + } + }, + Option::None(_) => { break (); } + }; + }; + result + } + } +} diff --git a/src/upgradeable/upgradeable.cairo b/src/upgradeable/upgradeable.cairo index b67b163..90f3127 100644 --- a/src/upgradeable/upgradeable.cairo +++ b/src/upgradeable/upgradeable.cairo @@ -5,6 +5,8 @@ mod UpgradeableComponent { use starknet::ClassHash; use starknet::SyscallResultTrait; + use core::zeroable::Zeroable; + use token_bound_accounts::interfaces::IUpgradeable; #[storage] @@ -30,7 +32,7 @@ mod UpgradeableComponent { impl InternalImpl< TContractState, +HasComponent, +Drop > of InternalTrait { - /// @notice eplaces the contract's class hash with `new_class_hash`. + /// @notice replaces the contract's class hash with `new_class_hash`. /// Emits an `Upgraded` event. fn _upgrade(ref self: ComponentState, new_class_hash: ClassHash) { assert(!new_class_hash.is_zero(), Errors::INVALID_CLASS); diff --git a/tests/test_account.cairo b/tests/test_account.cairo index ca28603..cd56b28 100644 --- a/tests/test_account.cairo +++ b/tests/test_account.cairo @@ -1,35 +1,24 @@ use starknet::{ContractAddress, contract_address_to_felt252, account::Call}; -use traits::TryInto; -use array::{ArrayTrait, SpanTrait}; -use result::ResultTrait; -use option::OptionTrait; -use integer::u256_from_felt252; +use core::integer::u256_from_felt252; use snforge_std::{ declare, start_prank, stop_prank, start_warp, stop_warp, ContractClassTrait, ContractClass, CheatTarget }; -use token_bound_accounts::interfaces::IAccount::IAccountDispatcher; -use token_bound_accounts::interfaces::IAccount::IAccountDispatcherTrait; -use token_bound_accounts::interfaces::IAccount::IAccountSafeDispatcher; -use token_bound_accounts::interfaces::IAccount::IAccountSafeDispatcherTrait; +use token_bound_accounts::interfaces::IAccount::{ + IAccountDispatcher, IAccountDispatcherTrait, IAccountSafeDispatcher, IAccountSafeDispatcherTrait +}; use token_bound_accounts::presets::account::Account; +use token_bound_accounts::interfaces::IUpgradeable::{ + IUpgradeableDispatcher, IUpgradeableDispatcherTrait +}; -use token_bound_accounts::interfaces::IUpgradeable::IUpgradeableDispatcher; -use token_bound_accounts::interfaces::IUpgradeable::IUpgradeableDispatcherTrait; - - -use token_bound_accounts::test_helper::hello_starknet::IHelloStarknetDispatcher; -use token_bound_accounts::test_helper::hello_starknet::IHelloStarknetDispatcherTrait; -use token_bound_accounts::test_helper::hello_starknet::HelloStarknet; - -use token_bound_accounts::test_helper::account_upgrade::IUpgradedAccountDispatcher; -use token_bound_accounts::test_helper::account_upgrade::IUpgradedAccountDispatcherTrait; -use token_bound_accounts::test_helper::account_upgrade::UpgradedAccount; - -use token_bound_accounts::test_helper::erc721_helper::IERC721Dispatcher; -use token_bound_accounts::test_helper::erc721_helper::IERC721DispatcherTrait; -use token_bound_accounts::test_helper::erc721_helper::ERC721; +use token_bound_accounts::test_helper::{ + hello_starknet::{IHelloStarknetDispatcher, IHelloStarknetDispatcherTrait, HelloStarknet}, + account_upgrade::{IUpgradedAccountDispatcher, IUpgradedAccountDispatcherTrait, UpgradedAccount}, + erc721_helper::{IERC721Dispatcher, IERC721DispatcherTrait, ERC721}, + simple_account::{ISimpleAccountDispatcher, ISimpleAccountDispatcherTrait, SimpleAccount} +}; const ACCOUNT: felt252 = 1234; const ACCOUNT2: felt252 = 5729; @@ -60,9 +49,16 @@ fn __setup__() -> (ContractAddress, ContractAddress) { let mut erc721_constructor_calldata = array!['tokenbound', 'TBA']; let erc721_contract_address = erc721_contract.deploy(@erc721_constructor_calldata).unwrap(); + // deploy recipient contract + let account_contract = declare("SimpleAccount"); + let mut recipient = account_contract + .deploy( + @array![883045738439352841478194533192765345509759306772397516907181243450667673002] + ) + .unwrap(); + // mint a new token let dispatcher = IERC721Dispatcher { contract_address: erc721_contract_address }; - let recipient: ContractAddress = ACCOUNT.try_into().unwrap(); dispatcher.mint(recipient, u256_from_felt252(1)); // deploy account contract @@ -202,7 +198,7 @@ fn test_owner() { let acct_dispatcher = IAccountDispatcher { contract_address: contract_address }; let token_dispatcher = IERC721Dispatcher { contract_address: erc721_contract_address }; - let owner = acct_dispatcher.owner(erc721_contract_address, u256_from_felt252(1)); + let owner = acct_dispatcher.owner(); let token_owner = token_dispatcher.ownerOf(u256_from_felt252(1)); assert(owner == token_owner, 'invalid owner'); } @@ -299,7 +295,7 @@ fn test_should_not_execute_when_locked() { let mut calls = array![call]; match safe_dispatcher.__execute__(calls) { - Result::Ok(_) => panic_with_felt252('should have panicked!'), + Result::Ok(_) => panic(array!['should have panicked!']), Result::Err(panic_data) => { stop_prank(CheatTarget::One(contract_address)); println!("panic_data: {:?}", panic_data); @@ -344,7 +340,7 @@ fn test_should_not_lock_if_not_owner() { start_prank(CheatTarget::One(contract_address), ACCOUNT2.try_into().unwrap()); start_warp(CheatTarget::One(contract_address), 1000); match dispatcher.lock(lock_duration) { - Result::Ok(_) => panic_with_felt252('should have panicked'), + Result::Ok(_) => panic(array!['should have panicked!']), Result::Err(panic_data) => { stop_prank(CheatTarget::One(contract_address)); stop_warp(CheatTarget::One(contract_address)); @@ -375,7 +371,7 @@ fn test_should_not_lock_if_already_locked() { // call the lock function again start_warp(CheatTarget::One(contract_address), 1000); match safe_dispatcher.lock(lock_duration) { - Result::Ok(_) => panic_with_felt252('should have panicked'), + Result::Ok(_) => panic(array!['should have panicked!']), Result::Err(panic_data) => { stop_prank(CheatTarget::One(contract_address)); stop_warp(CheatTarget::One(contract_address)); diff --git a/tests/test_registry.cairo b/tests/test_registry.cairo index 17c579f..6cd4385 100644 --- a/tests/test_registry.cairo +++ b/tests/test_registry.cairo @@ -1,25 +1,20 @@ use starknet::{ContractAddress, contract_address_to_felt252, class_hash_to_felt252}; -use traits::TryInto; -use array::{ArrayTrait, SpanTrait}; -use result::ResultTrait; -use option::OptionTrait; -use integer::u256_from_felt252; +use core::integer::u256_from_felt252; use snforge_std::{declare, start_prank, stop_prank, ContractClassTrait, ContractClass, CheatTarget}; -use token_bound_accounts::interfaces::IRegistry::IRegistryDispatcherTrait; -use token_bound_accounts::interfaces::IRegistry::IRegistryDispatcher; +use token_bound_accounts::interfaces::IRegistry::{IRegistryDispatcherTrait, IRegistryDispatcher}; use token_bound_accounts::registry::registry::Registry; -use token_bound_accounts::interfaces::IUpgradeable::IUpgradeableDispatcher; -use token_bound_accounts::interfaces::IUpgradeable::IUpgradeableDispatcherTrait; +use token_bound_accounts::interfaces::IUpgradeable::{ + IUpgradeableDispatcher, IUpgradeableDispatcherTrait +}; -use token_bound_accounts::interfaces::IAccount::IAccountDispatcher; -use token_bound_accounts::interfaces::IAccount::IAccountDispatcherTrait; +use token_bound_accounts::interfaces::IAccount::{IAccountDispatcher, IAccountDispatcherTrait}; use token_bound_accounts::presets::account::Account; -use token_bound_accounts::test_helper::erc721_helper::IERC721Dispatcher; -use token_bound_accounts::test_helper::erc721_helper::IERC721DispatcherTrait; -use token_bound_accounts::test_helper::erc721_helper::ERC721; +use token_bound_accounts::test_helper::erc721_helper::{ + IERC721Dispatcher, IERC721DispatcherTrait, ERC721 +}; const ACCOUNT: felt252 = 1234; @@ -68,7 +63,7 @@ fn test_create_account() { // confirm account deployment by checking the account owner let acct_dispatcher = IAccountDispatcher { contract_address: account_address }; - let TBA_owner = acct_dispatcher.owner(erc721_contract_address, u256_from_felt252(1)); + let TBA_owner = acct_dispatcher.owner(); assert(TBA_owner == token_owner, 'acct deployed wrongly'); }