Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions packages/bridge-controller/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Added

- Export `assetIdsMatch` util to compare assetIds. EVM assetIds are case insensitive ([#9831](https://github.com/MetaMask/core/pull/9831))

### Fixed

- Filter fees by `assetId` when coercing V1 quotes to V2 ([#9831](https://github.com/MetaMask/core/pull/9831))

## [79.1.0]

### Added
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { create, coerce, Infer, is, intersection } from '@metamask/superstruct';
import { parseCaipAssetType } from '@metamask/utils';
import { BigNumber } from 'bignumber.js';

import { assetIdsMatch } from '../utils/assets.js';
import { formatAddressToAssetId } from '../utils/caip-formatters.js';
import { sumAmounts } from '../utils/number-formatters.js';
import {
Expand Down Expand Up @@ -78,19 +78,19 @@ const QuoteV2FromV1 = coerce(QuoteSchemaV2, QuoteSchema, (value) => {
...restQuote
} = value;

const srcAssetV2 = toBridgeAssetV2(srcAsset);

return {
src: {
amount: new BigNumber(srcTokenAmount)
.plus(
intent
? 0
: (sumAmounts([
feeData[FeeType.TX_FEE],
feeData[FeeType.METABRIDGE],
])?.amount ?? 0),
)
.toFixed(),
asset: toBridgeAssetV2(srcAsset),
amount: sumAmounts([
{ amount: srcTokenAmount, asset: srcAssetV2 },
...(intent
? []
: [feeData[FeeType.TX_FEE], feeData[FeeType.METABRIDGE]].filter(
(fee) => assetIdsMatch(fee?.asset?.assetId, srcAssetV2.assetId),
)),
])?.amount,
asset: srcAssetV2,
...(walletAddress && { walletAddress }),
},
dest: {
Expand Down
1 change: 1 addition & 0 deletions packages/bridge-controller/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ export { toQuoteMetadataV1 } from './utils/quote-metadata/to-quote-metadata-v1.j
export { toQuoteMetadataV2 } from './utils/quote-metadata/to-quote-metadata-v2.js';

export { sumAmounts } from './utils/number-formatters.js';
export { assetIdsMatch } from './utils/assets.js';

export {
validateQuoteStreamComplete,
Expand Down
19 changes: 19 additions & 0 deletions packages/bridge-controller/src/utils/assets.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { KnownCaipNamespace, parseCaipAssetType } from '@metamask/utils';
import type { CaipAssetType } from '@metamask/utils';

import type { ExchangeRate, GenericQuoteRequest } from '../types.js';
Expand Down Expand Up @@ -39,3 +40,21 @@ export const toExchangeRates = (
}, {});
return exchangeRates;
};

export const assetIdsMatch = (
assetId1?: CaipAssetType,
assetId2?: CaipAssetType,
): boolean => {
if (!assetId2 || !assetId1) {
return false;
}

return (
assetId1 === assetId2 ||
(parseCaipAssetType(assetId1).chain.namespace ===
KnownCaipNamespace.Eip155 &&
parseCaipAssetType(assetId2).chain.namespace ===
KnownCaipNamespace.Eip155 &&
assetId1.toLowerCase() === assetId2.toLowerCase())
);
};
8 changes: 6 additions & 2 deletions packages/bridge-controller/src/utils/number-formatters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { BigNumber } from 'bignumber.js';

import type { DeepPartial } from '../types.js';
import type { QuoteResponse } from '../validators/quote-response.js';
import { assetIdsMatch } from './assets.js';

/**
* 1500000 -> 1.5
Expand Down Expand Up @@ -82,8 +83,11 @@ export const sumAmounts = (
/**
* Fees and prices can be denominated in different assets, so we need to check if all fees have the same units
*/
const isSameAssetForAllFees =
new Set(fees.map((fee) => fee.asset?.assetId?.toLowerCase())).size === 1;
const isSameAssetForAllFees = fees.reduce(
(acc, fee) =>
acc && assetIdsMatch(fee.asset?.assetId, fees[0]?.asset?.assetId),
true,
);

/**
* Keys that require the asset to be the same for all fees
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import type { QuoteResponseV1 } from '../../validators/quote-response-v1.js';
import { QuoteResponseSchemaV2 } from '../../validators/quote-response.js';
import type { QuoteResponse } from '../../validators/quote-response.js';
import type { TxData } from '../../validators/trade.js';
import { assetIdsMatch } from '../assets.js';
import { isEvmQuoteResponse, isNativeAddress } from '../bridge.js';
import { calcNormalizedTokenAmount } from '../number-formatters.js';
import type { QuoteMetadata, TokenAmountValues } from './types.js';
Expand Down Expand Up @@ -76,8 +77,7 @@ export const calcSentAmount = (
.filter(
(fee) =>
fee?.amount &&
fee.asset?.assetId?.toLowerCase() ===
srcAsset.assetId?.toLowerCase(),
assetIdsMatch(fee.asset?.assetId, srcAsset.assetId),
)
.reduce(
(acc, { amount }) => acc.plus(amount),
Expand Down Expand Up @@ -271,10 +271,12 @@ export const calcIncludedTxFees = (
return undefined;
}
// Use exchange rate of the token that is being used to pay for the transaction
const { exchangeRate, usdExchangeRate } =
txFee?.asset.assetId === srcAsset.assetId
? srcTokenExchangeRate
: destTokenExchangeRate;
const { exchangeRate, usdExchangeRate } = assetIdsMatch(
txFee?.asset?.assetId,
srcAsset.assetId,
)
? srcTokenExchangeRate
: destTokenExchangeRate;
const normalizedTxFeeAmount = calcNormalizedTokenAmount(
txFee?.amount,
txFee?.asset.decimals,
Expand All @@ -299,7 +301,7 @@ export const calcAdjustedReturn = (
}: QuoteResponseV1['quote'],
) => {
// If gas is included and is taken from the dest token, don't subtract network fee from return
if (txFee?.asset?.assetId?.toLowerCase() === destAssetId.toLowerCase()) {
if (assetIdsMatch(txFee?.asset?.assetId, destAssetId)) {
return {
valueInCurrency: toTokenAmount.valueInCurrency,
usd: toTokenAmount.usd,
Expand Down