Esempio n. 1
0
    def buy_data_tokens(
        self, pool_address: str, amount: int, max_OCEAN_amount: int, from_wallet: Wallet
    ) -> str:
        """
        Buy data tokens from this pool, paying `max_OCEAN_amount` of OCEAN tokens.
        If total spent <= max_OCEAN_amount.
        - Caller is spending OCEAN tokens, and receiving `amount` DataTokens
        - OCEAN tokens are going into pool, DataTokens are going out of pool

        The transaction fails if total spent exceeds `max_OCEAN_amount`.

        :param pool_address: str address of pool contract
        :param amount: int number of data tokens to add to this pool in *base*
        :param max_OCEAN_amount:
        :param from_wallet:
        :return: str transaction id/hash
        """
        ocean_tok = DataToken(self.web3, self.ocean_address)
        if ocean_tok.balanceOf(from_wallet.address) < max_OCEAN_amount:
            raise InsufficientBalance("Insufficient funds for buying DataTokens!")
        if ocean_tok.allowance(from_wallet.address, pool_address) < max_OCEAN_amount:
            ocean_tok.approve(pool_address, max_OCEAN_amount, from_wallet)

        dtoken_address = self.get_token_address(pool_address)
        pool = BPool(self.web3, pool_address)
        return pool.swapExactAmountOut(
            tokenIn_address=self.ocean_address,  # entering pool
            maxAmountIn=max_OCEAN_amount,  # ""
            tokenOut_address=dtoken_address,  # leaving pool
            tokenAmountOut=amount,  # ""
            maxPrice=2 ** 255,  # here we limit by max_num_OCEAN, not price
            from_wallet=from_wallet,
        )
Esempio n. 2
0
    def buy_at_fixed_rate(
        self,
        amount: int,
        wallet: Wallet,
        max_OCEAN_amount: int,
        exchange_id: Optional[Union[bytes, str]] = "",
        data_token: Optional[str] = "",
        exchange_owner: Optional[str] = "",
    ) -> bool:

        exchange, exchange_id = self.get_exchange_id_fallback_dt_and_owner(
            exchange_id, exchange_owner, data_token)

        # Figure out the amount of ocean tokens to approve before triggering the exchange function to do the swap
        ocean_amount = exchange.get_base_token_quote(exchange_id, amount)
        ocean_token = DataToken(self._web3, self.ocean_address)
        ocean_ticker = ocean_token.symbol()
        if ocean_amount > max_OCEAN_amount:
            raise ValidationError(
                f"Buying {pretty_ether_and_wei(amount, 'DataTokens')} requires {pretty_ether_and_wei(ocean_amount, ocean_ticker)} "
                f"tokens which exceeds the max_OCEAN_amount {pretty_ether_and_wei(max_OCEAN_amount, ocean_ticker)}."
            )
        if ocean_token.balanceOf(wallet.address) < ocean_amount:
            raise InsufficientBalance(
                f"Insufficient funds for buying {pretty_ether_and_wei(amount, 'DataTokens')}!"
            )
        if ocean_token.allowance(wallet.address,
                                 self._exchange_address) < ocean_amount:
            tx_id = ocean_token.approve(self._exchange_address, ocean_amount,
                                        wallet)
            tx_receipt = ocean_token.get_tx_receipt(self._web3, tx_id)
            if not tx_receipt or tx_receipt.status != 1:
                raise VerifyTxFailed(
                    f"Approve OCEAN tokens failed, exchange address was {self._exchange_address} and tx id was {tx_id}!"
                )
        tx_id = exchange.buy_data_token(exchange_id,
                                        data_token_amount=amount,
                                        from_wallet=wallet)
        return bool(exchange.get_tx_receipt(self._web3, tx_id).status)
