Skip to content
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

[Community Ownership] deploy Owner Token through Deployer contract #11954

Closed
2 tasks
Tracked by #11370
osmaczko opened this issue Aug 21, 2023 · 25 comments · Fixed by status-im/status-go#3970 or #12300
Closed
2 tasks
Tracked by #11370

[Community Ownership] deploy Owner Token through Deployer contract #11954

osmaczko opened this issue Aug 21, 2023 · 25 comments · Fixed by status-im/status-go#3970 or #12300
Assignees
Labels
backend-team E:Desktop Tokenized Ownership Implementation of the tokenization of community ownership and transfer of said ownership feature
Milestone

Comments

@osmaczko
Copy link
Contributor

osmaczko commented Aug 21, 2023

The Owner Token must be deployed by the community address. This is to prevent malicious owners from deploying multiple Owner Tokens with potentially harmful intentions in the future.

This will effectively bind the contract to the community. Clients will verify the owner token contract address by reviewing the transaction history of the community address; only the first deployment is valid.

Edit: Use Deployer contract method described in comments below


Ignore this if the way above works

To facilitate the deployment by the community address, it needs sufficient funds to cover the gas fees. Therefore, the procedure should be:

  1. The owner transfers ETH to the community address to cover gas fees.
  2. The community address deploys the Owner Token contract.
  3. The community address refunds any remaining ETH to the owner.
  4. The owner sets signerPublicKey with its chat PublicKey.

Acceptance criteria:

  • Owner Token contract is deployed by community address
  • Owner Token's signerPublicKey property points to Owner's chat PublicKey

Implementation:

Ideally, these four steps should be executed in a single atomic transaction. This ensures that either all operations succeed, or none are executed, preventing any intermediate and undesirable state. If executing all in one transaction is not feasible, a robust recovery/retry mechanism should be implemented in the event that any of the transactions fail.

Considerations:

Extend Owner Token's constructor with signerPublicKey parameter to avoid step 4.

@osmaczko osmaczko changed the title deploy Owner Token through community address [Community Ownership] deploy Owner Token through community address Aug 21, 2023
@osmaczko osmaczko added E:Desktop Tokenized Ownership Implementation of the tokenization of community ownership and transfer of said ownership feature labels Aug 21, 2023
@osmaczko osmaczko added this to the 0.15 milestone Aug 21, 2023
@jrainville
Copy link
Member

Lookup signing a transaction by the community and then send the transaction with the user wallet (to pay the gas)

@jrainville
Copy link
Member

It seems like if we go the route I suggested, it might make it so that the account paying the fee will still be the one marked as signer, which is not what we want, we need to find another solution

@jrainville
Copy link
Member

One option I discussed with @endulab is to have a "util/singleton" contract called CommunityOwnerTokenDeployer, that would basically be a factory that would be deployed once, and we'd "hardcode" the address in status-go.

Then, when deploying the Owner and TokenMaster tokens, we'd use this CommunityOwnerTokenDeployer contract instead and it would then store the addresses of the deployed token contracts in a map using the communityID.

Afterwards, when a user gets sent an OwnerToken, they can ask the CommunityOwnerTokenDeployer if that token is indeed the right one for the community. The contract will check its map and send the address of the deployed token.

We need to check with contract experts to know if this option is doable.

I do think it solves the problem of a malicious owner trying to scam with a fake owner token.

We then need to check if there are legal issues with deploying that type of CommunityOwnerTokenDeployer contract.

@osmaczko
Copy link
Contributor Author

I do think it solves the problem of a malicious owner trying to scam with a fake owner token.

If the CommunityOwnerTokenDeployer allows only for one contract per community then I think it solves it, no 🤔 ?

@jrainville
Copy link
Member

I do think it solves the problem of a malicious owner trying to scam with a fake owner token.

If the CommunityOwnerTokenDeployer allows only for one contract per community then I think it solves it, no 🤔 ?

Yep! (that's what I'm saying in the quoted text, maybe you misread)

@osmaczko
Copy link
Contributor Author

I do think it solves the problem of a malicious owner trying to scam with a fake owner token.

If the CommunityOwnerTokenDeployer allows only for one contract per community then I think it solves it, no 🤔 ?

Yep! (that's what I'm saying in the quoted text, maybe you misread)

Lol, I read "I don't think..", sorry 😅

@endulab
Copy link
Contributor

endulab commented Aug 24, 2023

A few thoughts:

  1. We need deployer contract to be deployed on all chains we support.
  2. Such a contract will need an upgrade policy - what if we change Owner/Master contracts or want to add another type of contract?
  3. This solution will require Status company engagement - this is the legal issue Jo mentioned. This is a question to @John-44 .
  4. I still want to discuss with @gravityblast the idea of meta-transactions (transaction in transaction).

