diff --git a/packages/bridge-controller/CHANGELOG.md b/packages/bridge-controller/CHANGELOG.md index 93c8e47bedc..8513141d315 100644 --- a/packages/bridge-controller/CHANGELOG.md +++ b/packages/bridge-controller/CHANGELOG.md @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added +- Add and export `calcSlippagePercentage`, a utility that calculates the absolute slippage percentage based on the adjusted return and the sent amount ([#5723](https://github.com/MetaMask/core/pull/5723)). - Error logs for invalid getQuote responses ([#5816](https://github.com/MetaMask/core/pull/5816)) ### Changed diff --git a/packages/bridge-controller/src/index.ts b/packages/bridge-controller/src/index.ts index 617506f8d7e..bc70fc9fe41 100644 --- a/packages/bridge-controller/src/index.ts +++ b/packages/bridge-controller/src/index.ts @@ -103,7 +103,11 @@ export { isCrossChain, } from './utils/bridge'; -export { isValidQuoteRequest, formatEtaInMinutes } from './utils/quote'; +export { + isValidQuoteRequest, + formatEtaInMinutes, + calcSlippagePercentage, +} from './utils/quote'; export { calcLatestSrcBalance } from './utils/balance'; diff --git a/packages/bridge-controller/src/utils/quote.test.ts b/packages/bridge-controller/src/utils/quote.test.ts index d08dd1bfc7b..4f018b8618a 100644 --- a/packages/bridge-controller/src/utils/quote.test.ts +++ b/packages/bridge-controller/src/utils/quote.test.ts @@ -14,6 +14,7 @@ import { calcSwapRate, calcCost, formatEtaInMinutes, + calcSlippagePercentage, } from './quote'; import type { GenericQuoteRequest, @@ -534,4 +535,37 @@ describe('Quote Metadata Utils', () => { expect(result.usd).toBeNull(); }); }); + + describe('calcSlippagePercentage', () => { + it.each([ + ['100', null, '100', null, '0'], + ['95', '95', '100', '100', '5'], + ['98.3', '98.3', '100', '100', '1.7'], + [null, '100', null, '100', '0'], + [null, null, null, '100', null], + ['105', '105', '100', '100', '5'], + ])( + 'calcSlippagePercentage: calculate slippage absolute value for received amount %p, usd %p, sent amount %p, usd %p to expected slippage %p', + ( + returnValueInCurrency: string | null, + returnUsd: string | null, + sentValueInCurrency: string | null, + sentUsd: string | null, + expectedSlippage: string | null, + ) => { + const result = calcSlippagePercentage( + { + valueInCurrency: returnValueInCurrency, + usd: returnUsd, + }, + { + amount: '1000', + valueInCurrency: sentValueInCurrency, + usd: sentUsd, + }, + ); + expect(result).toBe(expectedSlippage); + }, + ); + }); }); diff --git a/packages/bridge-controller/src/utils/quote.ts b/packages/bridge-controller/src/utils/quote.ts index 638c2e4a55d..07c5c6d01d7 100644 --- a/packages/bridge-controller/src/utils/quote.ts +++ b/packages/bridge-controller/src/utils/quote.ts @@ -304,6 +304,38 @@ export const calcCost = ( : null, }); +/** + * Calculates the slippage absolute value percentage based on the adjusted return and sent amount. + * + * @param adjustedReturn - Adjusted return value + * @param sentAmount - Sent amount value + * @returns the slippage in percentage + */ +export const calcSlippagePercentage = ( + adjustedReturn: ReturnType, + sentAmount: ReturnType, +): string | null => { + const cost = calcCost(adjustedReturn, sentAmount); + + if (cost.valueInCurrency && sentAmount.valueInCurrency) { + return new BigNumber(cost.valueInCurrency) + .div(sentAmount.valueInCurrency) + .times(100) + .abs() + .toString(); + } + + if (cost.usd && sentAmount.usd) { + return new BigNumber(cost.usd) + .div(sentAmount.usd) + .times(100) + .abs() + .toString(); + } + + return null; +}; + export const formatEtaInMinutes = ( estimatedProcessingTimeInSeconds: number, ) => {