Esempio n. 3
0
def test_fixed_rate_exchange(web3, alice_ocean, alice_wallet, T1, bob_wallet,
                             T2, contracts_addresses):
    """Tests for fixed rate exchange.

    tests:
        create
        generateExchangeId
        getExchange
        getExchanges
        getNumberOfExchanges
        get_base_token_quote
        buy_data_token

    """
    fixed_ex = FixedRateExchange(
        web3, contracts_addresses[FixedRateExchange.CONTRACT_NAME])
    num_ex = fixed_ex.getNumberOfExchanges()
    assert num_ex == len(fixed_ex.getExchanges()
                         ), "num exchanges do not match num of exchange ids."

    ocean_t = alice_ocean.OCEAN_address
    ocn_token = DataToken(web3, ocean_t)
    bob_ocean_balance = ocn_token.balanceOf(bob_wallet.address)
    assert bob_ocean_balance >= to_wei(100), (
        f"bob wallet does not have the expected OCEAN tokens balance, "
        f"got {from_wei(bob_ocean_balance)} instead of 100")

    # clear any previous ocean token allowance for the exchange contract
    assert (ocn_token.get_tx_receipt(
        web3, ocn_token.approve(fixed_ex.address, 1,
                                bob_wallet)).status == 1), "approve failed"
    assert ocn_token.allowance(bob_wallet.address, fixed_ex.address) == 1, ""

    rate = to_wei("0.1")
    tx_id = fixed_ex.create(ocean_t, T1.address, rate, alice_wallet)
    r = fixed_ex.get_tx_receipt(web3, tx_id)
    assert r.status == 1, f"create fixed rate exchange failed: TxId {tx_id}."

    ex_id = fixed_ex.generateExchangeId(ocean_t, T1.address,
                                        alice_wallet.address).hex()
    ex_data = fixed_ex.getExchange(ex_id)
    expected_values = (alice_wallet.address, T1.address, ocean_t, rate, True,
                       0)
    assert ex_data == expected_values, (
        f"fixed rate exchange {ex_id} with values {ex_data} "
        f"does not match the expected values {expected_values}")

    assert (
        fixed_ex.getNumberOfExchanges() == num_ex + 1
    ), f"Number of exchanges does not match, expected {num_ex+1} got {fixed_ex.getNumberOfExchanges()}."

    ###################
    # Test quote and buy datatokens
    amount = to_wei(10)  # 10 data tokens
    base_token_quote = fixed_ex.get_base_token_quote(ex_id, amount)
    expected_base_token_quote = int(amount * rate / to_wei(1))
    assert base_token_quote == (
        expected_base_token_quote
    ), f"quote does not seem correct: expected {expected_base_token_quote}, got {base_token_quote}"
    assert base_token_quote == to_wei(1), ""
    # buy without approving OCEAN tokens, should fail
    assert (
        run_failing_tx(fixed_ex, fixed_ex.buy_data_token, ex_id, amount,
                       bob_wallet) == 0
    ), (f"buy_data_token/swap on EX {ex_id} is expected to fail but did not, "
        f"maybe the FixedRateExchange is already approved as spender for bob_wallet."
        )
    # approve ocean tokens, buying should still fail because datatokens are not approved by exchange owner
    assert (ocn_token.get_tx_receipt(
        web3, ocn_token.approve(fixed_ex.address, base_token_quote,
                                bob_wallet)).status == 1), "approve failed"
    assert (
        run_failing_tx(fixed_ex, fixed_ex.buy_data_token, ex_id, amount,
                       bob_wallet) == 0
    ), (f"buy_data_token/swap on EX {ex_id} is expected to fail but did not, "
        f"maybe the FixedRateExchange is already approved as spender for bob_wallet."
        )

    # approve data token, now buying should succeed
    assert (T1.get_tx_receipt(
        web3, T1.approve(fixed_ex.address, amount,
                         alice_wallet)).status == 1), "approve failed"
    assert (ocn_token.allowance(bob_wallet.address,
                                fixed_ex.address) == base_token_quote), ""
    tx_id = fixed_ex.buy_data_token(ex_id, amount, bob_wallet)
    r = fixed_ex.get_tx_receipt(web3, tx_id)
    assert (
        r.status == 1
    ), f"buy_data_token/swap on EX {ex_id} failed with status 0: amount {amount}."
    # verify bob's datatokens balance
    assert T1.balanceOf(bob_wallet.address) == amount, (
        f"bobs datatoken balance is not right, "
        f"should be {amount}, got {T1.balanceOf(bob_wallet.address)}")
    assert ocn_token.allowance(bob_wallet.address, fixed_ex.address) == 0, ""

    #####################
    # create another ex then do more tests
    rate2 = to_wei("0.8")
    tx_id = fixed_ex.create(ocean_t, T2.address, rate2, alice_wallet)
    r = fixed_ex.get_tx_receipt(web3, tx_id)
    assert r.status == 1, f"create fixed rate exchange failed: TxId {tx_id}."

    assert fixed_ex.getNumberOfExchanges() == num_ex + 2, (
        f"Number of exchanges does not match, "
        f"expected {num_ex+2} got {fixed_ex.getNumberOfExchanges()}.")

    t2_ex_id = fixed_ex.generateExchangeId(ocean_t, T2.address,
                                           alice_wallet.address).hex()
    exchange_ids = {ti.hex() for ti in fixed_ex.getExchanges()}
    assert ex_id in exchange_ids, "exchange id not found."
    assert t2_ex_id in exchange_ids, "exchange id not found."

    ##############################
    # test activate/deactivate
    assert fixed_ex.isActive(ex_id) is True, f"exchange {ex_id} is not active."
    assert fixed_ex.isActive(
        t2_ex_id) is True, f"exchange {t2_ex_id} is not active."

    assert (
        run_failing_tx(fixed_ex, fixed_ex.deactivate, t2_ex_id,
                       bob_wallet) == 0
    ), f"exchange {t2_ex_id} deactivate (using bob_wallet) should fail but did not."

    assert (fixed_ex.get_tx_receipt(
        web3, fixed_ex.deactivate(t2_ex_id, alice_wallet)).status == 1
            ), f"exchange {t2_ex_id} deactivate failed."
    assert (fixed_ex.isActive(t2_ex_id) is False
            ), f"exchange {t2_ex_id} is active, but it should be deactivated."

    ###################################
    # try buying from deactivated ex
    amount = to_wei(4)  # num data tokens
    base_token_quote = fixed_ex.get_base_token_quote(
        t2_ex_id, amount)  # num base token (OCEAN tokens)
    expected_base_token_quote = int(amount * rate2 / to_wei(1))
    assert base_token_quote == (
        expected_base_token_quote
    ), f"quote does not seem correct: expected {expected_base_token_quote}, got {base_token_quote}"
    ocn_token.get_tx_receipt(
        web3, ocn_token.approve(fixed_ex.address, base_token_quote,
                                bob_wallet))
    # buy should fail (deactivated exchange)
    assert (
        run_failing_tx(fixed_ex, fixed_ex.buy_data_token, t2_ex_id, amount,
                       bob_wallet) == 0
    ), (f"buy_data_token/swap on EX {t2_ex_id} is expected to fail but did not, "
        f"maybe the FixedRateExchange is already approved as spender for bob_wallet."
        )
    assert (ocn_token.allowance(bob_wallet.address,
                                fixed_ex.address) == base_token_quote), ""
    assert (fixed_ex.get_tx_receipt(web3,
                                    fixed_ex.activate(
                                        t2_ex_id, alice_wallet)).status == 1
            ), f"exchange {t2_ex_id} deactivate failed."
    assert (fixed_ex.isActive(t2_ex_id) is
            True), f"exchange {t2_ex_id} is not active, but it should be."

    ##############################
    # buy should still fail as datatokens are not approved to spend by the exchange contract
    assert (
        run_failing_tx(fixed_ex, fixed_ex.buy_data_token, t2_ex_id, amount,
                       bob_wallet) == 0
    ), (f"buy_data_token/swap on EX {t2_ex_id} is expected to fail but did not, "
        f"maybe the FixedRateExchange is already approved as spender for bob_wallet."
        )

    # now buy tokens should succeed
    assert (T2.get_tx_receipt(
        web3, T2.approve(fixed_ex.address, amount * 3,
                         alice_wallet)).status == 1), "approve failed"
    assert (fixed_ex.get_tx_receipt(
        web3, fixed_ex.buy_data_token(t2_ex_id, amount,
                                      bob_wallet)).status == 1
            ), f"buy_data_token/swap on EX {ex_id} failed, "
    assert ocn_token.allowance(bob_wallet.address, fixed_ex.address) == 0, ""

    # approve again for another purchase
    ocn_token.get_tx_receipt(
        web3, ocn_token.approve(fixed_ex.address, base_token_quote,
                                bob_wallet))
    assert (
        run_failing_tx(fixed_ex, fixed_ex.buy_data_token, t2_ex_id, to_wei(5),
                       bob_wallet) == 0
    ), f"buy_data_token/swap on EX {t2_ex_id} should fail because not enough Ocean tokens are approved by buyer."

    # get new quote for new amount
    base_token_quote = fixed_ex.get_base_token_quote(
        t2_ex_id, to_wei(5))  # num base token (OCEAN tokens
    ocn_token.get_tx_receipt(
        web3, ocn_token.approve(fixed_ex.address, base_token_quote,
                                bob_wallet))
    assert (fixed_ex.get_tx_receipt(
        web3, fixed_ex.buy_data_token(t2_ex_id, to_wei(5),
                                      bob_wallet)).status == 1
            ), f"buy_data_token/swap on EX {t2_ex_id} failed."
    assert ocn_token.allowance(bob_wallet.address, fixed_ex.address) == 0, ""

    ##############################
    # test getRate/setRate
    assert (
        fixed_ex.getRate(t2_ex_id) == rate2
    ), f"T2 exchange rate does not match {rate2}, got {fixed_ex.getRate(t2_ex_id)}"
    assert (
        fixed_ex.getRate(ex_id) == rate
    ), f"T1 exchange rate does not match {rate}, got {fixed_ex.getRate(ex_id)}"
    rate2 = to_wei("0.75")
    assert (fixed_ex.get_tx_receipt(
        web3, fixed_ex.setRate(t2_ex_id, rate2,
                               alice_wallet)).status == 1), "setRate failed."
    assert (
        fixed_ex.getRate(t2_ex_id) == rate2
    ), f"T2 exchange rate does not match {rate2}, got {fixed_ex.getRate(t2_ex_id)}"

    assert (run_failing_tx(
        fixed_ex, fixed_ex.setRate, t2_ex_id, 0,
        alice_wallet) == 0), "should not accept rate of Zero."
    assert (run_failing_tx(
        fixed_ex, fixed_ex.setRate, t2_ex_id, -to_wei("0.05"),
        alice_wallet) == 0), "should not accept a negative rate."
    assert (fixed_ex.get_tx_receipt(
        web3, fixed_ex.setRate(t2_ex_id, to_wei(1000),
                               alice_wallet)).status == 1), "setRate failed."