@John-44
Copy link

John-44 commented Aug 24, 2023

A few thoughts:

  1. We need deployer contract to be deployed on all chains we support.
  2. Such a contract will need an upgrade policy - what if we change Owner/Master contracts or want to add another type of contract?

I don't think it would require an upgrade policy. If an update is needed, a new deplorer contract could just be deployed, and then we would make the Status client code aware of this new deplorer contract

  1. This solution will require Status company engagement - this is the legal issue Jo mentioned. This is a question to @John-44

I think this is probably fine, as long as the deplorer contract doesn't have an upgrade mechanism (so the only way to perform an upgrade is to deploy a new contract, and point the status client code at that new contract).

  1. I still want to discuss with @gravityblast the idea of meta-transactions (transaction in transaction).

@endulab
Copy link
Contributor

endulab commented Aug 24, 2023

I don't think it would require an upgrade policy. If an update is needed, a new deplorer contract could just be deployed, and then we would make the Status client code aware of this new deplorer contract.

In this case we need to use the new and old deployer contract, because old ones already keep community <-> owner token data. Or we break backward-compatibility ?

@0x-r4bbit
Copy link
Member

Hi everyone, reading this thread here and I might have some questions (because I do miss some context).

Afterwards, when a user gets sent an OwnerToken, they can ask the CommunityOwnerTokenDeployer if that token is indeed the right one for the community. The contract will check its map and send the address of the deployed token.

@jrainville This "they can ask the deployer token if it's indeed the right one" part - is that happening in status-go? Meaning, somehow a Status client gets notified that the logged-in account has received an owner token and now it wants to verify if it's indeed the owner token of this community?

If the answer is yes, then:

I don't think it would require an upgrade policy. If an update is needed, a new deplorer contract could just be deployed, and then we would make the Status client code aware of this new deplorer contract

^ This would become a problem. The CommunityOwnerTokenDeployer as described above would effectively function as a global registry for known communities <-> tokens. Without a proper upgrade mechanism and simply putting out another deployer contract, status-go wouldn't need to keep track of all deployer contracts in existence and ask them one by one. Not sure if that is feasible.

I think this is probably fine, as long as the deplorer contract doesn't have an upgrade mechanism (so the only way to perform an upgrade is to deploy a new contract, and point the status client code at that new contract).

@John-44 if this part is indeed fine, then we might want to revisit the deployment of owner/master token altogether because there's patterns that can be used to reduce gas costs by a lot, provided Status deploys some initial contract.
It talked with @gravityblast about this the other day and he said we couldn't use such a pattern because Status deploying a contract would not be an option.

If it is an option, we could maybe squeeze out some more gas, but would need to do some profiling on that.

@John-44
Copy link

John-44 commented Aug 24, 2023

I don't think it would require an upgrade policy. If an update is needed, a new deplorer contract could just be deployed, and then we would make the Status client code aware of this new deplorer contract.

In this case we need to use the new and old deployer contract, because old ones already keep community <-> owner token data. Or we break backward-compatibility ?

Could a new contract reference data related to previous deplorer contracts? If so, could this be a solution to the issue of preserving the data written to the previous contract when we deploy a replacement contract?

@John-44
Copy link

John-44 commented Aug 24, 2023

@John-44 if this part is indeed fine, then we might want to revisit the deployment of owner/master token altogether because there's patterns that can be used to reduce gas costs by a lot, provided Status deploys some initial contract.
It talked with @gravityblast about this the other day and he said we couldn't use such a pattern because Status deploying a contract would not be an option.

I think it's probably fine if Status deploys some initial contract for the owner/TokenMaster contracts only. Also any initial contract that Status deploys shouldn't have an upgrade mechinism.

The contracts where Status cannot deploy an initial contract for (even if it saves gas) are:

  • The mint Asset contract
  • The mint Collectable contract
  • The future token retail contracts

@0x-r4bbit
Copy link
Member

Hey everyone, a small update here.
I've had a quick call with @endulab and @mprakhov to discuss some details. Here's a summary of what we've discussed/concluded. Please chime in with any thoughts or corrections if you see stuff that needs adjustment:

  1. First and foremost, this issue is about eliminating an attack vector where a malicious owner could deploy multiple (malicious) owner token contracts and put their addresses into the community description. This is why we need some mechanism where clients can verify that a given contract address is indeed the one that was deployed for the owner tokens of a contract.
  2. To solve this, the original idea was to have the community itself the contract and rely on the heuristic that only the first contract deployment of such a community would be considered valid and therefore we'd get around the issue that multiple contracts could be deployed by owners with potentially malicious usage.
  3. @osmaczko has laid out some path forward where the owner would send funds to the community account and then the community would perform the deployment.

