Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: block adding too unbalanced #92

Merged
merged 14 commits into from
Oct 24, 2024
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ export function _useAddLiquidity(urlTxHash?: Hash) {
const [wethIsEth, setWethIsEth] = useState(false)
const [totalUSDValue, setTotalUSDValue] = useState('0')
const [proportionalSlippage, setProportionalSlippage] = useState<string>('0')

const { pool, refetch: refetchPool, isLoading } = usePool()
const { getToken, getNativeAssetToken, getWrappedNativeAssetToken, isLoadingTokenPrices } =
useTokens()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ import { BalAlert } from '@repo/lib/shared/components/alerts/BalAlert'
import { SafeAppAlert } from '@repo/lib/shared/components/alerts/SafeAppAlert'
import { useTokens } from '@repo/lib/modules/tokens/TokensProvider'

type PriceImpactErrorType = Error & { shortMessage: string }

// small wrapper to prevent out of context error
export function AddLiquidityForm() {
const { validTokens, proportionalSlippage } = useAddLiquidity()
Expand Down Expand Up @@ -87,6 +89,7 @@ function AddLiquidityMainForm() {
proportionalSlippage,
slippage,
setProportionalSlippage,
humanAmountsIn,
} = useAddLiquidity()

const nextBtn = useRef(null)
Expand All @@ -103,6 +106,20 @@ function AddLiquidityMainForm() {
setPriceImpact(priceImpactQuery.data)
}, [priceImpactQuery.data])

useEffect(() => {
humanAmountsIn.forEach(amount => {
if (priceImpactQuery.error?.message.includes('BAL#304') && amount.humanAmount) {
setValidationError(amount.tokenAddress, 'Amount is causing an unbalanced join')
groninge01 marked this conversation as resolved.
Show resolved Hide resolved
}
})
}, [priceImpactQuery.error])

useEffect(() => {
humanAmountsIn.forEach(amount => {
setValidationError(amount.tokenAddress, '')
})
}, [humanAmountsIn])
groninge01 marked this conversation as resolved.
Show resolved Hide resolved

const hasPriceImpact = priceImpact !== undefined && priceImpact !== null
const priceImpactLabel = hasPriceImpact ? fNum('priceImpact', priceImpact) : '-'

Expand Down
126 changes: 65 additions & 61 deletions packages/lib/modules/price-impact/PriceImpactAccordion.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import { usePriceImpact } from '@repo/lib/modules/price-impact/PriceImpactProvid
import { fNum } from '@repo/lib/shared/utils/numbers'
import { ReactNode, useEffect } from 'react'
import { PriceImpactAcceptModal } from './PriceImpactAcceptModal'
import { useTokenInputsValidation } from '../tokens/TokenInputsValidationProvider'

interface PriceImpactAccordionProps {
setNeedsToAcceptPIRisk: (value: boolean) => void
Expand All @@ -39,6 +40,8 @@ export function PriceImpactAccordion({
cannotCalculatePriceImpact = false,
}: PriceImpactAccordionProps) {
const acceptHighImpactDisclosure = useDisclosure()
const { hasValidationErrors } = useTokenInputsValidation()

const {
priceImpactLevel,
priceImpactColor,
Expand Down Expand Up @@ -88,69 +91,70 @@ export function PriceImpactAccordion({
<AccordionPanel py="md">{accordionPanelComponent}</AccordionPanel>
</AccordionItem>
</Accordion>
{(priceImpactLevel === 'high' || priceImpactLevel === 'max' || isUnknownPriceImpact) && (
<>
<VStack align="start" mt="md" spacing="md" w="full">
<Alert status="error">
<PriceImpactIcon mt="1" priceImpactLevel={priceImpactLevel} size={24} />
<Box ml="md">
<AlertTitle>
{isUnknownPriceImpact
? 'Unknown price impact'
: `Price impact is high: Exceeds ${
priceImpactLevel === 'high' ? '1' : '5'
}.00%`}
</AlertTitle>
<AlertDescription>
<Text color="font.dark" fontSize="sm">
{!hasValidationErrors &&
(priceImpactLevel === 'high' || priceImpactLevel === 'max' || isUnknownPriceImpact) && (
groninge01 marked this conversation as resolved.
Show resolved Hide resolved
<>
<VStack align="start" mt="md" spacing="md" w="full">
<Alert status="error">
<PriceImpactIcon mt="1" priceImpactLevel={priceImpactLevel} size={24} />
<Box ml="md">
<AlertTitle>
{isUnknownPriceImpact
? 'The price impact cannot be calculated. Only proceed if you know exactly what you are doing.'
: 'The higher the price impact, the worse exchange rate you get for this swap.'}
</Text>
</AlertDescription>
</Box>
</Alert>
<Card variant="subSection">
<CardBody>
<Text fontWeight="bold" mb="sm">
Price impact acknowledgement
</Text>
{isUnknownPriceImpact ? (
<Text color="grayText" fontSize="sm">
I accept that the price impact of this transaction is unknown. I understand that
proceeding may result in losses if my transaction moves the market price
unfavorably based on the current depth of the market.
</Text>
) : (
<Text color="grayText" fontSize="sm">
I accept the high price impact of{' '}
{priceImpact && fNum('priceImpact', priceImpact)}. I understand that this may
result in losses, since the size of my swap is likely to move the market price
unfavorably based on the current depth of the market.
? 'Unknown price impact'
: `Price impact is high: Exceeds ${
priceImpactLevel === 'high' ? '1' : '5'
}.00%`}
</AlertTitle>
<AlertDescription>
<Text color="font.dark" fontSize="sm">
{isUnknownPriceImpact
? 'The price impact cannot be calculated. Only proceed if you know exactly what you are doing.'
: 'The higher the price impact, the worse exchange rate you get for this swap.'}
</Text>
</AlertDescription>
</Box>
</Alert>
<Card variant="subSection">
<CardBody>
<Text fontWeight="bold" mb="sm">
Price impact acknowledgement
</Text>
)}
</CardBody>
<CardFooter pt="md">
{!acceptPriceImpactRisk ? (
<Button onClick={handleClick} variant="secondary" w="full">
I accept {isUnknownPriceImpact ? 'unknown' : 'high'} price impact
</Button>
) : (
<Button isDisabled variant="secondary" w="full">
{isUnknownPriceImpact ? 'Unknown' : 'High'} price impact accepted
</Button>
)}
</CardFooter>
</Card>
</VStack>
<PriceImpactAcceptModal
isOpen={acceptHighImpactDisclosure.isOpen}
onClose={acceptHighImpactDisclosure.onClose}
onOpen={acceptHighImpactDisclosure.onOpen}
setAcceptHighPriceImpact={setAcceptPriceImpactRisk}
/>
</>
)}
{isUnknownPriceImpact ? (
<Text color="grayText" fontSize="sm">
I accept that the price impact of this transaction is unknown. I understand
that proceeding may result in losses if my transaction moves the market price
unfavorably based on the current depth of the market.
</Text>
) : (
<Text color="grayText" fontSize="sm">
I accept the high price impact of{' '}
{priceImpact && fNum('priceImpact', priceImpact)}. I understand that this may
result in losses, since the size of my swap is likely to move the market price
unfavorably based on the current depth of the market.
</Text>
)}
</CardBody>
<CardFooter pt="md">
{!acceptPriceImpactRisk ? (
<Button onClick={handleClick} variant="secondary" w="full">
I accept {isUnknownPriceImpact ? 'unknown' : 'high'} price impact
</Button>
) : (
<Button isDisabled variant="secondary" w="full">
{isUnknownPriceImpact ? 'Unknown' : 'High'} price impact accepted
</Button>
)}
</CardFooter>
</Card>
</VStack>
<PriceImpactAcceptModal
isOpen={acceptHighImpactDisclosure.isOpen}
onClose={acceptHighImpactDisclosure.onClose}
onOpen={acceptHighImpactDisclosure.onOpen}
setAcceptHighPriceImpact={setAcceptPriceImpactRisk}
/>
</>
)}
</Box>
)
}
Loading