예제 #1
0
def test1(network, alice_wallet):
    bfactory_address = get_bfactory_address(network)
    bfactory = BFactory(bfactory_address)

    pool_address = bfactory.newBPool(from_wallet=alice_wallet)
    pool = BPool(pool_address)
    assert isinstance(pool, BPool)
예제 #2
0
    def get_all_pools(self,
                      from_block=0,
                      chunk_size=1000,
                      include_balance=False):
        web3 = Web3Provider.get_web3()
        current_block = web3.eth.blockNumber

        bfactory = BFactory(self.bfactory_address)
        logs = bfactory.get_event_logs(
            "BPoolRegistered",
            from_block,
            current_block,
            {},
            web3=web3,
            chunk_size=chunk_size,
        )
        if include_balance:
            pools = sorted(
                [(
                    lg.args.bpoolAddress,
                    from_base_18(
                        BPool(lg.args.bpoolAddress).getBalance(
                            self.ocean_address)),
                ) for lg in logs],
                key=lambda x: x[1],
                reverse=True,
            )
        else:
            pools = {lg.args.bpoolAddress for lg in logs}

        return pools
예제 #3
0
def test_bpool_creation(web3, config, alice_wallet):
    """Test the creation of a Balancer Pool from BFactory (happy flow)."""
    bfactory_address = get_bfactory_address(config.address_file, web3=web3)
    bfactory = BFactory(web3, bfactory_address)

    pool_address = bfactory.newBPool(from_wallet=alice_wallet)
    pool = BPool(web3, pool_address)
    assert isinstance(pool, BPool)
예제 #4
0
def test_bpool_creation(network, alice_wallet):
    """Test the creation of a Balancer Pool from BFactory (happy flow)."""
    bfactory_address = get_bfactory_address(network)
    bfactory = BFactory(bfactory_address)

    pool_address = bfactory.newBPool(from_wallet=alice_wallet)
    pool = BPool(pool_address)
    assert isinstance(pool, BPool)
예제 #5
0
def _deployBPool(network: str, from_wallet: Wallet) -> BPool:
    """Helper function to deploy a pool."""
    factory_address = get_bfactory_address(network)
    factory = BFactory(factory_address)
    pool_address = factory.newBPool(from_wallet=from_wallet)
    pool = BPool(pool_address)

    return pool
예제 #6
0
def _deployBPool(web3: Web3, address_file: str, network: str,
                 from_wallet: Wallet) -> BPool:
    """Helper function to deploy a pool."""
    factory_address = get_bfactory_address(address_file, network)
    factory = BFactory(web3, factory_address)
    pool_address = factory.newBPool(from_wallet=from_wallet)
    pool = BPool(web3, pool_address)

    return pool
예제 #7
0
def test_setSwapFee_fails(network, alice_wallet, alice_address, bob_wallet,
                          bob_address):
    factory = BFactory(get_bfactory_address(network))
    pool_address = factory.newBPool(alice_wallet)
    pool = BPool(pool_address)
    with pytest.raises(Exception):
        pool.setSwapFee(to_base_18(0.011),
                        from_wallet=bob_wallet)  # not ok, bob isn't controller
    pool.setController(bob_address, from_wallet=alice_wallet)
    pool.setSwapFee(to_base_18(0.011), from_wallet=bob_wallet)  # ok now
예제 #8
0
def test_setSwapFee_fails(network, config, web3, alice_wallet, alice_address,
                          bob_wallet, bob_address):
    """Tests that someone who isn't a controller can not set the swap fee."""
    factory = BFactory(web3, get_bfactory_address(config.address_file,
                                                  network))
    pool_address = factory.newBPool(alice_wallet)
    pool = BPool(web3, pool_address)
    with pytest.raises(Exception):
        pool.setSwapFee(to_wei("0.011"),
                        from_wallet=bob_wallet)  # not ok, bob isn't controller
    pool.setController(bob_address, from_wallet=alice_wallet)
    pool.setSwapFee(to_wei("0.011"), from_wallet=bob_wallet)  # ok now
