Exemplo n.º 1
0
def create_address(prefix: int = 0, data: bytes = None) -> 'Address':
    if data is None:
        data = create_tx_hash()
    hash_value = hashlib.sha3_256(data).digest()
    return Address(AddressPrefix(prefix), hash_value[-20:])
class TestWalletManager(TestCase):
    sender = Address(AddressPrefix(0), b"1" * 20)

    def setUp(self):
        self.key_value_mock = MockKeyValueDatabase({})
        self.db = IconScoreDatabase(self.sender,
                                    ContextDatabase(self.key_value_mock))
        IconScoreBase.get_owner = lambda score_object, score_address: self.sender

        self.smart_wallet = SmartWallet(self.db)
        type(self.smart_wallet).msg = PropertyMock(
            return_value=Message(sender=self.sender, value=10000))
        SmartWallet.Account = lambda _self, account: None
        self.smart_wallet.on_install(
            json.dumps({
                "id": 0,
                "tokenType": "icx",
                "balance": 3000,
                "sendLimit": 1000,
                "totalUsed": 500,
                "lastUsedDate": "2018-11-21",
                "dids": []
            }))
        # print test name
        print("=====================================================")
        print(f"{self._testMethodName}")

    def tearDown(self):
        print(f"end test")
        print("=====================================================")

    def test_transfer_direct_send(self):
        """GIVEN an account that has token icx and required did is nothing
        WHEN send icx lower than today used_limits
        THEN account update balance and limit and register event send_transaction
        """
        # GIVEN
        self.__setup_no_did_transfer_env()

        def TransferSuccessMock(contract, account_id: int, token_type: str,
                                token_address: str, to: str, amount: int):
            self.assertEqual(0, account_id)
            self.assertEqual("icx", token_type)
            self.assertEqual("", token_address)
            self.assertEqual("hx111111111111111111111111111111111111111111",
                             to)
            self.assertEqual(500, amount)

        SmartWallet.TransferSuccess = TransferSuccessMock

        # WHEN
        self.smart_wallet.transfer(
            account_id=0,
            token_type="icx",
            contract_addr="",
            to="hx111111111111111111111111111111111111111111",
            amount=500)

        # THEN
        updated_account = json.loads(self.smart_wallet._accounts[0])
        self.assertEqual(updated_account["totalUsed"], 1000)
        self.assertEqual(updated_account["balance"], 2500)

    def __setup_no_did_transfer_env(self):
        Icx.transfer = lambda contract, addr_to, amount: None
        self.smart_wallet._accounts = [
            json.dumps({
                "id": 0,
                "tokenType": "icx",
                "balance": 3000,
                "sendLimit": 1000,
                "totalUsed": 500,
                "lastUsedDate": "2018-11-21",
                "dids": []
            })
        ]
        type(self.smart_wallet).block = PropertyMock(
            return_value=Block(0, 1542773377))

    def test_transfer_amount_is_higher_than_balance_must_raise_revert(self):
        # GIVEN
        self.__setup_no_did_transfer_env()
        # WHEN THEN

        self.assertRaises(RevertException,
                          self.smart_wallet.transfer,
                          account_id=0,
                          token_type="icx",
                          contract_addr="",
                          to="hx111111111111111111111111111111111111111111",
                          amount=3500)

    def test_transfer_amount_is_higher_than_left_today_limit_must_raise_revert(
            self):
        # GIVEN
        self.__setup_no_did_transfer_env()
        # WHEN THEN

        self.assertRaises(RevertException,
                          self.smart_wallet.transfer,
                          account_id=0,
                          token_type="icx",
                          contract_addr="",
                          to="hx111111111111111111111111111111111111111111",
                          amount=600)

    def test_transfer_amount_is_higher_than_left_today_limit_but_can_if_day_change(
            self):
        # GIVEN
        self.__setup_no_did_transfer_env()
        # setup last date is 11_21
        ts_11_23 = 1542993377
        type(self.smart_wallet).block = PropertyMock(
            return_value=Block(0, ts_11_23))

        # THEN
        def TransferSuccessMock(contract, account_id: int, token_type: str,
                                token_address: str, to: str, amount: int):
            self.assertEqual(0, account_id)
            self.assertEqual("icx", token_type)
            self.assertEqual("", token_address)
            self.assertEqual("hx111111111111111111111111111111111111111111",
                             to)
            self.assertEqual(600, amount)

        SmartWallet.TransferSuccess = TransferSuccessMock
        # WHEN
        self.smart_wallet.transfer(
            account_id=0,
            token_type="icx",
            contract_addr="",
            to="hx111111111111111111111111111111111111111111",
            amount=600)
        # THEN
        account = json.loads(self.smart_wallet._accounts[0])
        self.assertEqual(2400, account["balance"])
        self.assertEqual(600, account["totalUsed"])
        self.assertEqual("2018-11-23", account["lastUsedDate"])

    def test_pending_transaction(self):
        """ GIVEN account with did_list not empty
        WHEN call transfer with transferable info
        THEN a transaction will be pending
        """
        # GIVEN
        self.__setup_processing_pending_tx()

        # THEN
        def PendingMock(_self, pending_tx: str):
            print(pending_tx)
            pending_tx_as_dict = json.loads(pending_tx)
            self.assertEqual(1, pending_tx_as_dict["id"])
            self.assertEqual(0, pending_tx_as_dict["from"])
            self.assertEqual("hx" + "1" * 40, pending_tx_as_dict["to"])
            self.assertEqual("icx", pending_tx_as_dict["tokenType"])
            self.assertEqual("", pending_tx_as_dict["contractAddr"])
            self.assertEqual(500, pending_tx_as_dict["amount"])
            self.assertEqual(["kakao", "chainId"], pending_tx_as_dict["dids"])

        SmartWallet.Pending = PendingMock

        # WHEN
        self.smart_wallet.transfer(account_id=0,
                                   token_type="icx",
                                   contract_addr="",
                                   to="hx" + "1" * 40,
                                   amount=500)

        # THEN
        pending_tx_db = DictDB(PENDING_TX, self.smart_wallet.db, str, 1)
        pending_tx_as_dict = json.loads(pending_tx_db[1])
        self.assertEqual(1, pending_tx_as_dict["id"])
        self.assertEqual(0, pending_tx_as_dict["from"])
        self.assertEqual("hx" + "1" * 40, pending_tx_as_dict["to"])
        self.assertEqual("icx", pending_tx_as_dict["tokenType"])
        self.assertEqual("", pending_tx_as_dict["contractAddr"])
        self.assertEqual(500, pending_tx_as_dict["amount"])
        self.assertEqual(["kakao", "chainId"], pending_tx_as_dict["dids"])

        pending_tx_list = json.loads(
            VarDB(PENDING_TX_ID_LIST, self.smart_wallet.db, str).get())
        self.assertEqual(1, len(pending_tx_list))
        self.assertEqual(1, pending_tx_list[0])

        last_tx_id = VarDB(LAST_TX_ID, self.smart_wallet.db, int).get()
        self.assertEqual(1, last_tx_id)

    def __setup_processing_pending_tx(self):
        Icx.transfer = lambda contract, addr_to, amount: None
        self.smart_wallet._accounts = [
            json.dumps({
                "id": 0,
                "tokenType": "icx",
                "balance": 3000,
                "sendLimit": 1000,
                "totalUsed": 500,
                "lastUsedDate": "2018-11-21",
                "dids": ["kakao", "chainId"]
            })
        ]
        type(self.smart_wallet).block = PropertyMock(
            return_value=Block(0, 1542773377))

    def test_approval(self):
        """ GIVEN account with two dids, and pending one tx from that account,
        WHEN call approval twice
        THEN first approval remove dids in pending tx, second remove pending tx
        with TransferSuccess event
        """
        # GIVEN
        self.__setup_processing_pending_tx()
        SmartWallet.Pending = lambda _self, pending_tx: None

        self.smart_wallet.transfer(account_id=0,
                                   token_type="icx",
                                   contract_addr="",
                                   to="hx" + "1" * 40,
                                   amount=500)

        # first WHEN
        def FirstApprovalMock(_self, tx_id, did):
            self.assertEqual(1, tx_id)
            self.assertEqual("kakao", did)

        SmartWallet.Approval = FirstApprovalMock
        self.smart_wallet.approval(1, "kakao", "true")

        # first THEN
        pending_tx_db = DictDB(PENDING_TX, self.smart_wallet.db, str, 1)
        pending_tx_as_dict = json.loads(pending_tx_db[1])
        self.assertEqual(["chainId"], pending_tx_as_dict["dids"])

        # second WHEN
        def SecondApprovalMock(_self, tx_id, did):
            self.assertEqual(1, tx_id)
            self.assertEqual("chainId", did)

        SmartWallet.Approval = SecondApprovalMock
        SmartWallet.TransferSuccess = lambda _self, account_id, token_type, contract_addr, to, amount: None

        self.smart_wallet.approval(1, "chainId", "true")

        # second THEN
        self.assertEqual("", pending_tx_db[1])
        self.assertEqual(
            json.dumps([]),
            VarDB(PENDING_TX_ID_LIST, self.smart_wallet.db, str).get())

    def test_transfer_account_to_account(self):
        """ GIVEN two accounts
        WHEN to address is 1
        THEN transfer success to account
        """
        # GIVEN
        self.__setup_no_did_transfer_env()
        self.smart_wallet._accounts\
            .append(json.dumps({
                    "id": 1,
                    "tokenType": "icx",
                    "balance": 3000,
                    "sendLimit": 1000,
                    "totalUsed": 500,
                    "lastUsedDate": "2018-11-21",
                    "dids": ["kakao", "chainId"]
            })
        )

        def TransferSuccessMock(contract, account_id: int, token_type: str,
                                token_address: str, to: str, amount: int):
            self.assertEqual(0, account_id)
            self.assertEqual("icx", token_type)
            self.assertEqual("", token_address)
            self.assertEqual("1", to)
            self.assertEqual(500, amount)

        SmartWallet.TransferSuccess = TransferSuccessMock

        self.smart_wallet.transfer(0, "icx", "", "1", 500)

        # THEN
        account0 = json.loads(self.smart_wallet._accounts[0])
        assert account0['balance'] == 2500
        assert account0['totalUsed'] == 1000

        account1 = json.loads(self.smart_wallet._accounts[1])
        assert account1['balance'] == 3500