def test_fixed_rate_exchange(alice_ocean, alice_wallet, T1, bob_wallet, T2,
                             contracts_addresses):
    """
    tests:
        create
        generateExchangeId
        getExchange
        getExchanges
        getNumberOfExchanges
        get_base_token_quote
        buy_data_token

    """
    base_unit = to_base_18(1.0)
    fixed_ex = FixedRateExchange(
        contracts_addresses[FixedRateExchange.CONTRACT_NAME])
    num_ex = fixed_ex.getNumberOfExchanges()
    assert num_ex == len(fixed_ex.getExchanges()
                         ), f'num exchanges do not match num of exchange ids.'

    ocean_t = alice_ocean.OCEAN_address
    ocn_token = DataToken(ocean_t)
    # owner_wallet = get_ganache_wallet()
    # ocn_token.transfer_tokens(bob_wallet.address, 100, owner_wallet)
    assert ocn_token.token_balance(bob_wallet.address) >= 100, \
        f'bob wallet does not have the expected OCEAN tokens balance, ' \
        f'got {ocn_token.token_balance(bob_wallet.address)} instead of 100'

    # clear any previous ocean token allowance for the exchange contract
    assert ocn_token.get_tx_receipt(
        ocn_token.approve(fixed_ex.address, 1,
                          bob_wallet)).status == 1, f'approve failed'
    assert ocn_token.allowance(bob_wallet.address, fixed_ex.address) == 1, f''

    rate = to_base_18(0.1)
    tx_id = fixed_ex.create(ocean_t, T1.address, rate, alice_wallet)
    r = fixed_ex.get_tx_receipt(tx_id)
    assert r.status == 1, f'create fixed rate exchange failed: TxId {tx_id}.'

    ex_id = fixed_ex.generateExchangeId(ocean_t, T1.address,
                                        alice_wallet.address).hex()
    ex_data = fixed_ex.getExchange(ex_id)
    expected_values = (alice_wallet.address, T1.address, ocean_t, rate, True,
                       0)
    assert ex_data == expected_values, f'fixed rate exchange {ex_id} with values {ex_data} ' \
                                       f'does not match the expected values {expected_values}'

    assert fixed_ex.getNumberOfExchanges() == num_ex+1, \
        f'Number of exchanges does not match, expected {num_ex+1} got {fixed_ex.getNumberOfExchanges()}.'

    ###################
    # Test quote and buy datatokens
    amount = to_base_18(10.0)  # 10 data tokens
    base_token_quote = fixed_ex.get_base_token_quote(ex_id, amount)
    # quote = from_base_18(base_token_quote)
    assert base_token_quote == (
        amount * rate / base_unit
    ), f'quote does not seem correct: expected {amount*rate/base_unit}, got {base_token_quote}'
    assert from_base_18(base_token_quote) == 1.0, f''
    # buy without approving OCEAN tokens, should fail
    assert run_failing_tx(
        fixed_ex, fixed_ex.buy_data_token, ex_id, amount, bob_wallet
    ) == 0, f'buy_data_token/swap on EX {ex_id} is expected to fail but did not, ' \
            f'maybe the FixedRateExchange is already approved as spender for bob_wallet.'
    # approve ocean tokens, buying should still fail because datatokens are not approved by exchange owner
    assert ocn_token.get_tx_receipt(
        ocn_token.approve(fixed_ex.address, base_token_quote,
                          bob_wallet)).status == 1, f'approve failed'
    assert run_failing_tx(
        fixed_ex, fixed_ex.buy_data_token, ex_id, amount, bob_wallet
    ) == 0, f'buy_data_token/swap on EX {ex_id} is expected to fail but did not, ' \
            f'maybe the FixedRateExchange is already approved as spender for bob_wallet.'

    # approve data token, now buying should succeed
    assert T1.get_tx_receipt(T1.approve(
        fixed_ex.address, amount, alice_wallet)).status == 1, f'approve failed'
    assert ocn_token.allowance(bob_wallet.address,
                               fixed_ex.address) == base_token_quote, f''
    tx_id = fixed_ex.buy_data_token(ex_id, amount, bob_wallet)
    r = fixed_ex.get_tx_receipt(tx_id)
    assert r.status == 1, f'buy_data_token/swap on EX {ex_id} failed with status 0: amount {amount}.'
    # verify bob's datatokens balance
    assert T1.balanceOf(bob_wallet.address) == amount, f'bobs datatoken balance is not right, ' \
                                                       f'should be {amount}, got {T1.balanceOf(bob_wallet.address)}'
    assert ocn_token.allowance(bob_wallet.address, fixed_ex.address) == 0, f''

    #####################
    # create another ex then do more tests
    rate2 = to_base_18(0.8)
    tx_id = fixed_ex.create(ocean_t, T2.address, rate2, alice_wallet)
    r = fixed_ex.get_tx_receipt(tx_id)
    assert r.status == 1, f'create fixed rate exchange failed: TxId {tx_id}.'

    assert fixed_ex.getNumberOfExchanges() == num_ex+2, f'Number of exchanges does not match, ' \
                                                        f'expected {num_ex+2} got {fixed_ex.getNumberOfExchanges()}.'

    t2_ex_id = fixed_ex.generateExchangeId(ocean_t, T2.address,
                                           alice_wallet.address).hex()
    exchange_ids = {ti.hex() for ti in fixed_ex.getExchanges()}
    assert ex_id in exchange_ids, f'exchange id not found.'
    assert t2_ex_id in exchange_ids, f'exchange id not found.'

    ##############################
    # test activate/deactivate
    assert fixed_ex.isActive(ex_id) is True, f'exchange {ex_id} is not active.'
    assert fixed_ex.isActive(
        t2_ex_id) is True, f'exchange {t2_ex_id} is not active.'

    assert run_failing_tx(
        fixed_ex, fixed_ex.deactivate, t2_ex_id, bob_wallet
    ) == 0, f'exchange {t2_ex_id} deactivate (using bob_wallet) should fail but did not.'

    assert fixed_ex.get_tx_receipt(fixed_ex.deactivate(
        t2_ex_id,
        alice_wallet)).status == 1, f'exchange {t2_ex_id} deactivate failed.'
    assert fixed_ex.isActive(
        t2_ex_id
    ) is False, f'exchange {t2_ex_id} is active, but it should be deactivated.'

    ###################################
    # try buying from deactivated ex
    amount = to_base_18(4.0)  # num data tokens
    base_token_quote = fixed_ex.get_base_token_quote(
        t2_ex_id, amount)  # num base token (OCEAN tokens
    assert base_token_quote == (amount * rate2 / base_unit), \
        f'quote does not seem correct: expected {amount*rate2/base_unit}, got {base_token_quote}'
    ocn_token.get_tx_receipt(
        ocn_token.approve(fixed_ex.address, base_token_quote, bob_wallet))
    # buy should fail (deactivated exchange)
    assert run_failing_tx(
        fixed_ex, fixed_ex.buy_data_token, t2_ex_id, amount, bob_wallet
    ) == 0, f'buy_data_token/swap on EX {t2_ex_id} is expected to fail but did not, ' \
            f'maybe the FixedRateExchange is already approved as spender for bob_wallet.'
    assert ocn_token.allowance(bob_wallet.address,
                               fixed_ex.address) == base_token_quote, f''
    assert fixed_ex.get_tx_receipt(fixed_ex.activate(
        t2_ex_id,
        alice_wallet)).status == 1, f'exchange {t2_ex_id} deactivate failed.'
    assert fixed_ex.isActive(
        t2_ex_id
    ) is True, f'exchange {t2_ex_id} is not active, but it should be.'

    ##############################
    # buy should still fail as datatokens are not approved to spend by the exchange contract
    assert run_failing_tx(
        fixed_ex, fixed_ex.buy_data_token, t2_ex_id, amount, bob_wallet
    ) == 0, f'buy_data_token/swap on EX {t2_ex_id} is expected to fail but did not, ' \
            f'maybe the FixedRateExchange is already approved as spender for bob_wallet.'

    # now buy tokens should succeed
    assert T2.get_tx_receipt(
        T2.approve(fixed_ex.address, amount * 3,
                   alice_wallet)).status == 1, f'approve failed'
    assert fixed_ex.get_tx_receipt(fixed_ex.buy_data_token(t2_ex_id, amount, bob_wallet)).status == 1, \
        f'buy_data_token/swap on EX {ex_id} failed, '
    assert ocn_token.allowance(bob_wallet.address, fixed_ex.address) == 0, f''

    # approve again for another purchase
    ocn_token.get_tx_receipt(
        ocn_token.approve(fixed_ex.address, base_token_quote, bob_wallet))
    assert run_failing_tx(
        fixed_ex, fixed_ex.buy_data_token, t2_ex_id, to_base_18(5.0),
        bob_wallet
    ) == 0, f'buy_data_token/swap on EX {t2_ex_id} should fail because not enough Ocean tokens are approved by buyer.'

    # get new quote for new amount
    base_token_quote = fixed_ex.get_base_token_quote(
        t2_ex_id, to_base_18(5.0))  # num base token (OCEAN tokens
    ocn_token.get_tx_receipt(
        ocn_token.approve(fixed_ex.address, base_token_quote, bob_wallet))
    assert fixed_ex.get_tx_receipt(
        fixed_ex.buy_data_token(t2_ex_id, to_base_18(5.0), bob_wallet)
    ).status == 1, f'buy_data_token/swap on EX {t2_ex_id} failed.'
    assert ocn_token.allowance(bob_wallet.address, fixed_ex.address) == 0, f''

    ##############################
    # test getRate/setRate
    assert fixed_ex.getRate(
        t2_ex_id
    ) == rate2, f'T2 exchange rate does not match {rate2}, got {fixed_ex.getRate(t2_ex_id)}'
    assert fixed_ex.getRate(
        ex_id
    ) == rate, f'T1 exchange rate does not match {rate}, got {fixed_ex.getRate(ex_id)}'
    rate2 = to_base_18(0.75)
    assert fixed_ex.get_tx_receipt(
        fixed_ex.setRate(t2_ex_id, rate2,
                         alice_wallet)).status == 1, f'setRate failed.'
    assert fixed_ex.getRate(
        t2_ex_id
    ) == rate2, f'T2 exchange rate does not match {rate2}, got {fixed_ex.getRate(t2_ex_id)}'

    assert run_failing_tx(
        fixed_ex, fixed_ex.setRate, t2_ex_id, to_base_18(0.0),
        alice_wallet) == 0, f'should not accept rate of Zero.'
    assert run_failing_tx(
        fixed_ex, fixed_ex.setRate, t2_ex_id, -to_base_18(0.05),
        alice_wallet) == 0, f'should not accept a negative rate.'
    assert fixed_ex.get_tx_receipt(
        fixed_ex.setRate(t2_ex_id, to_base_18(1000.0),
                         alice_wallet)).status == 1, f'setRate failed.'
