Skip to content

Commit 0c09d12

Browse files
chore: calc slippage percentage (#5723)
## Explanation Calculate slippage percentage ## References ## Changelog - calcSlippagePercentage added to Bridge Controller Utils ([#5723](#5723)) ## Checklist - [x] I've updated the test suite for new or updated code as appropriate - [x] I've updated documentation (JSDoc, Markdown, etc.) for new or updated code as appropriate - [x] I've communicated my changes to consumers by [updating changelogs for packages I've changed](https://github.com/MetaMask/core/tree/main/docs/contributing.md#updating-changelogs), highlighting breaking changes as necessary - [x] I've prepared draft pull requests for clients and consumer packages to resolve any breaking changes
1 parent 7fe7380 commit 0c09d12

File tree

4 files changed

+72
-1
lines changed

4 files changed

+72
-1
lines changed

packages/bridge-controller/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
99

1010
### Added
1111

12+
- 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)).
1213
- Error logs for invalid getQuote responses ([#5816](https://github.com/MetaMask/core/pull/5816))
1314

1415
### Changed

packages/bridge-controller/src/index.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,11 @@ export {
103103
isCrossChain,
104104
} from './utils/bridge';
105105

106-
export { isValidQuoteRequest, formatEtaInMinutes } from './utils/quote';
106+
export {
107+
isValidQuoteRequest,
108+
formatEtaInMinutes,
109+
calcSlippagePercentage,
110+
} from './utils/quote';
107111

108112
export { calcLatestSrcBalance } from './utils/balance';
109113

packages/bridge-controller/src/utils/quote.test.ts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import {
1414
calcSwapRate,
1515
calcCost,
1616
formatEtaInMinutes,
17+
calcSlippagePercentage,
1718
} from './quote';
1819
import type {
1920
GenericQuoteRequest,
@@ -534,4 +535,37 @@ describe('Quote Metadata Utils', () => {
534535
expect(result.usd).toBeNull();
535536
});
536537
});
538+
539+
describe('calcSlippagePercentage', () => {
540+
it.each([
541+
['100', null, '100', null, '0'],
542+
['95', '95', '100', '100', '5'],
543+
['98.3', '98.3', '100', '100', '1.7'],
544+
[null, '100', null, '100', '0'],
545+
[null, null, null, '100', null],
546+
['105', '105', '100', '100', '5'],
547+
])(
548+
'calcSlippagePercentage: calculate slippage absolute value for received amount %p, usd %p, sent amount %p, usd %p to expected slippage %p',
549+
(
550+
returnValueInCurrency: string | null,
551+
returnUsd: string | null,
552+
sentValueInCurrency: string | null,
553+
sentUsd: string | null,
554+
expectedSlippage: string | null,
555+
) => {
556+
const result = calcSlippagePercentage(
557+
{
558+
valueInCurrency: returnValueInCurrency,
559+
usd: returnUsd,
560+
},
561+
{
562+
amount: '1000',
563+
valueInCurrency: sentValueInCurrency,
564+
usd: sentUsd,
565+
},
566+
);
567+
expect(result).toBe(expectedSlippage);
568+
},
569+
);
570+
});
537571
});

packages/bridge-controller/src/utils/quote.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,38 @@ export const calcCost = (
304304
: null,
305305
});
306306

307+
/**
308+
* Calculates the slippage absolute value percentage based on the adjusted return and sent amount.
309+
*
310+
* @param adjustedReturn - Adjusted return value
311+
* @param sentAmount - Sent amount value
312+
* @returns the slippage in percentage
313+
*/
314+
export const calcSlippagePercentage = (
315+
adjustedReturn: ReturnType<typeof calcAdjustedReturn>,
316+
sentAmount: ReturnType<typeof calcSentAmount>,
317+
): string | null => {
318+
const cost = calcCost(adjustedReturn, sentAmount);
319+
320+
if (cost.valueInCurrency && sentAmount.valueInCurrency) {
321+
return new BigNumber(cost.valueInCurrency)
322+
.div(sentAmount.valueInCurrency)
323+
.times(100)
324+
.abs()
325+
.toString();
326+
}
327+
328+
if (cost.usd && sentAmount.usd) {
329+
return new BigNumber(cost.usd)
330+
.div(sentAmount.usd)
331+
.times(100)
332+
.abs()
333+
.toString();
334+
}
335+
336+
return null;
337+
};
338+
307339
export const formatEtaInMinutes = (
308340
estimatedProcessingTimeInSeconds: number,
309341
) => {

0 commit comments

Comments
 (0)