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
39 changes: 29 additions & 10 deletions apps/swap-service/src/swaps/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import type { Swap as PrismaSwap } from '@prisma/client'

import type { CreateSwapDto } from '@shapeshift/shared-types'
import { baseUnitToPrecision } from '@shapeshift/shared-utils'
import { mayachainAssetId, thorchainAssetId } from '@shapeshiftoss/caip'
import { bnOrZero } from '@shapeshiftoss/chain-adapters'
import type { Swap as SwapperSwap, SwapperName, SwapperSpecificMetadata } from '@shapeshiftoss/swapper'
import type { Asset } from '@shapeshiftoss/types'
Expand All @@ -15,6 +16,11 @@ const logger = new Logger('SwapsService')

const BPS_DENOMINATOR = 10000

// Native precisions of the THORChain/Maya native fee assets — the precision the affiliate fee
// amount is stored in for these chains.
const RUNE_PRECISION = 8
const CACAO_PRECISION = 10

// Historical rows may persist `{}` for affiliateVerificationDetails; coerce anything
// that doesn't satisfy the tightened shape (requires `hasAffiliate`) to null.
const toAffiliateVerificationDetails = (
Expand Down Expand Up @@ -119,16 +125,29 @@ const resolveActualFeeUsd = (swap: Swap): number | null => {
let priceUsd: string | null
let precision: number | null

if (swap.affiliateFeeAssetId === swap.sellAsset.assetId) {
priceUsd = swap.sellAssetUsd
precision = swap.sellAsset.precision
} else if (swap.affiliateFeeAssetId === swap.buyAsset.assetId) {
priceUsd = swap.buyAssetUsd
precision = swap.buyAsset.precision
} else {
priceUsd = swap.affiliateAssetUsd
// Fee asset is neither sell nor buy — precision unknown
precision = null
switch (swap.affiliateFeeAssetId) {
case swap.sellAsset.assetId:
priceUsd = swap.sellAssetUsd
precision = swap.sellAsset.precision
break
case swap.buyAsset.assetId:
priceUsd = swap.buyAssetUsd
precision = swap.buyAsset.precision
break
case thorchainAssetId:
// Thorchain collects the affiliate fee in RUNE.
priceUsd = swap.affiliateAssetUsd
precision = RUNE_PRECISION
break
case mayachainAssetId:
// Mayachain collects the affiliate fee in CACAO.
priceUsd = swap.affiliateAssetUsd
precision = CACAO_PRECISION
break
default:
priceUsd = swap.affiliateAssetUsd
// Fee asset is neither sell nor buy nor a known native fee asset — precision unknown
precision = null
}

if (!priceUsd || precision === null) return null
Expand Down
4 changes: 2 additions & 2 deletions apps/swap-service/src/utils/affiliateFeeAsset.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { AssetId } from '@shapeshiftoss/caip'
import { thorchainAssetId } from '@shapeshiftoss/caip'
import { mayachainAssetId, thorchainAssetId } from '@shapeshiftoss/caip'
import { SwapperName } from '@shapeshiftoss/swapper'
import type { Asset } from '@shapeshiftoss/types'

Expand All @@ -15,7 +15,7 @@ const SWAPPER_FEE_STRATEGY: Record<SwapperName, FeeAssetStrategy> = {
[SwapperName.Chainflip]: 'buy_asset',
[SwapperName.CowSwap]: 'sell_asset',
[SwapperName.Debridge]: 'sell_asset',
[SwapperName.Mayachain]: 'sell_asset',
[SwapperName.Mayachain]: mayachainAssetId,
[SwapperName.NearIntents]: 'sell_asset',
[SwapperName.Portals]: 'sell_asset',
[SwapperName.Relay]: null,
Expand Down
3 changes: 2 additions & 1 deletion apps/swap-service/src/verification/__tests__/maya.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ describe('verifyMaya', () => {
affiliateAddress: 'ssmaya',
verifiedSellAmountCryptoBaseUnit: '4000000000000000',
actualBuyAmountCryptoBaseUnit: '7340228',
actualAffiliateFeeAmountCryptoBaseUnit: '4237779000',
// CACAO fee from Midgard (1e8) scaled to native precision 10: 4237779000 × 100
actualAffiliateFeeAmountCryptoBaseUnit: '423777900000',
})
})

Expand Down
19 changes: 15 additions & 4 deletions apps/swap-service/src/verification/swap-verification.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -329,16 +329,24 @@ export class SwapVerificationService {
}

private verifyThorchain(swap: Swap): Promise<SwapVerificationResult> {
return this.verifyMidgardSwap(swap, { midgardUrl: env.VITE_THORCHAIN_MIDGARD_URL, affiliate: 'ss' })
return this.verifyMidgardSwap(swap, {
midgardUrl: env.VITE_THORCHAIN_MIDGARD_URL,
affiliate: 'ss',
feeAssetPrecision: 8,
})
}

private verifyMaya(swap: Swap): Promise<SwapVerificationResult> {
return this.verifyMidgardSwap(swap, { midgardUrl: env.VITE_MAYACHAIN_MIDGARD_URL, affiliate: 'ssmaya' })
return this.verifyMidgardSwap(swap, {
midgardUrl: env.VITE_MAYACHAIN_MIDGARD_URL,
affiliate: 'ssmaya',
feeAssetPrecision: 10,
})
}

private async verifyMidgardSwap(
swap: Swap,
config: { midgardUrl: string; affiliate: string },
config: { midgardUrl: string; affiliate: string; feeAssetPrecision: number },
): Promise<SwapVerificationResult> {
const txHash = swap.sellTxHash?.replace(/^0x/, '')
if (!txHash) return noAffiliateResult('FAILED', 'Missing sell txHash')
Expand Down Expand Up @@ -382,7 +390,10 @@ export class SwapVerificationService {
swap.sellAsset.precision,
),
actualBuyAmountCryptoBaseUnit: thorchainToNativePrecision(buyOut.coins[0].amount, swap.buyAsset.precision),
actualAffiliateFeeAmountCryptoBaseUnit: hasAffiliate ? feeOut?.coins[0].amount : undefined,
actualAffiliateFeeAmountCryptoBaseUnit:
hasAffiliate && feeOut?.coins[0]?.amount
? thorchainToNativePrecision(feeOut.coins[0].amount, config.feeAssetPrecision)
: undefined,
Comment thread
kaladinlight marked this conversation as resolved.
}
}

Expand Down
Loading