> ## Documentation Index
> Fetch the complete documentation index at: https://docs.leokit.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Fee Calculation Formulas

> Protocol-specific fee calculation formulas and fee structure explanations

## Overview

Different protocols use different fee models for cross-chain swaps. This reference provides the exact formulas and calculations used by each protocol.

## THORChain Fee Structure

THORChain fees consist of three main components: affiliate fees, outbound fees, and liquidity fees (slippage).

### Fee Components

| Fee Type      | Description                 | Calculation                            | Variable |
| ------------- | --------------------------- | -------------------------------------- | -------- |
| Affiliate Fee | Revenue share to integrator | `(inputAmount × affiliateBps) / 10000` | Optional |
| Outbound Fee  | Network fee for destination | Fixed per chain from API               | Required |
| Liquidity Fee | Pool slippage cost          | `(inputAmount × slippageBps) / 10000`  | Required |

### Formula

```typescript theme={null}
// Affiliate Fee
affiliateFee = (inputAmount * affiliateBps) / 10000;

// Outbound Fee
outboundFee = fixedOutboundFee; // From inbound_addresses API

// Liquidity Fee (Slippage)
liquidityFee = (inputAmount * slippageBps) / 10000;

// Total Fee
totalFee = affiliateFee + outboundFee + liquidityFee;

// Expected Output
expectedOutput = theoreticalOutput - totalFee;
```

### Example Calculation

Swap 1 BTC → ETH.USDC with 30 BPS affiliate fee and 150 BPS slippage:

```javascript theme={null}
const inputAmount = 100000000; // 1 BTC in satoshis
const affiliateBps = 30;
const slippageBps = 150;
const outboundFee = 100000; // 0.001 BTC from API
const theoreticalOutput = 65000000000; // 65,000 USDC

// Calculate fees
const affiliateFee = (100000000 * 30) / 10000;
// = 300000 (0.003 BTC)

const liquidityFee = (100000000 * 150) / 10000;
// = 1500000 (0.015 BTC)

const totalFee = 300000 + 100000 + 1500000;
// = 1900000 (0.019 BTC)

// Expected output
const expectedOutput = 65000000000 - (1900000 * 65000); // Convert to USDC
// ≈ 64876500000 (64,876.5 USDC)
```

### Basis Points (BPS) Explained

| BPS   | Percentage | Decimal |
| ----- | ---------- | ------- |
| 1     | 0.01%      | 0.0001  |
| 10    | 0.1%       | 0.001   |
| 30    | 0.3%       | 0.003   |
| 100   | 1%         | 0.01    |
| 150   | 1.5%       | 0.015   |
| 300   | 3%         | 0.03    |
| 10000 | 100%       | 1.0     |

### Slippage Calculation

```typescript theme={null}
const slippageBps = params.slippage_bps || params.liquidity_tolerance_bps || 150;

// Validate maximum
if (slippageBps >= 10000) {
  throw new Error("INVALID_TOLERANCE_BPS");
}

// Calculate slippage fee
const slippageFee = (inputAmount * slippageBps) / 10000;
```

**Default Slippage:** 150 BPS (1.5%)
**Maximum Slippage:** 9999 BPS (99.99%)

### Streaming Swap Fee Impact

Streaming swaps reduce slippage by splitting large swaps into smaller chunks:

```javascript theme={null}
// Single swap
const singleSwapSlippage = 500; // BPS

// Streaming swap (10 chunks)
const streamingQuantity = 10;
const avgSlippagePerChunk = 50; // BPS
const totalStreamingSlippage = 50 * 10; // Still 500 BPS total, but better execution
```

**Benefits:**

* Reduced price impact per sub-swap
* Better average execution price
* Lower total slippage for large amounts

## MAYAChain Fee Structure

MAYAChain uses a similar fee model to THORChain with some differences.

### Fee Components

Same as THORChain but with MAYAChain-specific parameters:

```typescript theme={null}
// Affiliate Fee
affiliateFee = (inputAmount * affiliateBps) / 10000;

// Outbound Fee
outboundFee = fixedOutboundFee; // From inbound_addresses API

// Liquidity Fee (Slippage)
liquidityFee = (inputAmount * toleranceBps) / 10000;

// Total Fee
totalFee = affiliateFee + outboundFee + liquidityFee;

// Expected Output
expectedOutput = theoreticalOutput - totalFee;
```

### CACAO Decimal Handling

**Critical:** MAYA.CACAO uses 10 decimals instead of 8!

```typescript theme={null}
const decimals = asset === 'MAYA.CACAO' ? 10 : 8;
const normalizedAmount = (amount / Math.pow(10, decimals)) * 1e8;

// Example: 10 CACAO
const amount = '100000000000'; // 10 CACAO (10 decimals)
const normalized = (100000000000 / 1e10) * 1e8;
// = 1000000000 (in standard 1e8 format)
```

