Skip to content

Commit 384ab81

Browse files
authored
Merge pull request #652 from pendulum-chain/increase-squidrouter-fee-buffer
Overpay squidrouter transaction value.
2 parents 049aeba + 7203258 commit 384ab81

File tree

15 files changed

+59
-31
lines changed

15 files changed

+59
-31
lines changed

api/src/api/controllers/brla.controller.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -190,9 +190,9 @@ export const triggerBrlaOfframp = async (
190190
}
191191
};
192192

193-
export const getOfframpStatus = async (
194-
req: Request<unknown, unknown, unknown, BrlaEndpoints.GetOfframpStatusRequest>,
195-
res: Response<BrlaEndpoints.GetOfframpStatusResponse | BrlaEndpoints.BrlaErrorResponse>,
193+
export const getRampStatus = async (
194+
req: Request<unknown, unknown, unknown, BrlaEndpoints.GetRampStatusRequest>,
195+
res: Response<BrlaEndpoints.GetRampStatusResponse | BrlaEndpoints.BrlaErrorResponse>,
196196
): Promise<void> => {
197197
try {
198198
const { taxId } = req.query;
@@ -230,7 +230,7 @@ export const getOfframpStatus = async (
230230
status: lastEventCached.data.status,
231231
});
232232
} catch (error) {
233-
handleApiError(error, res, 'getOfframpStatus');
233+
handleApiError(error, res, 'getRampStatus');
234234
}
235235
};
236236

@@ -406,7 +406,7 @@ export const startKYC2 = async (
406406
const subaccount = await brlaApiService.getSubaccount(taxId);
407407

408408
if (!subaccount) {
409-
res.status(httpStatus.BAD_REQUEST).json({ error: 'Subaccount not found'});
409+
res.status(httpStatus.BAD_REQUEST).json({ error: 'Subaccount not found' });
410410
return;
411411
}
412412

api/src/api/controllers/price.controller.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,9 @@ export const getPriceForProvider: RequestHandler<unknown, any, unknown, PriceQue
100100
res.status(httpStatus.BAD_GATEWAY).json({ error: err.message });
101101
} else {
102102
console.error('Unexpected server error:', err);
103-
res.status(httpStatus.INTERNAL_SERVER_ERROR).json({ error: 'An internal server error occurred while fetching the price.' });
103+
res
104+
.status(httpStatus.INTERNAL_SERVER_ERROR)
105+
.json({ error: 'An internal server error occurred while fetching the price.' });
104106
}
105107
}
106108
};

api/src/api/controllers/siwe.controller.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,4 +61,4 @@ export const validateSiweSignature = async (
6161
const message = error instanceof Error ? error.message : 'Unknown error';
6262
res.status(httpStatus.INTERNAL_SERVER_ERROR).json({ error: `Could not validate signature: ${message}` });
6363
}
64-
};
64+
};

api/src/api/controllers/stellar.controller.ts

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,9 @@ export const createStellarTransactionHandler = async (
3131
return;
3232
} catch (error) {
3333
console.error('Error in createStellarTransaction:', error);
34-
res.status(httpStatus.INTERNAL_SERVER_ERROR).json({ error: 'Failed to create transaction', details: (error as Error).message });
34+
res
35+
.status(httpStatus.INTERNAL_SERVER_ERROR)
36+
.json({ error: 'Failed to create transaction', details: (error as Error).message });
3537
}
3638
};
3739

@@ -51,7 +53,9 @@ export const signSep10ChallengeHandler = async (
5153
return;
5254
} catch (error) {
5355
console.error('Error in signSep10Challenge:', error);
54-
res.status(httpStatus.INTERNAL_SERVER_ERROR).json({ error: 'Failed to sign challenge', details: (error as Error).message });
56+
res
57+
.status(httpStatus.INTERNAL_SERVER_ERROR)
58+
.json({ error: 'Failed to sign challenge', details: (error as Error).message });
5559
}
5660
};
5761

@@ -69,7 +73,9 @@ export const getSep10MasterPKHandler = async (
6973
return;
7074
} catch (error) {
7175
console.error('Error in getSep10MasterPK:', error);
72-
res.status(httpStatus.INTERNAL_SERVER_ERROR).json({ error: 'Failed to get master public key', details: (error as Error).message });
76+
res
77+
.status(httpStatus.INTERNAL_SERVER_ERROR)
78+
.json({ error: 'Failed to get master public key', details: (error as Error).message });
7379
}
7480
};
7581

api/src/api/helpers/contracts.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@ export interface ContractBalance {
4444
approximateNumber: number;
4545
}
4646

