From 676ec6beb8ba8028f4f686641ec431f8230501f1 Mon Sep 17 00:00:00 2001 From: David Uhlmann Date: Tue, 14 May 2024 20:14:04 +1000 Subject: [PATCH] fix: make order confirmation button state based on simulation result - the button should be enabled if the simulation result is of the requested user input (even if the result is refreshing due to liquidity state changes) - the button should be disabled if the simulation result is not of the requested user input, because the estimated result may be very inaccurate (though hopefully it is not) --- src/components/cards/LimitOrderCard.tsx | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/src/components/cards/LimitOrderCard.tsx b/src/components/cards/LimitOrderCard.tsx index 4bb24f1b0..12f9a803b 100644 --- a/src/components/cards/LimitOrderCard.tsx +++ b/src/components/cards/LimitOrderCard.tsx @@ -479,7 +479,17 @@ function LimitOrder({ tokenA, tokenB }: { tokenA: Token; tokenB: Token }) { userBalanceTokenIn, ]); - const lastSimulatedMsgPlaceLimitOrder = useRef(); + // keep track of whether the simulation result was calculated on the given + // user inputs (but the dex price may be different) by tracking last msg + const [lastSimulatedMsgPlaceLimitOrder, setLastSimulatedMsgPlaceLimitOrder] = + useState(); + const simulationResultMatchesInput = useMemo(() => { + return ( + simulatedMsgPlaceLimitOrder !== undefined && + lastSimulatedMsgPlaceLimitOrder === simulatedMsgPlaceLimitOrder + ); + }, [lastSimulatedMsgPlaceLimitOrder, simulatedMsgPlaceLimitOrder]); + const { data: simulationResult, isValidating: isValidatingSimulation } = useSimulatedLimitOrderResult(simulatedMsgPlaceLimitOrder, { // if the limit order payload hasn't changed then keep the previous data @@ -487,16 +497,17 @@ function LimitOrder({ tokenA, tokenB }: { tokenA: Token; tokenB: Token }) { // don't keep when input goes to 0 Number(simulatedMsgPlaceLimitOrder?.amount_in) > 0 || // don't change if input exists and hasn't changed - (simulatedMsgPlaceLimitOrder !== undefined && - lastSimulatedMsgPlaceLimitOrder.current === - simulatedMsgPlaceLimitOrder), + simulationResultMatchesInput, // invalidate the request cache when the liquidity height changes memo: `height of ${meta?.height}`, }); // update last simulatedMsgPlaceLimitOrder for comparison on the next render useEffect(() => { - lastSimulatedMsgPlaceLimitOrder.current = simulatedMsgPlaceLimitOrder; - }, [simulatedMsgPlaceLimitOrder]); + // set only after simulation result has been found + if (!isValidatingSimulation) { + setLastSimulatedMsgPlaceLimitOrder(simulatedMsgPlaceLimitOrder); + } + }, [isValidatingSimulation, simulatedMsgPlaceLimitOrder]); const onFormSubmit = useCallback( function (event?: React.FormEvent) { @@ -951,7 +962,7 @@ function LimitOrder({ tokenA, tokenB }: { tokenA: Token; tokenB: Token }) { disabled={ isValidatingSwap || !simulationResult || - !coinOut || + !simulationResultMatchesInput || (!Number(amountInBaseAmount) && !Number(amountOutBaseAmount)) } >