Example #1
0
    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)
Example #2
0
    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
        )
Example #3
0
    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
Example #4
0
    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