At this point, I think it's also worth mentioning that, even though the flow above would ensure the community performs the deployment and therefore one can check on-chain if a given contract address was indeed the first one deployed by the community, it doesn't actually guarantee what is being deployed. A malicious owner can still go ahead and change the source of the contract being deployed (and still have the community perform the transaction, as the owner owns the private key at this point).

That being said, exploring the idea of a CommunityOwnerDeployer contract, I think this can indeed solve these issues and I'd like to invite everyone to challenge the trust assumptions and attack vectors.

Here's how I think this could work:

  1. As already mentioned, Status would deploy the deployer contract which acts as a registry of [communityID|ethAddress] <-> contractAddress (or vice versa).
  2. We assume that this contract can be trusted and whatever state is represented in this contract is considered valid. Hence, anyone can go and ask the contract what's the owner token contractAddress for any given communityID or communityEthAddress.
  3. Deployments of tokens happens through this contract, so everyone can verify on-chain that the source for token deployments is indeed legit and not something unexpected
  4. Now it's important to ensure the state in the registry contract cannot be tempered with, and I think there are two options here
    4.1. The community account itself performs the deployment and the deployer contract uses msg.sender (which is the communityEthAddress) for the registry mapping key. In this scenario, only the community itself can perform the deployment with the side effect of having its address stored in the registry
    4.2. Since we still have the issue of communities being without funds we could now explore the case of the owner account performing the deployment transaction. In this case however, msg.sender is no longer the community, so to ensure the communityID/address ends up in the registry, we'd have the owner provide a signature to the transaction that is signed by the community, proofing that it's fine to have the communityID/address used as key in the registry.
  5. The deployer contract checks if the provided tx has a valid signature and only if the there's not already a contract address stored in the registry for this community, does it store the address.
  6. There's also no need for clients to check the transaction history of the community

Questions to clarify

  • Do clients want to verify token master tokens as well? If yes then their addresses have to be stored in the registry too.
  • Is there a chance we'll introduce additional token types in the future that need to live in the registry? Given that contract upgrades are a no-go, this could be an issue. How do we want to handle this case?

Additional considerations

  • If there's a chance we'd want to change the deployment process in the future, we might want to consider having the registry live in its own contract and then have the deployer talk to it. That way, we can keep the same registry across deployer versions. However, things get tricky if we have to change the registry itself (mean, new token types that need to be supported)

@jrainville
Copy link
Member

Since we still have the issue of communities being without funds we could now explore the case of the owner account performing the deployment transaction. In this case however, msg.sender is no longer the community, so to ensure the communityID/address ends up in the registry, we'd have the owner provide a signature to the transaction that is signed by the community, proofing that it's fine to have the communityID/address used as key in the registry.

I think this 4.2 option is better. Like you said, 4.1 requires sending funds to the community which comes with a slew of possible problems and its not great UX.

Do clients want to verify token master tokens as well? If yes then their addresses have to be stored in the registry too.

I'm not sure. The control node has the last say (only one that can modify the community description), so normal clients don't need to access that information.
Maybe the control node would want that, but if we assume that the control node isn't compromised, then that means the community description is valid, hence the token masters are known and trustworthy.

Is there a chance we'll introduce additional token types in the future that need to live in the registry? Given that contract upgrades are a no-go, this could be an issue. How do we want to handle this case?

We should assume that we'll have new roles in the future. Will those roles need a special token like the TokenMaster does? I'm not sure. The admin for example can use any ERC721 or ERC20
If we assume that there will be new tokens, then it's probable that they will be similar to the TokenMaster one. I don't think from the top of my head that we'd have another "super-master" token like the Owner token.
That does mean that the Deployer contract could get upgraded. See next question.

If there's a chance we'd want to change the deployment process in the future, we might want to consider having the registry live in its own contract and then have the deployer talk to it. That way, we can keep the same registry across deployer versions. However, things get tricky if we have to change the registry itself (mean, new token types that need to be supported)

I think having the Registry in its own contract is a good idea. It's more probable that the Deployer will change than the Registry will.
Like I said above, we probably only want to keep Owner token address for a community, since the Owner is the one responsible for all the others.

@0x-r4bbit
Copy link
Member

I'm not sure. The control node has the last say (only one that can modify the community description), so normal clients don't need to access that information.
Maybe the control node would want that, but if we assume that the control node isn't compromised, then that means the community description is valid, hence the token masters are known and trustworthy.

So, as far as I understood, the idea was that any (member) node can verify that a given contract address is indeed an owner token contract address for some community. Hence we discussed the idea of a registry that maps communityID<->contractAddress.

