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

Superuser: Upgradeable security for Smart Contracts #50

Closed
federicobond opened this issue Nov 2, 2016 · 8 comments · Fixed by #952 or #978
Closed

Superuser: Upgradeable security for Smart Contracts #50

federicobond opened this issue Nov 2, 2016 · 8 comments · Fixed by #952 or #978
Labels
feature New contracts, functions, or helpers. good first issue Low hanging fruit for new contributors to get involved!

Comments

@federicobond
Copy link
Contributor

federicobond commented Nov 2, 2016

Scenario: you create a small crowdsale for your widget and it becomes really popular very quickly. Now there is a million dollar price tag on the poorly secured private key you used to deploy your contract and you start sleeping badly at night. Nobody worth their salt would secure a million dollars in a hot wallet.

Luckily, you remember that your contract inherits from Superuser, so next morning you generate a key in cold storage and take note of its address. You then use your owner account to configureSuperuser(address) and your sleep improves again because any sensitive method is using the requireSuperuser modifier. This modifier ensures that msg.sender is the superuser or (in case no superuser is configured, the owner). BOOM! Upgradeable security and peace of mind.

I will have a working implementation later today. Feel free to leave any feedback.

UPDATE: As was pointed out in the Slack channel, this is not a good example, as you can just transfer the ownership of the contract. A better example is when you want to keep a hot key for performing managerial actions but have a cold storage key as superuser in case the hot key is compromised.

@maraoz
Copy link
Contributor

maraoz commented Nov 2, 2016

👍 nice idea. Maybe the example is not the best, true, but I see the value

@maraoz maraoz added the feature New contracts, functions, or helpers. label Dec 19, 2016
@maraoz maraoz added the good first issue Low hanging fruit for new contributors to get involved! label Jun 14, 2017
@theethernaut
Copy link
Contributor

@federicobond would you like to make a PR to explore this idea?

@federicobond
Copy link
Contributor Author

I am not sure if the use case is general enough to warrant its inclusion in Zeppelin, but here are my updated thoughts on it:

A Superuser contract would inherit from Ownable. The superuser variable in this contract points to an address whose key should be kept in a cold wallet and never used for any other purpose. If there is a security breach and someone gets access to the owner key, this can be used as a last resort to regain control of the contract, transferring the ownership back to the original owner.

contract Superuser is Ownable {
    address public superuser;
    function setOwner(); // can only be called by superuser
    function transferSuperuser(); // can be called by superuser or owner if superuser is not defined
}

This could be useful if owner key must be used on a regular basis for administrative purposes.

@shrugs
Copy link
Contributor

shrugs commented May 4, 2018

This could/should be implemented with RBAC.sol now that it's available :)

@come-maiz
Copy link
Contributor

@federicobond still sounds relevant to me. Having two owners instead of one, good deal.
As @shrugs, now this is a lot easier. Maybe you can make a PR and then we discuss there if it makes sense to add it to openzeppelin, or we should just make a post to document how to do it. Are you still interested in helping with this?

@pmosse
Copy link
Contributor

pmosse commented May 19, 2018

Hey,

If we implement the Superuser contract with RBAC, instead of having a single superuser we would have an unlimited number of them, by creating the superuser role. Do you think this is okay in a practical scenario? Besides that, we should make sure that superusers can only be set once (either in the constructor or with a setSuperusers function). Once they are set, the owner shouldn't be able to modify them as the owner's account could get compromised in the future.
This could be implemented by following a similar idea to the Whitelist contract and creating the setSuperusers (onlyOwner and onlyIfSuperusersUndefined) and transferOwnership (onlySuperuser) functions.

If we only want a single superuser, then maybe a contract inheriting just from Ownable should be enough, following @federicobond's idea.

Let me know your thoughts and I can work in a PR.

(You should know I am doing my first steps in OZ and Blokchain in general :) )

Thanks!

@shrugs
Copy link
Contributor

shrugs commented May 19, 2018

You can have the only function allowed to change superusers be transferSuperuser() which will unset the previous super user and then assign the new super user.

contract Superuser is Ownable, RBAC {
  ROLE_SUPERUSER = "superuser";

  modifier onlySuperuser() {
    checkRole(msg.sender, ROLE_SUPERUSER);
    _;
  }

  constructor () {
    addRole(msg.sender, ROLE_SUPERUSER);
  }

  function transferSuperuser(address _newSuperuser) onlySuperuser() {
    removeRole(msg.sender, ROLE_SUPERUSER);
    addRole(_newSuperuser, ROLE_SUPERUSER);
  }
}

that's pseudo code, but it seems to be the gist of it. This is pretty much how I implemented RBACOwnable in a pending PR to OZ.

@shrugs
Copy link
Contributor

shrugs commented May 19, 2018

Implementing single-address roles in rbac is relatively straightforward. the only difference between RBAC with "only one person can have this role" and something like Ownable is that the user's address isn't directly accessible in the contract; the callee must know an address in order to call hasRole and see if that address actually does have that role.

pmosse added a commit to pmosse/openzeppelin-solidity that referenced this issue May 22, 2018
pmosse added a commit to pmosse/openzeppelin-solidity that referenced this issue May 24, 2018
shrugs referenced this issue in pmosse/openzeppelin-solidity Jun 2, 2018
pmosse added a commit to pmosse/openzeppelin-solidity that referenced this issue Jun 5, 2018
pmosse added a commit to pmosse/openzeppelin-solidity that referenced this issue Jun 5, 2018
frangio referenced this issue in pmosse/openzeppelin-solidity Jun 5, 2018
frangio pushed a commit that referenced this issue Jun 5, 2018
#978)

* Refactoring Superuser contract to allow Owners to transfer ownership when they are not superusers #50

* Refactoring tests to create a contract instance for each of them #50
djvex pushed a commit to djvex/openzeppelin-contracts that referenced this issue Jan 1, 2022
* Migrate to SLF4J

* Remove IDE warnings
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature New contracts, functions, or helpers. good first issue Low hanging fruit for new contributors to get involved!
Projects
None yet
6 participants