async def update_lp_order(self, update_result: Dict[str, any], tracked_pos: UniswapV3InFlightPosition): """ Unlike swap orders, lp orders only stop tracking when a remove position is detected. """ if update_result.get("confirmed", False): if update_result["receipt"].get("status", 0) == 1: transaction_results = await self._api_request("post", "eth/uniswap/v3/result", {"logs": json.dumps(update_result["receipt"]["logs"]), "pair": tracked_pos.trading_pair}) for result in transaction_results["info"]: if result["name"] == "IncreaseLiquidity" and tracked_pos.last_status == UniswapV3PositionStatus.PENDING_CREATE: token_id, amount0, amount1 = self.parse_liquidity_events(result["events"], transaction_results["baseDecimal"], transaction_results["quoteDecimal"]) tracked_pos.token_id = token_id tracked_pos.base_amount = amount0 tracked_pos.quote_amount = amount1 tracked_pos.last_status = UniswapV3PositionStatus.OPEN self.logger().info(f"Liquidity added for tokenID - {token_id}.") self.trigger_event(MarketEvent.RangePositionUpdated, RangePositionUpdatedEvent(self.current_timestamp, tracked_pos.hb_id, tracked_pos.last_tx_hash, tracked_pos.token_id, tracked_pos.base_amount, tracked_pos.quote_amount, tracked_pos.last_status.name )) self.trigger_event(MarketEvent.RangePositionCreated, RangePositionCreatedEvent(self.current_timestamp, tracked_pos.hb_id, tracked_pos.last_tx_hash, tracked_pos.token_id, tracked_pos.trading_pair, tracked_pos.fee_tier, tracked_pos.lower_price, tracked_pos.upper_price, tracked_pos.base_amount, tracked_pos.quote_amount, tracked_pos.last_status.name, tracked_pos.gas_price )) elif result["name"] == "DecreaseLiquidity" and tracked_pos.last_status == UniswapV3PositionStatus.PENDING_REMOVE: token_id, amount0, amount1 = self.parse_liquidity_events(result["events"], transaction_results["baseDecimal"], transaction_results["quoteDecimal"]) tracked_pos.token_id = token_id tracked_pos.last_status = UniswapV3PositionStatus.REMOVED self.logger().info(f"Liquidity decreased for tokenID - {token_id}.") self.trigger_event(MarketEvent.RangePositionUpdated, RangePositionUpdatedEvent(self.current_timestamp, tracked_pos.hb_id, tracked_pos.last_tx_hash, tracked_pos.token_id, tracked_pos.base_amount, tracked_pos.quote_amount, tracked_pos.last_status.name )) self.trigger_event(MarketEvent.RangePositionRemoved, RangePositionRemovedEvent(self.current_timestamp, tracked_pos.hb_id, tracked_pos.token_id)) self.stop_tracking_position(tracked_pos.hb_id) elif result["name"] == "Collect": pass # not sure how to handle this at the moment # token_id, amount0, amount1 = self.parse_liquidity_events(result["events"]) # tracked_order.update_exchange_order_id(token_id) # self.logger().info(f"Liquidity removed for tokenID - {token_id}.") else: self.logger().info( f"Error updating range position, token_id: {tracked_pos.token_id}, hb_id: {tracked_pos.hb_id}" ) self.trigger_event(MarketEvent.RangePositionFailure, RangePositionFailureEvent(self.current_timestamp, tracked_pos.hb_id)) self.stop_tracking_position(tracked_pos.hb_id) tracked_pos.last_status = UniswapV3PositionStatus.FAILED
async def _update_order_status(self): """ Calls REST API to get status update for each in-flight order. """ tasks, tracked_orders, tracked_positions, open_positions = [], [], [], [] if len(self._in_flight_orders) > 0: tracked_orders = list(self._in_flight_orders.values()) for tracked_order in tracked_orders: order_id = await tracked_order.get_exchange_order_id() tasks.append( self._api_request("post", "eth/poll", {"txHash": order_id})) if len(self._in_flight_positions) > 0: tracked_positions = [ pos for pos in self._in_flight_positions.values() if pos.last_status.is_pending() ] # We only want to poll update for pending positions open_positions = [ pos for pos in self._in_flight_positions.values() if pos.last_status.is_active() ] for tracked_pos in tracked_positions: last_hash = await tracked_pos.get_last_tx_hash() tasks.append( self._api_request("post", "eth/poll", {"txHash": last_hash})) if tasks: update_results = await safe_gather(*tasks, return_exceptions=True) for update_result, tracked_item in zip( update_results, tracked_orders + tracked_positions): self.logger().debug( f"Polling for order status updates of {len(tasks)} orders." ) if isinstance(update_result, Exception): raise update_result if "txHash" not in update_result: self.logger().info( f"Update_order_status txHash not in resp: {update_result}" ) continue if isinstance(tracked_item, UniswapInFlightOrder): await self.update_swap_order(update_result, tracked_item) else: await self.update_lp_order(update_result, tracked_item) # update info for each positions as well tasks = [] if len(open_positions) > 0: for tracked_pos in open_positions: tasks.append(self.get_position(tracked_pos.token_id)) if tasks: position_results = await safe_gather(*tasks, return_exceptions=True) for update_result, tracked_item in zip(position_results, open_positions): if not isinstance(update_result, Exception) and len( update_result.get("position", {})) > 0: tracked_item.lower_price = Decimal( update_result["position"].get("lowerPrice", "0")) tracked_item.upper_price = Decimal( update_result["position"].get("upperPrice", "0")) amount0 = Decimal(update_result["position"].get( "amount0", "0")) amount1 = Decimal(update_result["position"].get( "amount1", "0")) unclaimedToken0 = Decimal(update_result["position"].get( "unclaimedToken0", "0")) unclaimedToken1 = Decimal(update_result["position"].get( "unclaimedToken1", "0")) if amount0 == amount1 == unclaimedToken0 == unclaimedToken1 == s_decimal_0: self.logger().info( f"Detected that position with id: {tracked_item.token_id} is closed." ) tracked_item.last_status = UniswapV3PositionStatus.REMOVED # this will prevent it from being restored on next import self.trigger_event( MarketEvent.RangePositionUpdated, RangePositionUpdatedEvent( self.current_timestamp, tracked_item.hb_id, tracked_item.last_tx_hash, tracked_item.token_id, tracked_item.base_amount, tracked_item.quote_amount, tracked_item.last_status.name)) self.trigger_event( MarketEvent.RangePositionRemoved, RangePositionRemovedEvent(self.current_timestamp, tracked_item.hb_id, tracked_item.token_id)) self.stop_tracking_position(tracked_item.hb_id) else: if tracked_item.trading_pair.split( "-")[0] == update_result["position"]["token0"]: tracked_item.current_base_amount = amount0 tracked_item.current_quote_amount = amount1 tracked_item.unclaimed_base_amount = unclaimedToken0 tracked_item.unclaimed_quote_amount = unclaimedToken1 else: tracked_item.current_base_amount = amount1 tracked_item.current_quote_amount = amount0 tracked_item.unclaimed_base_amount = unclaimedToken1 tracked_item.unclaimed_quote_amount = unclaimedToken0