Circles IP 1 - Circles 2.0 Architecture

Regarding our upcoming Munich Pilot of Circlesland, we stumbled upon a few challenges in the core HUB and TOKEN contracts and would like to start working towards a new Circles 2.0 contract update.

We should also as well split the minting and transfer related topics (HUB 2.0 contract) from the web-of-trust (TRUST 2.0. contract) topics.

The challenges we encountered are the following:

1a) transferThrough is too restrictive and needs to be fixed in its limitation.

During optimizing pathfinder related challenges, we found out the following problematic behavior in the transferThrough() method. Let’s imagine this. Alice is joining at day 1, Bob is joining at day 10. Alice has f.e. collected 1000 A-Circles until then, Bob has only collected 100 B-Circles so far. When Bob now trusts Alice 100%, we would think Alice should be able to send all her 1000 A-Circles to Bob via the transferThrough() method, but Alice can send only 100 Alice Circles, since inside the checkSendLimit() method the current calculation of the “max” value, depends on Bob’s own holdings of his own B-Circles.
The result of this behavior is that, in case Alice would have send all here A-Circles to someone directly, she wouldn’t be able to receive any more Circles at all transitively, but her own personal Circles.

If you decompose this line of code: you’ll find that the transferrable amount depends on the holdings of the receiver’s own tokens:

userToToken[dest].balanceOf(dest) // Dest's balance of his/her own tokens 
.mul(limits[dest][tokenOwner]) // multiplied by Dest's limit of the tokens in transfer 
.div(oneHundred) // divided by 100

1b) Binary trust only
transferThrough should make trust binary, ether there is trust or not (remove the % trust limits).

2) Remove the 90 days deadman switch

As you all know, many users experience the problem of running into the 90 days deadman switch. We propose to completely remove this.

3) Shorter inflation rate intervals
Currently the 7% yearly inflation rate is calculated and updated only once per year, creating quite large jumps from one time interval to another. We propose to split this over the course of the year and do weekly update calculations.

4) Compatibility with group circle contracts
Regarding the first prototypes of Alex’s group circles, we found out that it is not possible to transitively change individual circles into group circles, because of some restrictions of the original HUB contract. This has been fixed in a fork by Alex and should be integrated into the 2.0 version.

5) Migrating balances
Regarding migrating old v1 balances into the version 2, we suggest adding to the signup method a second migration method, which allows existing v1 users to signup with their original v1 safe. In this process a new token will be created and all balances will be copied from the V1 Token to the the new V2 token. For this process, we can define a transition period of f.e. 3-6 months, where the migrate method is active. After block n, it should revert when called. Migration should be only possible to call once for each token migration.

6) Migrating trust relation (re-running them on the new trust contract)
Regarding the process of updating existing trust relations from the HUB 1.0 to the TRUST 2.0 contract, we propose a script on the client, which is re-running individually all the personal trust relations, after a client is upgrading a token from v1 to v2.

7) Add a follow trust method to the TRUST 2.0 contract
Any user or orga should be able to follow trust any other safe. This can be documented via the blockchain events startFollowTrust and stopFollowTrust. The transferThrough needs to pick up those relations as well.

Other open Topics to be discussed:

  • Do we need or miss any other indexing events that should be added?

Thanks for starting this discussion @samuelandert

I am not really in favour of simply removing it.
A reminder why we added it in the first place:
if a user looses access to a Safe they can only create a new Circles account. People would be required to trust the new account - however they should still trust the old one as otherwise those tokens would suddently become unspendable. This however creates the problem that you are now trusting 2 accounts of the same person that can still both produce UBI/Circles. So unless we have a solution to account recovery IMO we need the dead man switch. We should however change it in a way that other accounts can not delay it. We could also think about ways to make it easier to reactivate an account.


Thanks @samuelandert .