Here I'm asking if these nodes also want to verify that a token address is indeed the tokenmaster token address for that community. So, do we need communityID<->tokenMasterAddress as well?

I think having the Registry in its own contract is a good idea. It's more probable that the Deployer will change than the Registry will.

After further discussions offline with @3esmit , we might get away with not having a registry at all, but rather have contract addresses deterministically calculated. Will have to play around with this.

@endulab
Copy link
Contributor

endulab commented Aug 28, 2023

I also agree that option 4.2. is better than 4.1. 4.1 can be very problematic, especially in case of eg. not enough funds. It's hard to say what to do then, whether community should give back money to the owner or the owner should send more money to redo the transaction.

Regarding tokenMaster mapping, every change made by tokenMaster should be accepted by the control node after all. Control Node knows who is tokenMaster. I am not sure if a member need to verify any operations made by token master. At the first sight it seems that we do not need to keep a mapping for token master.

@John-44
Copy link

John-44 commented Aug 28, 2023

I prefer option 4.2

@jrainville
Copy link
Member

Regarding tokenMaster mapping, every change made by tokenMaster should be accepted by the control node after all. Control Node knows who is tokenMaster. I am not sure if a member need to verify any operations made by token master. At the first sight it seems that we do not need to keep a mapping for token master.

Yup, that's what I was trying to say, but I realize I wasn't being very clear 😅

0x-r4bbit added a commit to status-im/communities-contracts that referenced this issue Aug 30, 2023
This commit introduces the `CommunityTokenDeployer` contract discussed
in status-im/status-desktop#11954.

The idea is that, instead of having accounts deploy `OwnerToken` and
`MasterToken` directly, they'd use a deployer contract instead, which
maintains a registry of known `OwnerToken` addresses, mapped to Status
community addresses.

The following changes have been made:

It was, and still is, a requirement that both, `OwnerToken` and
`MasterToken` are deployed within a single transaction, so that when
something goes wrong, we don't end up in an inconsistent state.

That's why `OwnerToken` used to instantiated `MasterToken` and required
all of its constructor arguments as well.

Unfortunately, this resulted in compilation issues in the context of the
newly introduce deployer contract, where there are too many function
arguments.

Because we now delegate deployment to a dedicated contract, we can
instantiate both `OwnerToken` and `MasterToken` in a single transaction,
without having `OwnerToken` being responsible to instantiate
`MasterToken`.

This fixes the compilation issues and simplifies the constructor of
`OwnerToken`.

The new `CommunityTokenDeployer` contract is now responsble for
deploying the aforementioned tokens and ensures that they are deployed
within a single transaction.

To deploy an `OwnerToken` and `MasterToken` accounts can now call
`CommunityDeloyerToken.deploy(TokenConfig, TokenConfig,
DeploymentSignature)`.

The `DeploymentSignature` uses `EIP712` structured type hash data to let
the contract verify that the deployer is allowed to deploy the contracts
on behalf of a community account.
0x-r4bbit added a commit to status-im/communities-contracts that referenced this issue Aug 30, 2023
This commit introduces the `CommunityTokenDeployer` contract discussed
in status-im/status-desktop#11954.

The idea is that, instead of having accounts deploy `OwnerToken` and
`MasterToken` directly, they'd use a deployer contract instead, which
maintains a registry of known `OwnerToken` addresses, mapped to Status
community addresses.

The following changes have been made:

It was, and still is, a requirement that both, `OwnerToken` and
`MasterToken` are deployed within a single transaction, so that when
something goes wrong, we don't end up in an inconsistent state.

That's why `OwnerToken` used to instantiated `MasterToken` and required
all of its constructor arguments as well.

Unfortunately, this resulted in compilation issues in the context of the
newly introduce deployer contract, where there are too many function
arguments.

Because we now delegate deployment to a dedicated contract, we can
instantiate both `OwnerToken` and `MasterToken` in a single transaction,
without having `OwnerToken` being responsible to instantiate
`MasterToken`.

This fixes the compilation issues and simplifies the constructor of
`OwnerToken`.

The new `CommunityTokenDeployer` contract is now responsble for
deploying the aforementioned tokens and ensures that they are deployed
within a single transaction.

To deploy an `OwnerToken` and `MasterToken` accounts can now call
`CommunityDeloyerToken.deploy(TokenConfig, TokenConfig,
DeploymentSignature)`.

The `DeploymentSignature` uses `EIP712` structured type hash data to let
the contract verify that the deployer is allowed to deploy the contracts
on behalf of a community account.
0x-r4bbit added a commit to status-im/communities-contracts that referenced this issue Aug 30, 2023
This commit introduces the `CommunityTokenDeployer` contract discussed
in status-im/status-desktop#11954.

