@lazy-sol/access-control 1.0.6 → 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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;