Skip to content
1 change: 1 addition & 0 deletions api/.eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ module.exports = {
parser: '@typescript-eslint/parser',
plugins: ['@typescript-eslint'],
rules: {
'class-methods-use-this': 'off',
'no-console': 0,
'no-underscore-dangle': 0,
'no-unused-vars': 'off',
Expand Down
42 changes: 22 additions & 20 deletions api/src/api/helpers/contracts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,28 @@ export interface ContractBalance {
approximateNumber: number;
}


export function multiplyByPowerOfTen(bigDecimal: BigNumber, power: number) {
const newBigDecimal = new BigNumber(bigDecimal);
if (newBigDecimal.c[0] === 0) return newBigDecimal;

newBigDecimal.e += power;
return newBigDecimal;
}

export function stringifyBigWithSignificantDecimals(big: BigNumber, decimals: number) {
const rounded = roundDownToSignificantDecimals(big, decimals);

let significantDecimals;
if (rounded.eq(BIG_0)) {
significantDecimals = decimals;
} else {
significantDecimals = Math.max(decimals, Math.min(decimals, rounded.c.length) - 1 - rounded.e);
}

return rounded.toFixed(significantDecimals, 0);
}

export function parseContractBalanceResponse(decimals: number, balanceResponse: INumber | bigint): ContractBalance;

export function parseContractBalanceResponse(
Expand Down Expand Up @@ -79,23 +101,3 @@ export function parseContractBalanceResponse(
};
}

export function stringifyBigWithSignificantDecimals(big: BigNumber, decimals: number) {
const rounded = roundDownToSignificantDecimals(big, decimals);

let significantDecimals;
if (rounded.eq(BIG_0)) {
significantDecimals = decimals;
} else {
significantDecimals = Math.max(decimals, Math.min(decimals, rounded.c.length) - 1 - rounded.e);
}

return rounded.toFixed(significantDecimals, 0);
}

export function multiplyByPowerOfTen(bigDecimal: BigNumber, power: number) {
const newBigDecimal = new BigNumber(bigDecimal);
if (newBigDecimal.c[0] === 0) return newBigDecimal;

newBigDecimal.e += power;
return newBigDecimal;
}
7 changes: 5 additions & 2 deletions api/src/api/services/ramp/quote.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@ export class QuoteService extends BaseRampService {
const routeParams = createOnrampRouteParams(
'0x30a300612ab372cc73e53ffe87fb73d62ed68da3', // It does not matter.
amountOut.preciseQuotedAmountOut.rawBalance.toFixed(),
outTokenDetails!,
outTokenDetails,
getNetworkFromDestination(to)!,
'0x30a300612ab372cc73e53ffe87fb73d62ed68da3',
);
Expand All @@ -252,10 +252,12 @@ export class QuoteService extends BaseRampService {

// Check against our moonbeam funding amounts.
const squidrouterSwapValue = multiplyByPowerOfTen(Big(route.transactionRequest.value), -18);

const fundingAmountUnits =
getNetworkFromDestination(to) === Networks.Ethereum
? Big(MOONBEAM_EPHEMERAL_STARTING_BALANCE_UNITS_ETHEREUM)
: Big(MOONBEAM_EPHEMERAL_STARTING_BALANCE_UNITS);

const squidrouterSwapValueBuffer = getNetworkFromDestination(to) === Networks.Ethereum ? 10 : 2;

// Leave 10 glmr for other operations of the ephemeral, and as buffer for potential price changes.
Expand All @@ -267,9 +269,10 @@ export class QuoteService extends BaseRampService {
}

amountOut.preciseQuotedAmountOut = parseContractBalanceResponse(
outTokenDetails!.pendulumDecimals,
outTokenDetails.decimals,
BigInt(toAmountMin),
);

amountOut.roundedDownQuotedAmountOut = amountOut.preciseQuotedAmountOut.preciseBigDecimal.round(2, 0);
amountOut.effectiveExchangeRate = stringifyBigWithSignificantDecimals(
amountOut.preciseQuotedAmountOut.preciseBigDecimal.div(new Big(inputAmountAfterFees)),
Expand Down
2 changes: 1 addition & 1 deletion api/src/api/services/transactions/onrampTransactions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ export async function prepareOnrampTransactions(

// The output amount to be obtained on Moonbeam, differs from the amount to be obtained on destination evm chain.
const outputAmountRaw = (quote.metadata as QuoteTicketMetadata).onrampOutputAmountMoonbeamRaw;
const outputAmount = multiplyByPowerOfTen(new Big(outputAmountRaw), -outputTokenDetails.decimals);
const outputAmount = multiplyByPowerOfTen(new Big(outputAmountRaw), -outputTokenDetails.pendulumDecimals);

const inputTokenPendulumDetails = getPendulumDetails(quote.inputCurrency);
const outputTokenPendulumDetails = getPendulumDetails(quote.outputCurrency, toNetwork);
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/hooks/useGetNetworkIcon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export const NETWORK_ICONS: Record<Networks, string> = {
[Networks.AssetHub]: ASSET_HUB,
[Networks.Polygon]: POLYGON,
[Networks.Ethereum]: ETHEREUM,
// [Networks.BSC]: BSC,
[Networks.BSC]: BSC,
[Networks.Arbitrum]: ARBITRUM,
[Networks.Base]: BASE,
[Networks.Avalanche]: AVALANCHE,
Expand Down
10 changes: 6 additions & 4 deletions frontend/src/pages/progress/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,13 @@ import { useRampActions, useRampState, useRampStore } from '../../stores/rampSto
import { RampService } from '../../services/api';
import { getMessageForPhase } from './phaseMessages';
import { config } from '../../config';
import { useRampDirection } from '../../stores/rampDirectionStore';

// The order of the phases is important for the progress bar.
export const ONRAMPING_PHASE_SECONDS: Record<RampPhase, number> = {
initial: 0,
fundEphemeral: 20,
brlaTeleport: 90,
brlaTeleport: 5 * 60,
moonbeamToPendulumXcm: 30,
subsidizePreSwap: 24,
nablaApprove: 24,
Expand Down Expand Up @@ -55,6 +56,7 @@ export const OFFRAMPING_PHASE_SECONDS: Record<RampPhase, number> = {
subsidizePostSwap: 24,
spacewalkRedeem: 130,
stellarPayment: 6,
brlaPayoutOnMoonbeam: 30,

complete: 0,
timedOut: 0,
Expand All @@ -65,13 +67,12 @@ export const OFFRAMPING_PHASE_SECONDS: Record<RampPhase, number> = {
moonbeamToPendulumXcm: 0,
pendulumToAssethub: 0,
pendulumToMoonbeam: 0,
brlaPayoutOnMoonbeam: 0,
stellarCreateAccount: 0,
};

// This constant is used to denote how many of the phases are relevant for the progress bar.
// Not all phases are relevant for the progress bar, so we need to exclude some.
const RELEVANT_PHASES_COUNT = 12;
const RELEVANT_PHASES_COUNT = {off: 13, on: 12};

const useProgressUpdate = (
currentPhase: RampPhase,
Expand All @@ -81,7 +82,8 @@ const useProgressUpdate = (
setDisplayedPercentage: (value: (prev: number) => number) => void,
setShowCheckmark: (value: boolean) => void,
) => {
const numberOfPhases = RELEVANT_PHASES_COUNT;
const rampDirection = useRampDirection()
const numberOfPhases = rampDirection === "onramp" ? RELEVANT_PHASES_COUNT.on : RELEVANT_PHASES_COUNT.off;
const intervalRef = useRef<NodeJS.Timeout>(null);

useEffect(() => {
Expand Down
6 changes: 2 additions & 4 deletions frontend/src/pages/progress/phaseMessages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,14 @@ export function getMessageForPhase(ramp: RampState | undefined, t: TFunction<'tr
const fromNetwork = getNetworkFromDestination(quote.from);
const toNetwork = getNetworkFromDestination(quote.to);

if (!fromNetwork || !toNetwork) return t('pages.progress.initial');

const inputAssetSymbol =
currentState.type === 'off'
? getOnChainTokenDetailsOrDefault(fromNetwork, quote.inputCurrency as OnChainToken).assetSymbol
? getOnChainTokenDetailsOrDefault(fromNetwork!, quote.inputCurrency as OnChainToken).assetSymbol
: getAnyFiatTokenDetails(quote.inputCurrency as FiatToken).assetSymbol;
const outputAssetSymbol =
currentState.type === 'off'
? getAnyFiatTokenDetails(quote.outputCurrency as FiatToken).assetSymbol
: getOnChainTokenDetailsOrDefault(toNetwork, quote.outputCurrency as OnChainToken).assetSymbol;
: getOnChainTokenDetailsOrDefault(toNetwork!, quote.outputCurrency as OnChainToken).assetSymbol;

if (currentPhase === 'complete') return t('pages.progress.success');

Expand Down
2 changes: 1 addition & 1 deletion frontend/src/translations/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
"stellarPayment": "Transferring {{assetSymbol}} from Stellar --> local partner",
"squidrouterSwap": "Transferring {{assetSymbol}} from Moonbeam to {{network}}",
"pendulumToAssethub": "Transferring {{assetSymbol}} from Pendulum --> AssetHub",
"brlaTeleport": "Transferring newly minted assets to Moonbeam"
"brlaTeleport": "Your payment is being processed. This can take up to 5 minutes."
},
"success": {
"title": {
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/translations/pt.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
"stellarPayment": "Transferindo {{assetSymbol}} de Stellar --> parceiro local",
"squidrouterSwap": "Transferindo {{assetSymbol}} de Moonbeam para {{network}}",
"pendulumToAssethub": "Transferindo {{assetSymbol}} de Pendulum --> AssetHub",
"brlaTeleport": "Transferindo ativos recém-criados para Moonbeam"
"brlaTeleport": "Seu pagamento está sendo processado. Isso pode levar até 5 minutos."
},
"success": {
"title": {
Expand Down
29 changes: 13 additions & 16 deletions frontend/src/wagmiConfig.ts
Original file line number Diff line number Diff line change
@@ -1,49 +1,46 @@
import { polygon, arbitrum, base, avalanche, mainnet } from '@reown/appkit/networks';
import { http } from 'wagmi';
import { config } from './config';
import { arbitrum, avalanche, base, bsc, mainnet, polygon } from '@reown/appkit/networks';
import { WagmiAdapter } from '@reown/appkit-adapter-wagmi';
import { createAppKit } from '@reown/appkit/react';
import { http } from 'wagmi';

import { config } from './config';

// If we have an Alchemy API key, we can use it to fetch data from Polygon, otherwise use the default endpoint
const transports = config.alchemyApiKey
? {
[polygon.id]: http(`https://polygon-mainnet.g.alchemy.com/v2/${config.alchemyApiKey}`),
[mainnet.id]: http(`https://eth-mainnet.g.alchemy.com/v2/${config.alchemyApiKey}`),
// [bsc.id]: http(`https://bnb-mainnet.g.alchemy.com/v2/${config.alchemyApiKey}`),
[arbitrum.id]: http(`https://arb-mainnet.g.alchemy.com/v2/${config.alchemyApiKey}`),
[base.id]: http(`https://base-mainnet.g.alchemy.com/v2/${config.alchemyApiKey}`),
[avalanche.id]: http(`https://avax-mainnet.g.alchemy.com/v2/${config.alchemyApiKey}`),
[base.id]: http(`https://base-mainnet.g.alchemy.com/v2/${config.alchemyApiKey}`),
[bsc.id]: http(`https://bnb-mainnet.g.alchemy.com/v2/${config.alchemyApiKey}`),
[mainnet.id]: http(`https://eth-mainnet.g.alchemy.com/v2/${config.alchemyApiKey}`),
[polygon.id]: http(`https://polygon-mainnet.g.alchemy.com/v2/${config.alchemyApiKey}`),
}
: {
[polygon.id]: http(''),
[mainnet.id]: http(''),
// [bsc.id]: http(''),
[arbitrum.id]: http(''),
[base.id]: http(''),
[avalanche.id]: http(''),
[base.id]: http(''),
[bsc.id]: http(''),
[mainnet.id]: http(''),
[polygon.id]: http(''),
};

// 2. Create a metadata object - optional
const metadata = {
name: 'Vortex',
description: 'Vortex',
url: 'https://app.vortexfinance.co', // origin must match your domain & subdomain
icons: [],
};

// 3. Set the networks
const networks = [mainnet, polygon, arbitrum, base, avalanche];
const networks = [mainnet, polygon, arbitrum, base, avalanche, bsc];

const projectId = '495a5f574d57e27fd65caa26d9ea4f10';
// 4. Create Wagmi Adapter
const wagmiAdapter = new WagmiAdapter({
networks,
projectId,
ssr: false,
transports,
});

// 5. Create modal
createAppKit({
adapters: [wagmiAdapter],
// @ts-expect-error - networks is not typed
Expand Down
12 changes: 6 additions & 6 deletions shared/src/helpers/networks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export enum Networks {
Arbitrum = 'arbitrum',
Avalanche = 'avalanche',
Base = 'base',
// BSC = 'bsc',
BSC = 'bsc',
Ethereum = 'ethereum',
Polygon = 'polygon',
Moonbeam = 'moonbeam',
Expand Down Expand Up @@ -60,11 +60,11 @@ const NETWORK_METADATA: Record<Networks, NetworkMetadata> = {
displayName: 'Ethereum',
isEVM: true,
},
// [Networks.BSC]: {
// id: bsc.id,
// displayName: 'BNB Smart Chain',
// isEVM: true,
// },
[Networks.BSC]: {
id: bsc.id,
displayName: 'BNB Smart Chain',
isEVM: true,
},
[Networks.Arbitrum]: {
id: arbitrum.id,
displayName: 'Arbitrum One',
Expand Down
58 changes: 29 additions & 29 deletions shared/src/tokens/evm/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,35 +66,35 @@ export const evmTokenConfig: Record<Networks, Record<EvmToken, EvmTokenDetails>>
...PENDULUM_USDC_AXL,
},
},
// [Networks.BSC]: {
// [EvmToken.USDC]: {
// assetSymbol: 'USDC',
// erc20AddressSourceChain: '0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d', // USDC on BSC
// networkAssetIcon: 'bscUSDC',
// decimals: 18,
// network: Networks.BSC,
// type: TokenType.Evm,
// ...PENDULUM_USDC_AXL,
// },
// [EvmToken.USDT]: {
// assetSymbol: 'USDT',
// erc20AddressSourceChain: '0x55d398326f99059fF775485246999027B3197955', // USDT on BSC
// networkAssetIcon: 'bscUSDT',
// decimals: 18,
// network: Networks.BSC,
// type: TokenType.Evm,
// ...PENDULUM_USDC_AXL,
// },
// [EvmToken.USDCE]: {
// assetSymbol: 'USDC.e',
// erc20AddressSourceChain: '0x2791bca1f2de4661ed88a30c99a7a9449aa84174', // Placeholder, update with actual address
// networkAssetIcon: 'bscUSDC',
// decimals: 18,
// network: Networks.BSC,
// type: TokenType.Evm,
// ...PENDULUM_USDC_AXL,
// },
// },
[Networks.BSC]: {
[EvmToken.USDC]: {
assetSymbol: 'USDC',
erc20AddressSourceChain: '0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d', // USDC on BSC
networkAssetIcon: 'bscUSDC',
decimals: 18,
network: Networks.BSC,
type: TokenType.Evm,
...PENDULUM_USDC_AXL,
},
[EvmToken.USDT]: {
assetSymbol: 'USDT',
erc20AddressSourceChain: '0x55d398326f99059fF775485246999027B3197955', // USDT on BSC
networkAssetIcon: 'bscUSDT',
decimals: 18,
network: Networks.BSC,
type: TokenType.Evm,
...PENDULUM_USDC_AXL,
},
[EvmToken.USDCE]: {
assetSymbol: 'USDC.e',
erc20AddressSourceChain: '0x2791bca1f2de4661ed88a30c99a7a9449aa84174', // Placeholder, update with actual address
networkAssetIcon: 'bscUSDC',
decimals: 18,
network: Networks.BSC,
type: TokenType.Evm,
...PENDULUM_USDC_AXL,
},
},
[Networks.Arbitrum]: {
[EvmToken.USDC]: {
assetSymbol: 'USDC',
Expand Down
Loading