The idea is that, instead of having accounts deploy `OwnerToken` and
`MasterToken` directly, they'd use a deployer contract instead, which
maintains a registry of known `OwnerToken` addresses, mapped to Status
community addresses.

The following changes have been made:

It was, and still is, a requirement that both, `OwnerToken` and
`MasterToken` are deployed within a single transaction, so that when
something goes wrong, we don't end up in an inconsistent state.

That's why `OwnerToken` used to instantiated `MasterToken` and required
all of its constructor arguments as well.

Unfortunately, this resulted in compilation issues in the context of the
newly introduce deployer contract, where there are too many function
arguments.

Because we now delegate deployment to a dedicated contract, we can
instantiate both `OwnerToken` and `MasterToken` in a single transaction,
without having `OwnerToken` being responsible to instantiate
`MasterToken`.

This fixes the compilation issues and simplifies the constructor of
`OwnerToken`.

The new `CommunityTokenDeployer` contract is now responsble for
deploying the aforementioned tokens and ensures that they are deployed
within a single transaction.

To deploy an `OwnerToken` and `MasterToken` accounts can now call
`CommunityDeloyerToken.deploy(TokenConfig, TokenConfig,
DeploymentSignature)`.

The `DeploymentSignature` uses `EIP712` structured type hash data to let
the contract verify that the deployer is allowed to deploy the contracts
on behalf of a community account.
0x-r4bbit added a commit to status-im/communities-contracts that referenced this issue Aug 30, 2023
This commit introduces the `CommunityTokenDeployer` contract discussed
in status-im/status-desktop#11954.

The idea is that, instead of having accounts deploy `OwnerToken` and
`MasterToken` directly, they'd use a deployer contract instead, which
maintains a registry of known `OwnerToken` addresses, mapped to Status
community addresses.

The following changes have been made:

It was, and still is, a requirement that both, `OwnerToken` and
`MasterToken` are deployed within a single transaction, so that when
something goes wrong, we don't end up in an inconsistent state.

That's why `OwnerToken` used to instantiated `MasterToken` and required
all of its constructor arguments as well.

Unfortunately, this resulted in compilation issues in the context of the
newly introduce deployer contract, where there are too many function
arguments.

Because we now delegate deployment to a dedicated contract, we can
instantiate both `OwnerToken` and `MasterToken` in a single transaction,
without having `OwnerToken` being responsible to instantiate
`MasterToken`.

This fixes the compilation issues and simplifies the constructor of
`OwnerToken`.

The new `CommunityTokenDeployer` contract is now responsble for
deploying the aforementioned tokens and ensures that they are deployed
within a single transaction.

To deploy an `OwnerToken` and `MasterToken` accounts can now call
`CommunityDeloyerToken.deploy(TokenConfig, TokenConfig,
DeploymentSignature)`.

The `DeploymentSignature` uses `EIP712` structured type hash data to let
the contract verify that the deployer is allowed to deploy the contracts
on behalf of a community account.
@0x-r4bbit
Copy link
Member

Here's an illustration of the system as it's currently implemented in status-im/communities-contracts#2

@John-44 There'd be two contracts that need to be deployed by Status

@jrainville
Copy link
Member

@0x-r4bbit looks good to me!

John is off I think for the next week or so.

0x-r4bbit added a commit to status-im/communities-contracts that referenced this issue Sep 4, 2023
This commit introduces the `CommunityTokenDeployer` contract discussed
in status-im/status-desktop#11954.

The idea is that, instead of having accounts deploy `OwnerToken` and
`MasterToken` directly, they'd use a deployer contract instead, which
maintains a registry of known `OwnerToken` addresses, mapped to Status
community addresses.

The following changes have been made:

It was, and still is, a requirement that both, `OwnerToken` and
`MasterToken` are deployed within a single transaction, so that when
something goes wrong, we don't end up in an inconsistent state.

That's why `OwnerToken` used to instantiated `MasterToken` and required
all of its constructor arguments as well.

Unfortunately, this resulted in compilation issues in the context of the
newly introduce deployer contract, where there are too many function
arguments.

Because we now delegate deployment to a dedicated contract, we can
instantiate both `OwnerToken` and `MasterToken` in a single transaction,
without having `OwnerToken` being responsible to instantiate
`MasterToken`.

This fixes the compilation issues and simplifies the constructor of
`OwnerToken`.

The new `CommunityTokenDeployer` contract is now responsble for
deploying the aforementioned tokens and ensures that they are deployed
within a single transaction.

To deploy an `OwnerToken` and `MasterToken` accounts can now call
`CommunityDeloyerToken.deploy(TokenConfig, TokenConfig,
DeploymentSignature)`.

