Hey everyone,
we recently found ourselves working around some issues we already brought up in Earth Circle IP 1 - Circles 2.0 Architecture - #12 by ouie .
Instead of keep working around these issues with dirty tricks in the client software (which hurts compatibility) we decided to take the step and created a v2 Hub- and Token-contract.
We outline the goals and how we intend to achieve them below and kindly ask for feedback.
Goals
- Keep all existing trust relations working
- Remove the necessity to hold on to own tokens to be able to receive other tokens
- Allow accounts to use a trust list of a trusted entity to automatically accept tokens listed there (follow trust)
- Remove the possibility to keep tokens alive from âoutsideâ
- Have a shorter inflation period
- Have a well specified upgrade path for future versions
Organizations:
Besides not being a hard goal it turned out that no changes are required for organization wallets.
Upgrade process
Exchanging v1- for v2-Tokens
Everyone who holds v1 Tokens can exchange them for v2 Tokens as soon as the token owner migrated to the new version.
To do that, each v1 token holder sends their holdings to the hub v2 contract and then mints the same amount of v2 tokens.
This process should be automated by the client software so that whenever a user upgraded to v2 all holders of tokens of this user will exchange their tokens on the next usage of the client.
Persons
New signup
All new users have to signup at the v1 hub just as they would do now. Additionally, they have to call the v2 hubâs âmigrateâ function.
Migration from v1
If a user already got a circles safe and receives UBI then this person needs to deactivate their v1 token before the upgrade.
The client software should make sure that the outstanding UBI is minted a last time before the token is de-activated.
When the token was deactivated the user can call the âmigrateâ method on the v2 hub and then exchange all of their own tokens.
Organizations
Since the orga accounts didnât suffer from the receive-limitations in the first place, nothing changed.
However, an organization still can decide to register a Verifier which then has the same effect as on user accounts.
Implementation
We copied the Hub- and Token.sol contracts and modified them as described below. The new files have the âv2â appendix in their name.
Additionally, we added a new âVerifierâ interface which can be used to implement the âfollow trustâ functionality.
HubV2.sol
This is a copy of Hub.sol where all parts regarding trust have been removed.
It references the v1 Hub which is used to check trust limits and if a user/orga is already signed up.
We made some changes to existing functions and added some new:
checkSendLimit()
This method now treats trust as binary (either youâre trusted or youâre not).
We also removed the restriction which required users to hold own tokens in order to be able to receive other tokens.
The effect is that as long as you trust someone that person will be able to send (all) their tokens to you.
Also, we added a way to delegate the send-limit calculation to a different contract.
We use this to implement the âfollow trustâ which is explained below.
useVerifier()
Users can set a custom verifier if they like to do so. Verifiers are external contracts with the same interface as the âcheckSendLimitâ function (see VerifierI.sol).
The verifier is a fallback thatâs used when no trust relation exists between the sender and receiver (or the trust was set to zero).
The main use case we intended for it is the âfollow trustâ functionality where a user can decide to automatically accept all tokens that are accepted by another trusted entity.
migrate()
Since all users need to signup at the v1 Hub first they always âmigrateâ to the new version.
The method checks if the usersâ v1 Token is stopped (doesnât mint new UBI) and only then deploys and registers the new token.
mint()
Users who hold v1 tokens must have a way to exchange them for v2 tokens. This is what this method is for.
It uses the same principle as the group tokens but always burns the received v1 tokens.
Itâs used as following:
- [if token owner] Mint all outstanding v1 UBI
- Transfer v1 tokens to the v2 Hub
- Call mint() to get the same amount of v2 tokens back
! Steps two and three have to be completed in the same transaction otherwise someone else could mint instead of the original owner.
TokenV2.sol
The v1 token and v2 token are identical except for one additional method on the v2 Token.
Also, only the token owner can call the update-method now to prevent other people from keeping tokens âaliveâ.
update()
Same as in the v1 token except that it can now be called only by the token owner.
migrateMint()
This method can only be called from the v2 hub.
It is used to mint new v2 tokens for v1 token holders via the HubV2âs mint() function.
Source code
You can find the new contracts here: https://github.com/jaensen/circles-contracts/tree/fork-1
Theyâre forked from Alexâs fork which already includes the GroupCurrency contracts.
New files are:
as well as the corresponding interfaces:
Future updates
We think that future updates can be handled in the same way as this proposed update.