def test_safe_cli_happy_path(self): accounts = [self.ethereum_test_account, Account.create()] account_addresses = [account.address for account in accounts] safe_address = self.deploy_test_safe( owners=account_addresses, threshold=2, initial_funding_wei=self.w3.toWei(1, "ether"), ).safe_address safe = Safe(safe_address, self.ethereum_client) safe_operator = SafeOperator(safe_address, self.ethereum_node_url) prompt_parser = PromptParser(safe_operator) random_address = Account.create().address self.assertEqual(safe_operator.accounts, set()) prompt_parser.process_command( f"load_cli_owners {self.ethereum_test_account.key.hex()}") self.assertEqual(safe_operator.default_sender, self.ethereum_test_account) self.assertEqual(safe_operator.accounts, {self.ethereum_test_account}) prompt_parser.process_command( f"send_ether {random_address} 1") # No enough signatures self.assertEqual(self.ethereum_client.get_balance(random_address), 0) value = 123 prompt_parser.process_command( f"load_cli_owners {accounts[1].key.hex()}") prompt_parser.process_command(f"send_ether {random_address} {value}") self.assertEqual(self.ethereum_client.get_balance(random_address), value) # Change threshold self.assertEqual(safe_operator.safe_cli_info.threshold, 2) self.assertEqual(safe.retrieve_threshold(), 2) prompt_parser.process_command("change_threshold 1") self.assertEqual(safe_operator.safe_cli_info.threshold, 1) self.assertEqual(safe.retrieve_threshold(), 1) # Approve Hash safe_tx_hash = Web3.keccak(text="hola") self.assertFalse( safe_operator.safe.retrieve_is_hash_approved( accounts[0].address, safe_tx_hash)) prompt_parser.process_command( f"approve_hash {safe_tx_hash.hex()} {accounts[0].address}") self.assertTrue( safe_operator.safe.retrieve_is_hash_approved( accounts[0].address, safe_tx_hash)) # Remove owner self.assertEqual(len(safe_operator.safe_cli_info.owners), 2) self.assertEqual(len(safe.retrieve_owners()), 2) prompt_parser.process_command(f"remove_owner {accounts[1].address}") self.assertEqual(safe_operator.safe_cli_info.owners, [self.ethereum_test_account.address]) self.assertEqual(safe.retrieve_owners(), [self.ethereum_test_account.address])
def test_approve_hash(self): safe_address = self.deploy_test_safe( owners=[self.ethereum_test_account.address] ).safe_address safe_operator = SafeOperator(safe_address, self.ethereum_node_url) safe_tx_hash = Web3.keccak(text="random-test") random_account = Account.create() with self.assertRaises(AccountNotLoadedException): safe_operator.approve_hash(safe_tx_hash, random_account.address) with self.assertRaises(NonExistingOwnerException): safe_operator.accounts.add(random_account) safe_operator.approve_hash(safe_tx_hash, random_account.address) safe_operator.accounts.add(self.ethereum_test_account) safe_operator.default_sender = self.ethereum_test_account self.assertTrue( safe_operator.approve_hash(safe_tx_hash, self.ethereum_test_account.address) ) with self.assertRaises(HashAlreadyApproved): safe_operator.approve_hash(safe_tx_hash, self.ethereum_test_account.address)
def test_add_owner(self): safe_address = self.deploy_test_safe( owners=[self.ethereum_test_account.address]).safe_address safe_operator = SafeOperator(safe_address, self.ethereum_node_url) with self.assertRaises(ExistingOwnerException): safe_operator.add_owner(self.ethereum_test_account.address) new_owner = Account.create().address with self.assertRaises(NotEnoughSignatures): safe_operator.add_owner(new_owner) safe_operator.accounts.add(self.ethereum_test_account) with self.assertRaises(SenderRequiredException): safe_operator.add_owner(new_owner) safe_operator.default_sender = self.ethereum_test_account safe = Safe(safe_address, self.ethereum_client) self.assertTrue(safe_operator.add_owner(new_owner)) self.assertIn(self.ethereum_test_account, safe_operator.accounts) self.assertIn(new_owner, safe.retrieve_owners())
def test_remove_owner(self): safe_address = self.deploy_test_safe( owners=[self.ethereum_test_account.address]).safe_address safe_operator = SafeOperator(safe_address, self.ethereum_node_url) random_address = Account.create().address with self.assertRaises(NonExistingOwnerException): safe_operator.remove_owner(random_address) safe_operator.load_cli_owners([self.ethereum_test_account.key.hex()]) new_owner = Account.create().address safe = Safe(safe_address, self.ethereum_client) self.assertTrue(safe_operator.add_owner(new_owner)) self.assertIn(new_owner, safe.retrieve_owners()) self.assertTrue(safe_operator.remove_owner(new_owner)) self.assertNotIn(new_owner, safe_operator.accounts) self.assertNotIn(new_owner, safe.retrieve_owners())
def setup_operator(self, number_owners: int = 1, version="1.1.1") -> SafeOperator: assert number_owners >= 1, "Number of owners cannot be less than 1!" if version == "1.1.1": safe_address = self.deploy_test_safe( owners=[self.ethereum_test_account.address]).safe_address elif version == "1.3.0": safe_address = self.deploy_test_safe_v1_3_0( owners=[self.ethereum_test_account.address]).address else: raise ValueError(f"{version} not supported") safe_operator = SafeOperator(safe_address, self.ethereum_node_url) safe_operator.load_cli_owners([self.ethereum_test_account.key.hex()]) for _ in range(number_owners - 1): account = Account.create() safe_operator.add_owner(account.address) safe_operator.load_cli_owners([account.key.hex()]) return safe_operator
def test_load_cli_owner(self, get_contract_mock: MagicMock): random_address = Account.create().address safe_operator = SafeOperator(random_address, self.ethereum_node_url) random_accounts = [Account.create() for _ in range(3)] random_accounts_keys = [account.key.hex() for account in random_accounts] self.assertFalse(safe_operator.accounts) safe_operator.load_cli_owners(random_accounts_keys) self.assertEqual(len(safe_operator.accounts), len(random_accounts_keys)) # Test accounts are not duplicated safe_operator.load_cli_owners(random_accounts_keys) self.assertEqual(len(safe_operator.accounts), len(random_accounts_keys)) # Test invalid accounts don't make the method break safe_operator.load_cli_owners(["aloha", Account.create().key.hex(), "bye"]) self.assertEqual(len(safe_operator.accounts), len(random_accounts_keys) + 1) # TODO Test setting default sender, mock getBalance # Test unload cli owner safe_operator.default_sender = random_accounts[0] number_of_accounts = len(safe_operator.accounts) safe_operator.unload_cli_owners(["aloha", random_accounts[0].address, "bye"]) self.assertEqual(len(safe_operator.accounts), number_of_accounts - 1) self.assertFalse(safe_operator.default_sender)