Overview

Every swap involves various fees that affect the final output amount. dKit provides transparent fee breakdowns to help you understand the true cost of each route.

Fee Types

Network Fees (Gas)

Blockchain transaction fees paid to validators/miners.

Protocol Fees

Fees charged by the swap protocol for facilitating the trade.
ProviderFee StructureTypical Rate
THORChainDynamic based on network costs0.2-0.5%
ChainflipFixed percentage0.1-0.3%
MayaChainSimilar to THORChain0.2-0.5%
JupiterVaries by route0.0-0.3%
1inchPositive slippage capture0.0-0.1%
Example:
{
  "type": "PROTOCOL",
  "amount": "1000000",        // Amount in asset units
  "asset": "ETH.ETH",
  "chain": "ETH",
  "protocol": "THORCHAIN"
}

Liquidity Provider Fees

Compensation for liquidity providers who enable the swap.
{
  "type": "LIQUIDITY",
  "amount": "3000000",        // 0.3% of swap amount
  "asset": "ETH.USDC",
  "chain": "ETH",
  "protocol": "UNISWAP"
}
Typical LP Fees:
  • Stablecoin pairs: 0.01-0.05%
  • Major pairs: 0.05-0.3%
  • Exotic pairs: 0.3-1%

Affiliate Fees

Optional fees for integrators and affiliates.
{
  "type": "AFFILIATE",
  "amount": "1000000",        // Custom basis points
  "asset": "BTC.BTC",
  "chain": "BTC",
  "protocol": "THORCHAIN"
}
Setting Affiliate Fees:
const quote = await getQuote({
  sellAsset: "BTC.BTC",
  buyAsset: "ETH.ETH",
  sellAmount: "1.0",
  affiliate: "myAffiliate",   // THORName or address
  affiliateFee: 100           // 100 basis points = 1%
});

Tax Fees

Fees for tokens with built-in taxation mechanisms.
{
  "type": "TAX",
  "amount": "5000000",        // Token's tax amount
  "asset": "ETH.TAXTOKEN",
  "chain": "ETH",
  "protocol": "TOKEN_CONTRACT"
}

Fee Calculation Examples

Simple Swap Fee Breakdown

ETH to USDC swap on Ethereum:
const fees = [
  {
    type: "NETWORK",
    amount: "5000000000000000",    // 0.005 ETH gas
    asset: "ETH.ETH",
    chain: "ETH"
  },
  {
    type: "LIQUIDITY",
    amount: "3000000",              // 3 USDC (0.3% of 1000 USDC)
    asset: "ETH.USDC",
    chain: "ETH"
  }
];

// Total cost: 0.005 ETH + 3 USDC

Cross-Chain Swap Fees

BTC to ETH via THORChain:
const fees = [
  {
    type: "NETWORK",
    amount: "50000",                // BTC network fee
    asset: "BTC.BTC",
    chain: "BTC"
  },
  {
    type: "PROTOCOL",
    amount: "200000",               // THORChain fee (0.2%)
    asset: "BTC.BTC",
    chain: "THOR"
  },
  {
    type: "LIQUIDITY",
    amount: "100000000000000",      // LP fee in ETH
    asset: "ETH.ETH",
    chain: "THOR"
  },
  {
    type: "NETWORK",
    amount: "3000000000000000",     // ETH outbound fee
    asset: "ETH.ETH",
    chain: "ETH"
  }
];

Fee Optimization Strategies

1. Provider Selection

Compare total fees across providers:
const compareFees = (routes) => {
  return routes.map(route => {
    const totalFees = route.fees.reduce((sum, fee) => {
      // Convert all fees to USD for comparison
      const feeUSD = convertToUSD(fee.amount, fee.asset);
      return sum + feeUSD;
    }, 0);
    
    return {
      provider: route.providers[0],
      totalFeesUSD: totalFees,
      outputAmount: route.expectedBuyAmount
    };
  }).sort((a, b) => a.totalFeesUSD - b.totalFeesUSD);
};

2. Timing Optimization

Execute swaps during low-fee periods:
const getOptimalTiming = async () => {
  // Check gas prices for EVM chains
  const gasPrice = await getGasPrice('ETH');
  
  if (gasPrice.fast > 100) {  // Gwei
    return {
      recommendation: 'WAIT',
      reason: 'High network congestion',
      estimatedSavings: calculateSavings(gasPrice)
    };
  }
  
  return {
    recommendation: 'EXECUTE',
    currentFees: gasPrice.standard
  };
};

3. Batching Strategies

