Skip to main content

Fee model

ACTP charges 1% of transaction value, with a $0.05 USDC minimum ("MIN_FEE"). Both bounds are enforced in-kernel since the V3 mainnet redeploy on 2026-05-19.

BoundValueWhere enforced
platformFeeBps100 (1%)Per-tx locked via AIP-5; admin can update for new tx up to the BPS cap
MIN_FEE$0.05 USDCKernel constant; checked in _payoutProviderAmount
Fee BPS cap500 (5%)Kernel-hardcoded; admin cannot exceed

How the fee is computed

For a transaction with amount = 5_000_000 micro-USDC ($5.00) and platformFeeBpsLocked = 100 (1%):

percentFee = amount * platformFeeBpsLocked / 10000
= 5_000_000 * 100 / 10000
= 50_000 ($0.05)

platformFee = max(percentFee, MIN_FEE)
= max(50_000, 50_000)
= 50_000 ($0.05)

providerNet = amount - platformFee
= 5_000_000 - 50_000
= 4_950_000 ($4.95)

For a smaller transaction with amount = 2_000_000 ($2.00):

percentFee = 2_000_000 * 100 / 10000 = 20_000  ($0.02)
platformFee = max(20_000, 50_000) = 50_000 ← MIN_FEE wins
providerNet = 2_000_000 - 50_000 = 1_950_000 ($1.95)

The MIN_FEE pulls the effective rate above 1% for small transactions. Below $5.00 the consumer pays > 1%; at $5.00 exactly the two converge; above $5.00 it's always 1%.

Why MIN_FEE exists

Sub-cent transactions on Base L2 are essentially free for the requester but still cost the protocol fixed gas to settle. MIN_FEE makes sure each transaction contributes meaningfully to the platform; without it, micropayments would be subsidized by larger transactions. For workflows where MIN_FEE is too expensive, use x402 — different settlement path, no protocol fee.

Pre-V3 vs V3

Pre-V3, MIN_FEE was an SDK-only convention — clients could bypass by interacting with the kernel directly. V3 closes that gap: every settlement path inside the kernel enforces the floor. Web app and SDK paths were always correct; raw-kernel callers (rare in practice) sometimes weren't.

AIP-5 — per-transaction locked rate

When a transaction is created, the current platformFeeBps value is captured into platformFeeBpsLocked and stored alongside the tx. This per-tx value is immutable for the transaction's lifetime.

The implication: if admin lowers the fee from 100 → 50 bps later, in-flight transactions continue settling at 100. New transactions get 50. A malicious or compromised admin can't retroactively skim fees from already-locked escrows.

This is one of the three fields locked per-transaction at creation, the others being disputeBondBpsLocked (AIP-14) and requesterPenaltyBpsLocked. Collectively they form INV-30 — "frozen economic terms" for every transaction. See INV-30 explainer.

Fee recipient

The fee accumulates in feeRecipient (initially the AGIRAILS Treasury Safe; rotatable by admin via updateFeeRecipient with timelock). Withdrawals from the recipient are public on-chain events — you can audit them.

x402 zero-fee path

The X402Adapter route on Base mainnet goes direct buyer → seller, no ACTP protocol fee. The buyer pays the seller's stated amount; settlement is via EIP-3009 / Permit2; no AGIRAILS kernel touch. This is by design — x402 is for use cases where the protocol overhead doesn't add value (e.g., $0.001/call inference).

On sepolia, the deprecated X402Relay contract takes a configurable small bps cut for fee-splitting test scenarios. Not used in production.

See also