@@ -5,24 +5,26 @@ import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
55import "@openzeppelin/contracts/security/Pausable.sol " ;
66import "@openzeppelin/contracts/utils/math/SafeMath.sol " ;
77import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol " ;
8+ import "@openzeppelin/contracts/access/AccessControlEnumerable.sol " ;
89
910/**
1011 * @title ERC20Distribution
1112 * @dev A token distribution contract that sells an initial supply of tokens at a
1213 linearly decreasing exchange rate. After depletion of the initial supply, tokens
1314 can be recycled and resold at the end rate
1415 */
15- contract ERC20Distribution is Pausable {
16+ contract ERC20Distribution is Pausable , AccessControlEnumerable {
1617 using SafeMath for uint256 ;
1718 using SafeERC20 for IERC20 ;
1819 using ECDSA for bytes32 ;
20+
21+ bytes32 public constant KYCMANAGER_ROLE = keccak256 ("KYCMANAGER_ROLE " );
1922
2023 event TokensSold (address recipient , uint256 amountToken , uint256 amountEth , uint256 actualRate );
2124
2225 IERC20 public _trusted_token;
2326 address payable public _beneficiary;
2427
25- address public _owner;
2628 address public _kyc_approver; // address that signs the KYC approval
2729
2830 uint256 private _startrate_distribution_e18; // stored internally in high res
@@ -62,11 +64,12 @@ contract ERC20Distribution is Pausable {
6264 "TokenDistribution: start rate should be > end rate "
6365 );
6466
67+ _setupRole (DEFAULT_ADMIN_ROLE, _msgSender ());
68+ _setupRole (KYCMANAGER_ROLE, _msgSender ());
69+
6570 _trusted_token = distToken;
6671 _beneficiary = distBeneficiary;
6772
68- _owner = msg .sender ;
69-
7073 _startrate_distribution_e18 = distStartRate * (10 ** 18 );
7174 _endrate_distribution_e18 = distEndRate * (10 ** 18 );
7275
@@ -92,8 +95,8 @@ contract ERC20Distribution is Pausable {
9295 }
9396
9497 /**
95- * @dev standard getter for total_distribution_balance
96- */
98+ * @dev standard getter for total_distribution_balance
99+ */
97100 function total_distribution_balance () public view virtual returns (uint256 ) {
98101 return _total_distribution_balance;
99102 }
@@ -157,8 +160,9 @@ contract ERC20Distribution is Pausable {
157160 * @dev Function that sets a new KYC Approver address
158161 */
159162 function changeKYCApprover (address newKYCApprover ) public {
160- require (msg .sender == _owner,
161- "Only the contract owner can change the KYCApprover "
163+ require (
164+ hasRole (KYCMANAGER_ROLE, _msgSender ()),
165+ "KYC: _msgSender() does not have the KYC manager role "
162166 );
163167
164168 _kyc_approver = newKYCApprover;
@@ -212,8 +216,8 @@ contract ERC20Distribution is Pausable {
212216 bytes calldata proof ,
213217 uint256 validTo ) public payable {
214218
215- // anyone but contract owner must pass kyc
216- if (msg . sender != _owner ) {
219+ // anyone but contract admins must pass kyc
220+ if (hasRole (DEFAULT_ADMIN_ROLE, _msgSender ()) == false ) {
217221 require (
218222 purchaseAllowed (proof, msg .sender , validTo),
219223 "Buyer did not pass KYC procedure "
0 commit comments