Previous value in Frozen
event
Additionally, to better reflect your concern of indexing the correct unfrozen / frozen amounts during forceTransfers and burn, I’ve added a previousValue and newValue in the Frozen event, so that differences can be tracked. Now if a force transfer or a burn changes the freezing status, the Frozen event will emit both old and new value, so that changes in freezing status can be tracked.
I’m not sure emitting the previous value is necessary. If indexers want to keep track of the difference, they can check against their currently indexed value.
ERC20 tokens already behave by not emitting previous values in allowance nor balance changes. I’d argue the ERC-7943 should behave likewise.
Pausability
What makes me to hesitate about it [pausability] is:
- Do all use cases need this ? If we can name a few that don’t neccessarily require it, I wouldn’t go with it.
I’d say the majority of permissioned tokens, of which securities and RWAs should be a subset of, use it.
Doing a minor research about it, I can find:
- Stablecoins:
- Debt-based:
- Blackrock’s BUILD:
isPaused
. - Superstate’s USTB:
paused
.
- Blackrock’s BUILD:
- Real estate:
- RealT: none found, might be implemented through the
processor
entity.
- RealT: none found, might be implemented through the
- Gold:
- Tether Gold: none found, the only other permissioning feature is a blacklist.
- Paxos Gold:
paused
.
- OZ already has an historical and battle tested, widely adopted, solution for pausable contracts and it’s easy to think about this as one of the multiple potential extensions of an ERC-7943 minimal token.
I agree that there’s no need to standardize it for ease-of-use of the feature, as OZ already has the de-facto standard for pausability.
I’m more concerned about having a clear criteria for what features are included in the baseline ERC. One can argue that token freezing is not necessarily required within the ERC, as it can be enforced through forceTransfer
and vaults, but that it’s best to standardize it, and that pausability can be enforced through isTransferAllowed
and extensions, but that it’s also best to standardize it.
I’d aim for what we envision will be the requirements for 90% of the tokens into the baseline ERC, and leave the rest to extensions.
That said, I don’t have enough insights on pausability requirements to take a clear stand on its inclusion. To me, although most tokens have it, it feels operative and not a core token functionality, similarly to upgradeability.
Unfreezing in forced transfers
Yes, cases in which the freezing authority has more power (higher priority) in the entity performing a forced transfer. Those might be two separate entities. You can give forceTransfer rights to one or more entities, and setFrozen rights to completely different entities. An example might be perpetual contracts where a continous funding mechanism might leverage the forceTransfer functionality. In this sense, the forceTransfer would be functional to a perpetual contract funding mechanism but might not have the freedom to move more than frozen assets, since those might be seized by goverments or higher level authorities than a smart contract logic for perpetual contracts. What do you thinkg about this ?
I’d argue forced transfers are not the correct action for that use-case. I believe it has the same implications than using native ERC20 approvals, as you still depend on the user not front-running you to collect the fees, and using an all-powerful permissioned function to execute core business logic doesn’t seem right.
Still, the EIP suggests both things now, a forceTransfer and a burning CAN skips the freezing validations, but they also CAN NOT skip those. The most important thing is that if those automatically unfreeze, the must emit a frozen event to reflect that, before the native transfer event.
I agree it’s most important that unfreezing emits the Frozen
event before the native Transfer
one, and that it should fix indexing concerns, if ForcedTransfer
and Transfer
can only occur with unfrozen balances.
I believe the decision is a trade-off between:
- Forcing unfreezing in
forceTransfer
and ensuring standard implementation. - Allowing
forceTransfer
to revert on frozen balances and, therefore, a freezer role to be of higher status than a force transferer role.
I have a preference for option 1, as I don’t see any use-case for option 2 and consider forceTransfer
a “last resort” permissioning function.
If we can come up with option 2 use-cases, it would make total sense to keep it unopinionated.