예제 #9
0
    def get_creation_block(self, pool_address):
        bfactory = BFactory(self.web3, self.bfactory_address)
        current_block = self.web3.eth.block_number
        logs = bfactory.get_event_logs(
            "BPoolCreated",
            0,
            current_block,
            {"newBPoolAddress": pool_address},
            chunk_size=current_block,
        )
        if not logs:
            return {}
        assert len(logs) == 1, "cannot happen"

        return logs[0].blockNumber
예제 #10
0
    def get_creation_block(self, pool_address):
        web3 = Web3Provider.get_web3()
        bfactory = BFactory(self.bfactory_address)
        current_block = web3.eth.blockNumber
        logs = bfactory.get_event_logs('BPoolCreated',
                                       0,
                                       current_block,
                                       {'newBPoolAddress': pool_address},
                                       web3=web3,
                                       chunk_size=current_block)
        if not logs:
            return {}
        assert len(logs) == 1, 'cannot happen'

        return logs[0].blockNumber
예제 #11
0
    def get_all_pools(self):
        bfactory = BFactory(self._addresses.get(BFactory.CONTRACT_NAME))
        event_name = 'BPoolRegistered'
        event = getattr(bfactory.events, event_name)
        latest_block = self._web3.eth.blockNumber
        _from = self.bfactory_block
        chunk = 10000
        pools = []
        while _from < latest_block:
            event_filter = EventFilter(event_name,
                                       event,
                                       None,
                                       from_block=_from,
                                       to_block=_from + chunk - 1)
            try:
                logs = event_filter.get_all_entries(max_tries=10)
                logs = sorted(logs, key=lambda l: l.blockNumber)
                pools.extend([l.args.bpoolAddress for l in logs])
            except ValueError as e:
                logger.error(
                    f'get_all_pools BFactory {bfactory.address}, fromBlock {_from}, toBlock{_from+chunk-1}: {e}'
                )
            _from += chunk

        return pools
예제 #12
0
def get_bfactory_address(
    address_file: str, network: Optional[str] = None, web3: Optional[Web3] = None
) -> str:
    """Returns the BFactory address for given network or web3 instance
    Requires either network name or web3 instance.
    """
    return BFactory.configured_address(
        network or get_network_name(web3=web3), address_file
    )
