diff --git a/addresses.txt b/addresses.txt index 311e945..53d6d8b 100644 --- a/addresses.txt +++ b/addresses.txt @@ -1,26 +1,19 @@ -TESTNET: +----------------------------------------------------------------------------------------------- +MAINNET v1: -Registry: - - ClassHash: 0x7e616bcaaaaf4d22f756e0cabe0e312b6b8d753451ce0f4f6fc44936aae5ec7 - - Contract: 0x57cf5b3ac51e9ab1735f0720425d3889ac500fc8deac6567ad8163fd210aa92 +Registry; + - ClassHash: 0x2fee320389750aef9d6fe7d95754a75a68d4448c019cee2a34cb6b698972db9 + - Contract: 0x1b0ef7a47d9db8652f8a9010ecaf3e6537442bfab3afed13449b571fa1da37a Account: - - ClassHash: 0xe01784f9a93db5171ed32eaee0610326969980ecbcc4325753428d8227b96b - -Sample NFT: - - ClassHash: 0x6eac43a8dbb9431f51797486b08de7234420860d2051fa9bd8e9ce4b6203739 - - Contract: 0x6aaf25616b3177b62b8aa2212cb19affb7cf52a62d97d260c50c53f13547111 - -Sample TBA: - - Contract: 0x01d6e561Eb81D2E91c626048e9e324526AD6c63034c8Ef7D605faF082A9673a3 - - salt: 2030 ------------------------------------------------------------------------------------------------ + - ClassHash: 0x11bc9fabead984d714cf82ec46ffa23f4558f27ae73561542fed9fa8fb510ae -MAINNET: +------------------------------------------------------------------------------------------------ +MAINNET v2: Registry; - ClassHash: 0x2fee320389750aef9d6fe7d95754a75a68d4448c019cee2a34cb6b698972db9 - Contract: 0x1b0ef7a47d9db8652f8a9010ecaf3e6537442bfab3afed13449b571fa1da37a Account: - - ClassHash: 0x11bc9fabead984d714cf82ec46ffa23f4558f27ae73561542fed9fa8fb510ae \ No newline at end of file + - ClassHash: 0x499ef439944ff0a477c4ecc14785ad31f4c12300993e1ce6568f9c1f2c24c09 \ No newline at end of file diff --git a/src/account/account.cairo b/src/account/account.cairo index 6346b50..0258e11 100644 --- a/src/account/account.cairo +++ b/src/account/account.cairo @@ -142,6 +142,9 @@ mod Account { // @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: ContractState, duration: u64) { + self._assert_only_owner(); + let (lock_status, _) = self._is_locked(); + assert(!lock_status, 'Account: account already locked'); let current_timestamp = get_block_timestamp(); let unlock_time = current_timestamp + duration; self._unlock_timestamp.write(unlock_time); diff --git a/tests/test_account.cairo b/tests/test_account.cairo index 6579b79..3924f17 100644 --- a/tests/test_account.cairo +++ b/tests/test_account.cairo @@ -238,7 +238,12 @@ fn test_locking() { let dispatcher = IAccountDispatcher { contract_address }; let lock_duration = 3000_u64; + // get token owner + let token_dispatcher = IERC721Dispatcher { contract_address: erc721_contract_address }; + let token_owner = token_dispatcher.ownerOf(u256_from_felt252(1)); + // lock account + start_prank(CheatTarget::One(contract_address), token_owner); start_warp(CheatTarget::One(contract_address), 1000); dispatcher.lock(lock_duration); stop_warp(CheatTarget::One(contract_address)); @@ -258,7 +263,12 @@ fn test_should_not_execute_when_locked() { let dispatcher = IAccountSafeDispatcher { contract_address }; let lock_duration = 3000_u64; + // get token owner + let token_dispatcher = IERC721Dispatcher { contract_address: erc721_contract_address }; + let token_owner = token_dispatcher.ownerOf(u256_from_felt252(1)); + // lock account + start_prank(CheatTarget::One(contract_address), token_owner); start_warp(CheatTarget::One(contract_address), 1000); dispatcher.lock(lock_duration); stop_warp(CheatTarget::One(contract_address)); @@ -267,13 +277,6 @@ fn test_should_not_execute_when_locked() { let test_contract = declare('HelloStarknet'); let test_address = test_contract.deploy(@array![]).unwrap(); - // get token owner - let token_dispatcher = IERC721Dispatcher { contract_address: erc721_contract_address }; - let token_owner = token_dispatcher.ownerOf(u256_from_felt252(1)); - - // start prank - start_prank(CheatTarget::One(contract_address), token_owner); - // confirm call to execute fails let mut calldata = array![100]; let call = Call { @@ -299,23 +302,72 @@ fn test_should_not_upgrade_when_locked() { let dispatcher = IAccountSafeDispatcher { contract_address }; let lock_duration = 3000_u64; + // get token owner + let token_dispatcher = IERC721Dispatcher { contract_address: erc721_contract_address }; + let token_owner = token_dispatcher.ownerOf(u256_from_felt252(1)); + // lock account + start_prank(CheatTarget::One(contract_address), token_owner); start_warp(CheatTarget::One(contract_address), 1000); dispatcher.lock(lock_duration); stop_warp(CheatTarget::One(contract_address)); let new_class_hash = declare('UpgradedAccount').class_hash; + // call the upgrade function + match dispatcher.upgrade(new_class_hash) { + Result::Ok(_) => panic_with_felt252('should have panicked'), + Result::Err(panic_data) => { + stop_prank(CheatTarget::One(contract_address)); + panic_data.print(); + return(); + } + } +} + +#[test] +fn test_should_not_lock_if_not_owner() { + let (contract_address, erc721_contract_address) = __setup__(); + let dispatcher = IAccountSafeDispatcher { contract_address }; + let lock_duration = 3000_u64; + + // call the lock function + 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::Err(panic_data) => { + stop_prank(CheatTarget::One(contract_address)); + stop_warp(CheatTarget::One(contract_address)); + panic_data.print(); + return(); + } + } +} + +#[test] +fn test_should_not_lock_if_already_locked() { + let (contract_address, erc721_contract_address) = __setup__(); + let dispatcher = IAccountSafeDispatcher { contract_address }; + let lock_duration = 3000_u64; + // get token owner let token_dispatcher = IERC721Dispatcher { contract_address: erc721_contract_address }; let token_owner = token_dispatcher.ownerOf(u256_from_felt252(1)); - - // call the upgrade function + + // lock account start_prank(CheatTarget::One(contract_address), token_owner); - match dispatcher.upgrade(new_class_hash) { + start_warp(CheatTarget::One(contract_address), 1000); + dispatcher.lock(lock_duration); + stop_warp(CheatTarget::One(contract_address)); + + // call the lock function again + start_warp(CheatTarget::One(contract_address), 1000); + match dispatcher.lock(lock_duration) { Result::Ok(_) => panic_with_felt252('should have panicked'), Result::Err(panic_data) => { stop_prank(CheatTarget::One(contract_address)); + stop_warp(CheatTarget::One(contract_address)); panic_data.print(); return(); } @@ -328,7 +380,12 @@ fn test_should_unlock_once_duration_ends() { let dispatcher = IAccountDispatcher { contract_address }; let lock_duration = 3000_u64; + // get token owner + let token_dispatcher = IERC721Dispatcher { contract_address: erc721_contract_address }; + let token_owner = token_dispatcher.ownerOf(u256_from_felt252(1)); + // lock account + start_prank(CheatTarget::One(contract_address), token_owner); start_warp(CheatTarget::One(contract_address), 1000); dispatcher.lock(lock_duration); stop_warp(CheatTarget::One(contract_address));