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)
def get_pool_info(self, pool_address, dt_address=None, from_block=None, to_block=None, flags=None): if not flags: flags = self.POOL_INFO_FLAGS from18 = from_base_18 web3 = Web3Provider.get_web3() current_block = ( to_block if to_block is not None else web3.eth.blockNumber ) # RPC_CALL pool = BPool(pool_address) dt_address = (dt_address if dt_address else self.get_token_address( pool_address, pool, validate=False)) # RPC_CALL from_block = (from_block if from_block is not None else self.get_creation_block(pool_address)) # RPC_CALL pool_creator = None shares = None info_dict = {"address": pool.address, "dataTokenAddress": dt_address} if "datatokenInfo" in flags: dt = DataToken(dt_address) minter = dt.minter() token_holders = [] if "dtHolders" in flags: token_holders = dt.calculate_token_holders( from_block, to_block, 0.000001) order_logs = dt.get_start_order_logs(web3, from_block=from_block, to_block=to_block) info_dict["dataToken"] = { "address": dt.address(), "name": dt.datatoken_name(), "symbol": dt.symbol(), "deciamls": dt.decimals(), "cap": from18(dt.cap()), "totalSupply": from18(dt.totalSupply()), "minter": minter, "minterBalance": from18(dt.balanceOf(minter)), "numHolders": len(token_holders), "holders": token_holders, "numOrders": len(order_logs), } if "price" in flags: info_dict.update({ "spotPrice1DT": from18(pool.getSpotPrice(self.ocean_address, dt_address)), "totalPrice1DT": self.getOceanRequiredToBuyDT(pool_address, dt_amount=1.0), }) if "reserve" in flags: ocn_reserve = from18(pool.getBalance(self.ocean_address)) dt_reserve = from18(pool.getBalance(dt_address)) info_dict.update({ "oceanWeight": from18(pool.getDenormalizedWeight(self.ocean_address)), "oceanReserve": ocn_reserve, "dtWeight": from18(pool.getDenormalizedWeight(dt_address)), "dtReserve": dt_reserve, }) if "shares" in flags or "creator" in flags: pool_creator = pool.getController() shares = from18(pool.totalSupply()) info_dict.update({"creator": pool_creator}) if "shareHolders" in flags: pool_erc20 = DataToken(pool_address) pool_holders = pool_erc20.calculate_token_holders( from_block, current_block, 0.001) info_dict.update({ "numShareHolders": len(pool_holders), "shareHolders": pool_holders }) all_join_records = [] all_exit_records = [] if "liquidityTotals" in flags or "liquidity" in flags: all_join_records = self.get_all_liquidity_additions( web3, pool_address, from_block, current_block, dt_address, raw_result=False, ) # RPC_CALL total_ocn_additions = from18( sum(r[2] for r in all_join_records if r[1] == self.ocean_address)) all_exit_records = self.get_all_liquidity_removals( web3, pool_address, from_block, current_block, dt_address, raw_result=False, ) # RPC_CALL total_ocn_removals = from18( sum(r[2] for r in all_exit_records if r[1] == self.ocean_address)) info_dict.update({ "totalOceanAdditions": total_ocn_additions, "totalOceanRemovals": total_ocn_removals, }) if "liquidity" in flags: creator_shares = from18(pool.balanceOf(pool_creator)) creator_shares_percent = creator_shares / shares account_to_join_record = self.get_account_to_liquidity_records_map( all_join_records) ocean_additions = [ from18(r[2]) for r in account_to_join_record[pool_creator] if r[1] == self.ocean_address ] dt_additions = [ from18(r[2]) for r in account_to_join_record[pool_creator] if r[1] == dt_address ] account_to_exit_record = self.get_account_to_liquidity_records_map( all_exit_records) ocean_removals = [ from18(r[2]) for r in account_to_exit_record.get(pool_creator, []) if r[1] == self.ocean_address ] dt_removals = [ from18(r[2]) for r in account_to_exit_record.get(pool_creator, []) if r[1] == dt_address ] all_swap_records = self.get_all_swaps( web3, pool_address, from_block, current_block, dt_address, raw_result=False, ) account_to_swap_record = self.get_account_to_liquidity_records_map( all_swap_records) ocean_in = [ from18(r[2]) for r in account_to_swap_record.get(pool_creator, []) if r[1] == self.ocean_address ] dt_in = [ from18(r[2]) for r in account_to_swap_record.get(pool_creator, []) if r[1] == dt_address ] ocean_out = [ from18(r[4]) for r in account_to_swap_record.get(pool_creator, []) if r[3] == self.ocean_address ] dt_out = [ from18(r[4]) for r in account_to_swap_record.get(pool_creator, []) if r[3] == dt_address ] swap_fee = from18(pool.getSwapFee()) sum_ocean_additions = sum(ocean_additions) sum_ocean_removals = sum(ocean_removals) sum_ocn_swap_in = sum(ocean_in) sum_ocn_swap_out = sum(ocean_out) sum_dt_additions = sum(dt_additions) sum_dt_removals = sum(dt_removals) sum_dt_swap_in = sum(dt_in) sum_dt_swap_out = sum(dt_out) taxable_ocn = (sum_ocn_swap_in + sum_ocn_swap_out + sum_ocean_additions + sum_ocean_removals - ocean_additions[0]) taxable_dt = (sum_dt_swap_in + sum_dt_swap_out + sum_dt_additions + sum_dt_removals - dt_additions[0]) info_dict.update({ "totalShares": shares, "creator": pool_creator, "creatorShares": creator_shares, "creatorSharesPercentage": creator_shares_percent, "creatorFirstOceanStake": ocean_additions[0], "creatorFirstDTStake": dt_additions[0], "creatorTotalOceanStake": sum(ocean_additions), "creatorTotalDTStake": sum(dt_additions), "creatorTotalOceanUnstake": sum(ocean_removals), "creatorTotalDTUnstake": sum(dt_removals), "totalOceanSwapIn": sum_ocn_swap_in, "totalOceanSwapOut": sum_ocn_swap_out, "totalDTSwapIn": sum_dt_swap_in, "totalDTSwapOut": sum_dt_swap_out, "totalSwapFeesDT": swap_fee * taxable_dt, "totalSwapFeesOcean": swap_fee * taxable_ocn, }) info_dict.update({ "fromBlockNumber": from_block, "latestBlockNumber": current_block }) return info_dict