예제 #13
0
def test1(network, OCEAN_address, alice_wallet, alice_ocean, alice_address,
          bob_wallet):
    bfactory_address = get_bfactory_address(network)

    # ===============================================================
    # 1. Alice publishes a dataset (= publishes a datatoken)
    # For now, you're Alice:) Let's proceed.
    DT = alice_ocean.create_data_token("DataToken1",
                                       "DT1",
                                       alice_wallet,
                                       blob="localhost:8030")
    DT_address = DT.address

    # ===============================================================
    # 2. Alice hosts the dataset
    # Do from console:
    # >> touch /var/mydata/myFolder1/file
    # >> ENV DT="{'0x1234':'/var/mydata/myFolder1'}"
    # >> docker run @oceanprotocol/provider-py -e CONFIG=DT

    # ===============================================================
    # 3. Alice mints DTs
    DT.mint(alice_address, to_base_18(1000.0), alice_wallet)

    # ===============================================================
    # 4. Alice creates an OCEAN-DT pool (=a Balancer Pool)
    bfactory = BFactory(bfactory_address)
    pool_address = bfactory.newBPool(from_wallet=alice_wallet)
    pool = BPool(pool_address)

    pool.setPublicSwap(True, from_wallet=alice_wallet)

    pool.setSwapFee(to_base_18(0.1), from_wallet=alice_wallet)  # set 10% fee

    DT.approve(pool_address, to_base_18(90.0), from_wallet=alice_wallet)
    pool.bind(
        DT_address,
        to_base_18(90.0),
        balancer_constants.INIT_WEIGHT_DT_BASE,
        from_wallet=alice_wallet,
    )

    OCEAN_token = BToken(OCEAN_address)
    txid = OCEAN_token.approve(pool_address,
                               to_base_18(10.0),
                               from_wallet=alice_wallet)
    r = OCEAN_token.get_tx_receipt(txid)
    assert r and r.status == 1, f"approve failed, receipt={r}"
    pool.bind(
        OCEAN_address,
        to_base_18(10.0),
        balancer_constants.INIT_WEIGHT_OCEAN_BASE,
        from_wallet=alice_wallet,
    )

    # ===============================================================
    # 5. Alice adds liquidity to pool
    DT.approve(pool_address, to_base_18(9.0), from_wallet=alice_wallet)
    pool.rebind(
        DT_address,
        to_base_18(90.0 + 9.0),
        balancer_constants.INIT_WEIGHT_DT_BASE,
        from_wallet=alice_wallet,
    )

    OCEAN_token.approve(pool_address,
                        to_base_18(1.0),
                        from_wallet=alice_wallet)
    pool.rebind(
        OCEAN_address,
        to_base_18(10.0 + 1.0),
        to_base_18(balancer_constants.INIT_WEIGHT_OCEAN),
        from_wallet=alice_wallet,
    )

    # 6. Bob buys a DT from pool
    OCEAN_token.approve(pool_address, to_base_18(2.0), from_wallet=bob_wallet)
    pool.swapExactAmountOut(
        tokenIn_address=OCEAN_address,
        maxAmountIn_base=to_base_18(2.0),
        tokenOut_address=DT_address,
        tokenAmountOut_base=to_base_18(1.0),
        maxPrice_base=2**255,
        from_wallet=bob_wallet,
    )

    # ===============================================================
    # 7. Bob consumes dataset
    # <don't need to show here>

    # ===============================================================
    # 8. Alice removes liquidity
    pool.rebind(
        DT_address,
        to_base_18(90.0 + 9.0 - 2.0),
        balancer_constants.INIT_WEIGHT_DT_BASE,
        from_wallet=alice_wallet,
    )
    pool.rebind(
        OCEAN_address,
        to_base_18(10.0 + 1.0 - 3.0),
        balancer_constants.INIT_WEIGHT_OCEAN_BASE,
        from_wallet=alice_wallet,
    )

    # ===============================================================
    # 9. Alice sells data tokens
    DT.approve(pool_address, to_base_18(1.0), from_wallet=alice_wallet)
    pool.swapExactAmountIn(
        tokenIn_address=DT_address,
        tokenAmountIn_base=to_base_18(1.0),
        tokenOut_address=OCEAN_address,
        minAmountOut_base=to_base_18(0.0001),
        maxPrice_base=2**255,
        from_wallet=alice_wallet,
    )

    # ===============================================================
    # 10. Alice finalizes pool. Now others can add liquidity.
    pool.finalize(from_wallet=alice_wallet)

    # ===============================================================
    # 11. Bob adds liquidity
    DT.approve(pool_address, to_base_18(1.0), from_wallet=bob_wallet)
    OCEAN_token.approve(pool_address, to_base_18(1.0), from_wallet=bob_wallet)
    pool.joinPool(to_base_18(0.1),
                  [to_base_18(1.0), to_base_18(1.0)],
                  from_wallet=bob_wallet)

    # ===============================================================
    # 12. Bob adds liquidity AGAIN
    DT.approve(pool_address, to_base_18(1.0), from_wallet=bob_wallet)
    OCEAN_token.approve(pool_address, to_base_18(1.0), from_wallet=bob_wallet)
    pool.joinPool(to_base_18(0.1),
                  [to_base_18(1.0), to_base_18(1.0)],
                  from_wallet=bob_wallet)
예제 #14
0
def bfactory_address():
    return BFactory.configured_address(
        _NETWORK,
        ConfigProvider.get_config().address_file)
예제 #15
0
def get_bfactory_address(network=None):
    return BFactory.configured_address(
        network or Web3Helper.get_network_name(),
        ConfigProvider.get_config().address_file,
    )
예제 #16
0
def main():
    network = 'ganache'
    private_key = os.getenv('EVENTS_TESTS_PRIVATE_KEY')
    network_rpc = os.getenv('EVENTS_RPC', 'http://127.0.0.1:8545')

    config = Config(os.getenv('CONFIG_FILE'))
    ConfigProvider.set_config(config)
    # artifacts_path = os.getenv('ARTIFACTS_PATH', )
    artifacts_path = config.artifacts_path
    address_file = Path(
        os.getenv('ADDRESS_FILE',
                  os.path.join(artifacts_path,
                               'address.json'))).expanduser().resolve()
    print(f'deploying contracts and saving addresses in {address_file}')

    Web3Provider.init_web3(provider=get_web3_connection_provider(network_rpc))
    ContractHandler.set_artifacts_path(artifacts_path)

    web3 = Web3Provider.get_web3()

    addresses = dict()

    if os.path.exists(address_file):
        with open(address_file) as f:
            network_addresses = json.load(f)
    else:
        network_addresses = {network: {}}

    _addresses = network_addresses[network]

    # ****SET ENVT****
    # grab vars
    factory_deployer_private_key = private_key

    # ****SEE FUNDS****
    print(
        "Keys:\n%s\n" %
        Wallet(web3=web3, private_key=factory_deployer_private_key).keysStr())

    # ****DEPLOY****
    deployer_wallet = Wallet(web3, private_key=factory_deployer_private_key)
    minter_addr = deployer_wallet.address
    cap = 2**255

    print("****Deploy DataTokenTemplate: begin****")
    dt_address = DataToken.deploy(web3, deployer_wallet, artifacts_path,
                                  'Template Contract', 'TEMPLATE', minter_addr,
                                  DataToken.DEFAULT_CAP_BASE,
                                  DTFactory.FIRST_BLOB, minter_addr)
    addresses[DataToken.CONTRACT_NAME] = dt_address
    print("****Deploy DataTokenTemplate: done****\n")

    print("****Deploy DTFactory: begin****")
    dtfactory = DTFactory(
        DTFactory.deploy(web3, deployer_wallet, artifacts_path, dt_address,
                         minter_addr))
    addresses[DTFactory.CONTRACT_NAME] = dtfactory.address
    print("****Deploy DTFactory: done****\n")

    print("****Deploy BPool: begin****")
    bpool_address = BPool.deploy(web3, deployer_wallet, artifacts_path)
    bpool_template = BPool(bpool_address)
    addresses[BPool.CONTRACT_NAME] = bpool_address
    print("****Deploy BPool: done****\n")

    print("****Deploy 'BFactory': begin****")
    bfactory_address = BFactory.deploy(web3, deployer_wallet, artifacts_path,
                                       bpool_template.address)
    bfactory = BFactory(bfactory_address)
    addresses[BFactory.CONTRACT_NAME] = bfactory_address
    print("****Deploy 'BFactory': done****\n")

    print("****Deploy 'FixedRateExchange': begin****")
    addresses[FixedRateExchange.CONTRACT_NAME] = FixedRateExchange.deploy(
        web3, deployer_wallet, artifacts_path)
    print("****Deploy 'FixedRateExchange': done****\n")

    print("****Deploy 'Metadata': begin****")
    addresses[MetadataContract.CONTRACT_NAME] = MetadataContract.deploy(
        web3, deployer_wallet, artifacts_path)
    print("****Deploy 'Metadata': done****\n")

    if network == 'ganache' and 'Ocean' not in _addresses:
        print("****Deploy fake OCEAN: begin****")
        # For simplicity, hijack DataTokenTemplate.
        minter_addr = deployer_wallet.address
        OCEAN_cap = 1410 * 10**6  # 1.41B
        OCEAN_cap_base = to_base_18(float(OCEAN_cap))
        OCEAN_token = DataToken(
            DataToken.deploy(web3, deployer_wallet, artifacts_path, 'Ocean',
                             'OCEAN', minter_addr, OCEAN_cap_base, '',
                             minter_addr))
        addresses["Ocean"] = OCEAN_token.address
        print("****Deploy fake OCEAN: done****\n")

        print("****Mint fake OCEAN: begin****")
        OCEAN_token.mint(minter_addr,
                         OCEAN_cap_base,
                         from_wallet=deployer_wallet)
        print("****Mint fake OCEAN: done****\n")

        print("****Distribute fake OCEAN: begin****")
        amt_distribute = 1000
        amt_distribute_base = to_base_18(float(amt_distribute))
        for key_label in [
                'EVENTS_TESTS_PRIVATE_KEY', 'EVENTS_TESTS_PRIVATE_KEY2'
        ]:
            key = os.environ.get(key_label)
            if not key:
                continue

            dst_address = privateKeyToAddress(key)
            try:
                OCEAN_token.transfer(dst_address,
                                     amt_distribute_base,
                                     from_wallet=deployer_wallet)
            except ValueError:
                # handle nonce issue
                time.sleep(3)
                OCEAN_token.transfer(dst_address,
                                     amt_distribute_base,
                                     from_wallet=deployer_wallet)

        print("****Distribute fake OCEAN: done****\n")

    network_addresses[network].update(addresses)

    with open(address_file, 'w') as f:
        json.dump(network_addresses, f, indent=2)
    print(f'contracts deployed: {network_addresses}')
    return addresses
