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,
    )
Example #21
0
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)