47-
4847
export function multiplyByPowerOfTen(bigDecimal: BigNumber, power: number) {
4948
const newBigDecimal = new BigNumber(bigDecimal);
5049
if (newBigDecimal.c[0] === 0) return newBigDecimal;
@@ -100,4 +99,3 @@ export function parseContractBalanceResponse(
10099
approximateNumber: preciseBigDecimal.toNumber(),
101100
};
102101
}
103-

api/src/api/middlewares/validators.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -418,4 +418,4 @@ export const validateStartKyc2: RequestHandler = (req, res, next) => {
418418
}
419419

420420
next();
421-
};
421+
};

api/src/api/routes/v1/brla.route.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ router.route('/getUser').get(brlaController.getBrlaUser);
1212

1313
router.route('/getUserRemainingLimit').get(brlaController.getBrlaUserRemainingLimit);
1414

15-
router.route('/getOfframpStatus').get(brlaController.getOfframpStatus);
15+
router.route('/getRampStatus').get(brlaController.getRampStatus);
1616

1717
router.route('/getKycStatus').get(brlaController.fetchSubaccountKycStatus);
1818

api/src/api/services/phases/post-process/moonbeam-post-process-handler.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import logger from '../../../../config/logger';
55
import { ApiManager } from '../../pendulum/apiManager';
66
import { submitExtrinsic } from '@pendulum-chain/api-solang';
77