The `DeploymentSignature` uses `EIP712` structured type hash data to let
the contract verify that the deployer is allowed to deploy the contracts
on behalf of a community account.
0x-r4bbit added a commit to status-im/communities-contracts that referenced this issue Sep 4, 2023
This commit introduces the `CommunityTokenDeployer` contract discussed
in status-im/status-desktop#11954.

The idea is that, instead of having accounts deploy `OwnerToken` and
`MasterToken` directly, they'd use a deployer contract instead, which
maintains a registry of known `OwnerToken` addresses, mapped to Status
community addresses.

The following changes have been made:

It was, and still is, a requirement that both, `OwnerToken` and
`MasterToken` are deployed within a single transaction, so that when
something goes wrong, we don't end up in an inconsistent state.

That's why `OwnerToken` used to instantiated `MasterToken` and required
all of its constructor arguments as well.

Unfortunately, this resulted in compilation issues in the context of the
newly introduce deployer contract, where there are too many function
arguments.

Because we now delegate deployment to a dedicated contract, we can
instantiate both `OwnerToken` and `MasterToken` in a single transaction,
without having `OwnerToken` being responsible to instantiate
`MasterToken`.

This fixes the compilation issues and simplifies the constructor of
`OwnerToken`.

The new `CommunityTokenDeployer` contract is now responsble for
deploying the aforementioned tokens and ensures that they are deployed
within a single transaction.

To deploy an `OwnerToken` and `MasterToken` accounts can now call
`CommunityDeloyerToken.deploy(TokenConfig, TokenConfig,
DeploymentSignature)`.

The `DeploymentSignature` uses `EIP712` structured type hash data to let
the contract verify that the deployer is allowed to deploy the contracts
on behalf of a community account.
0x-r4bbit added a commit to status-im/communities-contracts that referenced this issue Sep 5, 2023
This commit introduces the `CommunityTokenDeployer` contract discussed
in status-im/status-desktop#11954.

The idea is that, instead of having accounts deploy `OwnerToken` and
`MasterToken` directly, they'd use a deployer contract instead, which
maintains a registry of known `OwnerToken` addresses, mapped to Status
community addresses.

The following changes have been made:

It was, and still is, a requirement that both, `OwnerToken` and
`MasterToken` are deployed within a single transaction, so that when
something goes wrong, we don't end up in an inconsistent state.

That's why `OwnerToken` used to instantiated `MasterToken` and required
all of its constructor arguments as well.

Unfortunately, this resulted in compilation issues in the context of the
newly introduce deployer contract, where there are too many function
arguments.

Because we now delegate deployment to a dedicated contract, we can
instantiate both `OwnerToken` and `MasterToken` in a single transaction,
without having `OwnerToken` being responsible to instantiate
`MasterToken`.

This fixes the compilation issues and simplifies the constructor of
`OwnerToken`.

The new `CommunityTokenDeployer` contract is now responsble for
deploying the aforementioned tokens and ensures that they are deployed
within a single transaction.

To deploy an `OwnerToken` and `MasterToken` accounts can now call
`CommunityDeloyerToken.deploy(TokenConfig, TokenConfig,
DeploymentSignature)`.

The `DeploymentSignature` uses `EIP712` structured type hash data to let
the contract verify that the deployer is allowed to deploy the contracts
on behalf of a community account.
0x-r4bbit added a commit to status-im/communities-contracts that referenced this issue Sep 5, 2023
This commit introduces the `CommunityTokenDeployer` contract discussed
in status-im/status-desktop#11954.

The idea is that, instead of having accounts deploy `OwnerToken` and
`MasterToken` directly, they'd use a deployer contract instead, which
maintains a registry of known `OwnerToken` addresses, mapped to Status
community addresses.

The following changes have been made:

It was, and still is, a requirement that both, `OwnerToken` and
`MasterToken` are deployed within a single transaction, so that when
something goes wrong, we don't end up in an inconsistent state.

That's why `OwnerToken` used to instantiated `MasterToken` and required
all of its constructor arguments as well.

Unfortunately, this resulted in compilation issues in the context of the
newly introduce deployer contract, where there are too many function
arguments.

Because we now delegate deployment to a dedicated contract, we can
instantiate both `OwnerToken` and `MasterToken` in a single transaction,
without having `OwnerToken` being responsible to instantiate
`MasterToken`.

This fixes the compilation issues and simplifies the constructor of
`OwnerToken`.

The new `CommunityTokenDeployer` contract is now responsble for
deploying the aforementioned tokens and ensures that they are deployed
within a single transaction.

To deploy an `OwnerToken` and `MasterToken` accounts can now call
`CommunityDeloyerToken.deploy(TokenConfig, TokenConfig,
DeploymentSignature)`.

