External Transaction Fee
Fixed fee in a separate ERC-20 token (e.g., USDC) charged on every mint, burn, or transfer. Fee is collected from the payer's allowance separately from the transferred amount.
Purpose: External Transaction Fee charges a fixed fee in a separate ERC-20 token (e.g., USDC) on every token operation. The fee is collected separately from the transferred amount — the full token amount is transferred plus an additional fee in the external token.
- Doc type: Reference
- What you'll find here: Business impact, risks, controls, failure modes, auditability, dependencies, and ordering notes
- Related:
Interface (capabilities)
This feature exposes the following capabilities. Fees are denominated in a separate ERC-20 token (e.g., USDC) and collected from the payer's allowance — the transferred token amount is not reduced.
| Capability | Who can call | Inputs | On-chain effect | Emits | Notes |
|---|---|---|---|---|---|
| Collect external fee on operation | Automatic (hook) | Triggered on mint, burn, transfer | Transfers fee token from payer to recipient | ExternalFeeCollected | Payer must have approved fee token |
| Set fee amounts | GOVERNANCE_ROLE | Fixed amounts per operation type | Updates fee amounts | FeesUpdated | Blocked after freeze |
| Set fee token | GOVERNANCE_ROLE | ERC-20 token address | Changes fee denomination token | FeeTokenUpdated | All payers must re-approve new token |
| Set fee recipient | GOVERNANCE_ROLE | Recipient address | Redirects future collections | FeeRecipientUpdated | Effective immediately |
| Freeze fees | GOVERNANCE_ROLE | None | Permanently locks configuration | FeesFrozen | Irreversible |
Business impact
- Holders / payers: Gross-based — payer must hold both the token being transferred AND sufficient balance of the fee ERC-20 token with sufficient allowance to the fee contract. Every operation has an additional cost denominated in the external token.
- Issuer / recipient: Fee collected in a stable or known ERC-20 asset, enabling predictable fee revenue independent of the token's own price.
- Economics: Decouples fee economics from the token's own value. Useful when fees must be denominated in a stable asset.
Risks & abuse cases
- Transaction revert on insufficient allowance: If the payer's external ERC-20 allowance is insufficient, the entire transaction reverts. Holders who have not approved the fee token will not be able to transfer.
- Fee token price risk: If the external fee token (e.g., a non-stable ERC-20) appreciates significantly, fee burden on payers may become prohibitive.
- Fee lock-in after freeze: Calling
freezeFees()locks fee amounts permanently. Ensure fee levels are correct before freezing.
Controls & guardrails
| Role | Actions | Recommended guardrail |
|---|---|---|
GOVERNANCE_ROLE | setFees() — set fee amounts per operation | Call freezeFees() after launch to lock |
GOVERNANCE_ROLE | setFeeToken() — set the external ERC-20 fee token | Audit carefully — changing fee token changes holder obligations |
GOVERNANCE_ROLE | setFeeRecipient() — set collection destination | Multi-sig controlled |
GOVERNANCE_ROLE | freezeFees() — lock fee configuration permanently | Call at launch |
Failure modes & edge cases
- No allowance: Payer with zero allowance on the fee token will see every transfer revert. Onboarding flows must prompt users to approve the fee token.
- Fee token contract failure: If the external ERC-20 contract is paused or fails, all token operations that trigger the fee hook will revert. Choose a battle-tested, non-upgradeable fee token.
- Fee token address change: Changing
feeTokenmid-deployment requires all payers to re-approve the new token. Coordinate with holder communication.
Auditability & operational signals
ExternalFeeCollected(payer, feeToken, feeAmount, recipient)— emitted per operation. Use for fee revenue tracking.FeesUpdated(sender, feeToken, amounts, recipient)— emitted on configuration changes.FeesFrozen(sender)— emitted once on freeze.
Dependencies
- External ERC-20 token contract — must be deployed and accessible. Payers must hold this token and approve the fee contract.
- Payer must have granted allowance to the feature contract before any transfer.
Compatibility & ordering notes
supportsRewriting = false— does not modify the token transfer amount.- Order after Transaction Fee in the feature array (Transaction Fee rewrites the amount; External Transaction Fee collects separately and independently).
- Compatible with compliance modules — runs after compliance checks on the token amount.
- Compatible with all other features.
Change impact
- Enable after launch: Immediately applies to all subsequent operations. Existing holders must approve the fee token before their next transfer.
- Disable: No retroactive effect. Payer approvals on the fee token contract remain but become unused.
- Fee amount change (pre-freeze): Effective immediately for all subsequent operations.
- Fee token change: All payers must re-approve the new token address.
See also
- Token Features Catalog — return to the full feature catalog
- Transaction Fee — in-token fee collection alternative
- Asset Contracts — deployment architecture and role model
Transaction Fee Accounting
Tracks per-transaction fees for off-chain reconciliation without collecting them on-chain. Emits events for invoicing and reporting workflows. No holder economic impact.
Voting Power
Delegated voting with historical tracking on DALPAsset. Enables on-chain governance participation compatible with Governor contracts. Requires holder delegation to activate voting weight.