Replies: 6 comments
-
|
Previous discussion: https://forum.solana.com/t/srfc-37-efficient-block-allow-list-token-standard/4036/1 |
Beta Was this translation helpful? Give feedback.
-
|
We (@exo-tech-xyz) have implemented both sRFC 37 and TransferHooks for handling token issuer compliance with Token2022. sRFC 37 is a much better implementation and we would be excited to see it adopted by more of the community. TL;DR; Both put additional burden on consuming protocols and offchain clients, but sRFC37 is a lot more manageable for many onchain programs. Firstly, the account overhead of sRFC37 is minimal. Under a scenario where it is safe to assume the TokenAccount (TA) has already been initialized and thawed, there are no additional accounts required in an instruction that transfers tokens. However, using TransferHooks there is always at least 1 for the ExtraAccountMetas, but often more. This requires the program developer wishing to support TransferHooks to consider the overhead on transaction size. The worst case scenario for the program developer is when you cannot allow your instruction to fail when the TA is frozen OR you must initialize and thaw the TA. This would require the usage of ExtraAccountMetas in a similar manner to TransferHooks, which is extremely painful to debug and brings up the same issues with TransferHooks. However, it's a drastic improvement to remove this logic from the hot path of transferring a token. My biggest issue with both implementations is that ExtraAccountMetas is extremely painful to debug. When an incorrect account is used, it's difficult to understand whether it's from an invalid pubkey or incorrect Seed. It also adds an unknown number of accounts into the transaction. I would not be opposed to a more opinionated standard that fixes the number of accounts and possibly even the PDA seeds. I do not know all of the intended use cases, so it is difficult for me to have a strong opinion. |
Beta Was this translation helpful? Give feedback.
-
|
I think this approach should work well for tokens that require holders of the token to be on a whitelist (i.e. having been through a KYC (know your client) process). The way how I would see this working:
So the only on-chain overhead for users of the token would be that they need to ensure the permissionless thaw in invoked on token account creation - this seems like a pretty workable solution for trading KYC'd tokens on Solana. Unless I missed something? |
Beta Was this translation helpful? Give feedback.
-
|
Hello everyone 👋 I’ve been digging into sRFC-37 and the related reference implementations (token-acl, token-acl-gate), and had a couple of questions around roadmap and design intent:
This looks like a strong alternative to transfer hooks for permissioned tokens, so I’d love to understand the intended direction. Thanks! |
Beta Was this translation helpful? Give feedback.
-
|
Hey @bohdan-shumyhora,
|
Beta Was this translation helpful? Give feedback.
-
|
Hello everyone, I’m currently exploring the new token-acl and token-acl-gate programs. While digging into the code, I found a few points that are a bit confusing for a newcomer. I would appreciate some clarification on the following:
However, in the token-acl implementation, the
I noticed that the token-acl-gate repo doesn't seem to perform these checks when destructuring accounts. Is there a reason why these safety checks are omitted in the current implementation?
But the token-acl helper This makes it impossible to use the token-acl-gate program with token-acl as-is. Are there any updates planned for token-acl or token-acl-gate soon to resolve these mismatches?
Are there any planned updates for the SDK or the gate program soon? Thank you for your help! |
Beta Was this translation helpful? Give feedback.

Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Summary
This proposal defines the Token Access Control List (ACL for short), a novel mechanism for permissioned tokens without the drawbacks of the existing solutions. By following this specification, issuers can create permissioned tokens using Token22, the Default Account State extension and an allow/block listing smart contract with delegated freezing authority.
Context
Permissioned tokens fall into one of three use cases:
This proposal targets use cases 1 and 2, these are the permissioning happy-paths that should have better UX without compromising performance.
Background
Permissioned tokens in solana, before Token22, were based on wrapper programs that would thaw/freeze token accounts during each user interaction, at the cost of UX.
Token22 aimed to introduce alternatives while maintaining UX. The transfer-hook extension has a standardized interface that enables everyone to transfer and still execute custom code without requiring specialized UIs.
Even though this fixes the wallet UX this comes with great cost to protocol developers as it adds friction in the form of overhead compute units used during transfers and account dependency hell. This complexity leads most protocols simply blacklisting all token Mints with the transfer-hook extension.
Alternatively, issuers can use the Default Account State (DAS) extension to create permissioned tokens. This alternative trades UX for DX. Developer experience and composability are maintained, but user experience becomes significantly degraded. Token holders require the issuers manual intervention to thaw their token accounts before interacting with protocols. The issuers need to constantly thaw token accounts for their users, this is specially bothersome when related to sanctions lists where issuers only care about blocking some users.
Proposal
A new mechanism that borrows experience from previous methods and uses the DAS extension along with a Smart Contract (hereon referred to by Token ACL) delegated freeze authority. Additionally a second, user defined, Smart Contract - Gate Program - that implements a specific interface with instructions that gate the ability of the previous one from permissionlessly calling the freeze and thaw functions on Token22 for a given Token Account. This approach borrows from the widely controversial transfer-hook workflow without compromising token transfer user and developer experience - it only checks whether the Token ACL should be able to permissionlessly thaw or freeze a TA.
The novelty in this workflow is the removed issuer friction of having to manually thaw every single token account without sacrificing composability and transaction compute usage for most allow/block listing scenarios. The only assumption is that there may be some on-chain record that enables the thawing gating business logic to allow or block a given wallet from permissionlessly thawing their TAs.
Additionally, with the freeze authority, it’s easy for issuers to revoke authorization anytime by freezing a user’s token account.
The Token ACL will have a canonical implementation (like the Token and Token22 programs), issuers who want to use this mechanism only need to write or use a single Smart Contract that implements the interface. When using the interface, the implementation decides whether a given method is supported or not, and how to behave if not supported - always accept or fail these instruction calls.
The Token ACL will still allow a regular defined Freeze Authority that is kept under control of the issuer and the Gate Program that gates the permissionless functions only has the ability to fail those transactions. This means that issuers can use a 3rd party created allow or block list and still remain in full control of their authorities without compromising any other functionality or authority.
Specification
Token Program
This standard requires a Token22 based token as it depends on the Default Account State extension.
The token needs to delegate the Freeze Authority to the Token ACL described in the next section.
Token ACL
The Token ACL is a smart contract that augments the capabilities of the freeze authority for a given token. This new program not only maintains the ability to freeze and thaw tokens using an issuer defined freeze authority but this also introduces the capability for permissionless thawing and permissionless freezing of token accounts by using an issuer defined Smart Contract with gating business rules.
In order for the Token ACL to work, it requires that issuers delegate their freeze authority over. Given that freezing and thawing is such an important part of RWA workflows, the program maintains the same baseline features.
The new permissionless features are a means for anyone to be able to thaw or freeze token accounts when issuers use DAS extension on Token22 Token mints. These new permissionless instructions will call certain functions of a freeze authority defined Smart Contract that is responsible for deciding whether a Token Account should be frozen or thawed.
Using either the permissionless thaw and/or the permissionless freeze should be optional and defined by the freeze authority. This enables greater flexibility and allows the Gate Program to be an allow or block list operated by a 3rd party independent of the token issuer and freeze authority.
In order to maintain a secure environment, the Token ACL should ensure that permissionless instructions de-escalate account permissions when calling into the Gate Program code to prevent abuse from bad actors.
Accounts
MintConfig
Is a PDA that stores configurations and is going to be the delegated freeze authority for a given token mint.
PDA derivation: [b“MINT_CFG”, mint_address]
Discriminator: u8 = 0x01
Structure:
mint: Pubkey
authority: Pubkey
gating_program: Pubkey
enable_permissionless_thaw: bool
enable_permissionless_freeze: bool
Instructions
set_authority
create_config
Can only be called once per Mint
set_gating_program
forfeit_freeze_authority
thaw (permissioned)
freeze (permissioned)
thaw_permissionless
freeze_permissionless
thaw_permissionless_idempotent
Initialized.freeze_permissionless_idempotent
Frozen.Interface
The interface needs two methods, both with optional implementations (should return an error when not implemented). Each implemented instruction requires the respective extra account metas PDA created and populated in order to enable account dependency resolution:
Permissionless thaw
Permissionless freeze
In order for gate programs to have assurances as to whether they're being called under the right circunstances, a Flag Account is created for the duration of the
can-thaw-permissionlessandcan-freeze-permissionlessoperations. This account is created with 0 lamports and a single byte of data which is set to 1. Programs that require some level of bookkeeping should check that the flag account fulfills 2 constraints:Extra accounts format: github.com/solana-program/libraries/tree/main/tlv-account-resolution
Unlike the transfer-hook interface, we’re not providing interface instructions to populate the extra account metas given that this is widely dependent on the protocol and user implementation.
Gate Program
The Gate Program in this workflow is responsible for implementing the interface instructions. The instructions themselves will not call the T22 to freeze/thaw, but simply check whether the caller should freeze or thaw.
For each of the thaw and freeze instructions, the smart contract also needs to create and populate the respective extra metas account.
The instructions should return an error value when the given operation is not supported, not valid, or doesn’t pass all checks to occur in a permissionless manner.
Here are some common workflows and how to execute them:
Permissionless thaw
This TA owner is blocked from interacting with my token?
This operation is supported permissionlessly in my contract?
This TA owner is allowed to interact with my token?
Permissionless freeze
This TA owner is blocked from interacting with my token?
This operation is supported permissionlessly in my contract?
This TA owner is allowed to interact with my token?
SDKs
TypeScript
The typescript SDK should be able to:
Rust
The rust SDK should implement a similar functionality compared to the transfer-hook interface with an on-chain and an off-chain component.
The on-chain component serves to help the proxy program to parse the extra-account-metas and build the respective CPI into the user-defined program, while the off-chain component serves to help build transactions from off-chain rust programs.
Reference: github.com/solana-program/transfer-hook/tree/main/interface
Workflow
Client Workflow
Client workflow in order to detect if they should use custom logic to deal with permissionless thaw is as follow:

Alternative Client Workflow
By leveraging the Metadata Extension we can create an alternative workflow to detect the usage of Token ACL that doesn’t incur existing workflows for Token Account creation in performance penalties due to being forced to retrieve additional accounts via getAccountInfo RPC calls. In order to enable this alternative workflow a metadata field with the key
token-acland value<gate_program>is expected. Further metadata could be added, but at the cost of increasing the Token Mint account size massively and resulting in diminishing returns. The presence of this field is enough to signal clients when a Token 2022 based Token Mint uses the Token ACL standard.With this we reduce the additional RPC requests to fetch the freeze-authority account that would be used to detect the usage of Token ACL. Additionally, by storing the <gate_program> address in this metadata field, the MintConfig is no longer required to be able to figure out what is the Gate Program address in order to derive the extra-metas-account address. Given that the Token Mint data is usually already present as clients need to know the balances, decimals and which token program, this means we’ll have the metadata readily available.
Execution Workflow
Execution workflow and transaction contents would be:

A protocol that creates a token account vault for a token that uses this standard wouldn't need to directly support the standard at the smart contract level. Upon creation of the token account, it can either call the permissionless thaw on the same transaction, or asynchronously using the CLI.
A protocol would need direct support if there are token transfers on the same instruction that creates the token account vault. Separating this into two distinct instructions (initialize + deposit) enables the workflow described in the previous paragraph instead.
Security
The Token ACL solves the largest security concern in this system - the ability for a 3rd party to insert malicious instructions in unsuspecting users transactions. Standardizing a way for wallets/contracts/client software to introduce a new instruction to thaw token accounts right after creation is a sure way to enable bad actors.
The Token ACL solves this by de-escalating the permissions and acting as a proxy into the actual custom code that decides whether or not to act on the permissionless thaw and freeze operations.
Implementations
Ongoing implementation: https://github.com/tiago18c/token-acl
Example Allow / Block list program that implements permissionless thaw: https://github.com/tiago18c/abl-srfc37
Beta Was this translation helpful? Give feedback.
All reactions