Adding new Superuser contract with test (#952)

* Adding new Superuser contract + tests
pull/949/head^2
Patricio Mosse 7 years ago committed by Matt Condon
parent e3f866c982
commit a0c03ee61c
  1. 62
      contracts/ownership/Superuser.sol
  2. 62
      test/ownership/Superuser.test.js

@ -0,0 +1,62 @@
pragma solidity ^0.4.23;
import "./Ownable.sol";
import "./rbac/RBAC.sol";
/**
* @title Superuser
* @dev The Superuser contract defines a single superuser who can transfer the ownership
* @dev of a contract to a new address, even if he is not the owner.
* @dev A superuser can transfer his role to a new address.
*/
contract Superuser is Ownable, RBAC {
string public constant ROLE_SUPERUSER = "superuser";
constructor () public {
addRole(msg.sender, ROLE_SUPERUSER);
}
/**
* @dev Throws if called by any account that's not a superuser.
*/
modifier onlySuperuser() {
checkRole(msg.sender, ROLE_SUPERUSER);
_;
}
/**
* @dev getter to determine if address has superuser role
*/
function isSuperuser(address _addr)
public
view
returns (bool)
{
return hasRole(_addr, ROLE_SUPERUSER);
}
/**
* @dev Allows the current superuser to transfer his role to a newSuperuser.
* @param _newSuperuser The address to transfer ownership to.
*/
function transferSuperuser(address _newSuperuser)
onlySuperuser
public
{
require(_newSuperuser != address(0));
removeRole(msg.sender, ROLE_SUPERUSER);
addRole(_newSuperuser, ROLE_SUPERUSER);
}
/**
* @dev Allows the current superuser to transfer control of the contract to a newOwner.
* @param _newOwner The address to transfer ownership to.
*/
function transferOwnership(address _newOwner) public onlySuperuser {
require(_newOwner != address(0));
owner = _newOwner;
emit OwnershipTransferred(owner, _newOwner);
}
}

@ -0,0 +1,62 @@
import expectThrow from '../helpers/expectThrow';
import expectEvent from '../helpers/expectEvent';
const Superuser = artifacts.require('Superuser');
require('chai')
.use(require('chai-as-promised'))
.should();
contract('Superuser', function (accounts) {
const [
firstOwner,
newSuperuser,
newOwner,
anyone,
] = accounts;
before(async function () {
this.superuser = await Superuser.new();
});
context('in normal conditions', () => {
it('should set the owner as the default superuser', async function () {
const ownerIsSuperuser = await this.superuser.isSuperuser(firstOwner);
ownerIsSuperuser.should.be.equal(true);
});
it('should change superuser after transferring', async function () {
await this.superuser.transferSuperuser(newSuperuser, { from: firstOwner });
const ownerIsSuperuser = await this.superuser.isSuperuser(firstOwner);
ownerIsSuperuser.should.be.equal(false);
const address1IsSuperuser = await this.superuser.isSuperuser(newSuperuser);
address1IsSuperuser.should.be.equal(true);
});
it('should change owner after transferring', async function () {
await expectEvent.inTransaction(
this.superuser.transferOwnership(newOwner, { from: newSuperuser }),
'OwnershipTransferred'
);
const currentOwner = await this.superuser.owner();
currentOwner.should.be.equal(newOwner);
});
});
context('in adversarial conditions', () => {
it('should prevent non-superusers from transfering the superuser role', async function () {
await expectThrow(
this.superuser.transferSuperuser(newOwner, { from: anyone })
);
});
it('should prevent non-superusers from setting a new owner', async function () {
await expectThrow(
this.superuser.transferOwnership(newOwner, { from: anyone })
);
});
});
});
Loading…
Cancel
Save