Skip to content

Commit

Permalink
Merge pull request #53 from horuslabsio/v3_account_test_cover
Browse files Browse the repository at this point in the history
Account v3 test coverage
  • Loading branch information
Darlington02 authored Sep 20, 2024
2 parents b272e97 + f887cb1 commit 8fab99f
Show file tree
Hide file tree
Showing 2 changed files with 329 additions and 1 deletion.
243 changes: 242 additions & 1 deletion tests/test_account_v3.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use snforge_std::{
start_cheat_account_contract_address, stop_cheat_account_contract_address,
start_cheat_transaction_hash, start_cheat_nonce, spy_events, EventSpyAssertionsTrait,
ContractClassTrait, ContractClass, start_cheat_chain_id, stop_cheat_chain_id,
start_cheat_chain_id_global, stop_cheat_chain_id_global
start_cheat_chain_id_global, stop_cheat_chain_id_global,
};
use core::hash::HashStateTrait;
use core::pedersen::PedersenTrait;
Expand All @@ -13,16 +13,32 @@ use token_bound_accounts::interfaces::IRegistry::{IRegistryDispatcherTrait, IReg
use token_bound_accounts::interfaces::IERC721::{
IERC721Dispatcher, IERC721DispatcherTrait, IERC721SafeDispatcher, IERC721SafeDispatcherTrait
};
use token_bound_accounts::interfaces::IExecutable::{
IExecutableDispatcher, IExecutableDispatcherTrait
};
use token_bound_accounts::interfaces::IUpgradeable::{
IUpgradeableDispatcher, IUpgradeableDispatcherTrait
};
use token_bound_accounts::interfaces::ILockable::{ILockableDispatcher, ILockableDispatcherTrait};
use token_bound_accounts::interfaces::IAccount::{IAccountDispatcher, IAccountDispatcherTrait};
use token_bound_accounts::interfaces::IPermissionable::{
IPermissionableDispatcher, IPermissionableDispatcherTrait
};
use token_bound_accounts::interfaces::ISignatory::{ISignatoryDispatcher, ISignatoryDispatcherTrait};
use token_bound_accounts::interfaces::IAccountV3::{IAccountV3Dispatcher, IAccountV3DispatcherTrait};
use token_bound_accounts::test_helper::{
hello_starknet::{IHelloStarknetDispatcher, IHelloStarknetDispatcherTrait, HelloStarknet},
simple_account::{ISimpleAccountDispatcher, ISimpleAccountDispatcherTrait, SimpleAccount},
account_upgrade::{IUpgradedAccountDispatcher, IUpgradedAccountDispatcherTrait, UpgradedAccount},
erc721_helper::ERC721
};


const ACCOUNT: felt252 = 1234;
const ACCOUNT1: felt252 = 5739;
const ACCOUNT2: felt252 = 5729;
const ACCOUNT3: felt252 = 6908;
const ACCOUNT4: felt252 = 4697;
const SALT: felt252 = 123;


Expand Down Expand Up @@ -124,3 +140,228 @@ fn test_context() {
assert(_implementation == implementation, 'invalid implementation');
assert(_salt == 20, 'invalid salt');
}


#[test]
fn test_owner_and_permissioned_accounts_is_valid_signer() {
let (erc721_contract_address, _, account_v3_contract_address, _, _,) = __setup__();
let acct_dispatcher = IAccountDispatcher { contract_address: account_v3_contract_address };

let signatory_dispatcher = ISignatoryDispatcher {
contract_address: account_v3_contract_address
};

let owner = acct_dispatcher.owner();

// get token owner
let token_dispatcher = IERC721Dispatcher { contract_address: erc721_contract_address };
let token_owner = token_dispatcher.ownerOf(1.try_into().unwrap());

let mut permission_addresses = ArrayTrait::new();
permission_addresses.append(ACCOUNT2.try_into().unwrap());
permission_addresses.append(token_owner);

let mut permissions = ArrayTrait::new();
permissions.append(true);
permissions.append(true);

start_cheat_caller_address(account_v3_contract_address, owner);

let permissionable_dispatcher = IPermissionableDispatcher {
contract_address: account_v3_contract_address
};
permissionable_dispatcher.set_permission(permission_addresses, permissions);

let has_permission2 = permissionable_dispatcher.has_permission(owner, token_owner);
assert(has_permission2 == true, 'Account: permitted');

stop_cheat_caller_address(account_v3_contract_address);

// check owner is a valid signer
start_cheat_caller_address(account_v3_contract_address, owner);
let is_valid_signer = signatory_dispatcher.is_valid_signer(owner);
assert(is_valid_signer == true, 'should be a valid signer');

stop_cheat_caller_address(account_v3_contract_address);

// check permission address is a valid signer
start_cheat_caller_address(account_v3_contract_address, token_owner);
let is_valid_signer = signatory_dispatcher.is_valid_signer(token_owner);
assert(is_valid_signer == true, 'should be a valid signer');

stop_cheat_caller_address(account_v3_contract_address);
}

#[test]
fn test_owner_and_any_permissioned_accounts_can_execute() {
let (erc721_contract_address, _, account_v3_contract_address, _, _,) = __setup__();
let acct_dispatcher = IAccountDispatcher { contract_address: account_v3_contract_address };
let safe_dispatcher = IExecutableDispatcher { contract_address: account_v3_contract_address };
let owner = acct_dispatcher.owner();

let mut permission_addresses = ArrayTrait::new();
permission_addresses.append(ACCOUNT2.try_into().unwrap());
permission_addresses.append(ACCOUNT3.try_into().unwrap());
permission_addresses.append(ACCOUNT4.try_into().unwrap());

let mut permissions = ArrayTrait::new();
permissions.append(true);
permissions.append(true);
permissions.append(false);

start_cheat_caller_address(account_v3_contract_address, owner);

let permissionable_dispatcher = IPermissionableDispatcher {
contract_address: account_v3_contract_address
};
permissionable_dispatcher.set_permission(permission_addresses, permissions);

let has_permission2 = permissionable_dispatcher
.has_permission(owner, ACCOUNT2.try_into().unwrap());
assert(has_permission2 == true, 'Account: permitted');

// deploy `HelloStarknet` contract for testing
let test_contract = declare("HelloStarknet").unwrap();
let (test_address, _) = test_contract.deploy(@array![]).unwrap();

// craft calldata for call array
let mut calldata = array![100].span();
let call = Call {
to: test_address,
selector: 1530486729947006463063166157847785599120665941190480211966374137237989315360,
calldata: calldata
};

start_cheat_caller_address(account_v3_contract_address, owner);
safe_dispatcher.execute(array![call]);

stop_cheat_caller_address(account_v3_contract_address);

start_cheat_caller_address(account_v3_contract_address, ACCOUNT2.try_into().unwrap());
safe_dispatcher.execute(array![call]);

stop_cheat_caller_address(account_v3_contract_address);
}

#[test]
#[should_panic(expected: ('Account: locked',))]
fn test_locked_account_cannot_execute() {
let (erc721_contract_address, _, account_v3_contract_address, _, _,) = __setup__();
let acct_dispatcher = IAccountDispatcher { contract_address: account_v3_contract_address };
let safe_dispatcher = IExecutableDispatcher { contract_address: account_v3_contract_address };

let owner = acct_dispatcher.owner();
let lock_duration = 30_u64;

let lockable_dispatcher = ILockableDispatcher { contract_address: account_v3_contract_address };

start_cheat_caller_address(account_v3_contract_address, owner);
lockable_dispatcher.lock(lock_duration);

stop_cheat_caller_address(account_v3_contract_address);

// deploy `HelloStarknet` contract for testing
let test_contract = declare("HelloStarknet").unwrap();
let (test_address, _) = test_contract.deploy(@array![]).unwrap();

// craft calldata for call array
let mut calldata = array![100].span();
let call = Call {
to: test_address,
selector: 1530486729947006463063166157847785599120665941190480211966374137237989315360,
calldata: calldata
};

start_cheat_caller_address(account_v3_contract_address, owner);
safe_dispatcher.execute(array![call]);
}

#[test]
fn test_owner_can_upgrade() {
let (erc721_contract_address, _, account_v3_contract_address, _, _,) = __setup__();
let new_class_hash = declare("UpgradedAccount").unwrap().class_hash;

// get token owner
let token_dispatcher = IERC721Dispatcher { contract_address: erc721_contract_address };
let token_owner = token_dispatcher.ownerOf(1.try_into().unwrap());

// call the upgrade function
let dispatcher = IUpgradeableDispatcher { contract_address: account_v3_contract_address };
start_cheat_caller_address(account_v3_contract_address, token_owner);
dispatcher.upgrade(new_class_hash);

// try to call the version function
let upgraded_dispatcher = IUpgradedAccountDispatcher {
contract_address: account_v3_contract_address
};
let version = upgraded_dispatcher.version();
assert(version == 1_u8, 'upgrade unsuccessful');
stop_cheat_caller_address(account_v3_contract_address);
}

#[test]
#[should_panic(expected: ('Account: unauthorized',))]
fn test_permissioned_accounts_can_not_upgrade() {
let (erc721_contract_address, _, account_v3_contract_address, _, _,) = __setup__();
let acct_dispatcher = IAccountDispatcher { contract_address: account_v3_contract_address };
let safe_dispatcher = IExecutableDispatcher { contract_address: account_v3_contract_address };
let new_class_hash = declare("UpgradedAccount").unwrap().class_hash;
let owner = acct_dispatcher.owner();

let mut permission_addresses = ArrayTrait::new();
permission_addresses.append(ACCOUNT2.try_into().unwrap());
permission_addresses.append(ACCOUNT3.try_into().unwrap());
permission_addresses.append(ACCOUNT4.try_into().unwrap());

let mut permissions = ArrayTrait::new();
permissions.append(true);
permissions.append(true);
permissions.append(false);

start_cheat_caller_address(account_v3_contract_address, owner);

let permissionable_dispatcher = IPermissionableDispatcher {
contract_address: account_v3_contract_address
};
permissionable_dispatcher.set_permission(permission_addresses, permissions);

let has_permission2 = permissionable_dispatcher
.has_permission(owner, ACCOUNT2.try_into().unwrap());
assert(has_permission2 == true, 'Account: permitted');

// call the upgrade function
let dispatcher = IUpgradeableDispatcher { contract_address: account_v3_contract_address };
start_cheat_caller_address(account_v3_contract_address, ACCOUNT2.try_into().unwrap());
dispatcher.upgrade(new_class_hash);
}

#[test]
fn test_only_owner_can_set_permissions() {
let (erc721_contract_address, _, account_v3_contract_address, _, _,) = __setup__();
let acct_dispatcher = IAccountDispatcher { contract_address: account_v3_contract_address };

let owner = acct_dispatcher.owner();

let mut permission_addresses = ArrayTrait::new();
permission_addresses.append(ACCOUNT2.try_into().unwrap());
permission_addresses.append(ACCOUNT3.try_into().unwrap());
permission_addresses.append(ACCOUNT4.try_into().unwrap());

let mut permissions = ArrayTrait::new();
permissions.append(true);
permissions.append(true);
permissions.append(true);

start_cheat_caller_address(account_v3_contract_address, owner);

let permissionable_dispatcher = IPermissionableDispatcher {
contract_address: account_v3_contract_address
};
permissionable_dispatcher.set_permission(permission_addresses, permissions);

let has_permission = permissionable_dispatcher
.has_permission(owner, ACCOUNT2.try_into().unwrap());

assert(has_permission == true, 'Account: not permitted');
stop_cheat_caller_address(account_v3_contract_address);
}
87 changes: 87 additions & 0 deletions tests/test_permissionable_component.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ use token_bound_accounts::interfaces::IPermissionable::{
use token_bound_accounts::interfaces::IExecutable::{
IExecutableDispatcher, IExecutableDispatcherTrait
};

use token_bound_accounts::interfaces::IUpgradeable::{
IUpgradeableDispatcher, IUpgradeableDispatcherTrait
};
use token_bound_accounts::interfaces::IERC721::{IERC721Dispatcher, IERC721DispatcherTrait};
use token_bound_accounts::components::presets::account_preset::AccountPreset;
use token_bound_accounts::components::permissionable::permissionable::PermissionableComponent;
Expand Down Expand Up @@ -212,3 +216,86 @@ fn test_set_permission_emits_event() {
);
}


#[test]
fn test_permissioned_accounts_can_execute() {
let (contract_address, _) = __setup__();
let acct_dispatcher = IAccountDispatcher { contract_address: contract_address };
let safe_dispatcher = IExecutableDispatcher { contract_address };
let owner = acct_dispatcher.owner();

let mut permission_addresses = ArrayTrait::new();
permission_addresses.append(ACCOUNT2.try_into().unwrap());
permission_addresses.append(ACCOUNT3.try_into().unwrap());
permission_addresses.append(ACCOUNT4.try_into().unwrap());

let mut permissions = ArrayTrait::new();
permissions.append(true);
permissions.append(true);
permissions.append(false);

start_cheat_caller_address(contract_address, owner);

let permissionable_dispatcher = IPermissionableDispatcher { contract_address };
permissionable_dispatcher.set_permission(permission_addresses, permissions);

let has_permission2 = permissionable_dispatcher
.has_permission(owner, ACCOUNT2.try_into().unwrap());
assert(has_permission2 == true, 'Account: permitted');

// deploy `HelloStarknet` contract for testing
let test_contract = declare("HelloStarknet").unwrap();
let (test_address, _) = test_contract.deploy(@array![]).unwrap();

// craft calldata for call array
let mut calldata = array![100].span();
let call = Call {
to: test_address,
selector: 1530486729947006463063166157847785599120665941190480211966374137237989315360,
calldata: calldata
};

start_cheat_caller_address(contract_address, ACCOUNT2.try_into().unwrap());
safe_dispatcher.execute(array![call]);

stop_cheat_caller_address(contract_address);
}

#[test]
fn test_permissioned_accounts_can_upgrade() {
let (contract_address, erc721_contract_address) = __setup__();
let acct_dispatcher = IAccountDispatcher { contract_address: contract_address };
let owner = acct_dispatcher.owner();

// get token owner
let token_dispatcher = IERC721Dispatcher { contract_address: erc721_contract_address };
let token_owner = token_dispatcher.ownerOf(1.try_into().unwrap());

let mut permission_addresses = ArrayTrait::new();
permission_addresses.append(ACCOUNT2.try_into().unwrap());
permission_addresses.append(token_owner);

let mut permissions = ArrayTrait::new();
permissions.append(true);
permissions.append(true);

start_cheat_caller_address(contract_address, owner);

let permissionable_dispatcher = IPermissionableDispatcher { contract_address };
permissionable_dispatcher.set_permission(permission_addresses, permissions);

let has_permission2 = permissionable_dispatcher.has_permission(owner, token_owner);
assert(has_permission2 == true, 'Account: permitted');

stop_cheat_caller_address(contract_address);

let new_class_hash = declare("UpgradedAccount").unwrap().class_hash;

// call the upgrade function
let dispatcher = IUpgradeableDispatcher { contract_address };

start_cheat_caller_address(contract_address, token_owner);
dispatcher.upgrade(new_class_hash);
stop_cheat_caller_address(contract_address);
}

0 comments on commit 8fab99f

Please sign in to comment.