Security Best Practices
This page covers important security considerations when integrating with CommissionRoad.
Always Collect a Commission
Critical Security Pattern
Always set commission to at least 1 wei — even if you intend to offer "free" transactions. A zero commission removes an important safety rail.
The Sweep Attack
When a commissionCall executes, CommissionRoad may hold tokens temporarily between calls in the batch. A malicious target contract could exploit this window:
- User submits a
commissionCallwithcommission = 0 - Batch includes a call to a malicious contract, followed by a
sweepERC20Tokencall - The malicious contract re-enters or calls
sweepERC20Tokenitself — draining the tokens before the user's sweep runs - With
commission = 0, the_collectCommissionsstep is a no-op — nothing reverts
Why a Nonzero Commission Prevents This
When commission > 0, CommissionRoad calls CommissionVault.depositCommission at the end of the transaction. For ERC20 commissions, the vault calls safeTransferFrom to pull tokens from CommissionRoad. If a malicious contract has already drained those tokens, safeTransferFrom reverts — taking the entire transaction with it.
The minimum commission acts as an implicit guard — it ensures the token balance is still intact at the end of execution.
Recommended Pattern
// ✅ Safe: Always collect at least dust
const commission = 1n; // 1 wei — negligible cost, maximum protection
await commissionRoad.write.commissionCall([
batchCallData,
nftId,
commissionToken,
commission,
], { value: totalEthNeeded + commission });// ❌ Unsafe: Zero commission removes the safety net
const commission = 0n;
await commissionRoad.write.commissionCall([
batchCallData,
nftId,
commissionToken,
commission, // No depositCommission call — sweep attacks possible
], { value: totalEthNeeded });Rule of Thumb
If in doubt, set commission = 1. The cost is negligible (1 wei), but it guarantees that depositCommission runs and validates the contract's token balance before the transaction completes.
Use the Allowlist
The Allowlist is an opt-in feature that lets NFT owners restrict which contracts can be called through their NFT ID. Together with the nonzero commission rule above, the allowlist provides defense in depth:
| Layer | Protects Against | How |
|---|---|---|
| Nonzero commission | Sweep attacks | Ensures depositCommission runs, reverting if tokens were drained |
| Allowlist | Unauthorized targets | Blocks calls to contracts not explicitly approved by the NFT owner |
Setup
// 1. Enable the allowlist
await commissionRoad.write.setAllowlistEnabled([nftId, true]);
// 2. Only allow known good contracts
await commissionRoad.write.setAllowlist([nftId, uniswapRouter, true]);
await commissionRoad.write.setAllowlist([nftId, aaveLending, true]);TIP
The allowlist also applies to EIP-7702 / Executor flows. You manage it in one place — on the CommissionRoad contract.