Skip to content

Fees (Fee)

What is Fee

Fee (commission) — is a percentage of the transfer amount that is retained by the bridge when transferring tokens between networks.

Why is fee needed?

Commission (fee) is charged by the bridge during cross-chain token transfers to cover operational costs and ensure economic sustainability of the protocol.

Important

Fee is charged only on the EVM network side. On the TVM side, no fee is applied.

Who receives the fee?

  • Fee accumulates on the MultiVault contract
  • Recipient: governance address (contract administrator)
  • Fee withdrawal: skim() function transfers accumulated fees to the governance address

Types of Fees

Deposit Fee

Fee is charged when depositing tokens from EVM to TVM network.

User sends 1000 USDT → Fee 10 USDT (1%) → 990 USDT goes to TVM

When applied:

  • When calling deposit() on the MultiVault contract
  • When calling depositByNativeToken() for native tokens (ETH, BNB, etc.)

Withdraw Fee

Fee is charged when withdrawing tokens from TVM to EVM network.

User withdraws 1000 USDT from TVM → Fee 10 USDT (1%) → Receives 990 USDT in EVM

When applied:

  • When calling saveWithdrawNative() / saveWithdrawAlien() on the MultiVault contract
  • After event confirmation by relays

Fee Collection Scheme

┌─────────────────────────────────────────────────────────────────┐
│                      EVM → TVM (Deposit)                        │
├─────────────────────────────────────────────────────────────────┤
│  User sends 1000 tokens                                         │
│       ↓                                                         │
│  MultiVault.deposit()                                           │
│       ↓                                                         │
│  Calculate fee: 1000 × depositFee / 10000                       │
│       ↓                                                         │
│  Fee (e.g. 10) stays on MultiVault                              │
│       ↓                                                         │
│  990 tokens transferred to TVM                                  │
└─────────────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────────────┐
│                      TVM → EVM (Withdraw)                       │
├─────────────────────────────────────────────────────────────────┤
│  User initiates withdraw of 1000 tokens in TVM                  │
│       ↓                                                         │
│  Event created, relays confirm                                  │
│       ↓                                                         │
│  User calls saveWithdraw*() on MultiVault                       │
│       ↓                                                         │
│  Calculate fee: 1000 × withdrawFee / 10000                      │
│       ↓                                                         │
│  Fee (e.g. 10) stays on MultiVault                              │
│       ↓                                                         │
│  User receives 990 tokens                                       │
└─────────────────────────────────────────────────────────────────┘

Default and Token-specific Fee

Two Configuration Levels

Fees are configured at two levels:

LevelDescriptionWhen Used
Default FeeGlobal default valuesWhen activating a new token
Token-specific FeeIndividual token settingsAfter token activation

Default Fee

Global fee settings, separated by token type:

ParameterDescription
defaultNativeDepositFeeDefault deposit fee for Native tokens (originally issued in TVM)
defaultNativeWithdrawFeeDefault withdraw fee for Native tokens
defaultAlienDepositFeeDefault deposit fee for Alien tokens (originally issued in EVM)
defaultAlienWithdrawFeeDefault withdraw fee for Alien tokens

Token-specific Fee

Individual settings for each token:

ParameterDescription
tokens_[token].depositFeeDeposit fee for specific token
tokens_[token].withdrawFeeWithdraw fee for specific token

How Fee is Applied

┌─────────────────────────────────────────────────────────────────┐
│           Fee Application Scheme During Token Activation        │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  First use of token                                             │
│       ↓                                                         │
│  _activateToken() is called                                     │
│       ↓                                                         │
│  Token type determined (Native or Alien relative to TVM)        │
│       ↓                                                         │
│  ┌─────────────────┐     ┌─────────────────┐                    │
│  │  Native token   │     │  Alien token    │                    │
│  │   (from TVM)    │     │   (from EVM)    │                    │
│  └────────┬────────┘     └────────┬────────┘                    │
│           ↓                       ↓                             │
│  defaultNativeDepositFee   defaultAlienDepositFee               │
│  defaultNativeWithdrawFee  defaultAlienWithdrawFee              │
│           ↓                       ↓                             │
│           └───────────┬───────────┘                             │
│                       ↓                                         │
│  Copied to tokens_[token].depositFee / withdrawFee              │
│                       ↓                                         │
│  All subsequent operations use token-specific fee               │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

Important

After token activation, changing default fee DOES NOT affect this token. To change the fee for an already activated token, you must explicitly call setTokenDepositFee() / setTokenWithdrawFee().

Fee Configuration

Setting default fee (for new tokens):

solidity
setDefaultNativeDepositFee(100);   // 1% for Native tokens (from TVM) deposit
setDefaultNativeWithdrawFee(50);   // 0.5% for Native tokens withdraw
setDefaultAlienDepositFee(100);    // 1% for Alien tokens (from EVM) deposit
setDefaultAlienWithdrawFee(50);    // 0.5% for Alien tokens withdraw

Setting token-specific fee (for existing tokens):

solidity
setTokenDepositFee(tokenAddress, 200);  // 2% deposit for specific token
setTokenWithdrawFee(tokenAddress, 100); // 1% withdraw for specific token

Data Structure

Constants

