Rename WhitelisterRole to WhitelistAdminRole. (#1589)
* Rename WhitelisterRole to WhitelistAdminRole. * Update WhitelistAdmin changelog entry.
This commit is contained in:
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
### New features:
|
### New features:
|
||||||
* Now targeting the 0.5.x line of Solidity compilers. For 0.4.24 support, use version 2.0 of OpenZeppelin.
|
* Now targeting the 0.5.x line of Solidity compilers. For 0.4.24 support, use version 2.0 of OpenZeppelin.
|
||||||
* `WhitelistCrowdsale`: a crowdsale where only whitelisted accounts (`WhitelistedRole`) can purchase tokens. Adding or removing accounts from the whitelist is done by whitelisters (`WhitelisterRole`). Similar to the pre-2.0 `WhitelistedCrowdsale`. ([#1525](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1525))
|
* `WhitelistCrowdsale`: a crowdsale where only whitelisted accounts (`WhitelistedRole`) can purchase tokens. Adding or removing accounts from the whitelist is done by whitelist admins (`WhitelistAdminRole`). Similar to the pre-2.0 `WhitelistedCrowdsale`. ([#1525](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1525), [#1589](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1589))
|
||||||
* `RefundablePostDeliveryCrowdsale`: replacement for `RefundableCrowdsale` (deprecated, see below) where tokens are only granted once the crowdsale ends (if it meets its goal). ([#1543](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1543))
|
* `RefundablePostDeliveryCrowdsale`: replacement for `RefundableCrowdsale` (deprecated, see below) where tokens are only granted once the crowdsale ends (if it meets its goal). ([#1543](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1543))
|
||||||
* `PausableCrowdsale`: allows for pausers (`PauserRole`) to pause token purchases. Other crowdsale operations (e.g. withdrawals and refunds, if applicable) are not affected. ([#832](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/832))
|
* `PausableCrowdsale`: allows for pausers (`PauserRole`) to pause token purchases. Other crowdsale operations (e.g. withdrawals and refunds, if applicable) are not affected. ([#832](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/832))
|
||||||
* `ERC20`: `transferFrom` and `_burnFrom ` now emit `Approval` events, to represent the token's state comprehensively through events. ([#1524](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1524))
|
* `ERC20`: `transferFrom` and `_burnFrom ` now emit `Approval` events, to represent the token's state comprehensively through events. ([#1524](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1524))
|
||||||
|
|||||||
47
contracts/access/roles/WhitelistAdminRole.sol
Normal file
47
contracts/access/roles/WhitelistAdminRole.sol
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
pragma solidity ^0.5.0;
|
||||||
|
|
||||||
|
import "../Roles.sol";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @title WhitelistAdminRole
|
||||||
|
* @dev WhitelistAdmins are responsible for assigning and removing Whitelisted accounts.
|
||||||
|
*/
|
||||||
|
contract WhitelistAdminRole {
|
||||||
|
using Roles for Roles.Role;
|
||||||
|
|
||||||
|
event WhitelistAdminAdded(address indexed account);
|
||||||
|
event WhitelistAdminRemoved(address indexed account);
|
||||||
|
|
||||||
|
Roles.Role private _whitelistAdmins;
|
||||||
|
|
||||||
|
constructor () internal {
|
||||||
|
_addWhitelistAdmin(msg.sender);
|
||||||
|
}
|
||||||
|
|
||||||
|
modifier onlyWhitelistAdmin() {
|
||||||
|
require(isWhitelistAdmin(msg.sender));
|
||||||
|
_;
|
||||||
|
}
|
||||||
|
|
||||||
|
function isWhitelistAdmin(address account) public view returns (bool) {
|
||||||
|
return _whitelistAdmins.has(account);
|
||||||
|
}
|
||||||
|
|
||||||
|
function addWhitelistAdmin(address account) public onlyWhitelistAdmin {
|
||||||
|
_addWhitelistAdmin(account);
|
||||||
|
}
|
||||||
|
|
||||||
|
function renounceWhitelistAdmin() public {
|
||||||
|
_removeWhitelistAdmin(msg.sender);
|
||||||
|
}
|
||||||
|
|
||||||
|
function _addWhitelistAdmin(address account) internal {
|
||||||
|
_whitelistAdmins.add(account);
|
||||||
|
emit WhitelistAdminAdded(account);
|
||||||
|
}
|
||||||
|
|
||||||
|
function _removeWhitelistAdmin(address account) internal {
|
||||||
|
_whitelistAdmins.remove(account);
|
||||||
|
emit WhitelistAdminRemoved(account);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,15 +1,15 @@
|
|||||||
pragma solidity ^0.5.0;
|
pragma solidity ^0.5.0;
|
||||||
|
|
||||||
import "../Roles.sol";
|
import "../Roles.sol";
|
||||||
import "./WhitelisterRole.sol";
|
import "./WhitelistAdminRole.sol";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @title WhitelistedRole
|
* @title WhitelistedRole
|
||||||
* @dev Whitelisted accounts have been approved by a Whitelister to perform certain actions (e.g. participate in a
|
* @dev Whitelisted accounts have been approved by a WhitelistAdmin to perform certain actions (e.g. participate in a
|
||||||
* crowdsale). This role is special in that the only accounts that can add it are Whitelisters (who can also remove it),
|
* crowdsale). This role is special in that the only accounts that can add it are WhitelistAdmins (who can also remove
|
||||||
* and not Whitelisteds themselves.
|
* it), and not Whitelisteds themselves.
|
||||||
*/
|
*/
|
||||||
contract WhitelistedRole is WhitelisterRole {
|
contract WhitelistedRole is WhitelistAdminRole {
|
||||||
using Roles for Roles.Role;
|
using Roles for Roles.Role;
|
||||||
|
|
||||||
event WhitelistedAdded(address indexed account);
|
event WhitelistedAdded(address indexed account);
|
||||||
@ -26,11 +26,11 @@ contract WhitelistedRole is WhitelisterRole {
|
|||||||
return _whitelisteds.has(account);
|
return _whitelisteds.has(account);
|
||||||
}
|
}
|
||||||
|
|
||||||
function addWhitelisted(address account) public onlyWhitelister {
|
function addWhitelisted(address account) public onlyWhitelistAdmin {
|
||||||
_addWhitelisted(account);
|
_addWhitelisted(account);
|
||||||
}
|
}
|
||||||
|
|
||||||
function removeWhitelisted(address account) public onlyWhitelister {
|
function removeWhitelisted(address account) public onlyWhitelistAdmin {
|
||||||
_removeWhitelisted(account);
|
_removeWhitelisted(account);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,47 +0,0 @@
|
|||||||
pragma solidity ^0.5.0;
|
|
||||||
|
|
||||||
import "../Roles.sol";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @title WhitelisterRole
|
|
||||||
* @dev Whitelisters are responsible for assigning and removing Whitelisted accounts.
|
|
||||||
*/
|
|
||||||
contract WhitelisterRole {
|
|
||||||
using Roles for Roles.Role;
|
|
||||||
|
|
||||||
event WhitelisterAdded(address indexed account);
|
|
||||||
event WhitelisterRemoved(address indexed account);
|
|
||||||
|
|
||||||
Roles.Role private _whitelisters;
|
|
||||||
|
|
||||||
constructor () internal {
|
|
||||||
_addWhitelister(msg.sender);
|
|
||||||
}
|
|
||||||
|
|
||||||
modifier onlyWhitelister() {
|
|
||||||
require(isWhitelister(msg.sender));
|
|
||||||
_;
|
|
||||||
}
|
|
||||||
|
|
||||||
function isWhitelister(address account) public view returns (bool) {
|
|
||||||
return _whitelisters.has(account);
|
|
||||||
}
|
|
||||||
|
|
||||||
function addWhitelister(address account) public onlyWhitelister {
|
|
||||||
_addWhitelister(account);
|
|
||||||
}
|
|
||||||
|
|
||||||
function renounceWhitelister() public {
|
|
||||||
_removeWhitelister(msg.sender);
|
|
||||||
}
|
|
||||||
|
|
||||||
function _addWhitelister(address account) internal {
|
|
||||||
_whitelisters.add(account);
|
|
||||||
emit WhitelisterAdded(account);
|
|
||||||
}
|
|
||||||
|
|
||||||
function _removeWhitelister(address account) internal {
|
|
||||||
_whitelisters.remove(account);
|
|
||||||
emit WhitelisterRemoved(account);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
17
contracts/mocks/WhitelistAdminRoleMock.sol
Normal file
17
contracts/mocks/WhitelistAdminRoleMock.sol
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
pragma solidity ^0.5.0;
|
||||||
|
|
||||||
|
import "../access/roles/WhitelistAdminRole.sol";
|
||||||
|
|
||||||
|
contract WhitelistAdminRoleMock is WhitelistAdminRole {
|
||||||
|
function removeWhitelistAdmin(address account) public {
|
||||||
|
_removeWhitelistAdmin(account);
|
||||||
|
}
|
||||||
|
|
||||||
|
function onlyWhitelistAdminMock() public view onlyWhitelistAdmin {
|
||||||
|
}
|
||||||
|
|
||||||
|
// Causes a compilation error if super._removeWhitelistAdmin is not internal
|
||||||
|
function _removeWhitelistAdmin(address account) internal {
|
||||||
|
super._removeWhitelistAdmin(account);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,17 +0,0 @@
|
|||||||
pragma solidity ^0.5.0;
|
|
||||||
|
|
||||||
import "../access/roles/WhitelisterRole.sol";
|
|
||||||
|
|
||||||
contract WhitelisterRoleMock is WhitelisterRole {
|
|
||||||
function removeWhitelister(address account) public {
|
|
||||||
_removeWhitelister(account);
|
|
||||||
}
|
|
||||||
|
|
||||||
function onlyWhitelisterMock() public view onlyWhitelister {
|
|
||||||
}
|
|
||||||
|
|
||||||
// Causes a compilation error if super._removeWhitelister is not internal
|
|
||||||
function _removeWhitelister(address account) internal {
|
|
||||||
super._removeWhitelister(account);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
11
test/access/roles/WhitelistAdminRole.test.js
Normal file
11
test/access/roles/WhitelistAdminRole.test.js
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
const { shouldBehaveLikePublicRole } = require('../../access/roles/PublicRole.behavior');
|
||||||
|
const WhitelistAdminRoleMock = artifacts.require('WhitelistAdminRoleMock');
|
||||||
|
|
||||||
|
contract('WhitelistAdminRole', function ([_, whitelistAdmin, otherWhitelistAdmin, ...otherAccounts]) {
|
||||||
|
beforeEach(async function () {
|
||||||
|
this.contract = await WhitelistAdminRoleMock.new({ from: whitelistAdmin });
|
||||||
|
await this.contract.addWhitelistAdmin(otherWhitelistAdmin, { from: whitelistAdmin });
|
||||||
|
});
|
||||||
|
|
||||||
|
shouldBehaveLikePublicRole(whitelistAdmin, otherWhitelistAdmin, otherAccounts, 'whitelistAdmin');
|
||||||
|
});
|
||||||
@ -1,12 +1,12 @@
|
|||||||
const { shouldBehaveLikePublicRole } = require('../../access/roles/PublicRole.behavior');
|
const { shouldBehaveLikePublicRole } = require('../../access/roles/PublicRole.behavior');
|
||||||
const WhitelistedRoleMock = artifacts.require('WhitelistedRoleMock');
|
const WhitelistedRoleMock = artifacts.require('WhitelistedRoleMock');
|
||||||
|
|
||||||
contract('WhitelistedRole', function ([_, whitelisted, otherWhitelisted, whitelister, ...otherAccounts]) {
|
contract('WhitelistedRole', function ([_, whitelisted, otherWhitelisted, whitelistAdmin, ...otherAccounts]) {
|
||||||
beforeEach(async function () {
|
beforeEach(async function () {
|
||||||
this.contract = await WhitelistedRoleMock.new({ from: whitelister });
|
this.contract = await WhitelistedRoleMock.new({ from: whitelistAdmin });
|
||||||
await this.contract.addWhitelisted(whitelisted, { from: whitelister });
|
await this.contract.addWhitelisted(whitelisted, { from: whitelistAdmin });
|
||||||
await this.contract.addWhitelisted(otherWhitelisted, { from: whitelister });
|
await this.contract.addWhitelisted(otherWhitelisted, { from: whitelistAdmin });
|
||||||
});
|
});
|
||||||
|
|
||||||
shouldBehaveLikePublicRole(whitelisted, otherWhitelisted, otherAccounts, 'whitelisted', whitelister);
|
shouldBehaveLikePublicRole(whitelisted, otherWhitelisted, otherAccounts, 'whitelisted', whitelistAdmin);
|
||||||
});
|
});
|
||||||
|
|||||||
@ -1,11 +0,0 @@
|
|||||||
const { shouldBehaveLikePublicRole } = require('../../access/roles/PublicRole.behavior');
|
|
||||||
const WhitelisterRoleMock = artifacts.require('WhitelisterRoleMock');
|
|
||||||
|
|
||||||
contract('WhitelisterRole', function ([_, whitelister, otherWhitelister, ...otherAccounts]) {
|
|
||||||
beforeEach(async function () {
|
|
||||||
this.contract = await WhitelisterRoleMock.new({ from: whitelister });
|
|
||||||
await this.contract.addWhitelister(otherWhitelister, { from: whitelister });
|
|
||||||
});
|
|
||||||
|
|
||||||
shouldBehaveLikePublicRole(whitelister, otherWhitelister, otherAccounts, 'whitelister');
|
|
||||||
});
|
|
||||||
Reference in New Issue
Block a user