Combine multiple swaps to amortize fixed fees:
const shouldBatchSwaps = (swaps) => {
  const individualCost = swaps.reduce((sum, swap) => {
    return sum + estimateNetworkFee(swap);
  }, 0);
  
  const batchedCost = estimateBatchNetworkFee(swaps);
  
  return {
    shouldBatch: batchedCost < individualCost,
    savings: individualCost - batchedCost
  };
};

4. Route Optimization

Choose routes that minimize fee layers:
const optimizeForFees = (routes) => {
  return routes.map(route => {
    const feeEfficiency = route.expectedBuyAmount / getTotalFees(route);
    
    return {
      ...route,
      feeEfficiency,
      recommendation: feeEfficiency > 100 ? 'GOOD' : 'EXPENSIVE'
    };
  }).sort((a, b) => b.feeEfficiency - a.feeEfficiency);
};

Streaming Swap Fees

THORChain streaming swaps have unique fee characteristics:
// Regular swap (single transaction)
const regularFees = {
  network: "50000",         // One network fee
  protocol: "200000",       // Standard protocol fee
  liquidity: "300000"       // Higher slippage
};

// Streaming swap (multiple sub-swaps)
const streamingFees = {
  network: "50000",         // Still one network fee
  protocol: "200000",       // Same protocol fee
  liquidity: "150000"       // Lower slippage due to smaller chunks
};

// Streaming is beneficial for large swaps despite longer time

Fee Estimation

Pre-Quote Estimation

Estimate fees before requesting quotes:
const estimateFees = (sellAsset, buyAsset, amount) => {
  const estimates = {
    network: estimateNetworkFee(sellAsset.split('.')[0]),
    protocol: amount * 0.003,  // ~0.3% average
    liquidity: amount * 0.003, // ~0.3% average
    total: 0
  };
  
  estimates.total = estimates.network + estimates.protocol + estimates.liquidity;
  
  return estimates;
};

Dynamic Fee Updates

Monitor fee changes in real-time:
const monitorFees = async () => {
  const feeWatcher = setInterval(async () => {
    const currentFees = await getCurrentFees();
    
    if (hasSignificantChange(currentFees, lastFees)) {
      // Re-quote if fees changed significantly
      await refreshQuote();
    }
    
    lastFees = currentFees;
  }, 30000); // Check every 30 seconds
};

Fee Display Best Practices

1. Transparent Breakdown

Always show users complete fee information:
const displayFees = (route) => {
  const breakdown = {
    'Network Fees': formatFee(route.fees.filter(f => f.type === 'NETWORK')),
    'Protocol Fees': formatFee(route.fees.filter(f => f.type === 'PROTOCOL')),
    'LP Fees': formatFee(route.fees.filter(f => f.type === 'LIQUIDITY')),
    'Affiliate Fees': formatFee(route.fees.filter(f => f.type === 'AFFILIATE')),
    'Total Fees': formatFee(route.fees)
  };
  
  return breakdown;
};

2. Relative Fee Display

Show fees as percentage of swap amount:
const calculateFeePercentage = (fees, swapAmount) => {
  const totalFeeValue = fees.reduce((sum, fee) => {
    return sum + convertToBaseAsset(fee.amount, fee.asset);
  }, 0);
  
  return (totalFeeValue / swapAmount * 100).toFixed(2) + '%';
};

3. Fee Impact Visualization

Help users understand fee impact:
const visualizeFeeImpact = (route) => {
  const inputValue = convertToUSD(route.sellAmount, route.sellAsset);
  const outputValue = convertToUSD(route.expectedBuyAmount, route.buyAsset);
  const feeValue = inputValue - outputValue;
  
  return {
    inputUSD: inputValue,
    outputUSD: outputValue,
    feesUSD: feeValue,
    feePercentage: (feeValue / inputValue * 100).toFixed(2),
    impact: getFeeImpactLevel(feeValue / inputValue)
  };
};

const getFeeImpactLevel = (percentage) => {
  if (percentage < 0.005) return 'MINIMAL';
  if (percentage < 0.01) return 'LOW';
  if (percentage < 0.03) return 'MODERATE';
  if (percentage < 0.05) return 'HIGH';
  return 'VERY_HIGH';
};

Common Fee Scenarios

High-Frequency Trading

For frequent swaps, minimize per-transaction costs:
  • Use providers with no protocol fees
  • Batch transactions when possible
  • Choose chains with low network fees
  • Consider fee rebate programs

Large Value Swaps

For large amounts, optimize for percentage fees:
  • Use streaming swaps to reduce slippage
  • Negotiate affiliate fee sharing
  • Consider OTC alternatives for very large amounts
  • Split across multiple routes if beneficial

Cross-Chain Arbitrage

Factor all fees into profit calculations:
  • Include both inbound and outbound network fees
  • Account for time value during execution
  • Consider MEV protection costs
  • Calculate break-even thresholds