def _remove_liquidity(self, pool_address: str, token_address: str, amount_base: int, max_pool_shares_base: int, from_wallet: Wallet) -> str: assert amount_base >= 0 if amount_base == 0: return '' assert max_pool_shares_base > 0, f'' pool = BPool(pool_address) if pool.balanceOf(from_wallet.address) == 0: return '' return pool.exitswapExternAmountOut(token_address, amount_base, max_pool_shares_base, from_wallet)
def _remove_liquidity( self, pool_address: str, token_address: str, amount: int, max_pool_shares: int, from_wallet: Wallet, ) -> str: assert amount >= 0 if amount == 0: return "" assert max_pool_shares > 0, "" pool = BPool(self.web3, pool_address) if pool.balanceOf(from_wallet.address) == 0: raise InsufficientBalance( "The current balance is already 0. Remove liquidity failed!" ) return pool.exitswapExternAmountOut( token_address, amount, max_pool_shares, from_wallet )
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: info_dict['dataToken'] = DataToken(dt_address).get_info( web3, from_block, current_block, include_holders=bool('dtHolders' in flags)) 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) all_transfers, block = pool_erc20.get_all_transfers_from_events( from_block, current_block) a_to_balance = DataToken.calculate_balances(all_transfers) _min = to_base_18(0.001) pool_holders = sorted( [(a, from_base_18(b)) for a, b in a_to_balance.items() if b > _min], key=lambda x: x[1], reverse=True) 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
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