Exemple #1
0
    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)