Exemplo n.º 3
0
def create_address(prefix: AddressPrefix = AddressPrefix.EOA) -> 'Address':
    return Address.from_bytes(prefix.to_bytes(1, 'big') + os.urandom(20))
class TestSmartWallet(TestCase):
    sender = Address(AddressPrefix(0), b"1" * 20)

    def setUp(self):
        self.key_value_mock = MockKeyValueDatabase({})
        self.db = IconScoreDatabase(self.sender,
                                    ContextDatabase(self.key_value_mock))
        IconScoreBase.get_owner = lambda score_object, score_address: self.sender

        self.smart_wallet = SmartWallet(self.db)
        type(self.smart_wallet).msg = PropertyMock(
            return_value=Message(sender=self.sender, value=10000))

        # print test name
        print(f"===== {self._testMethodName} ==========================")

    def tearDown(self):
        print("=================================================")

    def test_add_account(self):
        """
        GIVEN account to put
        WHEN on_install and call from the method `add_account`
        THEN _accounts have all of accounts (3)
        """
        # GIVEN
        SmartWallet.Account = lambda _self, acccount: None
        # WHEN
        sample_account = {
            "id": 0,
            "tokenType": "test_token_type",
            "contractAddr": "test_contract_addr",
            "balance": "test_balance",
            "sendLimit": "test_send_limit",
            "totalUsed": "test_total_used",
            "lastUsedDate": "test_last_used_date",
            "dids": "test_dids"
        }
        str_sample_account = json.dumps(sample_account)
        self.smart_wallet.on_install(str_sample_account)
        self.smart_wallet.add_account(str_sample_account)
        self.smart_wallet.add_account(str_sample_account)
        # THEN
        assert len(self.smart_wallet._accounts) == 3

    def test_change_setting_value(self):
        """
        GIVEN the previous account
        WHEN the previous account is updated
        THEN the account change to the new one
        """
        # GIVEN
        SmartWallet.Account = lambda _self, account: None
        sample_account = {
            "id": 0,
            "tokenType": "test_token_type",
            "contractAddr": "test_contract_addr",
            "balance": "test_balance",
            "sendLimit": "test_send_limit",
            "totalUsed": "test_total_used",
            "lastUsedDate": "test_last_used_date",
            "dids": "test_dids"
        }
        str_sample_account = json.dumps(sample_account)
        self.smart_wallet.on_install(str_sample_account)
        self.smart_wallet.add_account(str_sample_account)
        # WHEN
        sample_account["id"] = 1
        sample_account["tokenType"] = "new"
        str_sample_account = json.dumps(sample_account)
        self.smart_wallet._change_setting_value(account=str_sample_account)
        json_sample_account = json.loads(self.smart_wallet._accounts[1])
        # THEN
        self.assertEqual(json_sample_account["tokenType"], "new")

    @only_owner
    def _test_only_owner(self):
        pass

    def test_only_owner(self):
        self.msg = MagicMock(return_value=self.smart_wallet.owner)
        self.msg.sender = self.msg()
        self.owner = self.msg()
        self._test_only_owner()

        self.msg.sender = 123
        self.assertRaises(AttributeError, self._test_only_owner)