Adding new Superuser contract with test (#952)
* Adding new Superuser contract + testspull/949/head^2
parent
e3f866c982
commit
a0c03ee61c
@ -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…
Reference in new issue