Fix/whitelisted crowdsale (#981)
* fix: swithc WhitelistedCrowdsale to use Whitelist.sol * feat: refactor whitelist.sol, rbac.sol and whitelistedcrowdsale.sol * feat: add event arg assets and update whitelist * fix: update modifier comment and also test isWhitelisted * fix: remove onlyWhitelisted backwards compat attempt, fix explicit inheritance * fix: remove underscore prefix from event args * fix: user access/Whitelist
This commit is contained in:
@ -11,84 +11,80 @@ import "../ownership/rbac/RBAC.sol";
|
||||
* This simplifies the implementation of "user permissions".
|
||||
*/
|
||||
contract Whitelist is Ownable, RBAC {
|
||||
event WhitelistedAddressAdded(address addr);
|
||||
event WhitelistedAddressRemoved(address addr);
|
||||
|
||||
string public constant ROLE_WHITELISTED = "whitelist";
|
||||
|
||||
/**
|
||||
* @dev Throws if called by any account that's not whitelisted.
|
||||
* @dev Throws if operator is not whitelisted.
|
||||
* @param _operator address
|
||||
*/
|
||||
modifier onlyWhitelisted() {
|
||||
checkRole(msg.sender, ROLE_WHITELISTED);
|
||||
modifier onlyIfWhitelisted(address _operator) {
|
||||
checkRole(_operator, ROLE_WHITELISTED);
|
||||
_;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev add an address to the whitelist
|
||||
* @param addr address
|
||||
* @param _operator address
|
||||
* @return true if the address was added to the whitelist, false if the address was already in the whitelist
|
||||
*/
|
||||
function addAddressToWhitelist(address addr)
|
||||
function addAddressToWhitelist(address _operator)
|
||||
onlyOwner
|
||||
public
|
||||
{
|
||||
addRole(addr, ROLE_WHITELISTED);
|
||||
emit WhitelistedAddressAdded(addr);
|
||||
addRole(_operator, ROLE_WHITELISTED);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev getter to determine if address is in whitelist
|
||||
*/
|
||||
function whitelist(address addr)
|
||||
function whitelist(address _operator)
|
||||
public
|
||||
view
|
||||
returns (bool)
|
||||
{
|
||||
return hasRole(addr, ROLE_WHITELISTED);
|
||||
return hasRole(_operator, ROLE_WHITELISTED);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev add addresses to the whitelist
|
||||
* @param addrs addresses
|
||||
* @param _operators addresses
|
||||
* @return true if at least one address was added to the whitelist,
|
||||
* false if all addresses were already in the whitelist
|
||||
*/
|
||||
function addAddressesToWhitelist(address[] addrs)
|
||||
function addAddressesToWhitelist(address[] _operators)
|
||||
onlyOwner
|
||||
public
|
||||
{
|
||||
for (uint256 i = 0; i < addrs.length; i++) {
|
||||
addAddressToWhitelist(addrs[i]);
|
||||
for (uint256 i = 0; i < _operators.length; i++) {
|
||||
addAddressToWhitelist(_operators[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev remove an address from the whitelist
|
||||
* @param addr address
|
||||
* @param _operator address
|
||||
* @return true if the address was removed from the whitelist,
|
||||
* false if the address wasn't in the whitelist in the first place
|
||||
*/
|
||||
function removeAddressFromWhitelist(address addr)
|
||||
function removeAddressFromWhitelist(address _operator)
|
||||
onlyOwner
|
||||
public
|
||||
{
|
||||
removeRole(addr, ROLE_WHITELISTED);
|
||||
emit WhitelistedAddressRemoved(addr);
|
||||
removeRole(_operator, ROLE_WHITELISTED);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev remove addresses from the whitelist
|
||||
* @param addrs addresses
|
||||
* @param _operators addresses
|
||||
* @return true if at least one address was removed from the whitelist,
|
||||
* false if all addresses weren't in the whitelist in the first place
|
||||
*/
|
||||
function removeAddressesFromWhitelist(address[] addrs)
|
||||
function removeAddressesFromWhitelist(address[] _operators)
|
||||
onlyOwner
|
||||
public
|
||||
{
|
||||
for (uint256 i = 0; i < addrs.length; i++) {
|
||||
removeAddressFromWhitelist(addrs[i]);
|
||||
for (uint256 i = 0; i < _operators.length; i++) {
|
||||
removeAddressFromWhitelist(_operators[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,51 +1,14 @@
|
||||
pragma solidity ^0.4.24;
|
||||
|
||||
import "../Crowdsale.sol";
|
||||
import "../../ownership/Ownable.sol";
|
||||
import "../../access/Whitelist.sol";
|
||||
|
||||
|
||||
/**
|
||||
* @title WhitelistedCrowdsale
|
||||
* @dev Crowdsale in which only whitelisted users can contribute.
|
||||
*/
|
||||
contract WhitelistedCrowdsale is Crowdsale, Ownable {
|
||||
|
||||
mapping(address => bool) public whitelist;
|
||||
|
||||
/**
|
||||
* @dev Reverts if beneficiary is not whitelisted. Can be used when extending this contract.
|
||||
*/
|
||||
modifier isWhitelisted(address _beneficiary) {
|
||||
require(whitelist[_beneficiary]);
|
||||
_;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Adds single address to whitelist.
|
||||
* @param _beneficiary Address to be added to the whitelist
|
||||
*/
|
||||
function addToWhitelist(address _beneficiary) external onlyOwner {
|
||||
whitelist[_beneficiary] = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Adds list of addresses to whitelist. Not overloaded due to limitations with truffle testing.
|
||||
* @param _beneficiaries Addresses to be added to the whitelist
|
||||
*/
|
||||
function addManyToWhitelist(address[] _beneficiaries) external onlyOwner {
|
||||
for (uint256 i = 0; i < _beneficiaries.length; i++) {
|
||||
whitelist[_beneficiaries[i]] = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Removes single address from whitelist.
|
||||
* @param _beneficiary Address to be removed to the whitelist
|
||||
*/
|
||||
function removeFromWhitelist(address _beneficiary) external onlyOwner {
|
||||
whitelist[_beneficiary] = false;
|
||||
}
|
||||
|
||||
contract WhitelistedCrowdsale is Whitelist, Crowdsale {
|
||||
/**
|
||||
* @dev Extend parent behavior requiring beneficiary to be in whitelist.
|
||||
* @param _beneficiary Token beneficiary
|
||||
@ -55,8 +18,8 @@ contract WhitelistedCrowdsale is Crowdsale, Ownable {
|
||||
address _beneficiary,
|
||||
uint256 _weiAmount
|
||||
)
|
||||
onlyIfWhitelisted(_beneficiary)
|
||||
internal
|
||||
isWhitelisted(_beneficiary)
|
||||
{
|
||||
super._preValidatePurchase(_beneficiary, _weiAmount);
|
||||
}
|
||||
|
||||
@ -5,7 +5,7 @@ import "../access/Whitelist.sol";
|
||||
contract WhitelistMock is Whitelist {
|
||||
|
||||
function onlyWhitelistedCanDoThis()
|
||||
onlyWhitelisted
|
||||
onlyIfWhitelisted(msg.sender)
|
||||
view
|
||||
external
|
||||
{
|
||||
|
||||
@ -2,18 +2,18 @@ pragma solidity ^0.4.24;
|
||||
|
||||
import "../token/ERC20/ERC20.sol";
|
||||
import "../crowdsale/validation/WhitelistedCrowdsale.sol";
|
||||
import "../crowdsale/Crowdsale.sol";
|
||||
|
||||
|
||||
contract WhitelistedCrowdsaleImpl is WhitelistedCrowdsale {
|
||||
contract WhitelistedCrowdsaleImpl is Crowdsale, WhitelistedCrowdsale {
|
||||
|
||||
constructor (
|
||||
uint256 _rate,
|
||||
address _wallet,
|
||||
ERC20 _token
|
||||
)
|
||||
public
|
||||
Crowdsale(_rate, _wallet, _token)
|
||||
public
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -19,83 +19,83 @@ contract RBAC {
|
||||
|
||||
mapping (string => Roles.Role) private roles;
|
||||
|
||||
event RoleAdded(address addr, string roleName);
|
||||
event RoleRemoved(address addr, string roleName);
|
||||
event RoleAdded(address indexed operator, string role);
|
||||
event RoleRemoved(address indexed operator, string role);
|
||||
|
||||
/**
|
||||
* @dev reverts if addr does not have role
|
||||
* @param addr address
|
||||
* @param roleName the name of the role
|
||||
* @param _operator address
|
||||
* @param _role the name of the role
|
||||
* // reverts
|
||||
*/
|
||||
function checkRole(address addr, string roleName)
|
||||
function checkRole(address _operator, string _role)
|
||||
view
|
||||
public
|
||||
{
|
||||
roles[roleName].check(addr);
|
||||
roles[_role].check(_operator);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev determine if addr has role
|
||||
* @param addr address
|
||||
* @param roleName the name of the role
|
||||
* @param _operator address
|
||||
* @param _role the name of the role
|
||||
* @return bool
|
||||
*/
|
||||
function hasRole(address addr, string roleName)
|
||||
function hasRole(address _operator, string _role)
|
||||
view
|
||||
public
|
||||
returns (bool)
|
||||
{
|
||||
return roles[roleName].has(addr);
|
||||
return roles[_role].has(_operator);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev add a role to an address
|
||||
* @param addr address
|
||||
* @param roleName the name of the role
|
||||
* @param _operator address
|
||||
* @param _role the name of the role
|
||||
*/
|
||||
function addRole(address addr, string roleName)
|
||||
function addRole(address _operator, string _role)
|
||||
internal
|
||||
{
|
||||
roles[roleName].add(addr);
|
||||
emit RoleAdded(addr, roleName);
|
||||
roles[_role].add(_operator);
|
||||
emit RoleAdded(_operator, _role);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev remove a role from an address
|
||||
* @param addr address
|
||||
* @param roleName the name of the role
|
||||
* @param _operator address
|
||||
* @param _role the name of the role
|
||||
*/
|
||||
function removeRole(address addr, string roleName)
|
||||
function removeRole(address _operator, string _role)
|
||||
internal
|
||||
{
|
||||
roles[roleName].remove(addr);
|
||||
emit RoleRemoved(addr, roleName);
|
||||
roles[_role].remove(_operator);
|
||||
emit RoleRemoved(_operator, _role);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev modifier to scope access to a single role (uses msg.sender as addr)
|
||||
* @param roleName the name of the role
|
||||
* @param _role the name of the role
|
||||
* // reverts
|
||||
*/
|
||||
modifier onlyRole(string roleName)
|
||||
modifier onlyRole(string _role)
|
||||
{
|
||||
checkRole(msg.sender, roleName);
|
||||
checkRole(msg.sender, _role);
|
||||
_;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev modifier to scope access to a set of roles (uses msg.sender as addr)
|
||||
* @param roleNames the names of the roles to scope access to
|
||||
* @param _roles the names of the roles to scope access to
|
||||
* // reverts
|
||||
*
|
||||
* @TODO - when solidity supports dynamic arrays as arguments to modifiers, provide this
|
||||
* see: https://github.com/ethereum/solidity/issues/2467
|
||||
*/
|
||||
// modifier onlyRoles(string[] roleNames) {
|
||||
// modifier onlyRoles(string[] _roles) {
|
||||
// bool hasAnyRole = false;
|
||||
// for (uint8 i = 0; i < roleNames.length; i++) {
|
||||
// if (hasRole(msg.sender, roleNames[i])) {
|
||||
// for (uint8 i = 0; i < _roles.length; i++) {
|
||||
// if (hasRole(msg.sender, _roles[i])) {
|
||||
// hasAnyRole = true;
|
||||
// break;
|
||||
// }
|
||||
|
||||
Reference in New Issue
Block a user