Skip to main content
The ERC-20 standard defines a minimal interface, not a behavioral contract. Some non-standard behaviors are handled safely; others are structurally incompatible.

Supported Token Behaviors

The following token behaviors are handled correctly by the protocol:
  • Standard ERC-20 (no fees, no hooks) — Fully supported. Transfers deliver exactly the stated amount, escrow measurement is exact, and all accounting invariants hold as expected.
  • Fee-on-transfer tokens — Supported. The venue measures escrow from the actual received balance after transfer rather than the nominal deposit amount. The buyer’s slippage protection parameters (maxBuyerQuoteDebited, minSellerQuoteReceived, minAssetReceived) provide additional defense against unexpected shortfalls at fill time.
  • Tokens with transfer restrictions (e.g., pause, blacklist) — Supported conditionally. If a transfer is blocked at fill or redemption time — for example, because an address has been blacklisted after an offer was created — the transaction reverts cleanly. No funds are lost, but the operation must be retried after the restriction is lifted or the affected address is changed.

Unsupported and Risky Token Behaviors

The following token types are not recommended for use in Canopy offers:
Rebasing tokens (e.g., stETH, AMPL) — Rebasing tokens change their holders’ balances through direct balance mutations rather than transfers. Because the venue’s escrow records (assetRemaining, series.backing) are set at deposit/fill time and never updated for rebase events, the stored values will drift from the contract’s actual token balance over time. Negative rebases break 1:1 backing; positive rebases strand surplus in the venue. Do not use rebasing tokens as the offer asset.
Double-entry point tokens (e.g., USDT on certain chains) — Some tokens maintain two contract addresses that share a single balance state. The venue’s measured-transfer logic measures balances against a single address. If a transfer occurs through the other entry point, the measurement may be incorrect, causing escrow records to diverge from reality.
ERC-777 and tokens with exotic transfer callbacks — ERC-777 tokens invoke sender and recipient hooks on every transfer. If a hook re-enters the venue during a fill or deposit, the explicit reentrancy guard will cause the transaction to revert rather than proceeding with corrupted state. However, the interaction behavior may still be unexpected — particularly if the hook performs external calls that affect the token balance mid-execution. Exercise caution and test thoroughly.
Upgradeable tokens that can change decimals or behavior post-deployment — If a token contract is upgraded after an offer is created — changing its decimal precision, transfer semantics, or fee structure — the behavior of existing offers and claims against those series becomes undefined. Canopy has no mechanism to adapt to post-deployment changes in a token’s behavior. The assetDecimals field is cached at offer creation and never updated.

Fee-on-Transfer Deep Dive

Fee-on-transfer tokens deduct a percentage from every transfer, meaning the recipient receives less than the sender sent. The venue provides slippage protection on fills through fillWithLimits:
maxBuyerQuoteDebited sets the maximum total quote tokens debited from the buyer’s wallet, including the base quote cost, protocol fee, and any transfer taxes. The venue measures the buyer’s balance before and after the fill and reverts if the total debit exceeds this ceiling.
minSellerQuoteReceived sets the minimum quote amount the seller must actually receive after any transfer fees. Because fee-on-transfer quote tokens reduce the delivered amount, this parameter ensures the seller is not silently shortchanged. If net proceeds fall below this floor, the fill reverts.
minAssetReceived sets the minimum asset amount the buyer expects to receive. For fee-on-transfer asset tokens in spot fills, the amount delivered after the escrow transfer may be less than the nominal fill amount. This parameter ensures the buyer does not accept a fill with a materially degraded asset leg. If the buyer receives fewer assets than this floor, the fill reverts.
Used together, these three parameters allow both parties to define acceptable slippage envelopes and ensure that neither side is silently harmed by token-level fee mechanics. Set them conservatively — especially when working with tokens whose fee rates are configurable or can change over time.
The venue also measures outbound transfers (at cancel and redeem time) and will revert with UnsupportedTransferBehavior() if the venue’s balance does not decrease by exactly the expected amount or the recipient’s balance does not increase. This protects against tokens with unexpected transfer semantics.

Recommendations for Token Issuers

If you are a token issuer creating block offers for your own token, follow these practices before going live with large positions:
  1. Test with small amounts first. Create a minimal offer — the smallest denomination your token supports — and perform a complete fill and redemption cycle on testnet before creating production offers.
  2. Verify escrow measurement. After depositing collateral, read the offer’s assetRemaining field to confirm it matches the amount you expect. Any discrepancy indicates a fee-on-transfer or double-entry issue.
  3. Use slippage parameters conservatively. Set minSellerQuoteReceived and minAssetReceived based on your token’s actual observed transfer behavior, not its nominal fee rate. On-chain fees can differ from documentation.
  4. Check for upgrade risk. If your token is upgradeable, document and communicate to offer participants what governance controls constrain future upgrades. Unexpected upgrades during an active offer can break redemption assumptions.
Using an unsupported or risky token type does not necessarily result in immediate loss of funds — in many cases the contract will revert with UnsupportedTransferBehavior() rather than execute incorrectly. However, unexpected behavior can lead to stuck transactions, inaccurate escrow records, or degraded redemption values in ways that are difficult to detect without careful testing. Always validate token behavior on a testnet before deploying real assets into a Canopy offer.