Algorand Builder is a framework and set of templates to quickly develop dapps based on Algorand blockchain. One of the features which is highly appreciated, but not well understood on Algorand is a design of permissioned tokens.
Permissioned tokens have a mechanism limiting the token usage based on additional requirements. Securities may use the permissioned token mechanism to define complex compliance requirements, such as investor whitelisting and transfer restrictions. For example, only a verified, KYCed users can exchange tokens.
Specifically, we implement various mechanisms for permissioned tokens to:
Control the number of tokens minted for distribution and also allow flexibility for the administrator to issue more tokens in the future.
Create whitelists of accounts who are approved to buy/hold the tokens.
Support transfer restrictions(e.g., U.S. vs international).
Manage lock-ups as needed to ensure there are no transfers before they're allowed.
Implement new permission requirements that come up post-issuance, such as adding or removing investors to the whitelists or creating additional whitelists for new restrictions.
Take confidence in the ability to remove restrictions in the future if transfers become open or unlimited.
We design a permissioned tokens with emphasis for shares and equity.
The token should provide all legal information about the issuer and the underlying security. We will use ASA fields for that:
url must link to a the document specifying all legally required information as well as metadata(information about tokens, distribution description, code repository, ….). The document should be immutable. The document can be encrypted. We recommend storing the document in IPFS.
metadataHash is a blake2b hash of the document linked by url. If the document is encrypted, the hash should be computed from the unencrypted version.
total amount must envision all future needs and legally specified. In Algorand, all tokens must be created at the beginning and they will be stored the a reserve address. The process of distributing new tokens is done by creating a new supply from the tokens stored in the reserve address.
reserve is an account(key or lsig) which keeps all possible token supply. We recommend to use multisig key or lsig(logic signature).
Our template should provide clear placeholders or comments for the attributes above.
Allocation of tokens to shareholders
Once token is created, we should be able to issue tokens from reserve account to new stakeholders.
Issuer may reverse allocation or token transfer to some token holders. In that case we should be able to clawback the tokens of any address.
Issuer may cancel some tokens, and reclaim it back to the reserve address using the clawback account.
We must be able to quickly report the total amount of issued tokens. This is done by a simple mathematical operation: asa.total - asa.balance_of(reserve)
Issuer may pay out a dividend to token holders. Each token holder must be able to claim the dividend proportionally to the tokens they own. We must assure that we don’t have double spend - for each token we pay only once.(eg the problem might be if a token holder A, after claiming the dividend, sends tokens to account B, and then account B will try to claim the dividend again).
NOTE: we do not do that in the current milestone.
Solution: Use clawback to transfer assets
This is the solution we implement in algo-builder template.
We will use a stateless TEAL as a clawback, which will execute all asset transfers transactions. So if user A wants to transfer to user B, it will be an Asset Transfer transaction using clawback mechanism, where sender = clawback logic sig(standard clawback mechanism), asset_sender=asset_owner, asset_receiver=recipient. Moreover we will use a permissions stateful smart contract to store user information to check if an asset transfer is compliant.
This solution extends Algorand Dev Office Hour idea presented by Jason - using asset clawback as escrow for permissioned token.
In this template we have a new contract - controller.py which essentially"controls" the asset/token. It controls the general properties of the asset and also ensures that rule(s) smart contract(s) are called.
Create assets with setting default-frozen=true.
Solution: Use clawback to transfer assets