def test_getCrossConnectorReturn(self): connector_token2 = Address.from_string("cx" + os.urandom(20).hex()) connector_token2_weight = 500000 self.score.addConnector(connector_token2, connector_token2_weight, False) amount = 1000 self.score.getConnectorBalance = Mock(return_value=10000) with MultiPatch([ patch_property(IconScoreBase, 'msg', Message(self.owner)), patch.object(FixedMapFormula, 'calculate_cross_connector_return', return_value=1000) ]): result = self.score.get_cross_connector_return( self.initial_connector_token, connector_token2, amount) self.assertEqual(1000, result['amount']) self.assertEqual(0, result['fee']) # sets the fee to 1% self.score._max_conversion_fee.set(1000000) self.score._conversion_fee.set(10000) with MultiPatch([ patch_property(IconScoreBase, 'msg', Message(self.owner)), patch.object(FixedMapFormula, 'calculate_cross_connector_return', return_value=1000) ]): result = self.score.get_cross_connector_return( self.initial_connector_token, connector_token2, amount) self.assertEqual(980, result['amount']) self.assertEqual(20, result['fee'])
def test_tokenFallback_convert_called_wrong_params(self): # Mocks parent functions self.score.getOwner.return_value = self.owner self.score._is_active.return_value = True self.score._convert = Mock() network_address = Address.from_string("cx" + os.urandom(20).hex()) to_token = Address.from_string("cx" + os.urandom(20).hex()) # missing param `minReturn` data = { 'toToken': str(to_token), } token = self.initial_connector_token value = 100 with MultiPatch([ patch_property(IconScoreBase, 'msg', Message(token)), patch.object(InternalCall, 'other_external_call', return_value=network_address) ]): self.assertRaises(RevertException, self.score.tokenFallback, network_address, value, json_dumps(data).encode()) self.score._convert.assert_not_called()
def test_tokenFallback_cross_convert_called(self): # Mocks parent functions self.score.getOwner.return_value = self.owner self.score._is_active.return_value = True self.score._convert_cross_connector = Mock() network_address = Address.from_string("cx" + os.urandom(20).hex()) to_token = Address.from_string("cx" + os.urandom(20).hex()) to_token_weight = 500000 self.score.addConnector(to_token, to_token_weight, False) min_return = 10 data = {'toToken': str(to_token), 'minReturn': min_return} # success case token = self.initial_connector_token value = 100 with MultiPatch([ patch_property(IconScoreBase, 'msg', Message(token)), patch.object(InternalCall, 'other_external_call', return_value=network_address) ]): self.score.tokenFallback(network_address, value, json_dumps(data).encode()) assert_inter_call(self, self.score.address, self.score._registry.get(), 'getAddress', [ScoreRegistry.NETWORK]) self.score._convert_cross_connector.assert_called_with( network_address, token, to_token, value, min_return)
def test_isActive(self): with MultiPatch([ patch_property(IconScoreBase, 'msg', Message(self.owner)), patch.object(InternalCall, 'other_external_call'), ]) as mocks: mocks[1].return_value = self.score.address is_active = self.score.isActive() self.assertEqual(True, is_active) with MultiPatch([ patch_property(IconScoreBase, 'msg', Message(self.owner)), patch.object(InternalCall, 'other_external_call'), ]) as mocks: mocks[1].return_value = ZERO_SCORE_ADDRESS is_active = self.score.isActive() self.assertEqual(False, is_active)
def test_withdrawTokens(self): token_address = Address.from_string("cx" + "2" * 40) token_receiver = Address.from_string("hx" + "3" * 40) irc_token_score_interface = \ self.token_holder.create_interface_score(token_address, ProxyScore(ABCIRCToken)) irc_token_score_interface.transfer = Mock() with MultiPatch([ patch_property(IconScoreBase, 'msg', Message(self.token_owner)), patch.object(TokenHolder, 'create_interface_score', return_value=irc_token_score_interface) ]): amount = 10 # success case: withdraw 10 token self.token_holder.withdrawTokens(token_address, token_receiver, amount) self.token_holder.create_interface_score.assert_called_with( token_address, ProxyScore(ABCIRCToken)) irc_token_score_interface.transfer.assert_called_with( token_receiver, amount) self.token_holder.create_interface_score.reset_mock() irc_token_score_interface.transfer.reset_mock() # failure case: amount is under 0 invalid_amount = -1 self.assertRaises(RevertException, self.token_holder.withdrawTokens, token_address, token_receiver, invalid_amount) self.token_holder.create_interface_score.assert_not_called() irc_token_score_interface.transfer.assert_not_called() self.token_holder.create_interface_score.reset_mock() irc_token_score_interface.transfer.reset_mock() # failure case: 'to' address is this self.assertRaises(RevertException, self.token_holder.withdrawTokens, token_address, self.score_address, amount) self.token_holder.create_interface_score.assert_not_called() irc_token_score_interface.transfer.assert_not_called() self.token_holder.create_interface_score.reset_mock() irc_token_score_interface.transfer.reset_mock() # failure case: 'to' address is invalid address self.assertRaises(RevertException, self.token_holder.withdrawTokens, token_address, ZERO_SCORE_ADDRESS, amount) self.token_holder.create_interface_score.assert_not_called() irc_token_score_interface.transfer.assert_not_called() self.token_holder.create_interface_score.reset_mock() irc_token_score_interface.transfer.reset_mock()
def test_external_transfer(self): token_receiver = Address.from_string("hx" + "3" * 40) with MultiPatch([ patch_property(IconScoreBase, 'msg', Message(self.token_owner)), patch.object(IRCToken, '_transfer') ]): self.irc_token.transfer(token_receiver, 10) IRCToken._transfer.assert_called_with(self.token_owner, token_receiver, 10, b'None') self.irc_token.transfer(token_receiver, 10, b'test') IRCToken._transfer.assert_called_with(self.token_owner, token_receiver, 10, b'test')
def test_acceptTokenOwnership(self): with MultiPatch([ patch_property(IconScoreBase, 'msg', Message(self.owner)), patch.object(InternalCall, 'other_external_call'), ]): self.score.acceptTokenOwnership() self.score.require_owner_only.assert_called() assert_inter_call( self, self.score.address, self.score._token.get(), 'acceptOwnerShip', [] )
def test_getSaleReturn(self): amount = 1000 self.score.getConnectorBalance = Mock(return_value=10000) with MultiPatch([ patch_property(IconScoreBase, 'msg', Message(self.owner)), patch.object(InternalCall, 'other_external_call', return_value=10000), patch.object(FixedMapFormula, 'calculate_sale_return', return_value=1000) ]): result = self.score.get_sale_return(self.initial_connector_token, amount) self.assertEqual(1000, result['amount']) self.assertEqual(0, result['fee']) # sets the fee to 1% self.score._max_conversion_fee.set(1000000) self.score._conversion_fee.set(10000) with MultiPatch([ patch_property(IconScoreBase, 'msg', Message(self.owner)), patch.object(InternalCall, 'other_external_call', return_value=10000), patch.object(FixedMapFormula, 'calculate_sale_return', return_value=1000) ]): result = self.score.get_sale_return(self.initial_connector_token, amount) self.assertEqual(990, result['amount']) self.assertEqual(10, result['fee'])
def test_disableTokenTransfers(self): disable = True with MultiPatch([ patch_property(IconScoreBase, 'msg', Message(self.owner)), patch.object(InternalCall, 'other_external_call'), ]): self.score.disableTokenTransfers(disable) self.score.require_owner_only.assert_called() assert_inter_call( self, self.score.address, self.score._token.get(), 'disableTransfer', [disable] )
def test_transferTokenOwnership(self): new_owner = Address.from_string("hx" + "3" * 40) with MultiPatch([ patch_property(IconScoreBase, 'msg', Message(self.owner)), patch.object(InternalCall, 'other_external_call'), ]): self.score.transferTokenOwnership(new_owner) self.score.require_owner_only.assert_called() assert_inter_call( self, self.score.address, self.score._token.get(), 'transferOwnerShip', [new_owner])
def setUp(self): self.patcher = ScorePatcher(IcxToken) self.patcher.start() self.score_address = Address.from_string("cx" + "1" * 40) self.flexible_token_address = Address.from_string("cx" + "2" * 40) self.score = FlexibleTokenController(create_db(self.score_address)) self.owner = Address.from_string("hx" + "2" * 40) with MultiPatch([ patch_property(IconScoreBase, 'msg', Message(self.owner)), patch('contracts.utility.flexible_token_controller.require_valid_address') ]) as mocks: self.score.on_install(self.flexible_token_address) TokenHolder.on_install.assert_called_with(self.score) mocks[1].assert_called()
def test_getConnectorBalance(self): balance = 100 with MultiPatch([ patch_property(IconScoreBase, 'msg', Message(self.owner)), patch.object(InternalCall, 'other_external_call', return_value=balance) ]): result_balance = self.score.getConnectorBalance( self.initial_connector_token) assert_inter_call(self, self.score.address, self.initial_connector_token, 'balanceOf', [self.score.address]) self.assertEqual(result_balance, balance)
def test_withdrawFromToken(self): token = Address.from_string("cx" + "3" * 40) to = Address.from_string("hx" + "3" * 40) amount = 100 with MultiPatch([ patch_property(IconScoreBase, 'msg', Message(self.owner)), patch.object(InternalCall, 'other_external_call'), ]): self.score.withdrawFromToken(token, to, amount) self.score.require_owner_only.assert_called() assert_inter_call( self, self.score.address, self.score._token.get(), 'withdrawTokens', [token, to, amount] )
def test_updateRegistry(self): self.score._allow_registry_update.set(True) old_registry = self.score._registry.get() new_registry = Address.from_string("cx" + os.urandom(20).hex()) with MultiPatch([ patch_property(IconScoreBase, 'msg', Message(self.owner)), patch.object(InternalCall, 'other_external_call', return_value=new_registry) ]): self.score.updateRegistry() assert_inter_call(self, self.score.address, old_registry, 'getAddress', [ScoreRegistry.SCORE_REGISTRY]) self.assertEqual(old_registry, self.score._prev_registry.get()) self.assertEqual(new_registry, self.score._registry.get())
def test_convert_for_internal(self): min_return = 10 amount_to_convert = 5 convert_result_amount = 10 for_address = Address.from_string("hx" + "a" * 40) icx_token_score_interface = \ self.network_score.create_interface_score(self.icx_token, ProxyScore(ABCIcxToken)) icx_token_score_interface.withdrawTo = PropertyMock() irc_token_score_interface = \ self.network_score.create_interface_score(self.connector_token_list[0], ProxyScore(ABCIRCToken)) irc_token_score_interface.transfer = PropertyMock() # success case: finally converted token is Icx token ( Icx token SCORE's 'withdrawTo' method should be called ) converted_path = [ self.connector_token_list[0], self.flexible_token_address_list[0], self.icx_token ] # '_convert_by_path' method returns 'to' token Address, and converted amount with MultiPatch([ patch_property(IconScoreBase, 'msg', Message(self.network_owner)), patch.object(Network, '_convert_by_path', return_value=(self.icx_token, convert_result_amount)), patch.object(Network, 'create_interface_score', return_value=icx_token_score_interface) ]): # register icx_token self.network_score._icx_tokens[self.icx_token] = True self.network_score._convert_for_internal(converted_path, amount_to_convert, min_return, for_address) icx_token_score_interface.withdrawTo.assert_called_with( convert_result_amount, for_address) # success case: finally converted token is irc token ( token SCORE's 'transfer' method should be called ) converted_path = [ self.icx_token, self.flexible_token_address_list[0], self.connector_token_list[1] ] # '_convert_by_path' method returns 'to' token Address, and converted amount with MultiPatch([ patch_property(IconScoreBase, 'msg', Message(self.network_owner)), patch.object(Network, '_convert_by_path', return_value=(self.connector_token_list[1], convert_result_amount)), patch.object(Network, 'create_interface_score', return_value=irc_token_score_interface) ]): self.network_score._convert_for_internal(converted_path, amount_to_convert, min_return, for_address) irc_token_score_interface.transfer.assert_called_with( for_address, convert_result_amount, b'None')
def test_tokenFallback(self): # success case: input 'conversionResult' to _data ( convert_for_internal should not be called ) from_address = Address.from_string("hx" + "a" * 40) for_address = Address.from_string("hx" + "b" * 40) value = 10 min_return = 5 path = "{0},{1},{2}".format(str(self.connector_token_list[0]), str(self.flexible_token_address_list[0]), str(self.connector_token_list[1])) converted_path = [ Address.from_string(address) for address in path.split(",") ] data = dict() data["path"] = path data["minReturn"] = min_return data["for"] = str(for_address) stringed_data = json.dumps(data) decoded_data = stringed_data.encode(encoding='utf-8') with MultiPatch([ patch_property(IconScoreBase, 'msg', Message(self.connector_token_list[0])), patch.object(Network, '_convert_for_internal') ]): self.network_score.tokenFallback(from_address, value, b'conversionResult') self.network_score._convert_for_internal.assert_not_called() # failure case: input None data to the _data with MultiPatch([ patch_property(IconScoreBase, 'msg', Message(self.connector_token_list[0])), patch.object(Network, '_convert_for_internal') ]): self.assertRaises(RevertException, self.network_score.tokenFallback, from_address, value, b'None') self.assertRaises(RevertException, self.network_score.tokenFallback, from_address, value, None) # failure case: msg.sender is not equal to path[0] ( should be equal ) msg_sender = Address.from_string("cx" + "c" * 40) with MultiPatch([ patch_property(IconScoreBase, 'msg', Message(msg_sender)), patch.object(Network, '_convert_for_internal') ]): self.assertRaises(RevertException, self.network_score.tokenFallback, from_address, value, decoded_data) # success case: input valid data with MultiPatch([ patch_property(IconScoreBase, 'msg', Message(self.connector_token_list[0])), patch.object(Network, '_convert_for_internal'), patch.object(Network, '_require_valid_path'), patch('contracts.network.network.require_positive_value'), patch('contracts.network.network.require_valid_address'), ]) as mocks: self.network_score.tokenFallback(from_address, value, decoded_data) mocks[3].assert_called() # patched mock of require_positive_value mocks[4].assert_called() # patched mock of require_valid_address self.network_score._require_valid_path.assert_called_with( converted_path) self.network_score._convert_for_internal. \ assert_called_with(converted_path, value, min_return, for_address)
def test_transfer(self): eoa_token_receiver = Address.from_string("hx" + "3" * 40) score_token_receiver = Address.from_string("cx" + "3" * 40) with MultiPatch([ patch_property(IconScoreBase, 'msg', Message(self.token_owner)), patch.object(TokenFallbackInterface, 'tokenFallback') ]): # failure case: value is under 0 invalid_value = -1 self.assertRaises(RevertException, self.irc_token._transfer, self.token_owner, eoa_token_receiver, invalid_value, b'None') # failure case: value is higher than senders' total balance value = self.irc_token._balances[self.token_owner] + 1 self.assertRaises(RevertException, self.irc_token._transfer, self.token_owner, eoa_token_receiver, value, b'None') # success cass: transfer 10 token to token_receiver (EOA) with MultiPatch([ patch_property(IconScoreBase, 'msg', Message(self.token_owner)), patch.object(TokenFallbackInterface, 'tokenFallback') ]): value = 10 before_owner_balance = self.irc_token._balances[self.token_owner] before_eoa_receiver_balance = self.irc_token._balances[ eoa_token_receiver] self.irc_token._transfer(self.token_owner, eoa_token_receiver, value, b'None') self.assertEqual(before_owner_balance - value, self.irc_token._balances[self.token_owner]) self.assertEqual(before_eoa_receiver_balance + value, self.irc_token._balances[eoa_token_receiver]) TokenFallbackInterface.tokenFallback.assert_not_called() self.irc_token.Transfer.assert_called_with(self.token_owner, eoa_token_receiver, value, b'None') # success cass: transfer 10 token to token_receiver (SCORE) with MultiPatch([ patch_property(IconScoreBase, 'msg', Message(self.token_owner)), patch.object(TokenFallbackInterface, 'tokenFallback') ]): value = 10 before_owner_balance = self.irc_token._balances[self.token_owner] before_score_receiver_balance = self.irc_token._balances[ score_token_receiver] self.irc_token._transfer(self.token_owner, score_token_receiver, value, b'None') self.assertEqual(before_owner_balance - value, self.irc_token._balances[self.token_owner]) self.assertEqual(before_score_receiver_balance + value, self.irc_token._balances[score_token_receiver]) TokenFallbackInterface.tokenFallback.assert_called_with( self.token_owner, value, b'None') self.irc_token.Transfer.assert_called_with(self.token_owner, score_token_receiver, value, b'None')
def test_tokenFallback_deposit(self): # Mocks parent functions self.score.getOwner.return_value = self.owner self.score._is_active.return_value = False network_address = Address.from_string("cx" + os.urandom(20).hex()) # success case token = self.initial_connector_token sender = self.owner value = 100 with MultiPatch([ patch_property(IconScoreBase, 'msg', Message(token)), patch.object(InternalCall, 'other_external_call', return_value=network_address) ]): self.score.tokenFallback(sender, value, b'None') # the value is less than zero token = self.initial_connector_token sender = self.owner value = -100 with MultiPatch([ patch_property(IconScoreBase, 'msg', Message(token)), patch.object(InternalCall, 'other_external_call', return_value=network_address) ]): self.assertRaises(RevertException, self.score.tokenFallback, sender, value, b'None') # the sender is not owner token = self.initial_connector_token sender = Address.from_string("hx" + os.urandom(20).hex()) value = 100 with MultiPatch([ patch_property(IconScoreBase, 'msg', Message(token)), patch.object(InternalCall, 'other_external_call', return_value=network_address) ]): self.assertRaises(RevertException, self.score.tokenFallback, sender, value, b'None') # the token is not connector token token = Address.from_string("cx" + os.urandom(20).hex()) sender = self.owner value = 100 with MultiPatch([ patch_property(IconScoreBase, 'msg', Message(token)), patch.object(InternalCall, 'other_external_call', return_value=network_address) ]): self.assertRaises(RevertException, self.score.tokenFallback, sender, value, b'None') # the converter is active self.score._is_active.return_value = True token = self.initial_connector_token sender = self.owner value = 100 with MultiPatch([ patch_property(IconScoreBase, 'msg', Message(token)), patch.object(InternalCall, 'other_external_call', return_value=network_address) ]): self.assertRaises(RevertException, self.score.tokenFallback, sender, value, b'None')
def test_convertFor(self): icx_amount = 10 # failure case: input wrong path format min_return = 10 for_address = Address.from_string("hx" + "a" * 40) invalid_path = "{0}/{1}/{2}".format( str(self.icx_token), str(self.flexible_token_address_list[0]), str(self.connector_token_list[0])) with patch_property(IconScoreBase, 'msg', Message(self.network_owner, value=icx_amount)): self.assertRaises(InvalidParamsException, self.network_score.convertFor, invalid_path, min_return, for_address) # failure case: input path whose has invalid address as an element min_return = 10 for_address = Address.from_string("hx" + "a" * 40) invalid_path = "{0},{1},{2}".format(str(self.icx_token), str("invalid_address"), str(self.connector_token_list[1])) with patch_property(IconScoreBase, 'msg', Message(self.network_owner, value=icx_amount)): self.assertRaises(InvalidParamsException, self.network_score.convertFor, invalid_path, min_return, for_address) # failure case: input min return less than 0 invalid_min_return = -1 for_address = Address.from_string("hx" + "a" * 40) path = "{0},{1},{2}".format(str(self.icx_token), str(self.flexible_token_address_list[0]), str(self.connector_token_list[0])) with patch_property(IconScoreBase, 'msg', Message(self.network_owner, value=icx_amount)): self.assertRaises(RevertException, self.network_score.convertFor, path, invalid_min_return, for_address) # failure case: input path whose first address is not Icx token address min_return = 10 for_address = Address.from_string("hx" + "a" * 40) invalid_path = "{0},{1},{2}".format( str(self.connector_token_list[0]), str(self.flexible_token_address_list[0]), str(self.connector_token_list[1])) with patch_property(IconScoreBase, 'msg', Message(self.network_owner, value=icx_amount)): self.assertRaises(RevertException, self.network_score.convertFor, invalid_path, min_return, for_address) # success case: input valid path min_return = 10 for_address = Address.from_string("hx" + "a" * 40) path = "{0},{1},{2}".format(str(self.icx_token), str(self.flexible_token_address_list[0]), str(self.connector_token_list[1])) self.network_score._icx_tokens[self.icx_token] = True with MultiPatch([ patch_property(IconScoreBase, 'msg', Message(self.network_owner, value=icx_amount)), patch.object(Network, '_convert_for_internal') ]): self.network_score.convertFor(path, min_return, for_address) self.network_score.icx.transfer.assert_called_with( self.icx_token, icx_amount) converted_path = [ self.icx_token, self.flexible_token_address_list[0], self.connector_token_list[1] ] self.network_score._convert_for_internal.assert_called_with( converted_path, icx_amount, min_return, for_address)