The `DeploymentSignature` uses `EIP712` structured type hash data to let
the contract verify that the deployer is allowed to deploy the contracts
on behalf of a community account.
0x-r4bbit added a commit to status-im/communities-contracts that referenced this issue Sep 6, 2023
This commit introduces the `CommunityTokenDeployer` contract discussed
in status-im/status-desktop#11954.

The idea is that, instead of having accounts deploy `OwnerToken` and
`MasterToken` directly, they'd use a deployer contract instead, which
maintains a registry of known `OwnerToken` addresses, mapped to Status
community addresses.

The following changes have been made:

It was, and still is, a requirement that both, `OwnerToken` and
`MasterToken` are deployed within a single transaction, so that when
something goes wrong, we don't end up in an inconsistent state.

That's why `OwnerToken` used to instantiated `MasterToken` and required
all of its constructor arguments as well.

Unfortunately, this resulted in compilation issues in the context of the
newly introduce deployer contract, where there are too many function
arguments.

Because we now delegate deployment to a dedicated contract, we can
instantiate both `OwnerToken` and `MasterToken` in a single transaction,
without having `OwnerToken` being responsible to instantiate
`MasterToken`.

This fixes the compilation issues and simplifies the constructor of
`OwnerToken`.

The new `CommunityTokenDeployer` contract is now responsble for
deploying the aforementioned tokens and ensures that they are deployed
within a single transaction.

To deploy an `OwnerToken` and `MasterToken` accounts can now call
`CommunityDeloyerToken.deploy(TokenConfig, TokenConfig,
DeploymentSignature)`.

The `DeploymentSignature` uses `EIP712` structured type hash data to let
the contract verify that the deployer is allowed to deploy the contracts
on behalf of a community account.
@0x-r4bbit
Copy link
Member

Hey everyone,

another quick update. Turns out we ran into a contract size limit issue with deployer contract as it depends on the contract sources of both, the owner token and the master token.

I've done some experiments and ultimately we went with splitting up the contracts further, such that we also have a CommunityOwnerTokenFactory and a CommunityMasterTokenFactory, which are used by CommunityTokenDeployer.

This is what it looks like now:
community-token-deployer-dawing

I've also written a bunch of documentation about this in: status-im/communities-contracts#4
Would appreciate any reviews and feedback.

0x-r4bbit added a commit to status-im/communities-contracts that referenced this issue Sep 8, 2023
This commit introduces the `CommunityTokenDeployer` contract discussed
in status-im/status-desktop#11954.

The idea is that, instead of having accounts deploy `OwnerToken` and
`MasterToken` directly, they'd use a deployer contract instead, which
maintains a registry of known `OwnerToken` addresses, mapped to Status
community addresses.

The following changes have been made:

It was, and still is, a requirement that both, `OwnerToken` and
`MasterToken` are deployed within a single transaction, so that when
something goes wrong, we don't end up in an inconsistent state.

That's why `OwnerToken` used to instantiated `MasterToken` and required
all of its constructor arguments as well.

Unfortunately, this resulted in compilation issues in the context of the
newly introduce deployer contract, where there are too many function
arguments.

Because we now delegate deployment to a dedicated contract, we can
instantiate both `OwnerToken` and `MasterToken` in a single transaction,
without having `OwnerToken` being responsible to instantiate
`MasterToken`.

This fixes the compilation issues and simplifies the constructor of
`OwnerToken`.

The new `CommunityTokenDeployer` contract is now responsble for
deploying the aforementioned tokens and ensures that they are deployed
within a single transaction.

To deploy an `OwnerToken` and `MasterToken` accounts can now call
`CommunityDeloyerToken.deploy(TokenConfig, TokenConfig,
DeploymentSignature)`.

The `DeploymentSignature` uses `EIP712` structured type hash data to let
the contract verify that the deployer is allowed to deploy the contracts
on behalf of a community account.
0x-r4bbit added a commit to status-im/communities-contracts that referenced this issue Sep 13, 2023
This commit introduces the `CommunityTokenDeployer` contract discussed
in status-im/status-desktop#11954.

The idea is that, instead of having accounts deploy `OwnerToken` and
`MasterToken` directly, they'd use a deployer contract instead, which
maintains a registry of known `OwnerToken` addresses, mapped to Status
community addresses.

The following changes have been made:

It was, and still is, a requirement that both, `OwnerToken` and
`MasterToken` are deployed within a single transaction, so that when
something goes wrong, we don't end up in an inconsistent state.

That's why `OwnerToken` used to instantiated `MasterToken` and required
all of its constructor arguments as well.

Unfortunately, this resulted in compilation issues in the context of the
newly introduce deployer contract, where there are too many function
arguments.

Because we now delegate deployment to a dedicated contract, we can
instantiate both `OwnerToken` and `MasterToken` in a single transaction,
without having `OwnerToken` being responsible to instantiate
`MasterToken`.

