def test_close_trustline_interest_overflows( currency_network_adapter_custom_interest: CurrencyNetworkAdapter, accounts, web3): """Test that if the interests would put the balance above `max_balance` then the call to close the trustline with direct transfer fails""" from_address = accounts[0] to_address = accounts[1] current_time = web3.eth.getBlock("latest")["timestamp"] one_year_ago = current_time - SECONDS_PER_YEAR balance = 100 currency_network_adapter_custom_interest.set_account( from_address, to_address, creditline_given=1_000, creditline_received=1_000, interest_rate_given=100, interest_rate_received=100, m_time=one_year_ago, balance=balance, ) currency_network_adapter_custom_interest.close_trustline_by_direct_transfer( from_address, to_address, max_balance=balance, should_fail=True)
def test_set_account_not_owner( currency_network_adapter: CurrencyNetworkAdapter, not_owner, accounts): creditor = accounts[1] debtor = accounts[2] creditline_given = 123 creditline_received = 321 interest_rate_given = 1 interest_rate_received = 2 is_frozen = True m_time = 123456 balance = 1000 currency_network_adapter.set_account( creditor, debtor, creditline_given=creditline_given, creditline_received=creditline_received, interest_rate_given=interest_rate_given, interest_rate_received=interest_rate_received, is_frozen=is_frozen, m_time=m_time, balance=balance, should_fail=True, transaction_options={"from": not_owner}, )
def test_close_trustline_direct_transfer_event( currency_network_adapter_with_trustlines: CurrencyNetworkAdapter, accounts, web3): from_address = accounts[1] to_address = accounts[0] ( creditline_given, creditline_received, interest_rate_given, interest_rate_received, is_frozen, m_time, balance, ) = currency_network_adapter_with_trustlines.get_account( from_address, to_address) currency_network_adapter_with_trustlines.close_trustline_by_direct_transfer( from_address, to_address, min_balance=10_000, max_balance=20_000) block_time = web3.eth.getBlock("latest")["timestamp"] last_block_number = web3.eth.blockNumber balance_with_interests = ( currency_network_adapter_with_trustlines.balance_with_interests( balance, m_time, block_time, interest_rate_given, interest_rate_received)) assert currency_network_adapter_with_trustlines.is_trustline_closed( from_address, to_address) transfer_event_args = get_single_event_of_contract( currency_network_adapter_with_trustlines.contract, "Transfer", last_block_number)["args"] assert transfer_event_args["_from"] == from_address assert transfer_event_args["_to"] == to_address assert transfer_event_args["_value"] == balance_with_interests assert transfer_event_args["_extraData"] == b"" balance_update_event_args = get_single_event_of_contract( currency_network_adapter_with_trustlines.contract, "BalanceUpdate", last_block_number, )["args"] assert balance_update_event_args["_from"] == from_address assert balance_update_event_args["_to"] == to_address assert balance_update_event_args["_value"] == 0 trustline_update_event_args = get_single_event_of_contract( currency_network_adapter_with_trustlines.contract, "TrustlineUpdate", last_block_number, )["args"] assert trustline_update_event_args["_creditor"] == from_address assert trustline_update_event_args["_debtor"] == to_address assert trustline_update_event_args["_creditlineGiven"] == 0 assert trustline_update_event_args["_creditlineReceived"] == 0 assert trustline_update_event_args["_interestRateGiven"] == 0 assert trustline_update_event_args["_interestRateReceived"] == 0 assert trustline_update_event_args["_isFrozen"] is False
def test_balance(currency_network_contract, accounts): contract = currency_network_contract currency_network_adapter = CurrencyNetworkAdapter(currency_network_contract) currency_network_adapter.set_account( accounts[0], accounts[1], creditline_given=10, creditline_received=20, balance=4 ) assert contract.functions.balance(accounts[0], accounts[1]).call() == 4 assert contract.functions.balance(accounts[1], accounts[0]).call() == -4
def test_close_trustline_direct_transfer_with_balance( currency_network_adapter_with_trustlines: CurrencyNetworkAdapter, accounts): from_address = accounts[1] to_address = accounts[0] assert (currency_network_adapter_with_trustlines.balance( from_address, to_address) == 10_000) currency_network_adapter_with_trustlines.close_trustline_by_direct_transfer( from_address, to_address, min_balance=10_000, max_balance=20_000) assert currency_network_adapter_with_trustlines.is_trustline_closed( from_address, to_address)
def test_close_trustline_positive_balance( currency_network_contract_with_trustlines, accounts): currency_network_adapter = CurrencyNetworkAdapter( currency_network_contract_with_trustlines) A, B, C, D, E, *rest = accounts def get_balance(): return currency_network_adapter.balance(B, A) assert get_balance() > 0 currency_network_adapter.close_trustline(B, A, path=[B, A, C, D, B]) assert get_balance() == 0 assert currency_network_adapter.is_trustline_closed(A, B)
def currency_network_contract_with_trustlines(web3, accounts): contract = deploy_network(web3, **NETWORK_SETTING) for (A, B, clAB, clBA) in trustlines: CurrencyNetworkAdapter(contract).set_account( accounts[A], accounts[B], creditline_given=clAB, creditline_received=clBA ) return contract
def test_set_account( currency_network_adapter: CurrencyNetworkAdapter, owner, accounts, creditor_index, debtor_index, web3, ): creditor = accounts[creditor_index] debtor = accounts[debtor_index] creditline_given = 123 creditline_received = 321 interest_rate_given = 1 interest_rate_received = 2 is_frozen = True old_mtime = 123456 balance = 1000 currency_network_adapter.contract.functions.setAccount( creditor, debtor, creditline_given, creditline_received, interest_rate_given, interest_rate_received, is_frozen, old_mtime, balance, ).transact({"from": owner}) # Interests are applied when setting account for migration new_mtime = web3.eth.getBlock(web3.eth.blockNumber)["timestamp"] new_balance = currency_network_adapter.balance_with_interests( balance, old_mtime, new_mtime, interest_rate_given, interest_rate_received) assert currency_network_adapter.check_account( creditor, debtor, creditline_given, creditline_received, interest_rate_given, interest_rate_received, is_frozen, new_mtime, new_balance, )
def test_freezing_trustline_via_set_account( currency_network_contract_with_trustlines, accounts ): network = currency_network_contract_with_trustlines A, B, *rest = accounts CurrencyNetworkAdapter(network).set_account(A, B, is_frozen=True) assert network.functions.isTrustlineFrozen(accounts[0], accounts[1]).call() is True
def test_cannot_reopen_closed_trustline(currency_network_contract, accounts): currency_network_adapter = CurrencyNetworkAdapter( currency_network_contract) A, B, *rest = accounts currency_network_adapter.update_trustline(A, B, creditline_given=1000, creditline_received=1000) currency_network_adapter.close_trustline(A, B) currency_network_adapter.update_trustline(B, A, creditline_given=1000, creditline_received=1000) assert currency_network_adapter.is_trustline_closed(A, B)
def test_set_account_events( currency_network_adapter: CurrencyNetworkAdapter, owner, accounts, creditor_index, debtor_index, web3, ): creditor = accounts[creditor_index] debtor = accounts[debtor_index] creditline_given = 123 creditline_received = 321 interest_rate_given = 1 interest_rate_received = 2 is_frozen = True old_mtime = 123456 balance = 1000 block_number = web3.eth.blockNumber currency_network_adapter.contract.functions.setAccount( creditor, debtor, creditline_given, creditline_received, interest_rate_given, interest_rate_received, is_frozen, old_mtime, balance, ).transact({"from": owner}) new_mtime = web3.eth.getBlock(web3.eth.blockNumber)["timestamp"] new_balance = currency_network_adapter.balance_with_interests( balance, old_mtime, new_mtime, interest_rate_given, interest_rate_received) trustline_update_event_args = get_single_event_of_contract( currency_network_adapter.contract, "TrustlineUpdate", block_number)["args"] assert trustline_update_event_args["_creditor"] == creditor assert trustline_update_event_args["_debtor"] == debtor assert trustline_update_event_args["_creditlineGiven"] == creditline_given assert trustline_update_event_args[ "_creditlineReceived"] == creditline_received assert trustline_update_event_args[ "_interestRateGiven"] == interest_rate_given assert (trustline_update_event_args["_interestRateReceived"] == interest_rate_received) assert trustline_update_event_args["_isFrozen"] == is_frozen balance_update_event_args = get_single_event_of_contract( currency_network_adapter.contract, "BalanceUpdate", block_number)["args"] assert balance_update_event_args["_from"] == creditor assert balance_update_event_args["_to"] == debtor assert balance_update_event_args["_value"] == new_balance
def test_close_trustline_max_balance_fails( currency_network_adapter_custom_interest: CurrencyNetworkAdapter, accounts): """Test that trying to close a trustline with max balance fails when the balance exceeds max balance""" from_address = accounts[0] to_address = accounts[1] balance = 100 currency_network_adapter_custom_interest.set_account( from_address, to_address, creditline_given=1_000, creditline_received=1_000, balance=balance, ) currency_network_adapter_custom_interest.close_trustline_by_direct_transfer( from_address, to_address, max_balance=balance - 1, should_fail=True)
def currency_network_contract_with_max_uint_trustlines( currency_network_contract_no_fees, chain, web3, accounts): """Currency network that uses max_unit64 for all credit limits""" currency_network_contract = currency_network_contract_no_fees currency_network_adapter = CurrencyNetworkAdapter( currency_network_contract) for a in accounts[:3]: for b in accounts[:3]: if a is b: continue currency_network_adapter.set_account( a, b, creditline_given=MAX_UINT_64, creditline_received=MAX_UINT_64, interest_rate_given=1, interest_rate_received=1, ) return currency_network_contract
def currency_network_contract_authorized_with_trustlines( web3, global_authorized_address, accounts): network_setting = NETWORK_SETTING network_setting["authorized_addresses"] = [global_authorized_address] contract = deploy_network(web3, **NETWORK_SETTING) for (A, B, clAB, clBA) in trustlines: CurrencyNetworkAdapter(contract).set_account(accounts[A], accounts[B], creditline_given=clAB, creditline_received=clBA) return contract
def currency_network_contract_with_trustlines(chain, web3, accounts, interest_rate): currency_network_contract = deploy_network(web3, **NETWORK_SETTING) currency_network_adapter = CurrencyNetworkAdapter( currency_network_contract) current_time = int(time.time()) chain.time_travel(current_time + 10) for a in accounts[:4]: for b in accounts[:4]: if a is b: continue currency_network_adapter.set_account( a, b, creditline_given=1_000_000, creditline_received=1_000_000, interest_rate_given=interest_rate, interest_rate_received=interest_rate, m_time=current_time, ) currency_network_adapter.transfer(10000, path=[accounts[0], accounts[1]]) chain.time_travel(current_time + SECONDS_PER_YEAR) return currency_network_contract
def test_cannot_close_with_balance(currency_network_contract, accounts): currency_network_adapter = CurrencyNetworkAdapter( currency_network_contract) A, B, *rest = accounts currency_network_adapter.update_trustline(A, B, creditline_given=1000, creditline_received=1000, accept=True) currency_network_adapter.transfer(20, path=[A, B]) with pytest.raises(eth_tester.exceptions.TransactionFailed): currency_network_adapter.close_trustline(A, B)
def test_close_trustline_max_balance( currency_network_contract_with_max_uint_trustlines, accounts): """Test that closing a trustline with a triangular transfer as big as max_uint64 succeed""" currency_network_adapter = CurrencyNetworkAdapter( currency_network_contract_with_max_uint_trustlines) max_uint64 = 2**64 - 1 A, B, C, *rest = accounts currency_network_adapter.set_account( A, B, creditline_given=max_uint64, creditline_received=max_uint64, interest_rate_given=1, interest_rate_received=1, balance=max_uint64, ) def get_balance(): return currency_network_adapter.balance(A, B) assert get_balance() == max_uint64 currency_network_adapter.close_trustline(A, B, path=[A, B, C, A]) assert get_balance() == 0
def test_set_trustline_request_event( currency_network_adapter: CurrencyNetworkAdapter, owner, accounts, web3): creditor = accounts[0] debtor = accounts[1] creditline_given = 123 creditline_received = 321 interest_rate_given = 1 interest_rate_received = 2 is_frozen = True currency_network_adapter.set_trustline_request( creditor, debtor, creditline_given, creditline_received, interest_rate_given, interest_rate_received, is_frozen, transaction_options={"from": owner}, ) trustline_update_request_event_args = get_single_event_of_contract( currency_network_adapter.contract, "TrustlineUpdateRequest", web3.eth.blockNumber, )["args"] assert trustline_update_request_event_args["_creditor"] == creditor assert trustline_update_request_event_args["_debtor"] == debtor assert trustline_update_request_event_args[ "_creditlineGiven"] == creditline_given assert (trustline_update_request_event_args["_creditlineReceived"] == creditline_received) assert (trustline_update_request_event_args["_interestRateGiven"] == interest_rate_given) assert (trustline_update_request_event_args["_interestRateReceived"] == interest_rate_received) assert trustline_update_request_event_args["_isFrozen"] == is_frozen
def test_set_trustline_request( currency_network_adapter: CurrencyNetworkAdapter, owner, accounts, creditor_index, debtor_index, ): creditor = accounts[creditor_index] debtor = accounts[debtor_index] creditline_given = 123 creditline_received = 321 interest_rate_given = 1 interest_rate_received = 2 is_frozen = True currency_network_adapter.set_trustline_request( creditor, debtor, creditline_given, creditline_received, interest_rate_given, interest_rate_received, is_frozen, transaction_options={"from": owner}, ) # Check that the trustline request was successfully set by accepting it from the debtor currency_network_adapter.unfreeze_network( transaction_options={"from": owner}) currency_network_adapter.update_trustline( creditor_address=debtor, debtor_address=creditor, creditline_given=creditline_received, creditline_received=creditline_given, interest_rate_given=interest_rate_received, interest_rate_received=interest_rate_given, is_frozen=is_frozen, ) currency_network_adapter.check_account( a_address=creditor, b_address=debtor, creditline_given=creditline_given, creditline_received=creditline_received, interest_rate_given=interest_rate_given, interest_rate_received=interest_rate_received, is_frozen=is_frozen, balance=0, )
def test_set_trustline_request_not_owner( currency_network_adapter: CurrencyNetworkAdapter, not_owner, accounts, ): creditor = accounts[0] debtor = accounts[1] creditline_given = 123 creditline_received = 321 interest_rate_given = 1 interest_rate_received = 2 is_frozen = True currency_network_adapter.set_trustline_request( creditor, debtor, creditline_given, creditline_received, interest_rate_given, interest_rate_received, is_frozen, transaction_options={"from": not_owner}, should_fail=True, )
def currency_network_contract_with_trustlines(web3, accounts): contract = deploy_network( web3, currency_network_contract_name="TestCurrencyNetwork", name="TestCoin", symbol="T", decimals=6, fee_divisor=100, expiration_time=EXPIRATION_TIME, ) for (A, B, clAB, clBA) in trustlines: CurrencyNetworkAdapter(contract).set_account( accounts[A], accounts[B], creditline_given=clAB, creditline_received=clBA ) return contract
def test_apply_interests_not_possible_when_frozen( currency_network_contract_custom_interests_safe_ripple, accounts): adapter = CurrencyNetworkAdapter( currency_network_contract_custom_interests_safe_ripple) A, B, *rest = accounts adapter.update_trustline(A, B, accept=True) # should be fine adapter.contract.functions.applyInterests(B).transact({"from": A}) adapter.update_trustline(A, B, is_frozen=True, accept=True) with pytest.raises(TransactionFailed): adapter.contract.functions.applyInterests(B).transact({"from": A})
def test_apply_interests( currency_network_contract_custom_interests_safe_ripple, chain, accounts, value, rate): adapter = CurrencyNetworkAdapter( currency_network_contract_custom_interests_safe_ripple) A, B, *rest = accounts current_time = int(time.time()) chain.time_travel(current_time + 10) adapter.update_trustline( A, B, creditline_given=abs(value), creditline_received=abs(value), interest_rate_given=rate, interest_rate_received=rate, accept=True, ) if value > 0: adapter.transfer(value, path=[A, B]) else: adapter.transfer(-value, path=[B, A]) chain.time_travel(current_time + SECONDS_PER_YEAR + 10) assert adapter.balance(A, B) == -value # apply Interests adapter.contract.functions.applyInterests(B).transact({"from": A}) assert adapter.balance(A, B) == pytest.approx(-value * exp(rate / 10000), abs=3) # reapply interests should not change anything adapter.contract.functions.applyInterests(B).transact({"from": A}) assert adapter.balance(A, B) == pytest.approx(-value * exp(rate / 10000), abs=3) # Test apply interests in other direction chain.time_travel(current_time + 2 * SECONDS_PER_YEAR + 10) adapter.contract.functions.applyInterests(A).transact({"from": B}) assert adapter.balance(A, B) == pytest.approx(-value * exp(2 * rate / 10000), abs=4)
def currency_network_adapter( currency_network_contract_authorized_with_trustlines): return CurrencyNetworkAdapter( currency_network_contract_authorized_with_trustlines)
def currency_network_adapter_custom_interest(currency_network_contract_custom_interest): return CurrencyNetworkAdapter(currency_network_contract_custom_interest)
def currency_network_adapter(currency_network_contract): return CurrencyNetworkAdapter(currency_network_contract)