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

Set subnet owner explicitly + OwnableFacet for Gateway, SA, Registry #785

Merged
merged 7 commits into from
Mar 14, 2024

Conversation

cryptoAtwill
Copy link
Contributor

Currently the ownership of the subnet is the registry, this PR explicitly sets the ownership as a parameter and controlled by the deployer. The deployer could set this to its own address or some other address instead of forcing it to be the msg.sender.

@@ -38,7 +38,7 @@ contract SubnetActorDiamond {
SubnetID parentId;
}

constructor(IDiamond.FacetCut[] memory _diamondCut, ConstructorParams memory params) {
constructor(IDiamond.FacetCut[] memory _diamondCut, ConstructorParams memory params, address owner) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not add it to the constructor params?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Initially I thought this way will draw much more attention to this parameter as it's perhaps the single most important parameter. Then, from a practical point of view, it will not break a lot of existing code, it's gentler on ipc and unit tests.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm, but it seems to go against the grain of it, doesn't it? To have all parameters, plus this on the side?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The owner indeed tends to be a "meta" parameter as it governs the contracts themselves, not the logic of the subnet. We should rename ConstructorParams to SubnetConfig (as it represents the subnet configuration and it's not the totality of the constructor params) to make it clearer down the line.

That said, I would move the owner to the 2nd place to have all contract metadata params leading, then followed by the subnet config.

@@ -58,7 +58,7 @@ contract RegisterSubnetFacet is ReentrancyGuard {
});

// slither-disable-next-line reentrancy-benign
subnetAddr = address(new SubnetActorDiamond(diamondCut, _params));
subnetAddr = address(new SubnetActorDiamond(diamondCut, _params, msg.sender));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like the registry will set it to the sender, which seems reasonable, however my impression was that the creator should be able to specify a multisig address if they wanted to, so the power over the federated weights aren't in one hand.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe registry should also accept it as a parameter?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand that requires modifying the Rust code as well, so I'll defer to others for what to do here.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd keep it the way this PR proposes. In a monolithic permissioning model, it's highly conventional in smart contracts that the creator of X becomes the first owner and full controller of X; the creator can be the multisig.

My bet is that we will want a finer-grained permissioning model going forward (e.g. perms for relaying, checkpointing submission, upgrades, lifecycle actions, etc.), so it's not worth to introduce something adhoc here now.

One thing we should do is add the OwnershipFacet to expose an ERC173-compliant transferOwnership method. So one could have an EOA create the subnet, and then transfer ownership to the multisig that will manage it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added a Ownable contract that handles transfer ownership.

Copy link
Contributor

@raulk raulk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is fine, but it won't be straightforward to create the subnet with a multisig with our current tooling. We should implement OwnershipFacet so we can reuse our existing tooling (and submit the creation from an EOA), and then transfer ownership to a multisig.

@@ -58,7 +58,7 @@ contract RegisterSubnetFacet is ReentrancyGuard {
});

// slither-disable-next-line reentrancy-benign
subnetAddr = address(new SubnetActorDiamond(diamondCut, _params));
subnetAddr = address(new SubnetActorDiamond(diamondCut, _params, msg.sender));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd keep it the way this PR proposes. In a monolithic permissioning model, it's highly conventional in smart contracts that the creator of X becomes the first owner and full controller of X; the creator can be the multisig.

My bet is that we will want a finer-grained permissioning model going forward (e.g. perms for relaying, checkpointing submission, upgrades, lifecycle actions, etc.), so it's not worth to introduce something adhoc here now.

One thing we should do is add the OwnershipFacet to expose an ERC173-compliant transferOwnership method. So one could have an EOA create the subnet, and then transfer ownership to the multisig that will manage it.

Comment on lines 31 to 34
vm.prank(firstOwner);
o.transferOwnership(secondOwner);
require(o.owner() == secondOwner, "second owner not correct");
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need zero address test, since that's a scenario we control for.


error FunctionNotFound(bytes4 _functionSelector);

bool constant FEATURE_MULTILEVEL_CROSSMSG = false;
bool constant FEATURE_GENERAL_PUPRPOSE_CROSSMSG = true;
uint8 constant FEATURE_SUBNET_DEPTH = 2;

contract GatewayDiamond {
contract GatewayDiamond is Ownable {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't we need to add the Ownable methods to the diamond function selectors somehow? Otherwise they might not be externally invokable?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fyi here's how the diamond Upgrade determines if the user making the request is the "contract owner"

function diamondCut(FacetCut[] calldata _diamondCut, address _init, bytes calldata _calldata) external override {
It is using the method LibDiamond.enforceIsContractOwner();

the upgrade facet is helpful but it only adds in two methods - one that allows for explicitly changing the ownership (seems helpful and worth adding!) and the other returns the owner. I don't think we want to add is Ownable to the contract here because Owning happens in LibDiamond

@raulk
Copy link
Contributor

raulk commented Mar 13, 2024

@cryptoAtwill why break the diamond abstraction model and not go with an OwnershipFacet like I suggested above?

@cryptoAtwill
Copy link
Contributor Author

@raulk @snissn OwnableFacet works for me as well. Will migrate this.

@raulk raulk merged commit 0babe1b into main Mar 14, 2024
21 checks passed
@raulk raulk deleted the subnet-owner branch March 14, 2024 12:18
@raulk raulk changed the title Set subnet owner explicitly Set subnet owner explicitly + OwnableFacet for Gateway, SA, Registry Mar 15, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants