def test_ERC20(network, alice_wallet, alice_address, bob_wallet, bob_address, OCEAN_address): """Tests an OCEAN token approval, allowance and transfers.""" token = BToken(OCEAN_address) token.approve(bob_address, 0, from_wallet=alice_wallet) # generating ERC20 Tokens, so the symbol is irrelevant assert token.symbol() == "DTT" assert token.decimals() == 18 assert token.balanceOf(alice_address) > util.to_base_18(10.0) assert token.balanceOf(bob_address) > util.to_base_18(10.0) assert token.allowance(alice_address, bob_address) == 0 token.approve(bob_address, int(1e18), from_wallet=alice_wallet) assert token.allowance(alice_address, bob_address) == int(1e18) # alice sends all her OCEAN to Bob, then Bob sends it back alice_OCEAN = token.balanceOf(alice_address) bob_OCEAN = token.balanceOf(bob_address) token.transfer(bob_address, alice_OCEAN, from_wallet=alice_wallet) assert token.balanceOf(alice_address) == 0 assert token.balanceOf(bob_address) == (alice_OCEAN + bob_OCEAN) token.transfer(alice_address, alice_OCEAN, from_wallet=bob_wallet) assert token.balanceOf(alice_address) == alice_OCEAN assert token.balanceOf(bob_address) == bob_OCEAN
def buy_data( ocean, private_key, token_address, seller_wallet, min_amount, max_amount, ): """Buy a dataset on the market. Define wallet, verify that there is enough ganache ETH and OCEAN. Create an exchange_id for a new exchange. Args: ocean (): private_key (str): token_address (str): seller_wallet (Wallet): min_amount (float): max_amount (float): Returns: """ wallet = Wallet(ocean.web3, private_key, ocean.config.block_confirmations) assert ocean.web3.eth.get_balance(wallet.address) > 0, 'need ganache ETH' OCEAN_token = BToken(ocean.web3, ocean.OCEAN_address) assert OCEAN_token.balanceOf(wallet.address) > 0, 'need ganache OCEAN' exchange_id = ocean.exchange.create(token_address, to_wei(min_amount), seller_wallet) tx_result = ocean.exchange.buy_at_fixed_rate(to_wei(min_amount), wallet, to_wei(max_amount), exchange_id, token_address, seller_wallet.address) assert tx_result, 'failed buying data tokens at fixed rate.'
def _add_liquidity( self, pool_address: str, token_address: str, amount_base: int, from_wallet: Wallet, ) -> str: assert amount_base >= 0 if amount_base == 0: return "" pool = BPool(pool_address) token = BToken(token_address) assert token.balanceOf(from_wallet.address) >= amount_base, ( f"Insufficient funds, {amount_base} tokens are required of token address {token_address}, " f"but only a balance of {token.balanceOf(from_wallet.address)} is available." ) tx_id = token.approve(pool_address, amount_base, from_wallet) r = token.get_tx_receipt(tx_id) if not r or r.status != 1: return 0 pool_amount = pool.joinswapExternAmountIn(token_address, amount_base, 0, from_wallet) return pool_amount
def sell_data( ocean, private_key, data_token, amount, fixed_price=True, ): """Sell a dataset on the Ocean market. Mint the datatokens. In the create() step below, ganache OCEAN is needed. Finally, Approve the datatoken for sale. Args: ocean (): wallet (): data_token (): amount (): fixed_price (bool): Whether or not to sell the data at a fixed price. Returns: (bool): Returns True if successful. """ wallet = Wallet(ocean.web3, private_key, ocean.config.block_confirmations) data_token.mint(wallet.address, to_wei(amount), wallet) OCEAN_token = BToken(ocean.web3, ocean.OCEAN_address) assert OCEAN_token.balanceOf(wallet.address) > 0, 'need OCEAN' data_token.approve(ocean.exchange._exchange_address, to_wei(amount), wallet) return True
def test1(): # ocean instance 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) ocean = Ocean(config) OCEAN_address_before = ocean.OCEAN_address # deploy, distribute, etc deploy_fake_OCEAN() # test: OCEAN address should have changed OCEAN_address_after = ocean.OCEAN_address assert OCEAN_address_before != OCEAN_address_after # test: TEST_PRIVATE_KEY{1,2} should each hold OCEAN wallet1 = Wallet(ocean.web3, private_key=os.getenv("TEST_PRIVATE_KEY1")) wallet2 = Wallet(ocean.web3, private_key=os.getenv("TEST_PRIVATE_KEY2")) OCEAN_after = BToken(ocean.OCEAN_address) assert OCEAN_after.balanceOf(wallet1.address) > 0 assert OCEAN_after.balanceOf(wallet2.address) > 0
def sell_data_tokens( self, pool_address: str, amount: int, min_OCEAN_amount: int, from_wallet: Wallet ) -> str: """ Sell data tokens into this pool, receive `min_OCEAN_amount` of OCEAN tokens. If total income >= min_OCEAN_amount - Caller is spending DataTokens, and receiving OCEAN tokens - DataTokens are going into pool, OCEAN tokens are going out of pool The transaction fails if total income does not reach `min_OCEAN_amount` :param pool_address: str address of pool contract :param amount: int number of data tokens to add to this pool :param min_OCEAN_amount: :param from_wallet: :return: str transaction id/hash """ dtoken_address = self.get_token_address(pool_address) dt = BToken(self.web3, dtoken_address) if dt.balanceOf(from_wallet.address) < amount: raise InsufficientBalance("Insufficient funds for selling DataTokens!") if dt.allowance(from_wallet.address, pool_address) < amount: dt.approve(pool_address, amount, from_wallet=from_wallet) pool = BPool(self.web3, pool_address) return pool.swapExactAmountIn( tokenIn_address=dtoken_address, # entering pool tokenAmountIn=amount, # "" tokenOut_address=self.ocean_address, # leaving pool minAmountOut=min_OCEAN_amount, # "" maxPrice=2 ** 255, # here we limit by max_num_OCEAN, not price from_wallet=from_wallet, )
def add_liquidity_finalized( self, pool_address: str, bpt_amount: int, max_data_token_amount: int, max_OCEAN_amount: int, from_wallet: Wallet, ) -> str: """ Add liquidity to a pool that's been finalized. Buy bpt_amount tokens from the pool, spending DataTokens and OCEAN tokens as needed and up to the specified maximum amounts. :param pool_address: str address of pool contract :param bpt_amount: int number of pool shares to receive for adding the liquidity :param max_data_token_amount: int maximum amount of Data tokens to go into the pool :param max_OCEAN_amount: int maximum amount of OCEAN tokens to go into the pool :param from_wallet: Wallet instance :return: str transaction id/hash """ assert self._is_valid_pool(pool_address), "The pool address is not valid." dt_address = self.get_token_address(pool_address) dt = BToken(self.web3, dt_address) if dt.balanceOf(from_wallet.address) < max_data_token_amount: raise InsufficientBalance( f"Insufficient funds for adding liquidity for {dt.address} datatoken!" ) if dt.allowance(from_wallet.address, pool_address) < max_data_token_amount: dt.approve(pool_address, max_data_token_amount, from_wallet=from_wallet) OCEAN = BToken(self.web3, self.ocean_address) if OCEAN.balanceOf(from_wallet.address) < max_OCEAN_amount: raise InsufficientBalance( f"Insufficient funds for adding liquidity for {OCEAN.address} OCEAN token!" ) if OCEAN.allowance(from_wallet.address, pool_address) < max_OCEAN_amount: OCEAN.approve(pool_address, max_OCEAN_amount, from_wallet=from_wallet) pool = BPool(self.web3, pool_address) return pool.joinPool( bpt_amount, [max_data_token_amount, max_OCEAN_amount], from_wallet=from_wallet, )
def _add_liquidity(self, pool_address: str, token_address: str, amount_base: int, from_wallet: Wallet) -> str: assert amount_base >= 0 if amount_base == 0: return '' pool = BPool(pool_address) token = BToken(token_address) assert token.balanceOf(from_wallet.address) >= amount_base, \ f'Insufficient funds, {amount_base} tokens are required of token address {token_address}, ' \ f'but only a balance of {token.balanceOf(from_wallet.address)} is available.' token.approve(pool_address, amount_base, from_wallet) pool_amount = pool.joinswapExternAmountIn(token_address, amount_base, 0, from_wallet) return pool_amount
def _add_liquidity( self, pool_address: str, token_address: str, amount: int, from_wallet: Wallet ) -> str: assert amount >= 0 if amount == 0: return "" pool = BPool(self.web3, pool_address) token = BToken(self.web3, token_address) assert token.balanceOf(from_wallet.address) >= amount, ( f"Insufficient funds, {amount} tokens are required of token address {token_address}, " f"but only a balance of {token.balanceOf(from_wallet.address)} is available." ) if token.allowance(from_wallet.address, pool_address) < amount: tx_id = token.approve(pool_address, amount, from_wallet) r = token.get_tx_receipt(self.web3, tx_id) if not r or r.status != 1: raise VerifyTxFailed( f"Approve OCEAN tokens failed, pool was created at {pool_address}" ) pool_amount = pool.joinswapExternAmountIn(token_address, amount, 0, from_wallet) return pool_amount
def test_ERC20(network, alice_wallet, alice_address, bob_wallet, bob_address, OCEAN_address): token = BToken(OCEAN_address) token.approve(bob_address, 0, from_wallet=alice_wallet) assert token.symbol() == 'OCEAN' assert token.decimals() == 18 assert token.balanceOf(alice_address) > util.to_base_18(10.0) assert token.balanceOf(bob_address) > util.to_base_18(10.0) assert token.allowance(alice_address, bob_address) == 0 token.approve(bob_address, int(1e18), from_wallet=alice_wallet) assert token.allowance(alice_address, bob_address) == int(1e18) # alice sends all her OCEAN to Bob, then Bob sends it back alice_OCEAN = token.balanceOf(alice_address) bob_OCEAN = token.balanceOf(bob_address) token.transfer(bob_address, alice_OCEAN, from_wallet=alice_wallet) assert token.balanceOf(alice_address) == 0 assert token.balanceOf(bob_address) == (alice_OCEAN + bob_OCEAN) token.transfer(alice_address, alice_OCEAN, from_wallet=bob_wallet) assert token.balanceOf(alice_address) == alice_OCEAN assert token.balanceOf(bob_address) == bob_OCEAN