I agree with point 1 a lot. We see from experiences in Berlin that many people have troubles sending bigger amounts to others who have less, among other issues. There’s still a lot of research to be done on how to improve transitive transactions in general and think this is a good improvement of it. It should definitely smooth out exchange between people. One small note: I would not refer to it as “Binary Trust” as it can confuse some people into thinking that binary trust means you can only send max 50% but as Trust and Don’t Trust and communicate that if you trust someone, it means you are willing to accept 100% of their circles credits.

About point 2: I agree with Martin that it may not be wise to simply remove it but create a social recovery mechanism that makes this a seamless process. I wonder if it is possible to link sets of public keys to one user, where only keys that went inactive can be connected and “embedded” to the person’s new crc basic income account? I know @ Adz has been doing some work around these types of implementations so it may be worth checking with the #bitspossessed .

The inflation calculation rate sounds reasonable.

From point 4 onwards I think requires a deeper discussion. What exactly was the issue Alex encountered with transitive transactions and group currencies ? - It’s a design question to define who decides which individual currencies can be “merged” into a group currency. I think it’s important to think of the trade-offs of the different ways in which this can happen. For example, from a contract level it should be possible to let people choose /set the limits to the amount(%) of CRC units they wish to be turned into group CRC.

From a research side it would be very interesting to model how group currencies could run on specific clusters, specially as we experiment more with dapp nodes. Do you think this is feasible to test out?

Thanks a lot for this issue compilation.

For the deadman switch, would a feasible solution be to have “social recovery” by directly trusted users? That would be easy to implement and makes sense until a more sophisticated social recovery is specified. So any directly trusted user could reactivate a deactivated account.

