Skip to content

Improve error priority. #459

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

Merged
merged 7 commits into from
Feb 20, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/constants/tokenConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -370,7 +370,7 @@ export const OUTPUT_TOKEN_CONFIG: Record<OutputTokenType, OutputTokenDetailsSpac
symbol: 'BRL',
name: 'Brazilian Real',
},
erc20WrapperAddress: '6ftBYTotU4mmCuvUqJvk6qEP7uCzzz771pTMoxcbHFb9rcPv',
erc20WrapperAddress: '6eRq1yvty6KorGcJ3nKpNYrCBn9FQnzsBhFn4JmAFqWUwpnh',
minWithdrawalAmountRaw: '1',
maxWithdrawalAmountRaw: '50000000000000000000000000000000',
offrampFeesBasisPoints: 0,
Expand Down
42 changes: 31 additions & 11 deletions src/pages/swap/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@ import { FAQAccordion } from '../../sections/FAQAccordion';
import { HowToSell } from '../../sections/HowToSell';
import { PopularTokens } from '../../sections/PopularTokens';

type ExchangeRateCache = Partial<Record<InputTokenType, Partial<Record<OutputTokenType, number>>>>;

export const SwapPage = () => {
const formRef = useRef<HTMLDivElement | null>(null);
const feeComparisonRef = useRef<FeeComparisonRef>(null);
Expand All @@ -86,10 +88,18 @@ export const SwapPage = () => {
const [isOfframpSummaryDialogVisible, setIsOfframpSummaryDialogVisible] = useState(false);
const [cachedAnchorUrl, setCachedAnchorUrl] = useState<string | undefined>(undefined);
const [cachedId, setCachedId] = useState<string | undefined>(undefined);
const [termsAnimationKey, setTermsAnimationKey] = useState(0);
// This cache is used to show an error message to the user if the chosen input amount
// is expected to result in an output amount that is above the maximum withdrawal amount defined by the anchor
const [exchangeRateCache, setExchangeRateCache] = useState<ExchangeRateCache>({
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It took me a moment to figure out why we need this exchange rate cache. My first thought was that you'd use it to show amounts higher than what the liquidity allows, ie. to show output amounts that are otherwise 0. Then I realized you are using it only to know when the user is expected to be above the maximum offramp amount so we can show the error.

I'm fine if we keep this logic but let's add a comment above this cache. Maybe something like

// This cache is used to show an error message to the user if the chosen input amount is expected to result in an output amount that is above the maximum withdrawal amount defined by the anchor

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alright, fair enough. You were not far away though. I initially added for both replacing the 0 and the error priority thing.
Later remove it to keep consistency with the ticket.

usdc: { ars: 1200, eurc: 0.95, brl: 5.7 },
usdce: { ars: 1200, eurc: 0.95, brl: 5.7 },
usdt: { ars: 1200, eurc: 0.95, brl: 5.7 },
});

const { trackEvent } = useEventsContext();
const { selectedNetwork, setNetworkSelectorDisabled } = useNetwork();

const [termsAnimationKey, setTermsAnimationKey] = useState(0);
const {
error: signingServiceError,
isLoading: isSigningServiceLoading,
Expand Down Expand Up @@ -217,7 +227,11 @@ export const SwapPage = () => {
// Calculate the final amount after the offramp fees
const totalReceive = calculateTotalReceive(toAmount, toToken);
form.setValue('toAmount', totalReceive);
} else if (tokenOutAmount.error) {
setExchangeRateCache((prev) => ({
...prev,
[from]: { ...prev[from], [to]: tokenOutAmount.data!.effectiveExchangeRate },
}));
} else if (!tokenOutAmount.isLoading || tokenOutAmount.error) {
form.setValue('toAmount', '0');
} else {
// Do nothing
Expand Down Expand Up @@ -305,17 +319,20 @@ export const SwapPage = () => {

const amountOut = tokenOutAmount.data?.roundedDownQuotedAmountOut;

if (amountOut !== undefined) {
const maxAmountUnits = multiplyByPowerOfTen(Big(toToken.maxWithdrawalAmountRaw), -toToken.decimals);
const minAmountUnits = multiplyByPowerOfTen(Big(toToken.minWithdrawalAmountRaw), -toToken.decimals);
const maxAmountUnits = multiplyByPowerOfTen(Big(toToken.maxWithdrawalAmountRaw), -toToken.decimals);
const minAmountUnits = multiplyByPowerOfTen(Big(toToken.minWithdrawalAmountRaw), -toToken.decimals);

if (maxAmountUnits.lt(amountOut)) {
trackEvent({ event: 'form_error', error_message: 'more_than_maximum_withdrawal' });
return `Maximum withdrawal amount is ${stringifyBigWithSignificantDecimals(maxAmountUnits, 2)} ${
toToken.fiat.symbol
}.`;
}
const exchangeRate = tokenOutAmount.data?.effectiveExchangeRate || exchangeRateCache[from]?.[to];

if (fromAmount && exchangeRate && maxAmountUnits.lt(fromAmount.mul(exchangeRate))) {
console.log(exchangeRate, fromAmount!.mul(exchangeRate).toNumber());
trackEvent({ event: 'form_error', error_message: 'more_than_maximum_withdrawal' });
return `Maximum withdrawal amount is ${stringifyBigWithSignificantDecimals(maxAmountUnits, 2)} ${
toToken.fiat.symbol
}.`;
}

if (amountOut !== undefined) {
if (!config.test.overwriteMinimumTransferAmount && minAmountUnits.gt(amountOut)) {
trackEvent({ event: 'form_error', error_message: 'less_than_minimum_withdrawal' });
return `Minimum withdrawal amount is ${stringifyBigWithSignificantDecimals(minAmountUnits, 2)} ${
Expand All @@ -324,6 +341,9 @@ export const SwapPage = () => {
}
}

if (tokenOutAmount.error?.includes('Insufficient liquidity')) {
return 'The amount is temporarily not available. Please, try with a smaller amount.';
}
return tokenOutAmount.error;
}

Expand Down
Loading