Esempio n. 5
0
    def create(
        self,
        data_token_address: str,
        data_token_amount: int,
        OCEAN_amount: int,
        from_wallet: Wallet,
        data_token_weight: int = balancer_constants.INIT_WEIGHT_DT,
        swap_fee: int = balancer_constants.DEFAULT_SWAP_FEE,
    ) -> BPool:
        """
        Create a new pool with bound datatoken and OCEAN token then finalize it.
        The pool will have publicSwap enabled and swap fee is set
        to `balancer_constants.DEFAULT_SWAP_FEE`.
        Balances of both data tokens and OCEAN tokens must be sufficient in the
        `from_wallet`, otherwise this will fail.

        :param data_token_address: str address of the DataToken contract
        :param data_token_amount: int amount of initial liquidity of data tokens
        :param OCEAN_amount: int amount of initial liquidity of OCEAN tokens
        :param from_wallet: Wallet instance of pool owner
        :param data_token_weight: int weight of the data token to be set in the new pool must be >= 1 & <= 9
        :param swap_fee: int the fee taken by the pool on each swap transaction
        :return: BPool instance
        """
        bfactory = BFactory(self.web3, self.bfactory_address)
        pool_address = bfactory.newBPool(from_wallet)
        pool = BPool(self.web3, pool_address)
        logger.debug(f"pool created with address {pool_address}.")

        assert to_wei("1") <= data_token_weight <= to_wei("9")
        base_weight = to_wei(10) - data_token_weight

        # Must approve datatoken and Ocean tokens to the new pool as spender
        dt = DataToken(self.web3, data_token_address)
        if dt.balanceOf(from_wallet.address) < data_token_amount:
            raise InsufficientBalance(
                "Insufficient datatoken balance for pool creation!"
            )
        if dt.allowance(from_wallet.address, pool_address) < data_token_amount:
            tx_id = dt.approve(pool_address, data_token_amount, from_wallet)
            if dt.get_tx_receipt(self.web3, tx_id).status != 1:
                raise VerifyTxFailed(
                    f"Approve datatokens failed, pool was created at {pool_address}"
                )

        ot = DataToken(self.web3, self.ocean_address)
        if ot.balanceOf(from_wallet.address) < OCEAN_amount:
            raise InsufficientBalance("Insufficient OCEAN balance for pool creation!")
        if ot.allowance(from_wallet.address, pool_address) < OCEAN_amount:
            tx_id = ot.approve(pool_address, OCEAN_amount, from_wallet)
            if ot.get_tx_receipt(self.web3, tx_id).status != 1:
                raise VerifyTxFailed(
                    f"Approve OCEAN tokens failed, pool was created at {pool_address}"
                )
        tx_id = pool.setup(
            data_token_address,
            data_token_amount,
            data_token_weight,
            self.ocean_address,
            OCEAN_amount,
            base_weight,
            swap_fee,
            from_wallet,
        )
        if pool.get_tx_receipt(self.web3, tx_id).status != 1:
            raise VerifyTxFailed(
                f"pool.setup failed: txId={tx_id}, receipt={pool.get_tx_receipt(self.web3, tx_id)}"
            )

        logger.debug(
            f"create pool completed: poolAddress={pool_address}, pool setup TxId={tx_id}"
        )

        return pool