Skip to content

Commit

Permalink
Fix swaps crashing on tokens with 0 decimals (#6263)
Browse files Browse the repository at this point in the history
* allow swaps to use 0 decimals

* adopt the rest of the app to use 0 decimals if needed

* fix swaps e2e
  • Loading branch information
walmat authored Nov 13, 2024
1 parent 910a789 commit 35daa8b
Show file tree
Hide file tree
Showing 11 changed files with 37 additions and 33 deletions.
4 changes: 2 additions & 2 deletions src/__swaps__/screens/Swap/hooks/useSwapInputsController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -496,7 +496,7 @@ export function useSwapInputsController({
? Number(
convertRawAmountToDecimalFormat(
quoteResponse.sellAmount.toString(),
inputAsset?.networks[inputAsset.chainId]?.decimals || inputAsset?.decimals || 18
inputAsset?.networks[inputAsset.chainId]?.decimals ?? inputAsset?.decimals ?? 18
)
)
: undefined;
Expand All @@ -506,7 +506,7 @@ export function useSwapInputsController({
? Number(
convertRawAmountToDecimalFormat(
quoteResponse.buyAmountMinusFees.toString(),
outputAsset?.networks[outputAsset.chainId]?.decimals || outputAsset?.decimals || 18
outputAsset?.networks[outputAsset.chainId]?.decimals ?? outputAsset?.decimals ?? 18
)
)
: undefined;
Expand Down
7 changes: 5 additions & 2 deletions src/components/coin-row/FastTransactionCoinRow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,11 @@ const swapTypeValues = (changes: RainbowTransaction['changes'], status: RainbowT
// NOTE: For pending txns let's use the change values instead of
// the transaction balance change since that hasn't happened yet
if (status === TransactionStatus.pending) {
const valueOut = `${handleSignificantDecimals(convertRawAmountToDecimalFormat(tokenOut?.value?.toString() || '0', tokenOut?.asset.decimals || 18), tokenOut?.asset.decimals || 18)} ${tokenOut?.asset.symbol}`;
const valueIn = `+${handleSignificantDecimals(convertRawAmountToDecimalFormat(tokenIn?.value?.toString() || '0', tokenIn?.asset.decimals || 18), tokenIn?.asset.decimals || 18)} ${tokenIn?.asset.symbol}`;
const decimalsOut = typeof tokenOut?.asset.decimals === 'number' ? tokenOut.asset.decimals : 18;
const decimalsIn = typeof tokenIn?.asset.decimals === 'number' ? tokenIn.asset.decimals : 18;

const valueOut = `${handleSignificantDecimals(convertRawAmountToDecimalFormat(tokenOut?.value?.toString() || '0', decimalsOut), decimalsOut)} ${tokenOut?.asset.symbol}`;
const valueIn = `+${handleSignificantDecimals(convertRawAmountToDecimalFormat(tokenIn?.value?.toString() || '0', decimalsIn), decimalsIn)} ${tokenIn?.asset.symbol}`;

return [valueOut, valueIn];
}
Expand Down
2 changes: 1 addition & 1 deletion src/components/gas/GasSpeedButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ const GasSpeedButton = ({
}: GasSpeedButtonProps) => {
const { colors } = useTheme();
const { navigate, goBack } = useNavigation();
const { nativeCurrencySymbol, nativeCurrency } = useAccountSettings();
const { nativeCurrency } = useAccountSettings();
const rawColorForAsset = useColorForAsset(asset || {}, fallbackColor, false, true);

const { gasFeeParamsBySpeed, updateGasFeeOption, selectedGasFee, selectedGasFeeOption, currentBlockParams } = useGas();
Expand Down
11 changes: 6 additions & 5 deletions src/helpers/utilities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -217,9 +217,10 @@ export const handleSignificantDecimalsWorklet = (value: number | string, decimal
} else {
dec = Math.min(decimals, buffer);
}

return Number(value).toLocaleString('en-US', {
useGrouping: true,
minimumFractionDigits: 2,
minimumFractionDigits: Math.min(2, dec),
maximumFractionDigits: dec,
});
};
Expand Down Expand Up @@ -298,7 +299,7 @@ export const convertAmountToBalanceDisplayWorklet = (
buffer?: number
) => {
'worklet';
const decimals = asset?.decimals ?? 18;
const decimals = typeof asset?.decimals === 'number' ? asset.decimals : 18;
const display = handleSignificantDecimalsWorklet(value, decimals, buffer);
return `${display} ${asset?.symbol || ''}`;
};
Expand All @@ -309,7 +310,7 @@ export const convertAmountToBalanceDisplayWorklet = (
*/
export const convertRawAmountToBalanceWorklet = (value: number | string, asset: { decimals: number; symbol?: string }, buffer?: number) => {
'worklet';
const decimals = asset?.decimals ?? 18;
const decimals = typeof asset?.decimals === 'number' ? asset.decimals : 18;

const assetBalance = convertRawAmountToDecimalFormatWorklet(value, decimals);

Expand All @@ -328,7 +329,7 @@ export const convertRawAmountToBalance = (
buffer?: number,
trimTrailingZeros?: boolean
) => {
const decimals = asset?.decimals ?? 18;
const decimals = typeof asset?.decimals === 'number' ? asset.decimals : 18;
const assetBalance = convertRawAmountToDecimalFormat(value, decimals);

return {
Expand All @@ -346,7 +347,7 @@ export const convertAmountToBalanceDisplay = (
buffer?: number,
trimTrailingZeros?: boolean
) => {
const decimals = asset?.decimals ?? 18;
const decimals = typeof asset?.decimals === 'number' ? asset.decimals : 18;
const display = handleSignificantDecimals(value, decimals, buffer);
const formattedDisplay = trimTrailingZeros ? display.replace(/\.?0+$/, '') : display;
return `${formattedDisplay} ${asset?.symbol || ''}`;
Expand Down
3 changes: 2 additions & 1 deletion src/parsers/transactions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,8 @@ export const parseTransaction = async (
const nativeAsset = changes.find(change => change?.asset.isNativeAsset);
const nativeAssetPrice = nativeAsset?.price?.toString() || '0';

const value = toFixedDecimals(nativeAsset?.value || '', nativeAsset?.asset?.decimals || 18);
const decimals = typeof nativeAsset?.asset?.decimals === 'number' ? nativeAsset.asset.decimals : 18;
const value = toFixedDecimals(nativeAsset?.value || '', decimals);

// this is probably wrong, need to revisit
const native = convertAmountAndPriceToNativeDisplay(value, nativeAssetPrice, nativeCurrency);
Expand Down
1 change: 0 additions & 1 deletion src/resources/assets/assets.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import lang from 'i18n-js';
import isEmpty from 'lodash/isEmpty';
import { MMKV } from 'react-native-mmkv';
import { NativeCurrencyKey, ParsedAddressAsset } from '@/entities';
import { isNativeAsset } from '@/handlers/assets';
import { convertRawAmountToBalance } from '@/helpers/utilities';
Expand Down
2 changes: 1 addition & 1 deletion src/resources/assets/hardhatAssets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ export const fetchHardhatBalancesByChainId = async (
implementations: chainAsset.asset.implementations || {},
name: chainAsset.asset.name || 'Unknown Token',
symbol: chainAsset.asset.symbol || 'UNKNOWN',
decimals: chainAsset.asset.decimals || 18,
decimals: typeof chainAsset.asset.decimals === 'number' ? chainAsset.asset.decimals : 18,
icon_url: chainAsset.asset.icon_url || '',
price: chainAsset.asset.price || { value: 0, relative_change_24h: 0 },
};
Expand Down
19 changes: 6 additions & 13 deletions src/resources/defi/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,8 @@ export const parsePosition = (position: Position, currency: NativeCurrencyKey):
return {
...deposit,
underlying: deposit.underlying?.map(underlying => {
const nativeDisplay = convertRawAmountToNativeDisplay(
underlying.quantity,
underlying.asset.decimals,
underlying.asset.price?.value!,
currency
);
const decimals = typeof underlying.asset.decimals === 'number' ? underlying.asset.decimals : 18;
const nativeDisplay = convertRawAmountToNativeDisplay(underlying.quantity, decimals, underlying.asset.price?.value!, currency);

if (deposit.omit_from_total) {
totalLocked = add(totalLocked, nativeDisplay.amount);
Expand All @@ -50,12 +46,8 @@ export const parsePosition = (position: Position, currency: NativeCurrencyKey):
return {
...borrow,
underlying: borrow.underlying.map(underlying => {
const nativeDisplay = convertRawAmountToNativeDisplay(
underlying.quantity,
underlying.asset.decimals,
underlying.asset.price?.value!,
currency
);
const decimals = typeof underlying.asset.decimals === 'number' ? underlying.asset.decimals : 18;
const nativeDisplay = convertRawAmountToNativeDisplay(underlying.quantity, decimals, underlying.asset.price?.value!, currency);

if (borrow.omit_from_total) {
totalLocked = subtract(totalLocked, nativeDisplay.amount);
Expand All @@ -73,7 +65,8 @@ export const parsePosition = (position: Position, currency: NativeCurrencyKey):

let totalClaimables = '0';
const parsedClaimables = position.claimables?.map((claim: Claimable): RainbowClaimable => {
const nativeDisplay = convertRawAmountToNativeDisplay(claim.quantity, claim.asset.decimals, claim.asset.price?.value!, currency);
const decimals = typeof claim.asset.decimals === 'number' ? claim.asset.decimals : 18;
const nativeDisplay = convertRawAmountToNativeDisplay(claim.quantity, decimals, claim.asset.price?.value!, currency);

if (claim.omit_from_total) {
totalLocked = add(totalLocked, nativeDisplay.amount);
Expand Down
2 changes: 1 addition & 1 deletion src/screens/SendSheet.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -325,7 +325,7 @@ export default function SendSheet() {
let _assetAmount = '';
if (_nativeAmount.length) {
const priceUnit = !isUniqueAsset ? selected?.price?.value ?? 0 : 0;
const decimals = !isUniqueAsset ? selected?.decimals ?? 18 : 0;
const decimals = !isUniqueAsset ? (typeof selected?.decimals === 'number' ? selected.decimals : 18) : 0;
const convertedAssetAmount = convertAmountFromNativeValue(_nativeAmount, priceUnit, decimals);
_assetAmount = formatInputDecimals(convertedAssetAmount, _nativeAmount);
}
Expand Down
9 changes: 7 additions & 2 deletions src/screens/mints/MintSheet.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -159,15 +159,20 @@ const MintSheet = () => {
// if there is no max mint info, we fallback to 1 to be safe
const maxMintsPerWallet = Number(mintCollection.publicMintInfo?.maxMintsPerWallet);

const decimals =
typeof mintCollection.publicMintInfo?.price?.currency?.decimals === 'number'
? mintCollection.publicMintInfo?.price?.currency?.decimals
: 18;

const price = convertRawAmountToBalance(mintCollection.publicMintInfo?.price?.amount?.raw || pricePerMint || '0', {
decimals: mintCollection.publicMintInfo?.price?.currency?.decimals || 18,
decimals,
symbol: mintCollection.publicMintInfo?.price?.currency?.symbol || 'ETH',
});

// case where mint isnt eth? prob not with our current entrypoints
const mintPriceAmount = multiply(price.amount, quantity);
const mintPriceDisplay = convertAmountToBalanceDisplay(multiply(price.amount, quantity), {
decimals: mintCollection.publicMintInfo?.price?.currency?.decimals || 18,
decimals,
symbol: mintCollection.publicMintInfo?.price?.currency?.symbol || 'ETH',
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -289,12 +289,13 @@ export default function TransactionMasthead({ transaction }: { transaction: Rain
// NOTE: For pending transactions let's use the change value
// since the balance hasn't been updated yet.
if (isPendingSwap) {
const inAssetValueDisplay = `${handleSignificantDecimals(convertRawAmountToDecimalFormat(change?.value?.toString() || '0', change?.asset.decimals || 18), change?.asset.decimals || 18)} ${change?.asset.symbol}`;
const decimals = typeof change?.asset.decimals === 'number' ? change?.asset.decimals : 18;
const inAssetValueDisplay = `${handleSignificantDecimals(convertRawAmountToDecimalFormat(change?.value?.toString() || '0', decimals), decimals)} ${change?.asset.symbol}`;
return {
inAssetValueDisplay,
inAssetNativeDisplay: change?.asset.price?.value
? convertAmountAndPriceToNativeDisplay(
convertRawAmountToDecimalFormat(change?.value?.toString() || '0', change?.asset.decimals || 18),
convertRawAmountToDecimalFormat(change?.value?.toString() || '0', decimals),
change?.asset.price?.value || '0',
nativeCurrency
)?.display
Expand Down Expand Up @@ -322,12 +323,13 @@ export default function TransactionMasthead({ transaction }: { transaction: Rain
// NOTE: For pending transactions let's use the change value
// since the balance hasn't been updated yet.
if (isPendingSwap) {
const inAssetValueDisplay = `${handleSignificantDecimals(convertRawAmountToDecimalFormat(change?.value?.toString() || '0', change?.asset.decimals || 18), change?.asset.decimals || 18)} ${change?.asset.symbol}`;
const decimals = typeof change?.asset.decimals === 'number' ? change?.asset.decimals : 18;
const inAssetValueDisplay = `${handleSignificantDecimals(convertRawAmountToDecimalFormat(change?.value?.toString() || '0', decimals), decimals)} ${change?.asset.symbol}`;
return {
inAssetValueDisplay,
inAssetNativeDisplay: change?.asset.price?.value
? convertAmountAndPriceToNativeDisplay(
convertRawAmountToDecimalFormat(change?.value?.toString() || '0', change?.asset.decimals || 18),
convertRawAmountToDecimalFormat(change?.value?.toString() || '0', decimals),
change?.asset.price?.value || '0',
nativeCurrency
)?.display
Expand Down

0 comments on commit 35daa8b

Please sign in to comment.