8+
const CLEANUP_WAITING_TIME_MINUTES = 180; // 3 hours
89
/**
910
* Post process handler for Moonbeam cleanup operations
1011
*/
@@ -51,10 +52,12 @@ export class MoonbeamPostProcessHandler extends BasePostProcessHandler {
5152
const timeDifferenceMs = Date.now() - completeTime.getTime();
5253
const timeDifferenceMinutes = timeDifferenceMs / (1000 * 60);
5354

54-
if (timeDifferenceMinutes < 15) {
55+
if (timeDifferenceMinutes < CLEANUP_WAITING_TIME_MINUTES) {
5556
return [
5657
false,
57-
this.createErrorObject(`At least 15 minutes must pass after the complete phase for moonbeam cleanup`),
58+
this.createErrorObject(
59+
`At least ${CLEANUP_WAITING_TIME_MINUTES} minutes must pass after the complete phase for moonbeam cleanup`,
60+
),
5861
];
5962
}
6063
} catch (e) {

api/src/api/services/ramp/quote.service.ts

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -251,8 +251,7 @@ export class QuoteService extends BaseRampService {
251251
const { toAmountMin } = route.estimate;
252252

253253
// Check against our moonbeam funding amounts.
254-
const squidrouterSwapValue = multiplyByPowerOfTen(Big(route.transactionRequest.value), -18);
255-
254+
const squidrouterSwapValue = multiplyByPowerOfTen(new Big(route.transactionRequest.value), -18);
256255
const fundingAmountUnits =
257256
getNetworkFromDestination(to) === Networks.Ethereum
258257
? Big(MOONBEAM_EPHEMERAL_STARTING_BALANCE_UNITS_ETHEREUM)
@@ -268,10 +267,7 @@ export class QuoteService extends BaseRampService {
268267
});
269268
}
270269

271-
amountOut.preciseQuotedAmountOut = parseContractBalanceResponse(
272-
outTokenDetails.decimals,
273-
BigInt(toAmountMin),
274-
);
270+
amountOut.preciseQuotedAmountOut = parseContractBalanceResponse(outTokenDetails.decimals, BigInt(toAmountMin));
275271

276272
amountOut.roundedDownQuotedAmountOut = amountOut.preciseQuotedAmountOut.preciseBigDecimal.round(2, 0);
277273
amountOut.effectiveExchangeRate = stringifyBigWithSignificantDecimals(

api/src/api/services/slack.service.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@ export class SlackNotifier {
3434
}
3535

3636
public async sendMessage(message: SlackMessage): Promise<void> {
37-
3837
const slackUserId = process.env.SLACK_USER_ID;
3938

4039
const messageWithUserTag = {

api/src/api/services/transactions/squidrouter/config.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import { AXL_USDC_MOONBEAM, getNetworkId, Networks } from 'shared';
22

3+
export const SQUIDROUTER_FEE_OVERPAY = 0.25; // 25% overpayment
4+
35
interface ConfigBase {
46
toChainId: string;
57
axlUSDC_MOONBEAM: string;

api/src/api/services/transactions/squidrouter/onramp.ts

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,16 @@
11
import { createPublicClient, encodeFunctionData, http } from 'viem';
22
import { moonbeam } from 'viem/chains';
3-
import { AXL_USDC_MOONBEAM, EvmTokenDetails, getNetworkId, Networks } from 'shared';
3+
import { AXL_USDC_MOONBEAM, EvmTokenDetails, getNetworkFromDestination, getNetworkId, Networks } from 'shared';
44
import { createOnrampRouteParams, getRoute } from './route';
55

66
import erc20ABI from '../../../../contracts/ERC20';
7+
import Big from 'big.js';
8+
import { SQUIDROUTER_FEE_OVERPAY } from './config';
9+
import {
10+
MOONBEAM_EPHEMERAL_STARTING_BALANCE_UNITS,
11+
MOONBEAM_EPHEMERAL_STARTING_BALANCE_UNITS_ETHEREUM,
12+
} from '../../../../constants/constants';
13+
import { multiplyByPowerOfTen } from '../../pendulum/helpers';
714

815
export interface OnrampSquidrouterParams {
916
fromAddress: string;
@@ -35,6 +42,10 @@ export interface OnrampTransactionData {
3542
};
3643
}
3744

45+
function bigNumberMin(a: Big, b: Big): Big {
46+
return a.lt(b) ? a : b;
47+
}
48+
3849
export async function createOnrampSquidrouterTransactions(
3950
params: OnrampSquidrouterParams,
4051
): Promise<OnrampTransactionData> {
@@ -80,10 +91,21 @@ export async function createOnrampSquidrouterTransactions(
8091
maxPriorityFeePerGas: maxPriorityFeePerGas.toString(),
8192
};
8293

94+
const fundingAmountUnits =
95+
getNetworkFromDestination(params.toNetwork) === Networks.Ethereum
96+
? Big(MOONBEAM_EPHEMERAL_STARTING_BALANCE_UNITS_ETHEREUM)
97+
: Big(MOONBEAM_EPHEMERAL_STARTING_BALANCE_UNITS);
98+
const squidrouterSwapValueBuffer = getNetworkFromDestination(params.toNetwork) === Networks.Ethereum ? 10 : 2;
99+
const freeFundingAmountRaw = multiplyByPowerOfTen(fundingAmountUnits.minus(squidrouterSwapValueBuffer), 18); // 18 decimals for GLMR. Moonbeam is always starting chain.
100+
const overpaidFee = bigNumberMin(
101+
new Big(route.transactionRequest.value).mul(1 + SQUIDROUTER_FEE_OVERPAY),
102+
freeFundingAmountRaw,
103+
);
104+
83105
const swapData = {
84106
to: transactionRequest.target as `0x${string}`,
85107
data: transactionRequest.data,
86-
value: transactionRequest.value,
108+
value: overpaidFee.toFixed(0, 0),
87109
gas: transactionRequest.gasLimit,
88110
maxFeePerGas: maxFeePerGas.toString(),
89111
maxPriorityFeePerGas: maxPriorityFeePerGas.toString(),

frontend/src/services/api/brla.service.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,8 @@ export class BrlaService {
2929
* @param taxId The user's tax ID
3030
* @returns The offramp status
3131
*/
32-
static async getOfframpStatus(taxId: string): Promise<BrlaEndpoints.GetOfframpStatusResponse> {
33-
return apiRequest<BrlaEndpoints.GetOfframpStatusResponse>('get', `${this.BASE_PATH}/getOfframpStatus`, undefined, {
32+
static async getRampStatus(taxId: string): Promise<BrlaEndpoints.GetRampStatusResponse> {
33+
return apiRequest<BrlaEndpoints.GetRampStatusResponse>('get', `${this.BASE_PATH}/getRampStatus`, undefined, {
3434
params: { taxId },
3535
});
3636
}

frontend/src/services/signingService.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@ export const fetchSep10Signatures = async ({
178178
};
179179

180180
export const fetchOfframpStatus = async (taxId: string) => {
181-
const statusResponse = await fetch(`${SIGNING_SERVICE_URL}/v1/brla/getOfframpStatus?taxId=${taxId}`);
181+
const statusResponse = await fetch(`${SIGNING_SERVICE_URL}/v1/brla/getRampStatus?taxId=${taxId}`);
182182

183183
if (statusResponse.status !== 200) {
184184
if (statusResponse.status === 404) {

shared/src/endpoints/brla.endpoints.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,12 @@ export namespace BrlaEndpoints {
1111
kycLevel: number;
1212
}
1313

14-
// GET /brla/getOfframpStatus?taxId=:taxId
15-
export interface GetOfframpStatusRequest {
14+
// GET /brla/getRampStatus?taxId=:taxId
15+
export interface GetRampStatusRequest {
1616
taxId: string;
1717
}
1818

19-
export interface GetOfframpStatusResponse {
19+
export interface GetRampStatusResponse {
2020
type: string;
2121
status: string;
2222
}

0 commit comments

Comments
 (0)