-
Notifications
You must be signed in to change notification settings - Fork 18
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
KIP-0019: coin-v6 and fungible-v3 #43
base: master
Are you sure you want to change the base?
Changes from all commits
e91886c
4d0cff8
b590ada
e651a76
a6d47f0
b49dbbc
7310398
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||
---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,93 @@ | ||||||||
--- | ||||||||
KIP: 0019 | ||||||||
Title: Coin-v6 and fungible-v3 | ||||||||
Author: Robert Soeldner (robert@kadena.io) | ||||||||
Status: Draft | ||||||||
Type: Standard | ||||||||
Category: | ||||||||
Created: 2023-05-02 | ||||||||
--- | ||||||||
|
||||||||
## Abstract | ||||||||
|
||||||||
The next iteration of the coin contract proposes three main changes to enhance | ||||||||
the _maintainability_ and _security_ of the contract. | ||||||||
|
||||||||
Firstly, the `rotate` function, which is responsible rotating an account guard in a contract that implements the `fungible-v2` interface, | ||||||||
will be removed. In the case of fungible tokens that also implement the `fungible-xchain` interface, this will result "correct by construction" cross-chain transactions by avoiding the risk of locking funds sent to the receiving account. | ||||||||
|
||||||||
Secondly, the constants and some functions within the contracts will be reorganized to | ||||||||
increase maintainability (see [Rationale](#rationale)). This is intended to make the codebase more structured and easier | ||||||||
to maintain, reducing the chances of errors and improving the overall quality of the contract. | ||||||||
|
||||||||
Finally, verification related code of the coin contract will be modified to allow for | ||||||||
formal verification. This will enable rigorous proves of the contract's code to ensure | ||||||||
its correctness and reliability. By incorporating these changes, the new iteration of the | ||||||||
coin contract aims to provide a more secure and efficient platform for the exchange of | ||||||||
cryptocurrencies. | ||||||||
|
||||||||
## Motivation | ||||||||
|
||||||||
The presence of the `rotate` function in the current implementation of the contract undermines the | ||||||||
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. I highly recommend not to remove Kadena's chain has the unique property that our address is not tied to the keypair (or keyset in our case). So being able to rotate is a huge benefit. Allowing users to keep the same address, but changing their keyset to sign with. 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. I agree with @EnoF here that rotation is unique to the Pact language in that you can rotate the underlying governance of a particular account in the coin contract, but there is a distinction here that needs to be made: The removal of So the question here that needs to be answered is this: should guards be arbitrarily rotatable, or should rotation be restricted to when it makes sense? 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. As an addendum: also, keep in mind that 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. If I understood this correctly, this means that users should be encouraged to create accounts like:
And then they will be able to rotate said keyset like:
Which then makes the 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. @EnoF close! You understood correctly, but for the interest of the KIP process, there are some details to iron out. Namely, let's look at the call you've written: (coin.create-account "k:mykey" (keyset-ref-guard "r:my-keyset")) This would not be correct because the account name for an (coin.create-account
(create-principal (keyset-ref-guard "<some keyset name>"))
(keyset-ref-guard "<some keyset name>")) The call to (define-keyset "<some keyset name>" (read-keyset 'new-keyset))
Yes, exactly. If the keyset is defined on the target chain, then the keys may rotate underneath it, but the keyset name reference is a static string, which does not change. We have documentation for this in the principal account section of the readthedocs, but I'll work on writing up a concrete tutorial/introduction and tie it in with this proposal to ease everyone's minds. 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. @emilypi I tried creating an account using a
In the hopes that the keyset would be guarded like a Then I thought maybe I could use
This should prevent your keyset ref from being squatted, but it is quite a bit of boilerplate. I think it would be a good compromise between UX/DX and security if we would 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. @EnoF I see your point using For later reference, repl script using the KIP-0019 infrastructure showing key-rotation.
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. Note that So to prevent this from happening, we need to have |
||||||||
integrity of cross-chain transfers. Specifically, executing the rotate function before the | ||||||||
completion of a cross-chain transfer can result in the locking of funds. | ||||||||
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. It may be nice here to explain why the funds would be locked. i.e. "the cross chain transfer is permanently tied to a given guard, and rotating the keys of the coin contract makes that saved guard invalid." It may also be good here to explain the recommended workaround: migrating to keyset references before the update to coin contract. |
||||||||
|
||||||||
The removal of `rotate` will _not_ remove the ability for accounts to have Rotatableg governance. | ||||||||
This is a misconception, it will remove the ability to arbitrarily rotate account governance from | ||||||||
any guard to any guard. However, the feature still remains that if one uses a keyset reference and | ||||||||
stores a `keyset-ref-guard`, then keys are rotateable via `define-keyset`. | ||||||||
Since keysets are namespaced, users may unambiguously name and store guards they expect to rotate, | ||||||||
and the principal account type associated with them is the `r:` protocol, so they may be stored | ||||||||
under unique account addresses as well. | ||||||||
|
||||||||
Moreover, the utilization of our formal verification system can significantly enhance the | ||||||||
security of the contract. Therefore, necessary changes to allow the verification of the contract | ||||||||
are introduced. | ||||||||
|
||||||||
## Timeline | ||||||||
The KIP process has a time constraint of *1.5 months*, which will end on June 30th AoE, | ||||||||
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. We extended the time constraint until mid July:
Suggested change
|
||||||||
during which participants are expected to share their feedback. | ||||||||
|
||||||||
| Date | Event | | ||||||||
|------------|-------------------------------- | | ||||||||
| 2023-05-02 | Publication of initial document | | ||||||||
| 2023-06-30 | Deadline of KIP-0019 | | ||||||||
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
|
||||||||
|
||||||||
|
||||||||
## Rationale | ||||||||
Changes within `fungible-v3.pact`: | ||||||||
* Model annotation for the schema `account-details`: Add new invariant expressing positive | ||||||||
balance (`>= balance 0.0`). | ||||||||
* Model annotation for defun `get-balance`: Add new property that `!= account ""` | ||||||||
and `>= result 0.0`. | ||||||||
* Model annotation for defun `details`: Add property that the account is not empty `!= account ""`. | ||||||||
* Model annotation for defun `enforce-unit`: Add property that the amount is | ||||||||
not negative `>= amount 0.0`. | ||||||||
* Model annotation for defun `create-account`: Add property that the account is not | ||||||||
empty `!= account ""`. | ||||||||
|
||||||||
Changes within `coin-v6.pact`: | ||||||||
* Change the `fungible-v2` interface to `fungible-v3`. | ||||||||
* Bless old coin contract (coin v5). | ||||||||
* Move constants (`COIN_CHARSET`, `MINIMUM_PRECISION`, `MINIMUM_ACCOUNT_LENGTH`, | ||||||||
`MAXIMUM_ACCOUNT_LENGTH`, and `VALID_CHAIN_IDS`) to a different section. | ||||||||
* Move utility functions (`enforce-unit`, and `validate-account`) to a different section. | ||||||||
* Replace `enforce (!= sender ...` by `validate-account` in defun `DEBIT` and `CREDIT`. | ||||||||
* Remove defcap `ROTATE` | ||||||||
* Add additional `enforce` to express that gas consumtion must be greater than | ||||||||
zero (`enforce (> total 0.0)`) within defun `redeem-gas`. | ||||||||
* Enforce the refund unit `enforce-unit refund` within defun `redeem-gas`. | ||||||||
* Add `validate-account` to defun `get-balance`. | ||||||||
* Add `validate-account` to defun `details`. | ||||||||
* Within `fund-tx` enforce a valid miner within the `defpact` step. | ||||||||
* Add invariant `>= balance 0.0` for the `allocation-schema`. | ||||||||
|
||||||||
## Backwards Compatibility | ||||||||
|
||||||||
N/A | ||||||||
|
||||||||
## Specification | ||||||||
|
||||||||
* [coin-v6.pact](kip-0019/coin-v6.pact) | ||||||||
* [coin-v6.repl](kip-0019/coin-v6.repl) | ||||||||
* [fungible-v3.pact](fungible-v3.pact) |
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.
you don't need to rotate to get funds stuck in cross chain. Only specifying the wrong receiver keyset is enough. You can specify any arbitrary keyset (correct me if wrong), the sending chain can't check if the account exists on the receiving chain and with which keyset it was created. getting stuck doing rotate during crosschain is a special case, i'm not sure that happens in the real world..
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.
rotate saved me a few times from such errors. if I specified the wrong keyset during cross chain but still a keyset I have control of. It would fail on the second part but could fix it by rotating the receiver to the matching key when finding out the mistake. Then attempt the continuation part again.
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.
the only way that removing rotate can contribute to eliminating the risk on stuck cross-chain is if you are going to disable cross-chain on non-principal -classic arbitrary- account names and validate-principal for the principal account name in the first initial step of the defpact for cross-chain. Sorry if that is already implied in the KIP here, I might have missed it then..
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.
Just to be clear here, we're not trying to make the blockchain your mother. If you type in the wrong receiver or their governance details, you will lose your funds unless you have a means of recovery available, like you own the keys and you simply sent to the wrong one of your many accounts. The problems you describe are endemic of any call to a transfer in which you fat finger details. We cannot and do not want to guard you against unforced errors like what you describe - you must take reasonable care. However, we can protect against nondeterministic problems such as the person you're sending to being able to rotate in between your crosschain transfers.
And yes, there is another KIP out to enforce that
create-account
from the nextcoin
version onward only works for principal account creation.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.
@trendzetter I'm very happy you brought up this point and started interacting in this discussion. As Emily said, we currently do not protect against typing a wrong receiver, but this KIP aims to increase the security. The additional model annotations will provide more secure properties and trust into the contract.
(I'm on my way creating the new KIP for the
create-account
restriction.)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.
To add color to @rsoeldner - no blockchain does protect you against these things. There's always the possibility that a) you fail to transfer because you've used
coin.transfer
, or b) you fat fingered acoin.transfer-create
, which is not considerd a "safe" transfer for this exact reason. We offer remedies for this:The
/local
endpoint, which can simulate transactions before you execute the on-chain transaction. Wallets are always encouraged to use this to confirm details for both the data query side (receiver exists, guards match etc.), and the simulated transaction execution side in which the transaction is run against the most recent blockchain state. Automating this workflow is standard.The signing api (under construction)
I can only see people running into the problem of fat-fingering if they either execute their own queries and fail to check their details beforehand, or if they're using transfer scripts that fail to do so. To be clear: I agree that your problems are indeed real UX problems, but it's something wallets and dApp developers need to attack using the existing tools. Deferring to the base protocol to enforce them is overly-paternal IMO, and a divergence in the nature of the blockchain.
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.
I think there is in itself nothing wrong with protecting people from destroying their coins if it doesn't have an unacceptable cost. I was triggered into responding thinking that removing rotate in itself wouldn't improve the overall situation much, not nostalgia for rotate or dangerous legacy style accounts (yes it exists!)
But given this is part of a salami with more slices I think it might be feasible and desirable to make it impossible to destroy coins, and make it extremely unlikely you accidentally send the coins to a random other valid account (valid principal accounts are less likely to be found by accident). So I am looking forward to the changes on create-account (transfer-create&transfer-crosschain?). Old style accounts can then be safely used to migrate out through simple transfer to a principal account name.