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: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 throughfillWithLimits:
maxBuyerQuoteDebited — Cap on total buyer outlay
maxBuyerQuoteDebited — Cap on total buyer outlay
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 — Floor on net seller proceeds
minSellerQuoteReceived — Floor on net seller proceeds
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 — Floor on assets delivered to buyer
minAssetReceived — Floor on assets delivered to buyer
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.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:- 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.
- Verify escrow measurement. After depositing collateral, read the offer’s
assetRemainingfield to confirm it matches the amount you expect. Any discrepancy indicates a fee-on-transfer or double-entry issue. - Use slippage parameters conservatively. Set
minSellerQuoteReceivedandminAssetReceivedbased on your token’s actual observed transfer behavior, not its nominal fee rate. On-chain fees can differ from documentation. - 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.