### Tolerance Parameter Validation

MAYAChain requires **only one** tolerance parameter:

```typescript theme={null}
if (params.tolerance_bps && params.liquidity_tolerance_bps) {
  throw new Error("CONFLICTING_TOLERANCE_PARAMS");
}

const tolerance = params.tolerance_bps || params.liquidity_tolerance_bps || 150;
```

## Chainflip Fee Structure

Chainflip uses multiple fee types with different multipliers.

### Fee Types

| Type    | Display Name  | Multiplier | Description                            |
| ------- | ------------- | ---------- | -------------------------------------- |
| INGRESS | Deposit Fee   | 1x         | Fee to deposit to Chainflip vault      |
| NETWORK | Network Fee   | 1x         | Blockchain network fees                |
| EGRESS  | Broadcast Fee | 1x         | Fee to send from vault to destination  |
| BROKER  | Affiliate Fee | 1.5x       | Partner commission (multiplied by 1.5) |

### Formula

```typescript theme={null}
// Sum all fees with multipliers
const totalFee = fees.reduce((sum, fee) => {
  const multiplier = fee.type === 'BROKER' ? 1.5 : 1;
  return sum + (fee.amount * multiplier);
}, 0);

// Expected Output
expectedOutput = inputAmount * exchangeRate - totalFee;
```

### Example Calculation

```javascript theme={null}
const fees = [
  { type: 'INGRESS', amount: 5000 },   // 0.00005 BTC
  { type: 'NETWORK', amount: 3000 },   // 0.00003 BTC
  { type: 'EGRESS', amount: 8000 },    // 0.00008 BTC
  { type: 'BROKER', amount: 10000 }    // 0.0001 BTC
];

const totalFee = fees.reduce((sum, fee) => {
  const multiplier = fee.type === 'BROKER' ? 1.5 : 1;
  return sum + (fee.amount * multiplier);
}, 0);

// Calculation:
// INGRESS: 5000 * 1 = 5000
// NETWORK: 3000 * 1 = 3000
// EGRESS: 8000 * 1 = 8000
// BROKER: 10000 * 1.5 = 15000
// Total: 31000 satoshis (0.00031 BTC)
```

### DCA (Dollar Cost Averaging) Impact

Chainflip supports DCA to reduce price impact:

```javascript theme={null}
const dcaParams = {
  numberOfChunks: 5,
  chunkIntervalBlocks: 2
};

// Fees are applied per chunk, but overall impact is reduced
const feePerChunk = totalFee / numberOfChunks;
```

### Boost Fee

Optional boost fee for faster execution:

```javascript theme={null}
const boostFeeBps = 10; // 0.1%
const boostFee = (inputAmount * boostFeeBps) / 10000;

// Total with boost
const totalWithBoost = totalFee + boostFee;
```

### Low Liquidity Warning

When `lowLiquidityWarning: true`:

```javascript theme={null}
const recommendedSlippage = quote.recommendedSlippageTolerancePercent;
const recommendedSlippageBps = recommendedSlippage * 100;

// Use higher slippage for low liquidity pools
const adjustedSlippage = Math.max(slippageBps, recommendedSlippageBps);
```

## Relay Fee Structure

Relay uses a comprehensive fee model with multiple components.

### Fee Components

| Fee Type        | Description                | Source          |
| --------------- | -------------------------- | --------------- |
| Gas             | Blockchain gas fees        | Per transaction |
| Relayer         | Bridge relayer fee         | Per bridge      |
| Relayer Gas     | Gas for relayer operations | Per bridge      |
| Relayer Service | Service fee for relaying   | Per bridge      |
| App             | Application/affiliate fee  | Optional        |

### Formula

```typescript theme={null}
// Extract fees from response
const { gas, relayer, relayerGas, relayerService, app } = quote.fees;

// Total USD cost
const totalFeeUSD =
  (gas?.usd || 0) +
  (relayer?.usd || 0) +
  (relayerGas?.usd || 0) +
  (relayerService?.usd || 0) +
  (app?.usd || 0);

// Output calculation
expectedOutput = quote.details.currencyOut.amount;
```

### Example Calculation

```javascript theme={null}
const fees = {
  gas: { usd: 5.50, amount: '2000000000000000' },
  relayer: { usd: 2.00, amount: '800000000000000' },
  relayerGas: { usd: 1.50, amount: '600000000000000' },
  relayerService: { usd: 1.00, amount: '400000000000000' },
  app: { usd: 0.50, amount: '200000000000000' }
};

const totalFeeUSD = 5.50 + 2.00 + 1.50 + 1.00 + 0.50;
// = 10.50 USD
```

### App Fee Configuration

Set custom affiliate fees:

```javascript theme={null}
const appFees = {
  recipient: '0xClientFeeAddress...',
  fee: '30' // BPS (0.3%)
};

// Applied to total transaction value
const appFeeAmount = (inputAmount * 30) / 10000;
```

