detectTransferRestrictionFrom
New update regarding the interface
Add a spender-aware companion to detectTransferRestriction, called detectTransferRestrictionFrom, plus a note on reusing it for mint/burn.
- this change is backward compatible.
- Nothing in the mandatory ERC-1404 interface changes, the mandatory ERC-165 interface id stays the same, and any existing implementation remains compliant with no edits.
Reason
detectTransferRestriction(from, to, value) describes a transfer purely in terms of from, to, and value.
It has no spender parameter, so it can’t express a restriction that depends on the party initiating a delegated transfer.
For ERC-20, transferFrom is executed by a spender that may differ from from. A perfectly reasonable compliance policy — “this operator is frozen”, or “this operator hasn’t passed its own KYC/AML” — is therefore invisible to detectTransferRestriction.
An integrator predicting a transferFrom outcome by calling only the base method mispredicts exactly these cases: the view returns 0, and the transferFrom then reverts.
What I’m proposing to add
1. Optional detectTransferRestrictionFrom
function detectTransferRestrictionFrom(address spender, address from, address to, uint256 value) external view returns (uint8);
Returns a restriction code for the delegated transfer of value from from to to initiated by spender, or 0 if unrestricted. Same restriction-code space as detectTransferRestriction, same messageForTransferRestriction lookup.
An implementation that exposes it MUST:
- keep it consistent with delegated-transfer enforcement — a
transferFrom by spender is rejected if detectTransferRestrictionFrom(spender, from, to, value) returns non-zero;
- return exactly
detectTransferRestriction(from, to, value) when spender == from (a direct transfer is the degenerate delegated transfer whose initiator is the holder);
- not change the meaning of, or consistency required of, the base method — the base method still describes the
from/to/value conditions; the extension only adds the spender dimension.
2. A separate ERC-165 id for discovery
- Mandatory ERC-1404 id:
0xab84a5c8 — unchanged, XOR of the two base-method selectors.
- Optional extension id:
0x78a8de7d — XOR of all three selectors.
An implementation exposing the extension advertises both. The extension id deliberately covers all three selectors so a single supportsInterface(0x78a8de7d) == true proves all three methods are present. (It has to be computed as an explicit XOR of the three selectors — type(IExtension).interfaceId on an interface that only declares the added method would cover just one selector and mustn’t be used here.)
3. Mint/burn can reuse the spender path
Mint and burn stay out of the mandatory scope (supply-changing ops, not transfer/transferFrom), and checking them stays an optional MAY.
The new note: where an implementation does check mint/burn and exposes the extension, the spender parameter of detectTransferRestrictionFrom MAY carry the operator initiating the mint or burn, so the policy can restrict that operator directly — rather than trying to pass address(0) (the ERC-20 mint/burn counterparty) into the base method, which a whitelist policy would just reject.
Why it’s backward compatible
- Mandatory interface unchanged —
detectTransferRestriction and messageForTransferRestriction keep identical signatures and semantics. An existing ERC-1404 token is still conforming with zero changes.
- Mandatory ERC-165 id unchanged —
supportsInterface(0xab84a5c8) still answers for the two base methods; the extension lives under a distinct id a base-only integrator can ignore.
- Purely additive and optional — the extension is a
MAY. A token that never implements it loses nothing and violates nothing; base-only integrators keep working exactly as before.
- Consistent by construction where it matters — the
spender == from rule forces the extension to agree with the base method on direct transfers, so the two can’t contradict each other for the case they both describe.
- No new mandatory conformance bar — the mint/burn note is doubly gated (
MAY check and MAY use spender), imposing nothing on existing implementations.
Feedback
Let me know if you have any feedback on that. The Pull Request contains already the different changed proposed here