예제 #17
0
def deploy(network, addresses_file):
    config = ExampleConfig.get_config()
    ConfigProvider.set_config(config)
    Web3Provider.init_web3(
        provider=get_web3_connection_provider(config.network_url))
    ContractHandler.set_artifacts_path(config.artifacts_path)

    artifacts_path = ContractHandler.artifacts_path
    if not addresses_file:
        addresses_file = config.address_file
    else:
        addresses_file = Path(addresses_file).expanduser().resolve()

    ocean = get_publisher_ocean_instance()
    web3 = ocean.web3

    addresses = dict()

    if os.path.exists(addresses_file):
        with open(addresses_file) as f:
            network_addresses = json.load(f)
    else:
        network_addresses = {network: {}}

    if network == "ganache" and network not in network_addresses:
        network = "development"

    _addresses = network_addresses[network]

    # ****SET ENVT****
    # grab vars
    factory_deployer_private_key = get_ganache_wallet().private_key

    # corner cases
    if invalidKey(factory_deployer_private_key):
        print("Need valid FACTORY_DEPLOYER_PRIVATE_KEY")
        sys.exit(0)

    # ****SEE FUNDS****
    print("Keys:\n%s" % Wallet(
        web3=get_web3(), private_key=factory_deployer_private_key).keysStr())
    print("")

    # ****DEPLOY****
    deployer_wallet = Wallet(web3, private_key=factory_deployer_private_key)
    minter_addr = deployer_wallet.address
    # cap = 2 ** 255 not used

    if DTFactory.CONTRACT_NAME not in _addresses:
        print("****Deploy DataTokenTemplate: begin****")
        dt_address = DataToken.deploy(
            web3,
            deployer_wallet,
            artifacts_path,
            "Template Contract",
            "TEMPLATE",
            minter_addr,
            DataToken.DEFAULT_CAP_BASE,
            DTFactory.FIRST_BLOB,
            minter_addr,
        )
        addresses[DataToken.CONTRACT_NAME] = dt_address
        print("****Deploy DataTokenTemplate: done****\n")

        print("****Deploy DTFactory: begin****")
        dtfactory = DTFactory(
            DTFactory.deploy(web3, deployer_wallet, artifacts_path, dt_address,
                             minter_addr))
        addresses[DTFactory.CONTRACT_NAME] = dtfactory.address
        print("****Deploy DTFactory: done****\n")

    if BFactory.CONTRACT_NAME not in _addresses:
        print("****Deploy BPool: begin****")
        bpool_address = BPool.deploy(web3, deployer_wallet, artifacts_path)
        bpool_template = BPool(bpool_address)
        addresses[BPool.CONTRACT_NAME] = bpool_address
        print("****Deploy BPool: done****\n")

        print("****Deploy 'BFactory': begin****")
        bfactory_address = BFactory.deploy(web3, deployer_wallet,
                                           artifacts_path,
                                           bpool_template.address)
        _ = BFactory(bfactory_address)
        addresses[BFactory.CONTRACT_NAME] = bfactory_address
        print("****Deploy 'BFactory': done****\n")

    if FixedRateExchange.CONTRACT_NAME not in _addresses:
        print("****Deploy 'FixedRateExchange': begin****")
        addresses[FixedRateExchange.CONTRACT_NAME] = FixedRateExchange.deploy(
            web3, deployer_wallet, artifacts_path)
        print("****Deploy 'FixedRateExchange': done****\n")

    if MetadataContract.CONTRACT_NAME not in _addresses:
        print("****Deploy 'Metadata': begin****")
        addresses[MetadataContract.CONTRACT_NAME] = MetadataContract.deploy(
            web3, deployer_wallet, artifacts_path)
        print("****Deploy 'Metadata': done****\n")

    if network in ("ganache", "development"):
        print("****Deploy fake OCEAN: begin****")
        # For simplicity, hijack DataTokenTemplate.
        minter_addr = deployer_wallet.address
        OCEAN_cap = 1410 * 10**6  # 1.41B
        OCEAN_cap_base = util.to_base_18(float(OCEAN_cap))
        OCEAN_token = DataToken(
            DataToken.deploy(
                web3,
                deployer_wallet,
                artifacts_path,
                "Ocean",
                "OCEAN",
                minter_addr,
                OCEAN_cap_base,
                "",
                minter_addr,
            ))
        addresses["Ocean"] = OCEAN_token.address
        print("****Deploy fake OCEAN: done****\n")

        print("****Mint fake OCEAN: begin****")
        OCEAN_token.mint(minter_addr,
                         OCEAN_cap_base,
                         from_wallet=deployer_wallet)
        print("****Mint fake OCEAN: done****\n")

        print("****Distribute fake OCEAN: begin****")
        amt_distribute = 1000
        amt_distribute_base = util.to_base_18(float(amt_distribute))
        for key_label in ["TEST_PRIVATE_KEY1", "TEST_PRIVATE_KEY2"]:
            key = os.environ.get(key_label)
            if not key:
                continue

            dst_address = privateKeyToAddress(key)
            OCEAN_token.transfer(dst_address,
                                 amt_distribute_base,
                                 from_wallet=deployer_wallet)

        print("****Distribute fake OCEAN: done****\n")

    network_addresses[network].update(addresses)

    with open(addresses_file, "w") as f:
        json.dump(network_addresses, f, indent=2)

    return addresses
