From c4ae53c77561bcc96f9f7eb52ac63d4548a7a5fa Mon Sep 17 00:00:00 2001 From: Gianfranco Date: Mon, 19 May 2025 08:59:53 -0300 Subject: [PATCH 1/9] overpay squidrouter transaction value --- api/src/api/services/transactions/squidrouter/config.ts | 2 ++ api/src/api/services/transactions/squidrouter/offramp.ts | 7 +++++-- api/src/api/services/transactions/squidrouter/onramp.ts | 6 +++++- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/api/src/api/services/transactions/squidrouter/config.ts b/api/src/api/services/transactions/squidrouter/config.ts index 1c05b60e2..b93021826 100644 --- a/api/src/api/services/transactions/squidrouter/config.ts +++ b/api/src/api/services/transactions/squidrouter/config.ts @@ -1,5 +1,7 @@ import { AXL_USDC_MOONBEAM, getNetworkId, Networks } from 'shared'; +export const SQUIDROUTER_FEE_OVERPAY_PERCENTAGE = 0.5; // 50% overpayment + interface ConfigBase { toChainId: string; axlUSDC_MOONBEAM: string; diff --git a/api/src/api/services/transactions/squidrouter/offramp.ts b/api/src/api/services/transactions/squidrouter/offramp.ts index cc49396fe..54d5d5b78 100644 --- a/api/src/api/services/transactions/squidrouter/offramp.ts +++ b/api/src/api/services/transactions/squidrouter/offramp.ts @@ -7,7 +7,8 @@ import { createOfframpRouteParams, getRoute } from './route'; import erc20ABI from '../../../../contracts/ERC20'; import { createRandomString, createSquidRouterHash } from '../../../helpers/squidrouter'; import encodePayload from './payload'; -import { getSquidRouterConfig } from './config'; +import { getSquidRouterConfig, SQUIDROUTER_FEE_OVERPAY_PERCENTAGE } from './config'; +import Big from 'big.js'; export interface OfframpSquidrouterParams { fromAddress: string; @@ -64,6 +65,8 @@ export async function createOfframpSquidrouterTransactions( const { maxFeePerGas, maxPriorityFeePerGas } = await publicClient.estimateFeesPerGas(); + const overpayedFee = (new Big(transactionRequest.value)).mul(1 + SQUIDROUTER_FEE_OVERPAY_PERCENTAGE).toString(); + return { approveData: { to: params.inputTokenDetails.erc20AddressSourceChain as `0x${string}`, // TODO check if this is correct @@ -76,7 +79,7 @@ export async function createOfframpSquidrouterTransactions( swapData: { to: transactionRequest.target as `0x${string}`, data: transactionRequest.data as `0x${string}`, - value: transactionRequest.value, + value: overpayedFee, gas: transactionRequest.gasLimit, // TODO do we still need * 2 here? maxFeePerGas: String(maxFeePerGas), maxPriorityFeePerGas: String(maxFeePerGas), diff --git a/api/src/api/services/transactions/squidrouter/onramp.ts b/api/src/api/services/transactions/squidrouter/onramp.ts index 4bb6537d2..5b9ae4281 100644 --- a/api/src/api/services/transactions/squidrouter/onramp.ts +++ b/api/src/api/services/transactions/squidrouter/onramp.ts @@ -4,6 +4,8 @@ import { AXL_USDC_MOONBEAM, EvmTokenDetails, getNetworkId, Networks } from 'shar import { createOnrampRouteParams, getRoute } from './route'; import erc20ABI from '../../../../contracts/ERC20'; +import Big from 'big.js'; +import { SQUIDROUTER_FEE_OVERPAY_PERCENTAGE } from './config'; export interface OnrampSquidrouterParams { fromAddress: string; @@ -80,10 +82,12 @@ export async function createOnrampSquidrouterTransactions( maxPriorityFeePerGas: maxPriorityFeePerGas.toString(), }; + const overpayedFee = (new Big(transactionRequest.value)).mul(1 + SQUIDROUTER_FEE_OVERPAY_PERCENTAGE).toString(); + const swapData = { to: transactionRequest.target as `0x${string}`, data: transactionRequest.data, - value: transactionRequest.value, + value: overpayedFee, gas: transactionRequest.gasLimit, maxFeePerGas: maxFeePerGas.toString(), maxPriorityFeePerGas: maxPriorityFeePerGas.toString(), From 4974cc03bc413bdd54aa7ace0ac7762970f2a60a Mon Sep 17 00:00:00 2001 From: Gianfranco Date: Mon, 19 May 2025 10:10:12 -0300 Subject: [PATCH 2/9] rename const --- api/src/api/services/transactions/squidrouter/config.ts | 2 +- api/src/api/services/transactions/squidrouter/offramp.ts | 4 ++-- api/src/api/services/transactions/squidrouter/onramp.ts | 8 ++++---- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/api/src/api/services/transactions/squidrouter/config.ts b/api/src/api/services/transactions/squidrouter/config.ts index b93021826..4fe700ec3 100644 --- a/api/src/api/services/transactions/squidrouter/config.ts +++ b/api/src/api/services/transactions/squidrouter/config.ts @@ -1,6 +1,6 @@ import { AXL_USDC_MOONBEAM, getNetworkId, Networks } from 'shared'; -export const SQUIDROUTER_FEE_OVERPAY_PERCENTAGE = 0.5; // 50% overpayment +export const SQUIDROUTER_FEE_OVERPAY = 0.5; // 50% overpayment interface ConfigBase { toChainId: string; diff --git a/api/src/api/services/transactions/squidrouter/offramp.ts b/api/src/api/services/transactions/squidrouter/offramp.ts index 54d5d5b78..e7dce7bc2 100644 --- a/api/src/api/services/transactions/squidrouter/offramp.ts +++ b/api/src/api/services/transactions/squidrouter/offramp.ts @@ -7,7 +7,7 @@ import { createOfframpRouteParams, getRoute } from './route'; import erc20ABI from '../../../../contracts/ERC20'; import { createRandomString, createSquidRouterHash } from '../../../helpers/squidrouter'; import encodePayload from './payload'; -import { getSquidRouterConfig, SQUIDROUTER_FEE_OVERPAY_PERCENTAGE } from './config'; +import { getSquidRouterConfig, SQUIDROUTER_FEE_OVERPAY } from './config'; import Big from 'big.js'; export interface OfframpSquidrouterParams { @@ -65,7 +65,7 @@ export async function createOfframpSquidrouterTransactions( const { maxFeePerGas, maxPriorityFeePerGas } = await publicClient.estimateFeesPerGas(); - const overpayedFee = (new Big(transactionRequest.value)).mul(1 + SQUIDROUTER_FEE_OVERPAY_PERCENTAGE).toString(); + const overpayedFee = (new Big(transactionRequest.value)).mul(1 + SQUIDROUTER_FEE_OVERPAY).toString(); return { approveData: { diff --git a/api/src/api/services/transactions/squidrouter/onramp.ts b/api/src/api/services/transactions/squidrouter/onramp.ts index 5b9ae4281..6c7a16e01 100644 --- a/api/src/api/services/transactions/squidrouter/onramp.ts +++ b/api/src/api/services/transactions/squidrouter/onramp.ts @@ -5,7 +5,7 @@ import { createOnrampRouteParams, getRoute } from './route'; import erc20ABI from '../../../../contracts/ERC20'; import Big from 'big.js'; -import { SQUIDROUTER_FEE_OVERPAY_PERCENTAGE } from './config'; +import { SQUIDROUTER_FEE_OVERPAY } from './config'; export interface OnrampSquidrouterParams { fromAddress: string; @@ -81,9 +81,9 @@ export async function createOnrampSquidrouterTransactions( maxFeePerGas: maxFeePerGas.toString(), maxPriorityFeePerGas: maxPriorityFeePerGas.toString(), }; - - const overpayedFee = (new Big(transactionRequest.value)).mul(1 + SQUIDROUTER_FEE_OVERPAY_PERCENTAGE).toString(); - + console.log('original: ', transactionRequest.value); + const overpayedFee = (new Big(transactionRequest.value)).mul(1 + SQUIDROUTER_FEE_OVERPAY).toString(); + console.log('Overpayed fee: ', overpayedFee); const swapData = { to: transactionRequest.target as `0x${string}`, data: transactionRequest.data, From 48dbe635882ccdeb15f39d1e698da10dcd98c2a8 Mon Sep 17 00:00:00 2001 From: Gianfranco Date: Mon, 19 May 2025 10:41:12 -0300 Subject: [PATCH 3/9] increase waiting time for moonbeam cleanup --- .../phases/post-process/moonbeam-post-process-handler.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/api/src/api/services/phases/post-process/moonbeam-post-process-handler.ts b/api/src/api/services/phases/post-process/moonbeam-post-process-handler.ts index dbaea0c20..a4aa342ba 100644 --- a/api/src/api/services/phases/post-process/moonbeam-post-process-handler.ts +++ b/api/src/api/services/phases/post-process/moonbeam-post-process-handler.ts @@ -5,6 +5,7 @@ import logger from '../../../../config/logger'; import { ApiManager } from '../../pendulum/apiManager'; import { submitExtrinsic } from '@pendulum-chain/api-solang'; +const CLEANUP_WAITING_TIME_MINUTES = 180; // 3 hours /** * Post process handler for Moonbeam cleanup operations */ @@ -51,10 +52,10 @@ export class MoonbeamPostProcessHandler extends BasePostProcessHandler { const timeDifferenceMs = Date.now() - completeTime.getTime(); const timeDifferenceMinutes = timeDifferenceMs / (1000 * 60); - if (timeDifferenceMinutes < 15) { + if (timeDifferenceMinutes < CLEANUP_WAITING_TIME_MINUTES) { return [ false, - this.createErrorObject(`At least 15 minutes must pass after the complete phase for moonbeam cleanup`), + this.createErrorObject(`At least ${CLEANUP_WAITING_TIME_MINUTES} minutes must pass after the complete phase for moonbeam cleanup`), ]; } } catch (e) { From 4aa25b2a63c674da5d0fdaa18fac1076dda7fff2 Mon Sep 17 00:00:00 2001 From: Gianfranco Date: Mon, 19 May 2025 16:14:53 -0300 Subject: [PATCH 4/9] add overpay fee factor to quote service pre-check condition --- api/src/api/services/ramp/quote.service.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/api/src/api/services/ramp/quote.service.ts b/api/src/api/services/ramp/quote.service.ts index d076f3b81..cfd5e7178 100644 --- a/api/src/api/services/ramp/quote.service.ts +++ b/api/src/api/services/ramp/quote.service.ts @@ -26,6 +26,7 @@ import { MOONBEAM_EPHEMERAL_STARTING_BALANCE_UNITS_ETHEREUM, } from '../../../constants/constants'; import { multiplyByPowerOfTen } from '../pendulum/helpers'; +import { SQUIDROUTER_FEE_OVERPAY } from '../transactions/squidrouter/config'; /** * Trims trailing zeros from a decimal string, keeping at least two decimal places. * @param decimalString - The decimal string to format @@ -250,8 +251,9 @@ export class QuoteService extends BaseRampService { const { route } = routeResult.data; const { toAmountMin } = route.estimate; + const overpayedFee = (new Big(route.transactionRequest.value)).mul(1 + SQUIDROUTER_FEE_OVERPAY); // Check against our moonbeam funding amounts. - const squidrouterSwapValue = multiplyByPowerOfTen(Big(route.transactionRequest.value), -18); + const squidrouterSwapValue = multiplyByPowerOfTen(overpayedFee, -18); const fundingAmountUnits = getNetworkFromDestination(to) === Networks.Ethereum ? Big(MOONBEAM_EPHEMERAL_STARTING_BALANCE_UNITS_ETHEREUM) From 9534856645a930df7ea69a0f9ec070826ff96656 Mon Sep 17 00:00:00 2001 From: Gianfranco Date: Tue, 20 May 2025 08:19:50 -0300 Subject: [PATCH 5/9] typo --- api/src/api/services/ramp/quote.service.ts | 6 +++--- api/src/api/services/transactions/squidrouter/config.ts | 2 +- api/src/api/services/transactions/squidrouter/offramp.ts | 4 ++-- api/src/api/services/transactions/squidrouter/onramp.ts | 6 ++---- 4 files changed, 8 insertions(+), 10 deletions(-) diff --git a/api/src/api/services/ramp/quote.service.ts b/api/src/api/services/ramp/quote.service.ts index 617c09770..5f22a4110 100644 --- a/api/src/api/services/ramp/quote.service.ts +++ b/api/src/api/services/ramp/quote.service.ts @@ -251,9 +251,9 @@ export class QuoteService extends BaseRampService { const { route } = routeResult.data; const { toAmountMin } = route.estimate; - const overpayedFee = (new Big(route.transactionRequest.value)).mul(1 + SQUIDROUTER_FEE_OVERPAY); + const overpaidFee = (new Big(route.transactionRequest.value)).mul(1 + SQUIDROUTER_FEE_OVERPAY); // Check against our moonbeam funding amounts. - const squidrouterSwapValue = multiplyByPowerOfTen(overpayedFee, -18); + const squidrouterSwapValue = multiplyByPowerOfTen(overpaidFee, -18); const fundingAmountUnits = getNetworkFromDestination(to) === Networks.Ethereum ? Big(MOONBEAM_EPHEMERAL_STARTING_BALANCE_UNITS_ETHEREUM) @@ -265,7 +265,7 @@ export class QuoteService extends BaseRampService { if (squidrouterSwapValue.gte(fundingAmountUnits.minus(squidrouterSwapValueBuffer))) { throw new APIError({ status: httpStatus.SERVICE_UNAVAILABLE, - message: 'Cannot service this route at the moment. Please try again later.', + message: 'Cannot service this route at the moment. Please ¡ry again later.', }); } diff --git a/api/src/api/services/transactions/squidrouter/config.ts b/api/src/api/services/transactions/squidrouter/config.ts index 4fe700ec3..986bba618 100644 --- a/api/src/api/services/transactions/squidrouter/config.ts +++ b/api/src/api/services/transactions/squidrouter/config.ts @@ -1,6 +1,6 @@ import { AXL_USDC_MOONBEAM, getNetworkId, Networks } from 'shared'; -export const SQUIDROUTER_FEE_OVERPAY = 0.5; // 50% overpayment +export const SQUIDROUTER_FEE_OVERPAY = 0.25; // 25% overpayment interface ConfigBase { toChainId: string; diff --git a/api/src/api/services/transactions/squidrouter/offramp.ts b/api/src/api/services/transactions/squidrouter/offramp.ts index e7dce7bc2..4836f15c3 100644 --- a/api/src/api/services/transactions/squidrouter/offramp.ts +++ b/api/src/api/services/transactions/squidrouter/offramp.ts @@ -65,7 +65,7 @@ export async function createOfframpSquidrouterTransactions( const { maxFeePerGas, maxPriorityFeePerGas } = await publicClient.estimateFeesPerGas(); - const overpayedFee = (new Big(transactionRequest.value)).mul(1 + SQUIDROUTER_FEE_OVERPAY).toString(); + const overpaidFee = (new Big(transactionRequest.value)).mul(1 + SQUIDROUTER_FEE_OVERPAY).toString(); return { approveData: { @@ -79,7 +79,7 @@ export async function createOfframpSquidrouterTransactions( swapData: { to: transactionRequest.target as `0x${string}`, data: transactionRequest.data as `0x${string}`, - value: overpayedFee, + value: overpaidFee, gas: transactionRequest.gasLimit, // TODO do we still need * 2 here? maxFeePerGas: String(maxFeePerGas), maxPriorityFeePerGas: String(maxFeePerGas), diff --git a/api/src/api/services/transactions/squidrouter/onramp.ts b/api/src/api/services/transactions/squidrouter/onramp.ts index 6c7a16e01..291b5ac46 100644 --- a/api/src/api/services/transactions/squidrouter/onramp.ts +++ b/api/src/api/services/transactions/squidrouter/onramp.ts @@ -81,13 +81,11 @@ export async function createOnrampSquidrouterTransactions( maxFeePerGas: maxFeePerGas.toString(), maxPriorityFeePerGas: maxPriorityFeePerGas.toString(), }; - console.log('original: ', transactionRequest.value); - const overpayedFee = (new Big(transactionRequest.value)).mul(1 + SQUIDROUTER_FEE_OVERPAY).toString(); - console.log('Overpayed fee: ', overpayedFee); + const overpaidFee = (new Big(transactionRequest.value)).mul(1 + SQUIDROUTER_FEE_OVERPAY).toString(); const swapData = { to: transactionRequest.target as `0x${string}`, data: transactionRequest.data, - value: overpayedFee, + value: overpaidFee, gas: transactionRequest.gasLimit, maxFeePerGas: maxFeePerGas.toString(), maxPriorityFeePerGas: maxPriorityFeePerGas.toString(), From 7d74934d45eb5104bd39c3c12ae6104f96c50c4d Mon Sep 17 00:00:00 2001 From: Gianfranco Date: Tue, 20 May 2025 09:56:17 -0300 Subject: [PATCH 6/9] rename status endpoint --- api/src/api/controllers/brla.controller.ts | 8 ++++---- api/src/api/routes/v1/brla.route.ts | 2 +- frontend/src/services/api/brla.service.ts | 4 ++-- frontend/src/services/signingService.tsx | 2 +- shared/src/endpoints/brla.endpoints.ts | 6 +++--- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/api/src/api/controllers/brla.controller.ts b/api/src/api/controllers/brla.controller.ts index 6f97d28eb..e882393f5 100644 --- a/api/src/api/controllers/brla.controller.ts +++ b/api/src/api/controllers/brla.controller.ts @@ -190,9 +190,9 @@ export const triggerBrlaOfframp = async ( } }; -export const getOfframpStatus = async ( - req: Request, - res: Response, +export const getRampStatus = async ( + req: Request, + res: Response, ): Promise => { try { const { taxId } = req.query; @@ -230,7 +230,7 @@ export const getOfframpStatus = async ( status: lastEventCached.data.status, }); } catch (error) { - handleApiError(error, res, 'getOfframpStatus'); + handleApiError(error, res, 'getRampStatus'); } }; diff --git a/api/src/api/routes/v1/brla.route.ts b/api/src/api/routes/v1/brla.route.ts index 8ea6719b6..e2c87178a 100644 --- a/api/src/api/routes/v1/brla.route.ts +++ b/api/src/api/routes/v1/brla.route.ts @@ -12,7 +12,7 @@ router.route('/getUser').get(brlaController.getBrlaUser); router.route('/getUserRemainingLimit').get(brlaController.getBrlaUserRemainingLimit); -router.route('/getOfframpStatus').get(brlaController.getOfframpStatus); +router.route('/getRampStatus').get(brlaController.getRampStatus); router.route('/getKycStatus').get(brlaController.fetchSubaccountKycStatus); diff --git a/frontend/src/services/api/brla.service.ts b/frontend/src/services/api/brla.service.ts index ec0fb4509..fc81213ac 100644 --- a/frontend/src/services/api/brla.service.ts +++ b/frontend/src/services/api/brla.service.ts @@ -29,8 +29,8 @@ export class BrlaService { * @param taxId The user's tax ID * @returns The offramp status */ - static async getOfframpStatus(taxId: string): Promise { - return apiRequest('get', `${this.BASE_PATH}/getOfframpStatus`, undefined, { + static async getRampStatus(taxId: string): Promise { + return apiRequest('get', `${this.BASE_PATH}/getRampStatus`, undefined, { params: { taxId }, }); } diff --git a/frontend/src/services/signingService.tsx b/frontend/src/services/signingService.tsx index bd82a65d2..bb5d53f7f 100644 --- a/frontend/src/services/signingService.tsx +++ b/frontend/src/services/signingService.tsx @@ -178,7 +178,7 @@ export const fetchSep10Signatures = async ({ }; export const fetchOfframpStatus = async (taxId: string) => { - const statusResponse = await fetch(`${SIGNING_SERVICE_URL}/v1/brla/getOfframpStatus?taxId=${taxId}`); + const statusResponse = await fetch(`${SIGNING_SERVICE_URL}/v1/brla/getRampStatus?taxId=${taxId}`); if (statusResponse.status !== 200) { if (statusResponse.status === 404) { diff --git a/shared/src/endpoints/brla.endpoints.ts b/shared/src/endpoints/brla.endpoints.ts index 2062abc88..4a2e1056a 100644 --- a/shared/src/endpoints/brla.endpoints.ts +++ b/shared/src/endpoints/brla.endpoints.ts @@ -11,12 +11,12 @@ export namespace BrlaEndpoints { kycLevel: number; } - // GET /brla/getOfframpStatus?taxId=:taxId - export interface GetOfframpStatusRequest { + // GET /brla/getRampStatus?taxId=:taxId + export interface GetRampStatusRequest { taxId: string; } - export interface GetOfframpStatusResponse { + export interface GetRampStatusResponse { type: string; status: string; } From f73f7aa5a9c2ecbaae467c75cb94aaead3c9bd86 Mon Sep 17 00:00:00 2001 From: Gianfranco Date: Tue, 20 May 2025 10:08:29 -0300 Subject: [PATCH 7/9] revert endpoint renaming --- api/src/api/controllers/brla.controller.ts | 8 ++++---- api/src/api/routes/v1/brla.route.ts | 2 +- frontend/src/services/api/brla.service.ts | 4 ++-- frontend/src/services/signingService.tsx | 2 +- shared/src/endpoints/brla.endpoints.ts | 6 +++--- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/api/src/api/controllers/brla.controller.ts b/api/src/api/controllers/brla.controller.ts index 6f97d28eb..e882393f5 100644 --- a/api/src/api/controllers/brla.controller.ts +++ b/api/src/api/controllers/brla.controller.ts @@ -190,9 +190,9 @@ export const triggerBrlaOfframp = async ( } }; -export const getOfframpStatus = async ( - req: Request, - res: Response, +export const getRampStatus = async ( + req: Request, + res: Response, ): Promise => { try { const { taxId } = req.query; @@ -230,7 +230,7 @@ export const getOfframpStatus = async ( status: lastEventCached.data.status, }); } catch (error) { - handleApiError(error, res, 'getOfframpStatus'); + handleApiError(error, res, 'getRampStatus'); } }; diff --git a/api/src/api/routes/v1/brla.route.ts b/api/src/api/routes/v1/brla.route.ts index 8ea6719b6..e2c87178a 100644 --- a/api/src/api/routes/v1/brla.route.ts +++ b/api/src/api/routes/v1/brla.route.ts @@ -12,7 +12,7 @@ router.route('/getUser').get(brlaController.getBrlaUser); router.route('/getUserRemainingLimit').get(brlaController.getBrlaUserRemainingLimit); -router.route('/getOfframpStatus').get(brlaController.getOfframpStatus); +router.route('/getRampStatus').get(brlaController.getRampStatus); router.route('/getKycStatus').get(brlaController.fetchSubaccountKycStatus); diff --git a/frontend/src/services/api/brla.service.ts b/frontend/src/services/api/brla.service.ts index ec0fb4509..fc81213ac 100644 --- a/frontend/src/services/api/brla.service.ts +++ b/frontend/src/services/api/brla.service.ts @@ -29,8 +29,8 @@ export class BrlaService { * @param taxId The user's tax ID * @returns The offramp status */ - static async getOfframpStatus(taxId: string): Promise { - return apiRequest('get', `${this.BASE_PATH}/getOfframpStatus`, undefined, { + static async getRampStatus(taxId: string): Promise { + return apiRequest('get', `${this.BASE_PATH}/getRampStatus`, undefined, { params: { taxId }, }); } diff --git a/frontend/src/services/signingService.tsx b/frontend/src/services/signingService.tsx index bd82a65d2..bb5d53f7f 100644 --- a/frontend/src/services/signingService.tsx +++ b/frontend/src/services/signingService.tsx @@ -178,7 +178,7 @@ export const fetchSep10Signatures = async ({ }; export const fetchOfframpStatus = async (taxId: string) => { - const statusResponse = await fetch(`${SIGNING_SERVICE_URL}/v1/brla/getOfframpStatus?taxId=${taxId}`); + const statusResponse = await fetch(`${SIGNING_SERVICE_URL}/v1/brla/getRampStatus?taxId=${taxId}`); if (statusResponse.status !== 200) { if (statusResponse.status === 404) { diff --git a/shared/src/endpoints/brla.endpoints.ts b/shared/src/endpoints/brla.endpoints.ts index 2062abc88..4a2e1056a 100644 --- a/shared/src/endpoints/brla.endpoints.ts +++ b/shared/src/endpoints/brla.endpoints.ts @@ -11,12 +11,12 @@ export namespace BrlaEndpoints { kycLevel: number; } - // GET /brla/getOfframpStatus?taxId=:taxId - export interface GetOfframpStatusRequest { + // GET /brla/getRampStatus?taxId=:taxId + export interface GetRampStatusRequest { taxId: string; } - export interface GetOfframpStatusResponse { + export interface GetRampStatusResponse { type: string; status: string; } From 20fbbec16ff6e4a090be5a4223309217b6a1ed39 Mon Sep 17 00:00:00 2001 From: Gianfranco Date: Tue, 20 May 2025 13:23:24 -0300 Subject: [PATCH 8/9] remove overpayment on offramp, improve checks against funding amount --- api/src/api/services/ramp/quote.service.ts | 6 ++---- .../transactions/squidrouter/offramp.ts | 9 +++------ .../transactions/squidrouter/onramp.ts | 20 ++++++++++++++++--- 3 files changed, 22 insertions(+), 13 deletions(-) diff --git a/api/src/api/services/ramp/quote.service.ts b/api/src/api/services/ramp/quote.service.ts index 5f22a4110..bc2991b65 100644 --- a/api/src/api/services/ramp/quote.service.ts +++ b/api/src/api/services/ramp/quote.service.ts @@ -26,7 +26,6 @@ import { MOONBEAM_EPHEMERAL_STARTING_BALANCE_UNITS_ETHEREUM, } from '../../../constants/constants'; import { multiplyByPowerOfTen } from '../pendulum/helpers'; -import { SQUIDROUTER_FEE_OVERPAY } from '../transactions/squidrouter/config'; /** * Trims trailing zeros from a decimal string, keeping at least two decimal places. * @param decimalString - The decimal string to format @@ -251,9 +250,8 @@ export class QuoteService extends BaseRampService { const { route } = routeResult.data; const { toAmountMin } = route.estimate; - const overpaidFee = (new Big(route.transactionRequest.value)).mul(1 + SQUIDROUTER_FEE_OVERPAY); // Check against our moonbeam funding amounts. - const squidrouterSwapValue = multiplyByPowerOfTen(overpaidFee, -18); + const squidrouterSwapValue = multiplyByPowerOfTen(new Big(route.transactionRequest.value), -18); const fundingAmountUnits = getNetworkFromDestination(to) === Networks.Ethereum ? Big(MOONBEAM_EPHEMERAL_STARTING_BALANCE_UNITS_ETHEREUM) @@ -265,7 +263,7 @@ export class QuoteService extends BaseRampService { if (squidrouterSwapValue.gte(fundingAmountUnits.minus(squidrouterSwapValueBuffer))) { throw new APIError({ status: httpStatus.SERVICE_UNAVAILABLE, - message: 'Cannot service this route at the moment. Please ¡ry again later.', + message: 'Cannot service this route at the moment. Please try again later.', }); } diff --git a/api/src/api/services/transactions/squidrouter/offramp.ts b/api/src/api/services/transactions/squidrouter/offramp.ts index 4836f15c3..3699c4e5f 100644 --- a/api/src/api/services/transactions/squidrouter/offramp.ts +++ b/api/src/api/services/transactions/squidrouter/offramp.ts @@ -1,14 +1,13 @@ import { createPublicClient, encodeFunctionData, http } from 'viem'; import { moonbeam } from 'viem/chains'; -import { EvmTokenDetails, EvmTransactionData, Networks } from 'shared'; +import { EvmTokenDetails, EvmTransactionData, getNetworkFromDestination, Networks } from 'shared'; import { decodeAddress } from '@polkadot/util-crypto'; import { u8aToHex } from '@polkadot/util'; import { createOfframpRouteParams, getRoute } from './route'; import erc20ABI from '../../../../contracts/ERC20'; import { createRandomString, createSquidRouterHash } from '../../../helpers/squidrouter'; import encodePayload from './payload'; -import { getSquidRouterConfig, SQUIDROUTER_FEE_OVERPAY } from './config'; -import Big from 'big.js'; +import { getSquidRouterConfig } from './config'; export interface OfframpSquidrouterParams { fromAddress: string; @@ -65,8 +64,6 @@ export async function createOfframpSquidrouterTransactions( const { maxFeePerGas, maxPriorityFeePerGas } = await publicClient.estimateFeesPerGas(); - const overpaidFee = (new Big(transactionRequest.value)).mul(1 + SQUIDROUTER_FEE_OVERPAY).toString(); - return { approveData: { to: params.inputTokenDetails.erc20AddressSourceChain as `0x${string}`, // TODO check if this is correct @@ -79,7 +76,7 @@ export async function createOfframpSquidrouterTransactions( swapData: { to: transactionRequest.target as `0x${string}`, data: transactionRequest.data as `0x${string}`, - value: overpaidFee, + value: transactionRequest.value, gas: transactionRequest.gasLimit, // TODO do we still need * 2 here? maxFeePerGas: String(maxFeePerGas), maxPriorityFeePerGas: String(maxFeePerGas), diff --git a/api/src/api/services/transactions/squidrouter/onramp.ts b/api/src/api/services/transactions/squidrouter/onramp.ts index 291b5ac46..27b49bd6a 100644 --- a/api/src/api/services/transactions/squidrouter/onramp.ts +++ b/api/src/api/services/transactions/squidrouter/onramp.ts @@ -1,11 +1,13 @@ import { createPublicClient, encodeFunctionData, http } from 'viem'; import { moonbeam } from 'viem/chains'; -import { AXL_USDC_MOONBEAM, EvmTokenDetails, getNetworkId, Networks } from 'shared'; +import { AXL_USDC_MOONBEAM, EvmTokenDetails, getNetworkFromDestination, getNetworkId, Networks } from 'shared'; import { createOnrampRouteParams, getRoute } from './route'; import erc20ABI from '../../../../contracts/ERC20'; import Big from 'big.js'; import { SQUIDROUTER_FEE_OVERPAY } from './config'; +import { MOONBEAM_EPHEMERAL_STARTING_BALANCE_UNITS, MOONBEAM_EPHEMERAL_STARTING_BALANCE_UNITS_ETHEREUM } from '../../../../constants/constants'; +import { multiplyByPowerOfTen } from '../../pendulum/helpers'; export interface OnrampSquidrouterParams { fromAddress: string; @@ -37,6 +39,10 @@ export interface OnrampTransactionData { }; } +function bigNumberMin(a: Big, b: Big): Big { + return a.lt(b) ? a : b; +} + export async function createOnrampSquidrouterTransactions( params: OnrampSquidrouterParams, ): Promise { @@ -81,11 +87,19 @@ export async function createOnrampSquidrouterTransactions( maxFeePerGas: maxFeePerGas.toString(), maxPriorityFeePerGas: maxPriorityFeePerGas.toString(), }; - const overpaidFee = (new Big(transactionRequest.value)).mul(1 + SQUIDROUTER_FEE_OVERPAY).toString(); + + const fundingAmountUnits = getNetworkFromDestination(params.toNetwork) === Networks.Ethereum + ? Big(MOONBEAM_EPHEMERAL_STARTING_BALANCE_UNITS_ETHEREUM) + : Big(MOONBEAM_EPHEMERAL_STARTING_BALANCE_UNITS); + const squidrouterSwapValueBuffer = getNetworkFromDestination(params.toNetwork) === Networks.Ethereum ? 10 : 2; + const freeFundingAmountRaw = multiplyByPowerOfTen(fundingAmountUnits.minus(squidrouterSwapValueBuffer), 18); // 18 decimals for GLMR. Moonbeam is always starting chain. + const overpaidFee = bigNumberMin((new Big(route.transactionRequest.value)).mul(1 + SQUIDROUTER_FEE_OVERPAY), freeFundingAmountRaw); + + const swapData = { to: transactionRequest.target as `0x${string}`, data: transactionRequest.data, - value: overpaidFee, + value: overpaidFee.toFixed(0,0), gas: transactionRequest.gasLimit, maxFeePerGas: maxFeePerGas.toString(), maxPriorityFeePerGas: maxPriorityFeePerGas.toString(), From 72032583967324c6741077a2cdb1b804414c3f2d Mon Sep 17 00:00:00 2001 From: Gianfranco Date: Tue, 20 May 2025 13:32:38 -0300 Subject: [PATCH 9/9] cleanup, prettier --- api/src/api/controllers/brla.controller.ts | 2 +- api/src/api/controllers/price.controller.ts | 4 +++- api/src/api/controllers/siwe.controller.ts | 2 +- api/src/api/controllers/stellar.controller.ts | 12 +++++++--- api/src/api/helpers/contracts.ts | 2 -- api/src/api/middlewares/validators.ts | 2 +- .../moonbeam-post-process-handler.ts | 4 +++- api/src/api/services/ramp/quote.service.ts | 5 +--- api/src/api/services/slack.service.ts | 1 - .../transactions/squidrouter/offramp.ts | 2 +- .../transactions/squidrouter/onramp.ts | 24 ++++++++++++------- 11 files changed, 35 insertions(+), 25 deletions(-) diff --git a/api/src/api/controllers/brla.controller.ts b/api/src/api/controllers/brla.controller.ts index e882393f5..783c2cbb5 100644 --- a/api/src/api/controllers/brla.controller.ts +++ b/api/src/api/controllers/brla.controller.ts @@ -406,7 +406,7 @@ export const startKYC2 = async ( const subaccount = await brlaApiService.getSubaccount(taxId); if (!subaccount) { - res.status(httpStatus.BAD_REQUEST).json({ error: 'Subaccount not found'}); + res.status(httpStatus.BAD_REQUEST).json({ error: 'Subaccount not found' }); return; } diff --git a/api/src/api/controllers/price.controller.ts b/api/src/api/controllers/price.controller.ts index f37c51fe9..ef345cb7a 100644 --- a/api/src/api/controllers/price.controller.ts +++ b/api/src/api/controllers/price.controller.ts @@ -100,7 +100,9 @@ export const getPriceForProvider: RequestHandler { } next(); -}; \ No newline at end of file +}; diff --git a/api/src/api/services/phases/post-process/moonbeam-post-process-handler.ts b/api/src/api/services/phases/post-process/moonbeam-post-process-handler.ts index a4aa342ba..bfb79475f 100644 --- a/api/src/api/services/phases/post-process/moonbeam-post-process-handler.ts +++ b/api/src/api/services/phases/post-process/moonbeam-post-process-handler.ts @@ -55,7 +55,9 @@ export class MoonbeamPostProcessHandler extends BasePostProcessHandler { if (timeDifferenceMinutes < CLEANUP_WAITING_TIME_MINUTES) { return [ false, - this.createErrorObject(`At least ${CLEANUP_WAITING_TIME_MINUTES} minutes must pass after the complete phase for moonbeam cleanup`), + this.createErrorObject( + `At least ${CLEANUP_WAITING_TIME_MINUTES} minutes must pass after the complete phase for moonbeam cleanup`, + ), ]; } } catch (e) { diff --git a/api/src/api/services/ramp/quote.service.ts b/api/src/api/services/ramp/quote.service.ts index bc2991b65..cc245a0a0 100644 --- a/api/src/api/services/ramp/quote.service.ts +++ b/api/src/api/services/ramp/quote.service.ts @@ -267,10 +267,7 @@ export class QuoteService extends BaseRampService { }); } - amountOut.preciseQuotedAmountOut = parseContractBalanceResponse( - outTokenDetails.decimals, - BigInt(toAmountMin), - ); + amountOut.preciseQuotedAmountOut = parseContractBalanceResponse(outTokenDetails.decimals, BigInt(toAmountMin)); amountOut.roundedDownQuotedAmountOut = amountOut.preciseQuotedAmountOut.preciseBigDecimal.round(2, 0); amountOut.effectiveExchangeRate = stringifyBigWithSignificantDecimals( diff --git a/api/src/api/services/slack.service.ts b/api/src/api/services/slack.service.ts index 042dca077..66b47fe87 100644 --- a/api/src/api/services/slack.service.ts +++ b/api/src/api/services/slack.service.ts @@ -34,7 +34,6 @@ export class SlackNotifier { } public async sendMessage(message: SlackMessage): Promise { - const slackUserId = process.env.SLACK_USER_ID; const messageWithUserTag = { diff --git a/api/src/api/services/transactions/squidrouter/offramp.ts b/api/src/api/services/transactions/squidrouter/offramp.ts index 3699c4e5f..cc49396fe 100644 --- a/api/src/api/services/transactions/squidrouter/offramp.ts +++ b/api/src/api/services/transactions/squidrouter/offramp.ts @@ -1,6 +1,6 @@ import { createPublicClient, encodeFunctionData, http } from 'viem'; import { moonbeam } from 'viem/chains'; -import { EvmTokenDetails, EvmTransactionData, getNetworkFromDestination, Networks } from 'shared'; +import { EvmTokenDetails, EvmTransactionData, Networks } from 'shared'; import { decodeAddress } from '@polkadot/util-crypto'; import { u8aToHex } from '@polkadot/util'; import { createOfframpRouteParams, getRoute } from './route'; diff --git a/api/src/api/services/transactions/squidrouter/onramp.ts b/api/src/api/services/transactions/squidrouter/onramp.ts index 27b49bd6a..af15502c0 100644 --- a/api/src/api/services/transactions/squidrouter/onramp.ts +++ b/api/src/api/services/transactions/squidrouter/onramp.ts @@ -6,7 +6,10 @@ import { createOnrampRouteParams, getRoute } from './route'; import erc20ABI from '../../../../contracts/ERC20'; import Big from 'big.js'; import { SQUIDROUTER_FEE_OVERPAY } from './config'; -import { MOONBEAM_EPHEMERAL_STARTING_BALANCE_UNITS, MOONBEAM_EPHEMERAL_STARTING_BALANCE_UNITS_ETHEREUM } from '../../../../constants/constants'; +import { + MOONBEAM_EPHEMERAL_STARTING_BALANCE_UNITS, + MOONBEAM_EPHEMERAL_STARTING_BALANCE_UNITS_ETHEREUM, +} from '../../../../constants/constants'; import { multiplyByPowerOfTen } from '../../pendulum/helpers'; export interface OnrampSquidrouterParams { @@ -40,7 +43,7 @@ export interface OnrampTransactionData { } function bigNumberMin(a: Big, b: Big): Big { - return a.lt(b) ? a : b; + return a.lt(b) ? a : b; } export async function createOnrampSquidrouterTransactions( @@ -87,19 +90,22 @@ export async function createOnrampSquidrouterTransactions( maxFeePerGas: maxFeePerGas.toString(), maxPriorityFeePerGas: maxPriorityFeePerGas.toString(), }; - - const fundingAmountUnits = getNetworkFromDestination(params.toNetwork) === Networks.Ethereum - ? Big(MOONBEAM_EPHEMERAL_STARTING_BALANCE_UNITS_ETHEREUM) - : Big(MOONBEAM_EPHEMERAL_STARTING_BALANCE_UNITS); + + const fundingAmountUnits = + getNetworkFromDestination(params.toNetwork) === Networks.Ethereum + ? Big(MOONBEAM_EPHEMERAL_STARTING_BALANCE_UNITS_ETHEREUM) + : Big(MOONBEAM_EPHEMERAL_STARTING_BALANCE_UNITS); const squidrouterSwapValueBuffer = getNetworkFromDestination(params.toNetwork) === Networks.Ethereum ? 10 : 2; const freeFundingAmountRaw = multiplyByPowerOfTen(fundingAmountUnits.minus(squidrouterSwapValueBuffer), 18); // 18 decimals for GLMR. Moonbeam is always starting chain. - const overpaidFee = bigNumberMin((new Big(route.transactionRequest.value)).mul(1 + SQUIDROUTER_FEE_OVERPAY), freeFundingAmountRaw); - + const overpaidFee = bigNumberMin( + new Big(route.transactionRequest.value).mul(1 + SQUIDROUTER_FEE_OVERPAY), + freeFundingAmountRaw, + ); const swapData = { to: transactionRequest.target as `0x${string}`, data: transactionRequest.data, - value: overpaidFee.toFixed(0,0), + value: overpaidFee.toFixed(0, 0), gas: transactionRequest.gasLimit, maxFeePerGas: maxFeePerGas.toString(), maxPriorityFeePerGas: maxPriorityFeePerGas.toString(),