### Price Impact Calculation

Relay differentiates between total impact and swap impact:

```javascript theme={null}
const totalImpact = {
  usd: 25.50,
  percent: 1.275  // (25.50 / 2000) * 100
};

const swapImpact = {
  usd: 15.30,
  percent: 0.765  // (15.30 / 2000) * 100
};

// totalImpact = fees + slippage
// swapImpact = slippage only
```

### Multi-Step Route Fees

Each step in a multi-hop route has separate fees:

```javascript theme={null}
const route = {
  steps: [
    { action: 'approve', estimatedFees: { gas: { usd: 2.0 } } },
    { action: 'bridge', estimatedFees: { gas: { usd: 5.0 }, relayer: { usd: 3.0 } } },
    { action: 'swap', estimatedFees: { gas: { usd: 4.0 } } }
  ]
};

// Total fees
const totalFees = route.steps.reduce((sum, step) => {
  return sum + Object.values(step.estimatedFees).reduce((s, f) => s + f.usd, 0);
}, 0);
// = 14.0 USD
```

## NEAR Fee Structure

NEAR uses a simplified fee model based on USD value difference.

### Formula

```typescript theme={null}
// Single network fee combining all costs
networkFee = quote.amountInUsd - quote.amountOutUsd;

// Expected output
expectedOutput = quote.amountOut;
```

### Example Calculation

```javascript theme={null}
const quote = {
  amountIn: '1000000000',        // 1000 USDC
  amountInUsd: 1000.00,
  amountOut: '20150000000000000', // 0.02015 ETH
  amountOutUsd: 985.50
};

// Network fee in USD
const networkFee = 1000.00 - 985.50;
// = 14.50 USD

// Represents all protocol costs combined
```

### Gas Fees

NEAR uses fixed gas amounts:

```javascript theme={null}
// ft_transfer (token transfers)
const ftTransferGas = '30000000000000'; // 30 TGas

// Attached deposit (required for token operations)
const attachedDeposit = '1'; // 1 yoctoNEAR
```

## Fee Comparison Example

Same swap across different protocols:

### Scenario: 1 BTC → ETH.USDC

| Protocol  | Affiliate     | Outbound | Liquidity       | Other       | Total USD |
| --------- | ------------- | -------- | --------------- | ----------- | --------- |
| THORChain | \$20 (30 BPS) | \$65     | \$100 (150 BPS) | -           | \$185     |
| MAYAChain | \$20 (30 BPS) | \$60     | \$95 (150 BPS)  | -           | \$175     |
| Chainflip | \$30 (BROKER) | -        | -               | \$25 (fees) | \$55      |
| Relay     | -             | -        | -               | \$45 (all)  | \$45      |

**Note:** Actual fees vary based on network conditions, liquidity, and current rates.

## Fee Optimization Strategies

### Minimize Slippage

```javascript theme={null}
// For stable pairs, use lower slippage
const stablePairSlippage = 50; // 0.5%

// For volatile pairs, use higher slippage
const volatilePairSlippage = 300; // 3%

// For large amounts, use streaming swaps (THORChain/MAYA)
const streamingParams = {
  streaming_quantity: 10,
  streaming_interval: 3
};
```

### Choose Optimal Protocol

```javascript theme={null}
// Compare total fees across protocols
function selectOptimalProtocol(quotes) {
  return quotes.reduce((best, quote) => {
    const currentFees = quote.fees.reduce((sum, f) => sum + f.usd, 0);
    const bestFees = best.fees.reduce((sum, f) => sum + f.usd, 0);
    return currentFees < bestFees ? quote : best;
  });
}
```

### Balance Speed vs Cost

```javascript theme={null}
// Fast but potentially higher fees
const fastestQuote = quotes.reduce((fastest, q) =>
  q.total_swap_seconds < fastest.total_swap_seconds ? q : fastest
);

// Cheapest but potentially slower
const cheapestQuote = quotes.reduce((cheapest, q) => {
  const qFees = q.fees.reduce((sum, f) => sum + f.usd, 0);
  const cheapestFees = cheapest.fees.reduce((sum, f) => sum + f.usd, 0);
  return qFees < cheapestFees ? q : cheapest;
});
```

## Best Practices

1. **Always display total fees in USD** for user transparency
2. **Break down fee components** to help users understand costs
3. **Show price impact separately** from network fees
4. **Use protocol-recommended slippage** for low liquidity pools
5. **Cache outbound fees** from THORChain/MAYA APIs (update hourly)
6. **Account for decimal differences** (especially MAYA.CACAO's 10 decimals)
7. **Multiply BROKER fees by 1.5x** for Chainflip calculations
8. **Compare effective rates** (output/input) across protocols, not just fees
9. **Warn users about high price impact** (>5%) before swap execution
10. **Update gas prices frequently** (every 1-2 minutes) for accurate estimates