예제 #18
0
    def create(self,
               data_token_address: str,
               data_token_amount: float,
               OCEAN_amount: float,
               from_wallet: Wallet,
               data_token_weight: float = balancer_constants.INIT_WEIGHT_DT,
               swap_fee: float = 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: float amount of initial liquidity of data tokens
        :param OCEAN_amount: float amount of initial liquidity of OCEAN tokens
        :param from_wallet: Wallet instance of pool owner
        :param data_token_weight: float weight of the data token to be set in the new pool must be >= 1 & <= 9
        :param swap_fee: float the fee taken by the pool on each swap transaction
        :return: BPool instance
        """

        bfactory = BFactory(self.bfactory_address)
        pool_address = bfactory.newBPool(from_wallet)
        pool = BPool(pool_address)
        logger.debug(f'pool created with address {pool_address}.')

        assert 1 <= data_token_weight <= 9
        base_weight = 10.0 - data_token_weight

        # Must approve datatoken and Ocean tokens to the new pool as spender
        dt = DataToken(data_token_address)
        tx_id = dt.approve_tokens(pool_address,
                                  data_token_amount,
                                  from_wallet,
                                  wait=True)
        if dt.get_tx_receipt(tx_id).status != 1:
            raise AssertionError(
                f'Approve datatokens failed, pool was created at {pool_address}'
            )

        ot = DataToken(self.ocean_address)
        tx_id = ot.approve_tokens(pool_address,
                                  OCEAN_amount,
                                  from_wallet,
                                  wait=True)
        if ot.get_tx_receipt(tx_id).status != 1:
            raise AssertionError(
                f'Approve OCEAN tokens failed, pool was created at {pool_address}'
            )

        tx_id = pool.setup(data_token_address, to_base_18(data_token_amount),
                           to_base_18(data_token_weight), self.ocean_address,
                           to_base_18(OCEAN_amount), to_base_18(base_weight),
                           to_base_18(swap_fee), from_wallet)
        if pool.get_tx_receipt(tx_id).status != 1:
            raise AssertionError(
                f'pool.setup failed: txId={tx_id}, receipt={pool.get_tx_receipt(tx_id)}'
            )

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

        return pool
예제 #19
0
def bfactory_address(config):
    return BFactory.configured_address(_NETWORK, config.address_file)
예제 #20
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
예제 #21
0
def _deployBPool(network: str, from_wallet: Wallet) -> BPool:
    factory_address = get_bfactory_address(network)
    factory = BFactory(factory_address)
    pool_address = factory.newBPool(from_wallet=from_wallet)
    pool = BPool(pool_address)
    return pool