This fixes the compilation issues and simplifies the constructor of
`OwnerToken`.

The new `CommunityTokenDeployer` contract is now responsble for
deploying the aforementioned tokens and ensures that they are deployed
within a single transaction.

To deploy an `OwnerToken` and `MasterToken` accounts can now call
`CommunityDeloyerToken.deploy(TokenConfig, TokenConfig,
DeploymentSignature)`.

The `DeploymentSignature` uses `EIP712` structured type hash data to let
the contract verify that the deployer is allowed to deploy the contracts
on behalf of a community account.
@jrainville jrainville changed the title [Community Ownership] deploy Owner Token through community address [Community Ownership] deploy Owner Token through Deployer contract Sep 18, 2023
0x-r4bbit added a commit to status-im/communities-contracts that referenced this issue Sep 19, 2023
This commit introduces the `CommunityTokenDeployer` contract discussed
in status-im/status-desktop#11954.

The idea is that, instead of having accounts deploy `OwnerToken` and
`MasterToken` directly, they'd use a deployer contract instead, which
maintains a registry of known `OwnerToken` addresses, mapped to Status
community addresses.

The following changes have been made:

It was, and still is, a requirement that both, `OwnerToken` and
`MasterToken` are deployed within a single transaction, so that when
something goes wrong, we don't end up in an inconsistent state.

That's why `OwnerToken` used to instantiated `MasterToken` and required
all of its constructor arguments as well.

Unfortunately, this resulted in compilation issues in the context of the
newly introduce deployer contract, where there are too many function
arguments.

Because we now delegate deployment to a dedicated contract, we can
instantiate both `OwnerToken` and `MasterToken` in a single transaction,
without having `OwnerToken` being responsible to instantiate
`MasterToken`.

This fixes the compilation issues and simplifies the constructor of
`OwnerToken`.

The new `CommunityTokenDeployer` contract is now responsble for
deploying the aforementioned tokens and ensures that they are deployed
within a single transaction.

To deploy an `OwnerToken` and `MasterToken` accounts can now call
`CommunityDeloyerToken.deploy(TokenConfig, TokenConfig,
DeploymentSignature)`.

The `DeploymentSignature` uses `EIP712` structured type hash data to let
the contract verify that the deployer is allowed to deploy the contracts
on behalf of a community account.
0x-r4bbit added a commit to status-im/communities-contracts that referenced this issue Sep 19, 2023
This commit introduces the `CommunityTokenDeployer` contract discussed
in status-im/status-desktop#11954.

The idea is that, instead of having accounts deploy `OwnerToken` and
`MasterToken` directly, they'd use a deployer contract instead, which
maintains a registry of known `OwnerToken` addresses, mapped to Status
community addresses.

The following changes have been made:

It was, and still is, a requirement that both, `OwnerToken` and
`MasterToken` are deployed within a single transaction, so that when
something goes wrong, we don't end up in an inconsistent state.

That's why `OwnerToken` used to instantiated `MasterToken` and required
all of its constructor arguments as well.

Unfortunately, this resulted in compilation issues in the context of the
newly introduce deployer contract, where there are too many function
arguments.

Because we now delegate deployment to a dedicated contract, we can
instantiate both `OwnerToken` and `MasterToken` in a single transaction,
without having `OwnerToken` being responsible to instantiate
`MasterToken`.

This fixes the compilation issues and simplifies the constructor of
`OwnerToken`.

The new `CommunityTokenDeployer` contract is now responsble for
deploying the aforementioned tokens and ensures that they are deployed
within a single transaction.

To deploy an `OwnerToken` and `MasterToken` accounts can now call
`CommunityDeloyerToken.deploy(TokenConfig, TokenConfig,
DeploymentSignature)`.

The `DeploymentSignature` uses `EIP712` structured type hash data to let
the contract verify that the deployer is allowed to deploy the contracts
on behalf of a community account.
endulab added a commit that referenced this issue Sep 29, 2023
endulab added a commit that referenced this issue Sep 29, 2023
endulab added a commit that referenced this issue Sep 29, 2023
endulab added a commit that referenced this issue Sep 29, 2023
endulab added a commit that referenced this issue Sep 29, 2023
endulab added a commit that referenced this issue Oct 4, 2023
endulab added a commit that referenced this issue Oct 4, 2023
endulab added a commit that referenced this issue Oct 4, 2023
endulab added a commit that referenced this issue Oct 4, 2023
endulab added a commit that referenced this issue Oct 4, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backend-team E:Desktop Tokenized Ownership Implementation of the tokenization of community ownership and transfer of said ownership feature
Projects
Archived in project
5 participants