-
Notifications
You must be signed in to change notification settings - Fork 318
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
CPS-0003? | Smart tokens #382
Closed
Closed
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -0,0 +1,141 @@ | ||||||
--- | ||||||
CPS: ? | ||||||
Title: Smart Tokens | ||||||
Status: Open | ||||||
Category: ? | ||||||
Authors: | ||||||
- Istvan Szentandrasi <[email protected]> | ||||||
Proposed Solutions: [] | ||||||
Discussions: | ||||||
- https://github.com/cardano-foundation/cps/pulls/? | ||||||
Created: 2022-11-20 | ||||||
--- | ||||||
|
||||||
# DRAFT - smart tokens | ||||||
|
||||||
## Abstract | ||||||
|
||||||
The aim of this problem statement is to raise the issue around the ability to control a native token's lifecycle at more points in time. | ||||||
Currently only forging of the tokens can be controlled, but not interactions with them. Extending the blockchain to support other interactions is non-trivial and might require many tradeoffs. | ||||||
|
||||||
## Problem | ||||||
|
||||||
The Mary era introduced native tokens, that could be minted/burned using native scripts. These native scripts for example could allow defining basic conditions to allow forging like required signatures or time validity range. The native tokens are identified with `policyId` and `assetName`. The `policyId` identifies the "publisher" or "publishers" while `assetName` can be an arbitrary. | ||||||
|
||||||
With the Alonzo era, plutus scripts were introduced. They allowed extending the functionality of the native scripts with more generic logic scoped at the transaction level. The format and shape of native tokens didn't change - the `policyId` became the hash of the plutus scripts pushing the "publisher" role responsibility to smart contracts. | ||||||
|
||||||
Skipping ahead, although Babbage didn't add any additional functionality directly, the addition of reference inputs indirectly opened additional use-cases to the the token's lifecycle. To be specific an example: imagine an decentralized bridge with a wrapped token that gets dynamically minted or burned. As a safeguard they would introduce a global UTxO (e.g. with a datum including signature by a multisig wallet or validity token) controlled by recognized members or governance voting mechanism that includes an `enable` flag. The enable flag could be checked by the wrapped token minting policy through a reference input. When a governance vote would pass, the UTxO datum could be changed and the flag could be set to freeze the token. | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
|
||||||
Even in the Babbage era, after the token is minted, there is no way to control the token after it leaves a smart-contract environment. Users can freely exchange tokens and transfer among each other. This allows cheaper, more efficient and more open ecosystem. In contrast with this, ERC-20 tokens are smart-contracts that fully control any interaction with a token. | ||||||
|
||||||
Similar to how UTxO addresses can be optionally fully controlled by smart-contracts, there could be potential also to optionally control other lifecycle points of a token than just forging on Cardano. | ||||||
|
||||||
## Use cases | ||||||
|
||||||
There are multiple use-cases that would benefit from having the ability to validate token interactions. | ||||||
|
||||||
From the **NFT space**, having royalties for tokens is currently a social contract where the publisher provides the royalty information while minting the tokens. The marketplaces can choose to honor this information and transfer part of the token sales towards the author. The problem is, this is not enforced and "black market" can thrive. As an author of an art NFT, I would like to benefit from any token transfers that involve smart contracts (a marketplace platform). | ||||||
|
||||||
From the **dapp-space**, consider validity and authorization tokens. For example, liquidity pools the liquidity provider token minting can be authorized by a validity token. This token _should_ be fully controlled by the liquidity pool smart contracts. If it were to leak out of the liquidity pool smart contract, it would give the ability to anyone to mint LP tokens and drain liquidity pools of the actual funds (as seen in the Minswap security vulnerability). IF the authorization token was itself controlled by a smart contract, even after it left the liquidity pool, the vulnerability could be avoided. | ||||||
|
||||||
Another use-case comes up around **bridged wrapped tokens**. Due to regulations, some publishers might require the ability to freeze or selectively allow specific flow directions for the token at times. These issues were raised also at the `interoperability working group`. Bridges bridging stables from Ethereum would like more control over the wrapped bridged tokens to be in-line with regulations and help with security. | ||||||
|
||||||
When it comes to regulations, also **native stable coins** are another case, where the publisher might want to control the ability to freeze or require authorization with interactions of their tokens. | ||||||
|
||||||
**TBD: add more examples** | ||||||
|
||||||
## Goals | ||||||
|
||||||
The first main goal is to **achieve a consensus** if having more control over the tokens is actually something that would be in-line with the values and direction of Cardano. There are multiple tradeoffs from the usability perspective. Having validated lifecycle for tokens would have an impact on all dapps and all wallets. | ||||||
|
||||||
The second main goal is **create a CIP** with the technical direction how smart tokens could function. Below is a potential direction and possible issues and roadblocks that would need to be addressed in the CIP. | ||||||
|
||||||
### Validating token transfers | ||||||
|
||||||
A direct way to support the use-cases above, would be to require a validator minting policy to be executed, whenever a token is included in a transaction. Currently plutus smart contract have 4 different usages: | ||||||
|
||||||
- SPEND - used by utxo validator scripts | ||||||
- MINT - used minting policy scripts | ||||||
- REWARD and CERTIFY - for staking use-cases | ||||||
|
||||||
UTxOs have basically 2 operations associated with them: | ||||||
|
||||||
- READ - by reference inputs | ||||||
- SPEND - whenever the utxo is an input | ||||||
|
||||||
From these only the SPEND is controlled by smart-contracts. Currently reference inputs cannot control the transactions they are in (which is a topic for another CPS). | ||||||
|
||||||
In comparison, the operations with tokens are 3 fold: | ||||||
|
||||||
- mint | ||||||
- burn | ||||||
- transfer | ||||||
|
||||||
The MINT plutus scripts control mint and burn, but not transfer. There are 2 possible directions how the transfer could be validated: | ||||||
|
||||||
1. Call the token policy with the `MINT`, also whenever a smart token is transferred. The minting policy then could decide based on the redeemer for how it should validate the transaction. | ||||||
2. Introduce a `TRANSFER` operation and a separate script type that would be used for this exact use-case. | ||||||
|
||||||
Both of these options would strain wallets and dapps, as they would need additional specific logic to handle smart tokens. The token validation scripts might not be generic enough and might be costly to do in every interaction. As the blockchain evolves, some interactions couldn't be predicted by the token and evolving the scripts would be problematic. | ||||||
|
||||||
A workaround might be, if some smart-token policies delegated the validation to some validations scripts. Unfortunately, without adding the ability to execute validation on referenced scripts, even this would require either: minting/forging a token in the transaction or spending an utxo with the desired validation logic. This approach doesn't seem scalable-enough, either. | ||||||
|
||||||
### Identifying smart tokens | ||||||
|
||||||
Drawing parallels with addresses, on cardano addresses have a 1 byte header identifying if they are a script address, pubkey address, reward address, etc. Unfortunately this is not the case with tokens currently. Policy IDs unfortunately do not have headers and it's assumed that it's always the hash of a native or plutus script. | ||||||
|
||||||
The identification is necessary, so that the nodes knows when it would require an additional transfer script to be present in the transaction. There might be 3 directions how "smart" or "validated" tokens could be identified in transactions: | ||||||
|
||||||
**1. segregate tokens** | ||||||
In this case, the validated and smart tokens could be separated in the transaction structures. In the CDDL: | ||||||
|
||||||
```cddl | ||||||
value = coin / [coin,multiasset<uint>] / [coin, multiasset<uint>, smartasset<uint>] | ||||||
mint = multiasset<int64> / [multiasset<uint>, smartasset<uint>] | ||||||
``` | ||||||
|
||||||
Alternatively the value could be "objectified" similar to babbage tx outputs: | ||||||
|
||||||
```cddl | ||||||
value = { | ||||||
0: coin, | ||||||
? 1: multiasset<uint>, | ||||||
? 2: smartasset<uint> | ||||||
} | ||||||
``` | ||||||
|
||||||
This explicit segregation would have the benefit that it could be easier backwards compatible. In this format also the policy ids could remain as `hash28` script hashes. | ||||||
|
||||||
**2. add policy headers** | ||||||
This would be a breaking change to the structures and policies. Basically it would be redefining the multiasset structure to: | ||||||
|
||||||
``` | ||||||
multiasset<a> = { * policy_id_with_header => { * asset_name => a } } | ||||||
; token identifier format: | ||||||
; [ 8 bit header | policy_id ]; | ||||||
; 0 - open transfer token | ||||||
; 1 - smart token | ||||||
policy_id_with_header = bytes | ||||||
policy_id = scripthash | ||||||
``` | ||||||
|
||||||
**3. policy id length** | ||||||
|
||||||
In this situation, similar to how value can be just a coin or an array, the `policy_id` could be redefiend to be: | ||||||
|
||||||
``` | ||||||
policy_id = scripthash / bytes ; as above [ 8 bit header | scripthash ] | ||||||
``` | ||||||
|
||||||
Both 2. and 3. are relatively error-prone, as many projects and tools assume 28byte policy IDs. Especially when encoding them as `subject` - for example for the offchain registry, there would be no way to tell, if the policyID is with the header or not. | ||||||
|
||||||
**TBD** add more considerations | ||||||
|
||||||
## Open Questions | ||||||
|
||||||
1. How to support wallets to start supporting validators? | ||||||
1. How would wallets know how to interact with these tokens? - smart contract registry? | ||||||
1. Is there a possibility to have a transition period, so users won't have their funds blocked until the wallets start supporting smart tokens? | ||||||
1. Can this be achieved without a hard fork? | ||||||
1. How to make validator scripts generic enough without impacting costs significantly? | ||||||
1. TBD |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.