ConstantValueDescription
MAX_BPS10,000100% in basis points (1 BPS = 0.01%)
FEE_LIMIT5,000Maximum allowed fee = 50%

Token Structure

Stores token information, including fees. Each token has individual fee settings.

AttributeTypeDescription
activationuintBlock number of token activation
blacklistedboolToken blacklist flag
depositFeeuintDeposit fee (in BPS)
withdrawFeeuintWithdrawal fee (in BPS)
isNativebooltrue = Native token (from TVM), false = Alien token (from EVM)
customaddressCustom token address

Storage Variables

VariableTypeDescription
tokens_mapping(address => Token)Mapping token address → configuration
defaultNativeDepositFeeuintDefault fee for Native token (from TVM) deposit
defaultNativeWithdrawFeeuintDefault fee for Native token withdrawal
defaultAlienDepositFeeuintDefault fee for Alien token (from EVM) deposit
defaultAlienWithdrawFeeuintDefault fee for Alien token withdrawal

Fee Enum

ValueDescription
DepositDeposit fee
WithdrawWithdrawal fee

Fee Calculation

Formula

fee = amount × feeRate / MAX_BPS

Where:

  • amount — transfer amount
  • feeRate — fee rate in BPS (basis points)
  • MAX_BPS = 10,000 (100%)

Calculation Function

FunctionDescription
_calculateMovementFee()Calculates fee based on operation type (Deposit/Withdraw) and token rate

Calculation Examples

AmountFee Rate (BPS)Fee Rate (%)Fee
1,000,000100.1%1,000
1,000,0001001%10,000
1,000,0005005%50,000
1,000,0005,00050%500,000 (maximum)

Fee Management

Default Fee Setting Functions

FunctionParametersDescription
setDefaultNativeDepositFee()fee: uintSets default deposit fee for Native tokens (from TVM)
setDefaultNativeWithdrawFee()fee: uintSets default withdraw fee for Native tokens
setDefaultAlienDepositFee()fee: uintSets default deposit fee for Alien tokens (from EVM)
setDefaultAlienWithdrawFee()fee: uintSets default withdraw fee for Alien tokens

Token Fee Setting Functions

FunctionParametersDescription
setTokenDepositFee()token: address, fee: uintSets deposit fee for specific token
setTokenWithdrawFee()token: address, fee: uintSets withdraw fee for specific token

Fee Withdrawal

FunctionParametersDescription
skim()token: addressTransfers accumulated token fees to governance address

The function calculates accumulated fee as the difference between contract balance and locked liquidity (liquidity[token]).

Access Rights

ActionRequired RoleContract
Set default feegovernanceMultiVaultFacetFees
Set token feegovernanceMultiVaultFacetFees
Withdraw fees (skim)governanceMultiVaultFacetFees

Events

EventParametersDescription
UpdateDefaultNativeDepositFeefeeChange in default deposit fee for Native tokens
UpdateDefaultNativeWithdrawFeefeeChange in default withdraw fee for Native tokens
UpdateDefaultAlienDepositFeefeeChange in default deposit fee for Alien tokens
UpdateDefaultAlienWithdrawFeefeeChange in default withdraw fee for Alien tokens
UpdateTokenDepositFeetoken, feeChange in deposit fee for token
UpdateTokenWithdrawFeetoken, feeChange in withdraw fee for token
SkimFeetoken, skim_to_everscale, amountWithdrawal of accumulated fees

Limits

ParameterValueDescription
MAX_BPS10,000100% in basis points
FEE_LIMIT5,000Maximum fee = 50%

Attempting to set fee > FEE_LIMIT will result in transaction rejection.

Fee in Different Flows

EVM → TVM (deposit)

  1. User calls deposit() on MultiVault
  2. depositFee is calculated via _calculateMovementFee()
  3. Fee is deducted from transfer amount
  4. Fee remains on MultiVault contract (accumulates)
  5. Amount minus fee is transferred to TVM network

TVM → EVM (withdraw)

  1. User initiates withdraw in TVM network (no fee charged)
  2. Event contract is created with transfer information
  3. Relay nodes confirm the event
  4. User calls saveWithdraw*() on MultiVault in EVM
  5. withdrawFee is calculated via _calculateMovementFee()
  6. Fee is deducted, user receives amount minus fee

API Reference

POST /payload/build

Returns fee information in response:

FieldTypeDescription
feeAmountstringCalculated fee in token's smallest units
tokenAmountstringToken amount after fee deduction

Risks and Edge Cases

Risk/ErrorCauseProtection/Solution
Fee > AmountFee exceeds transfer amountTransaction reverts (underflow)
Fee = 50%+Attempt to set fee above limitCheck fee <= FEE_LIMIT
Zero governanceFee recipient not setgovernance set during initialization
Token not activatedFee not set for tokenToken activates automatically on first use
Default fee changeDoesn't affect existing tokensMust explicitly call setTokenFee for each token

Error Codes

Error CodeDescription
"Fee: limit exceeded"Attempt to set fee > FEE_LIMIT (5000 BPS = 50%)
"Fees: no fees to skim"Calling skim() when accumulated fee = 0
"Actors: only governance"Calling setDefaultFee not from governance address
"Actors: only governance or management"Calling skim() not from governance/management

ChainConnect Bridge Documentation