For the compatibility with Group Currencies, I wrote more about the changes here (Suggestion for group currencies - #5 by alculexum) - the change of the Hub.sol contract was to modify/loosen the validateTransferThrough (circles-contracts/OrgaHub.sol at master · ice09/circles-contracts · GitHub) but that might be wrong for other reasons, so feedback would be great.

This shows how the process flow is in the sample: circles-contracts/ at master · ice09/circles-contracts · GitHub

I think the deadman switch problematic is a social problem and should be pushed to the edge of trusted peers.

@alculexum I like your idea, but how about we do it the other way around. An account stays active until a specified amount of trusted people is deactivating it. (we can work here with the variables of min f.e. 3, % f.e. 20% of my trusted friends, and max, f.e. 50 trusted friends and we might add additionally to this a default timeout deadman switch parameter of 1 year instead of 90 days.

Let’s try to split the deadman switch challenge up into the following 4 cases:

A user got hacked, but is still alive:
In this case, the user would tell his peers, to deactivate the original account and retrust a newly signed up successor user. The question here remains, if we should encourage or even enforce contract wise, to remove trust to those circles, making the hack a collateral damage for everyone.

A user lost his access key:
In this case, the user would tell his peers, to deactivate the original account and retrust the newly signed up successor user. When the user finds his key again, he could still transfer his old assets to his new safe, but can not mint ubi on the old account anymore.

A user died:
In this case, the trusted users would claim, that a person died and once the predefined threshold of claims is reached, the account gets deactivated and can not mint ubi anymore.

A user got mobbed by his peers:
In this case, the user would have been deactivated falsely by his trusted peers. His only option is to -re-start completely a fresh and get re-trusted by a different community of friends.

Another topic is about updating and changing parameters in the new CirclesHUB 2.0 contract.
I am currently researching the capabilities of the 1hive garden DAO’s interface. They have a very genius combination of conviction voting (see: Gardens Launch Party 🌻🎊 - YouTube) and decision voting.
There it would be theoretically possible to make some parameters of the HUB contract updatable, when we give the voting app contract of 1hive the permission to execute update calls on the CirclesHUB 2.0 contract.

Sounds complicated to me, especially the last case will happen a lot I think and gives people direct power of wealth of other people, that doesn’t feel good to me.

About the other way around, why wouldn’t it work? I don’t see misuse here, if I want to keep my account alive I do. If I have myself as a false trust I can reactivate my account, but this I could do anyways. Also there is no misuse possible by others as they can just reactivate. Just in case of user died/lost keys someone could still use the old CRC, but that would vanish as the user would have to re-trust everyone and those would then have to untrust the first account. This could probably be supported by a decent UI/UX.

I think it would strengthen the trust network this way around. The last case can happen anyhow via untrusting, so this is a generell social dilemma of the web-of-trust itself.
What you can always do to intervene misuse is to put a timeout veto in-between deactivating. So, when the user still has access he can stop the deactivation process for example for a period of 1 week.

Yes, but untrusting seems more an individual decision to me, the deactivation is more a “mobbing attack” then. But a veto could be useful anyways, with this also other mechanisms for deactivation could be possible (like I name someone who can deactivate me, but I can also veto if that was misused).

Maybe we should play with the variables here, as you said make them more strict and explicit. I can name f.e. 3 out 5 trusted persons, which can do this for me, including a timeout period. Same goes later for proper social recovery.

I have made a GitHub fork of the contracts and added all the topics into separate issues:

Notes from the Bitspossessed dev team (working for

(We met with the lands team 2022-02-01 and discussed the changes together but posting a summary of our thoughts here too for references)

  1. transferThrough is too restrictive and needs to be fixed in its limitation.
  • In favour of deleting the whole functionality of sendLimits and trustLimits, and implementing it at the app level (through the pathfinder)
  • We can try to use pathfinder to improve the health of the network and compensate for some problems we tried to solve with trust limits before
  • Keep binary trust (0% vs 100%), and not having the sendLimit in the hubTransfers (= you value someone’s else as much as yours)
  • Use to educate the users better in what trust other tokens means, and improve the understanding that the user is actually holding its own tokens and other people tokens. When you trust someone it means that you trust your token as much as your own.
  • Idea: include notification system if trust has repeatedly been revoked to a contact, combined with other trust guiding tools
  1. Liveness trigger / deadman switch
  • Change the UBItrigger / livelinessTrigger so that it can only be called by the owner of the safe that is connected to the token
    • This requires a change in the contracts - checking that the sender in the transaction is the owner address of that account.
  • If this is not feasible:
    • We oppose completely removing it but want to extend it to years
    • We see the issue in notifying the user about logging in to keep the account alive without being logged in to get notified. (Email is the only solution we see)
    • One reason for keeping it is to avoid money laundering through old accounts since a non-owner can keep a UBI-collecting account active and use the tokens transitively to use their own tokens. No one can revoke trust in that person if the owner is gone and not logging in.
    • We thought about having trust reviewing recommendations for inactive in wallets that are unrelated to smart contracts but then the old tokens of a dead account becomes useless and that’s not really the goal
    • If we keep it we would like it to be called the liveliness trigger
    • Option to have a simpler migration process, replacing the token but keeping the same safe if your account has been locked by the switch
    • Until we communicate it well and have a recovery process we can keep the account alive with scripts
  1. Shorter inflation rate intervals
  • There is not a technical challenge to this. We don’t have a strong opinion for or against it.
  • In order to have a decision on this, maybe the business/user side should be included.
  • Propose: change the name “inflation” because there are many different concepts that we incorrectly call the same thing:
    • how the total amount of circles grows over time
    • the change in how people personally value their circles and prices in CRC of goods and services changes in personal transactions
    • how the conversion rate to euros changes over time
    • how much the UBI is raised yearly
  • We call all of these things “inflation” and they are not the same
  • What is the actual problem we are trying to tackle? For example, in other situations like salary/rent, this “jump” happens. Why is that a problem within circles? We could see it as equivalent to a yearly salary increase. We don’t mind changing this though. But not obvious that it is more intuitive for users.
  1. Compatibility with group circle contracts
    The proposal from land → Suggestion for group currencies
    We definitely think we have to make contracts compatible with group currencies IF we decide we want to introduce them.
    It is important to recognize that group currencies and these changes would allow people to convert your circles’ tokens into their group currency without your consent by them trusting you and holding some of your circles. This might be undesirable as the user could end up with fewer circles to access in the system if they do not trust that group currency.
    Or are we missing something? We will take a closer look at the group currencies soon.

  2. and 6) How we think the migration process will look like:

  • Once the client is implemented for the new contracts version, then any user that logins will trigger the migration automatically and start living in the new system (hub, trust network… etc)
  • What are the benefits of separating the Hub on two smart contracts
  • Why do we have a time window for the users to do the migrations?
    (We prioritized discussing what to put into the contracts over how to migrate at this point in the process)
  1. Add a follow trust method to the TRUST 2.0 contract
    A more technical and deep conversation is needed here, but no opposition from our side
  • How have they thought about keeping the trust level between users?
  • How to represent it in the trust graph?
  1. DAO that can govern the hub
    Earth Circle IP 1 - Circles 2.0 Contracts - #6 by samuelandert
    Let’s talk about this at the All-Stars meeting, with all parties involved.

Proposal from

  1. Recovery mechanism idea (for locked accounts?)
    We could unassign the token-user relationship (in the hub contract). The migration process could involve keeping the same account and just assigning a different token. No need to create another account and maybe add a restriction that each user has just one token that is issued at the time does this need update in the Hub contract?

General Questions that we have

  • How will we do the design phase and deployment of the new contracts?
  • How do we involve the current users to understand the changes of the contracts and the choices they have in the migration?
  • How is the review going to be done?

Following our meeting, we saw the path forward as:

  • team will take responsibility for preparing architectural diagrams
  • we will all continue the discussion with martin next week at FullNode and include other stakeholders such as the coop and product owner of

Let me know if something is too unclear. It is a brief summary of all the things we internally discussed so far.


Thanks for all the input. Since this topic becomes cluttered with too many different challenges to be tackled, I am pulling them each out into separate proposals to be discussed and defined in more detail.

I would like to continue in this thread the core contract architecture discussions, around modularization and clarification of fixed non-changeable and flexible upgradeable parameters via opt-in extensions.

So far we agreed during our Berlin-Workshop on the following:

  1. The user become their own Token owners (unlike the existing design, where one master hub controls everything), which they can then register at different default and custom extensions by giving allowances to their token holdings.

  2. The very Circles Core minting logic stays fixed at 7% inflation / demurrage per year and is a non-changeable parameter global agreed by all Circles Teams. All individual owned Circles derive from this contract.

  3. The Web-Of-Trust Contract becomes binary and defaults to 100%. If TransitiveTransfer methods would like to extend their own rules on limits, they can introduce them with custom extensions.

  1. Are there examples for these extensions? I am not sure how compliancy between the extensions can be ensured on a multiple-hop-transfer.
  2. So if minting stays fixed, what would be dynamic on those Tokens (similar to 1.)?
  3. Just to be sure that means that one “wrong” trust might cause a total loss of my funds?
  1. I think this is matter of interfaces. But there doesn’t explicitly needs to be interoperability between two different extensions. There for sure can be two isolated communities, using their same circles, but different transferMethods. One further improvement we might gain from this kind of architecture is upgradeability as well, without needing hard forks anymore.

  2. There won’t be any dynamic rules in the CoreToken contract. Regarding 1): in one specific transfer through implementation there can be a combination of fixed and or dynamic parameters set. Just depending on the community implementing their own set of rules. Those contracts can become quite complex, or stay as simple as our current transferThrough method.

  3. Only for the amount of FakeCircles you are trusting, not anything more.

We in the Bitspossessed, working on, have some updates on our opinions on some of the contents of Circles 2.0 proposal.
The following is based on conversations within the Bitspossessed, including conversations with Andreas and Sarah (the developers of the first circles system) and with Julio from the Circles Coop.

  • Trust limits:

    • Absolute in favour of removing trust limits functionality.
    • The new HUB2.0 contract will have new implementations of transferThrough() and checkSendLimit(), which should ignore trust limits (and only interpret binary trust).
  • Separate the Hub into 2 contracts:

    • We are in favor of separating Trust functionality in a different contract (called TRUST), although we don’t see it as necessary.
    • The TRUST contract should in that case be very simple.
    • We think that it might not be necessary to create a new TRUST2.0 contract since there is the old HUB that already stores all the trust relationships and trust() method.
      • If trust rules (besides trust limits) are not going to change, we think a new contract is not needed. In the transfer contract we can interpret any trust limit different than 0 as 100%.
    • Or if we have a new TRUST contract, there are 2 options:
      1. Migrate trusts from the old HUB (HUB1.0) to the new TRUST or HUB2.0 contract
      2. Keeping trust in HUB1.0
        • in HUB2.0 there would be new implementation signup() method, and new userToToken and tokenToUser mappings
        • in TRUST contract we would just call trust() and checkTrust() in HUB1.0 with the trust limit = 100
    • We have to discuss further if we prefer migrating trusts, or just read /write in HUB1.0. But we are inclined to not add extra unnecessary steps that may lead to errors or bugs in the migration of the Web of Trust.
  • Dead-man-switch/liveness trigger:

    • In favor of making the update() method private so that only the token owner can call it.
    • Once the update method is private the account is automatically not minting until the user calls update() again and if that is indefinite it is essentially working like the Dead-man-switch/Liveness trigger, in that it stops UBI minting.
    • Thus we are in favor of removing it all together because there’s no longer a use case.
  • Inflation period:

    • We are ok with changing it or not, but we don’t feel it is as important and we would deprioritize its discussion and implementation.
  • FollowTrust:

    • The implementation of this creates a lot of complexity in asking “does this safe trust this token?”
    • Circles is already complex in terms of transitive transfer queries and this only makes it worse and the system would become more thorny.
    • It is not necessary to implement this on the contract level. A “copy” trust can easily be implemented on top of contract level with the behaviour: you trust who the other user trusts at a given point of time instead of subscribing to someone elses trust which is also vulnerable in terms of network dynamics, giving a lot of power to some users.

As discussed in the All Stars meeting today between the Circles Coop, Circles Land and Bitspossessed, here is the suggested Roadmap for making Circles 2.0 reality

Link to color coded pdf version:

Non color coded version:

  • discussion: on what to include (bits and land)

  • discussion: on what to include (bits internal including Sarah Friend)


  • post: update from bits in forum on 2.0 (bits)

  • admin: set up a shared place for documenting agreements and decisions (bits)

  • discussion: group currency mechanics expectation (coop and bits)

  • implement: PR for removal of dead man’s switch and private update method (bits)

  • post: mapping out different balance migration option (bits)

  • post: mapping out different balance migration option (bits)

  • discussion: conversation with Ben about contract updates (bits and land)


  • discussion: internal technical overview for group currencies (bits internal including Sarah Friend)

  • post: sharing group currency input (bits)

  • discussion: migration options and user communication (bits and coop)

  • discussion: migration of balances and trust (bits and land)

  • implement: PR for removal of trust limits (bits or land)

  • implement: [optional in opinion of bits] PR for shorter inflation rate intervals (land)

- [ ] implement: follow trust


  • decision: review / accept contract updates (bits, land)

  • decision: decide what migration path to choose for balances (bits, land, coop)

  • decision: decide what migration path to choose for trust (bits, land, coop)

  • discussion: come up with a technical migration plan and time-line (bits, land)

  • decision: technical migration details (bits and land)


  • discussion: group currency input (bits, land, coop)

  • implement: group currency updates (?)

  • implement: prepare migration (needs to be broken down) (bits and land)


  • implement: prepare migration

  • implement: group currency updates (?)


  • implement: prepare migration


  • implement: MIGRATION takes place
1 Like

Thanks for the timeline! If there you are interested I am happy to participate in the discussions about contract updates and group currency (tech) things, just ping me in Telegram.

1 Like