Skip to main content

FeeCollectorV1

Collects ERC-20 token fees from project contracts when they send cross-chain messages. Deployed and configured by VIA Labs — developers interact with it indirectly through ViaIntegrationV1.setMaxFee().

Currently fees are set to zero on all chains. This contract exists as infrastructure for future fee models.

For the fee mechanics overview, see Fees & Gas.


How Fees Are Resolved

When pay(sender) is called by the gateway, the fee amount is resolved:

whitelist[sender]Fee chargedMeaning
0 (default)feeAmount (global default)Standard rate
1 to 9998That exact valueCustom rate for this sender
99990Free pass (FREE constant)
10000+That exact valueCustom rate

If maxFee[sender] is set and the resolved fee exceeds it, the entire send() reverts with FeeMaxCap.


Dual-Fee System

FeeCollectorV1 can collect two independent fees in a single pay() call:

1. ERC-20 Token Fee

  • Collected via safeTransferFrom(sender, beneficiary, amount)
  • Amount resolved by whitelist logic above
  • Project auto-approves the token when calling setMessageGateway()

2. Native Gas Fee (Optional)

  • Collected in native currency (ETH, MATIC, etc.) via msg.value
  • Enabled per-sender via sourceGasAmountWhitelist[sender] = true
  • Must be exact — msg.value must equal sourceGasAmount
  • Sent to beneficiary via low-level call

Native gas fee is collected before the token fee. Both go to the same beneficiary.


Functions (Owner)

FunctionParametersDescription
setAmountuint256 amountSet the global default fee (in token smallest units)
setTokenaddress addrSet the ERC-20 fee token (e.g., USDC)
setBeneficiaryaddress addrSet where collected fees go
setWhitelistaddress addr, uint256 amountPer-sender custom fee. 0 = use default, 9999 = free
setSourceGasAmountuint256 amountSet native gas fee amount (in wei)
setSourceGasWhitelistaddress addr, bool enabledEnable/disable native gas fee for a sender

Functions (Project)

FunctionParametersDescription
setMaxFeeuint256 amountCap the fee per message. Called by the project contract (msg.sender). 0 = no cap.

Functions (Gateway)

FunctionParametersDescription
payaddress senderCollect fees. Only callable by the gateway.

Errors

ErrorWhen
CallerMismatchpay() called by non-gateway address
FeeMaxCapResolved fee exceeds maxFee[sender]
InvalidSourceGasFeemsg.value doesn't match sourceGasAmount
SourceGasFeeNotPaidNative gas fee transfer to beneficiary failed

Token Approval

Developers don't manually approve the fee token. When ViaIntegrationV1.setMessageGateway() is called, it automatically:

  1. Queries gateway.feeCollector() to get this contract's address
  2. Queries feeCollector.feeToken() to get the token address
  3. Calls feeToken.approve(feeCollector, type(uint256).max)