@lazy-sol/access-control 1.0.6 → 1.1.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,5 +1,5 @@
1
1
  // SPDX-License-Identifier: MIT
2
- pragma solidity >=0.4.22;
2
+ pragma solidity >=0.8.4;
3
3
 
4
4
  import "../AccessControl.sol";
5
5
 
@@ -11,4 +11,10 @@ contract AccessControlMock is AccessControl {
11
11
  function restricted() public restrictedTo(RESTRICTED_ROLE) {
12
12
  emit Restricted();
13
13
  }
14
+ function requireSenderInRole(uint256 required) public view {
15
+ _requireSenderInRole(required);
16
+ }
17
+ function requireAccessCondition(bool condition) public pure {
18
+ _requireAccessCondition(condition);
19
+ }
14
20
  }
package/hardhat.config.js CHANGED
@@ -453,12 +453,12 @@ function get_endpoint_url(network_name) {
453
453
  // create a key: https://www.alchemy.com/
454
454
  if(process.env.ALCHEMY_KEY) {
455
455
  switch(network_name) {
456
- case "mainnet": return "https://eth-mainnet.alchemyapi.io/v2/" + process.env.ALCHEMY_KEY;
457
- case "ropsten": return "https://eth-ropsten.alchemyapi.io/v2/" + process.env.ALCHEMY_KEY;
458
- case "rinkeby": return "https://eth-rinkeby.alchemyapi.io/v2/" + process.env.ALCHEMY_KEY;
459
- case "kovan": return "https://eth-kovan.alchemyapi.io/v2/" + process.env.ALCHEMY_KEY;
460
- case "goerli": return "https://eth-goerli.alchemyapi.io/v2/" + process.env.ALCHEMY_KEY;
461
- case "sepolia": return "https://eth-sepolia.alchemyapi.io/v2/" + process.env.ALCHEMY_KEY;
456
+ case "mainnet": return "https://eth-mainnet.g.alchemyapi.io/v2/" + process.env.ALCHEMY_KEY;
457
+ case "ropsten": return "https://eth-ropsten.g.alchemyapi.io/v2/" + process.env.ALCHEMY_KEY;
458
+ case "rinkeby": return "https://eth-rinkeby.g.alchemyapi.io/v2/" + process.env.ALCHEMY_KEY;
459
+ case "kovan": return "https://eth-kovan.g.alchemyapi.io/v2/" + process.env.ALCHEMY_KEY;
460
+ case "goerli": return "https://eth-goerli.g.alchemyapi.io/v2/" + process.env.ALCHEMY_KEY;
461
+ case "sepolia": return "https://eth-sepolia.g.alchemyapi.io/v2/" + process.env.ALCHEMY_KEY;
462
462
  case "polygon": return "https://polygon-mainnet.g.alchemy.com/v2/" + process.env.ALCHEMY_KEY;
463
463
  case "mumbai": return "https://polygon-mumbai.g.alchemy.com/v2/" + process.env.ALCHEMY_KEY;
464
464
  case "base_mainnet": return "https://base-mainnet.g.alchemy.com/v2/" + process.env.ALCHEMY_KEY;
package/index.js CHANGED
@@ -9,6 +9,9 @@ const {
9
9
  not,
10
10
  } = require("./scripts/include/features_roles");
11
11
 
12
+ // RBAC behaviours
13
+ const {behavesLikeRBAC} = require("./test/include/rbac.behaviour");
14
+
12
15
  // Re-export the functions
13
16
  module.exports = {
14
17
  ROLE_ACCESS_MANAGER,
@@ -16,4 +19,5 @@ module.exports = {
16
19
  FULL_PRIVILEGES_MASK,
17
20
  or,
18
21
  not,
22
+ behavesLikeRBAC,
19
23
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lazy-sol/access-control",
3
- "version": "1.0.6",
3
+ "version": "1.1.1",
4
4
  "description": "Enable the modular plug and play (PnP) architecture for your dapp by incorporating the role-based access control (RBAC) into the smart contracts",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -21,19 +21,21 @@
21
21
  ],
22
22
  "author": "Basil Gorin",
23
23
  "license": "MIT",
24
- "dependencies": {
25
- "@lazy-sol/a-missing-gem": "^1.0.9",
26
- "@nomiclabs/hardhat-truffle5": "^2.0.7",
27
- "hardhat": "^2.22.6",
28
- "hardhat-deploy": "^0.11.45"
29
- },
30
24
  "devDependencies": {
31
- "@lazy-sol/zeppelin-test-helpers": "^1.0.1",
25
+ "@lazy-sol/a-missing-gem": "^1.0.10",
26
+ "@lazy-sol/zeppelin-test-helpers": "^1.0.5",
27
+ "@nomiclabs/hardhat-truffle5": "^2.0.7",
28
+ "hardhat": "^2.22.13",
29
+ "hardhat-deploy": "^0.11.45",
32
30
  "hardhat-gas-reporter": "^1.0.10",
33
- "solidity-coverage": "^0.8.12"
31
+ "solidity-coverage": "^0.8.13"
34
32
  },
35
33
  "overrides": {
34
+ "axios": ">=1.7.5",
35
+ "micromatch": "^4.0.8",
36
+ "tar": "^6.2.1",
36
37
  "tough-cookie": "^4.1.3",
37
- "yargs-parser": "^5.0.1"
38
+ "yargs-parser": "^5.0.1",
39
+ "ws": "^8.0.0"
38
40
  }
39
41
  }
@@ -3,23 +3,14 @@
3
3
  * (doesn't return any value on successful operation)
4
4
  *
5
5
  * @param a0 smart contract owner
6
- * @param H0 initial token holder address
7
6
  * @returns USDT ERC20 instance
8
7
  */
9
- async function deploy_usdt(a0, H0 = a0) {
8
+ async function deploy_usdt(a0) {
10
9
  // smart contracts required
11
10
  const USDTContract = artifacts.require("TetherToken");
12
11
 
13
- // deploy the token
14
- const token = await USDTContract.new(0, "Tether USD", "USDT", 6, {from: a0});
15
-
16
- // move the initial supply if required
17
- if(H0 !== a0) {
18
- await token.transfer(H0, S0, {from: a0});
19
- }
20
-
21
- // return the reference
22
- return token;
12
+ // deploy the token and return the reference
13
+ return await USDTContract.new(0, "Tether USD", "USDT", 6, {from: a0});
23
14
  }
24
15
 
25
16
  /**
@@ -15,16 +15,17 @@ const {
15
15
  MAX_UINT256,
16
16
  } = constants;
17
17
 
18
- // BN utils
18
+ // BN constants and utilities
19
19
  const {
20
20
  random_bn255,
21
21
  random_bn256,
22
- } = require("@lazy-sol/a-missing-gem/bn_utils");
22
+ } = require("@lazy-sol/a-missing-gem");
23
23
 
24
24
  // RBAC core features and roles
25
25
  const {
26
26
  not,
27
- ROLE_ACCESS_MANAGER, FULL_PRIVILEGES_MASK,
27
+ ROLE_ACCESS_MANAGER,
28
+ FULL_PRIVILEGES_MASK,
28
29
  } = require("../../scripts/include/features_roles");
29
30
 
30
31
  /**
@@ -40,6 +41,18 @@ function behavesLikeRBAC(deployment_fn, a0, a1, a2) {
40
41
  const by = a1;
41
42
  const to = a2;
42
43
 
44
+ describe("requireAccessCondition(condition) pure function", function() {
45
+ let access_control;
46
+ beforeEach(async function() {
47
+ access_control = await deployment_fn.call(this, a0, ZERO_ADDRESS, 0);
48
+ });
49
+ it("throws if condition is false", async function() {
50
+ await expectRevert(access_control.requireAccessCondition(false, {from: a0}), "AccessDenied()");
51
+ });
52
+ it("succeeds if condition is true", async function() {
53
+ await access_control.requireAccessCondition(true, {from: a0});
54
+ });
55
+ });
43
56
  describe("deployment and initial state", function() {
44
57
  function deploy_and_check(owner, features) {
45
58
  let access_control;
@@ -81,7 +94,7 @@ function behavesLikeRBAC(deployment_fn, a0, a1, a2) {
81
94
  deploy_and_check(a1, random_bn256());
82
95
  });
83
96
  });
84
- describe("when deployed with not initial features", function() {
97
+ describe("when deployed with no initial features", function() {
85
98
  let access_control;
86
99
  beforeEach(async function() {
87
100
  access_control = await deployment_fn.call(this, a0);
@@ -92,7 +105,7 @@ function behavesLikeRBAC(deployment_fn, a0, a1, a2) {
92
105
  beforeEach(async function() {
93
106
  await access_control.updateRole(by, ROLE_ACCESS_MANAGER, {from: a0});
94
107
  });
95
- describe("when ACCESS_MANAGER has full set of permissions", function() {
108
+ describe("when ACCESS_MANAGER has the full set of permissions", function() {
96
109
  beforeEach(async function() {
97
110
  await access_control.updateRole(by, MAX_UINT256, {from: a0});
98
111
  });
@@ -271,6 +284,7 @@ function behavesLikeRBAC(deployment_fn, a0, a1, a2) {
271
284
  it("operator becomes an ACCESS_MANAGER", async function() {
272
285
  expect(await access_control.isOperatorInRole(to, ROLE_ACCESS_MANAGER), "operator").to.be.true;
273
286
  expect(await access_control.isSenderInRole(ROLE_ACCESS_MANAGER, {from: to}), "sender").to.be.true;
287
+ await access_control.requireSenderInRole(ROLE_ACCESS_MANAGER, {from: to});
274
288
  });
275
289
  });
276
290
  describe("when ACCESS_MANAGER revokes ACCESS_MANAGER permission from itself", function() {
@@ -280,15 +294,16 @@ function behavesLikeRBAC(deployment_fn, a0, a1, a2) {
280
294
  it("operator ceases to be an ACCESS_MANAGER", async function() {
281
295
  expect(await access_control.isOperatorInRole(by, ROLE_ACCESS_MANAGER), "operator").to.be.false;
282
296
  expect(await access_control.isSenderInRole(ROLE_ACCESS_MANAGER, {from: by}), "sender").to.be.false;
297
+ await expectRevert(access_control.requireSenderInRole(ROLE_ACCESS_MANAGER, {from: to}), "AccessDenied()");
283
298
  });
284
299
  });
285
300
  });
286
301
  describe("otherwise (no ACCESS_MANAGER permission)", function() {
287
302
  it("updateFeatures reverts", async function() {
288
- await expectRevert(access_control.updateFeatures(1, {from: by}), "access denied");
303
+ await expectRevert(access_control.updateFeatures(1, {from: by}), "AccessDenied()");
289
304
  });
290
305
  it("updateRole reverts", async function() {
291
- await expectRevert(access_control.updateRole(to, 1, {from: by}), "access denied");
306
+ await expectRevert(access_control.updateRole(to, 1, {from: by}), "AccessDenied()");
292
307
  });
293
308
  });
294
309
  }
@@ -72,7 +72,7 @@ contract("OwnableToAccessControlAdapter tests", function(accounts) {
72
72
  from: a1,
73
73
  to: adapter.address,
74
74
  data: target.contract.methods.transferOwnership(a2).encodeABI(),
75
- }), "access denied");
75
+ }), "AccessDenied()");
76
76
  });
77
77
  describe("once an account has authorization to execute transferOwnership function", function() {
78
78
  beforeEach(async function() {
@@ -43,12 +43,12 @@ contract("OwnableToAccessControlAdapter: RBAC tests", function(accounts) {
43
43
  ({target, adapter} = await deploy_ownable_to_ac_adapter(a0));
44
44
  });
45
45
 
46
- it("it is impossible to configure the access role from unauthorized account", async function() {
46
+ it("it is impossible to configure the access role from an unauthorized account", async function() {
47
47
  const operator = a1;
48
48
  await adapter.updateRole(operator, not(ROLE_ACCESS_ROLES_MANAGER), {from: a0});
49
- await expectRevert(adapter.updateAccessRole("1", 1, {from: operator}), "access denied");
49
+ await expectRevert(adapter.updateAccessRole("1", 1, {from: operator}), "AccessDenied()");
50
50
  });
51
- it("it is possible to configure the access role from authorized account", async function() {
51
+ it("it is possible to configure the access role from the authorized account", async function() {
52
52
  const operator = a1;
53
53
  await adapter.updateRole(operator, ROLE_ACCESS_ROLES_MANAGER, {from: a0});
54
54
  adapter.updateAccessRole("1", 1, {from: operator});
@@ -38,7 +38,7 @@ contract('AccessControl (RBAC) "restrictedTo" Modifier tests', function(accounts
38
38
  access_control = await deploy_access_control(a0);
39
39
  });
40
40
  it("function protected with restrictedTo modifier fails when run not by an admin", async function() {
41
- await expectRevert(access_control.restricted({from: a1}), "access denied");
41
+ await expectRevert(access_control.restricted({from: a1}), "AccessDenied()");
42
42
  });
43
43
  describe("function protected with restrictedTo modifier succeeds when run by admin", async function() {
44
44
  let receipt;