@lazy-sol/access-control 1.0.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,150 @@
1
+ /**
2
+ * Deploys USDT token, used to test non ERC20 compliant transfer function
3
+ * (doesn't return any value on successful operation)
4
+ *
5
+ * @param a0 smart contract owner
6
+ * @param H0 initial token holder address
7
+ * @returns USDT ERC20 instance
8
+ */
9
+ async function deploy_usdt(a0, H0 = a0) {
10
+ // smart contracts required
11
+ const USDTContract = artifacts.require("TetherToken");
12
+
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;
23
+ }
24
+
25
+ /**
26
+ * Deploys AccessControl contract
27
+ *
28
+ * @param a0 smart contract deployer
29
+ * @param owner smart contract owner, super admin, optional
30
+ * @param features initial smart contract features, optional
31
+ * @returns AccessControl instance
32
+ */
33
+ async function deploy_access_control(a0, owner = a0, features = 0) {
34
+ // deploy AccessControlMock
35
+ const AccessControlMock = artifacts.require("AccessControlMock");
36
+
37
+ // deploy and return the instance
38
+ return await AccessControlMock.new(owner, features, {from: a0});
39
+ }
40
+
41
+ /**
42
+ * Deploys OwnableToAccessControlAdapter
43
+ * Deploys OZ Ownable contract (TetherToken) if target is not specified
44
+ * Transfers the ownership on the ownable to the adapter
45
+ *
46
+ * @param a0 smart contract deployer, owner, super admin
47
+ * @param target target OZ Ownable contract address or instance, optional
48
+ * @returns OwnableToAccessControlAdapter instance
49
+ */
50
+ async function deploy_ownable_to_ac_adapter(a0, target) {
51
+ // deploy the target if required
52
+ if(!target) {
53
+ target = await deploy_usdt(a0);
54
+ }
55
+ // wrap the target into the Ownable if required
56
+ else if(!target.address) {
57
+ const Ownable = artifacts.require("contracts/AdapterFactory.sol:Ownable");
58
+ target = await Ownable.at(target);
59
+ }
60
+
61
+ // deploy adapter
62
+ const adapter = await deploy_no_deps_ownable_to_ac_adapter(a0, target);
63
+
64
+ // transfer ownership to the adapter
65
+ await target.transferOwnership(adapter.address, {from: a0});
66
+
67
+ // return both instances
68
+ return {target, adapter};
69
+ }
70
+
71
+ /**
72
+ * Deploys OwnableToAccessControlAdapter
73
+ *
74
+ * @param a0 smart contract deployer, owner, super admin
75
+ * @param target target OZ Ownable contract address or instance, required
76
+ * @returns OwnableToAccessControlAdapter instance
77
+ */
78
+ async function deploy_no_deps_ownable_to_ac_adapter(a0, target) {
79
+ // artifacts in use
80
+ const OwnableToAccessControlAdapter = artifacts.require("OwnableToAccessControlAdapter");
81
+ // deploy and return the deployd instance
82
+ return await OwnableToAccessControlAdapter.new(target.address || target, a0, {from: a0});
83
+ }
84
+
85
+ /**
86
+ * Deploys the AdapterFactory
87
+ *
88
+ * @param a0 deployer address, optional
89
+ * @returns AdapterFactory instance
90
+ */
91
+ async function deploy_adapter_factory(a0) {
92
+ // artifacts in use
93
+ const AdapterFactory = artifacts.require("AdapterFactory");
94
+ // deploy and return the deployd instance
95
+ return await AdapterFactory.new(a0? {from: a0}: undefined);
96
+ }
97
+
98
+ /**
99
+ * Deploys OwnableToAccessControlAdapter via the AdapterFactory
100
+ * Deploys the AdapterFactory and target Ownable if required
101
+ *
102
+ * @param a0 deployer address, target owner, required
103
+ * @param factory AdapterFactory instance or address, optional
104
+ * @param target Ownable instance or address, optional
105
+ * @returns OwnableToAccessControlAdapter instance
106
+ */
107
+ async function factory_deploy_ownable_to_ac_adapter(a0, factory, target) {
108
+ if(!factory) {
109
+ factory = await deploy_adapter_factory(a0);
110
+ }
111
+ else if(!factory.address) {
112
+ const AdapterFactory = artifacts.require("AdapterFactory");
113
+ factory = await AdapterFactory.at(factory);
114
+ }
115
+
116
+ if(!target) {
117
+ target = await deploy_usdt(a0);
118
+ }
119
+ else if(!target.address) {
120
+ const Ownable = artifacts.require("contracts/AdapterFactory.sol:Ownable");
121
+ target = await Ownable.at(target);
122
+ }
123
+
124
+ // deploy the adapter via the AdapterFactory
125
+ const receipt = await factory.deployNewOwnableToAccessControlAdapter(target.address, {from: a0});
126
+ const {
127
+ adapterAddress,
128
+ ownableTargetAddress,
129
+ } = receipt.logs.find(log => log.event === "NewOwnableToAccessControlAdapterDeployed").args;
130
+
131
+ // connect to the adapter
132
+ const OwnableToAccessControlAdapter = artifacts.require("OwnableToAccessControlAdapter");
133
+ const adapter = await OwnableToAccessControlAdapter.at(adapterAddress);
134
+
135
+ // transfer ownership to the adapter
136
+ await target.transferOwnership(adapter.address, {from: a0});
137
+
138
+ // return the results
139
+ return {factory, target, adapter};
140
+ }
141
+
142
+ // export public deployment API
143
+ module.exports = {
144
+ deploy_usdt,
145
+ deploy_access_control,
146
+ deploy_no_deps_ownable_to_ac_adapter,
147
+ deploy_ownable_to_ac_adapter,
148
+ deploy_adapter_factory,
149
+ factory_deploy_ownable_to_ac_adapter,
150
+ }
@@ -0,0 +1,42 @@
1
+ // copy and export all the features and roles constants from different contracts
2
+
3
+ // Auxiliary BN stuff
4
+ const BN = web3.utils.BN;
5
+ const TWO = new BN(2);
6
+
7
+ // Access manager is responsible for assigning the roles to users,
8
+ // enabling/disabling global features of the smart contract
9
+ const ROLE_ACCESS_MANAGER = TWO.pow(new BN(255));
10
+
11
+ // Upgrade manager is responsible for smart contract upgrades
12
+ const ROLE_UPGRADE_MANAGER = TWO.pow(new BN(254));
13
+
14
+ // Access Roles manager is responsible for assigning the access roles to functions
15
+ const ROLE_ACCESS_ROLES_MANAGER = TWO.pow(new BN(253));
16
+
17
+ // Bitmask representing all the possible permissions (super admin role)
18
+ const FULL_PRIVILEGES_MASK = TWO.pow(new BN(256)).subn(1);
19
+
20
+ // combine the role (permission set) provided
21
+ function or(...roles) {
22
+ let roles_sum = new BN(0);
23
+ for(let role of roles) {
24
+ roles_sum = roles_sum.or(new BN(role));
25
+ }
26
+ return roles_sum;
27
+ }
28
+
29
+ // negates the role (permission set) provided
30
+ function not(...roles) {
31
+ return FULL_PRIVILEGES_MASK.xor(or(...roles));
32
+ }
33
+
34
+ // export public module API
35
+ module.exports = {
36
+ ROLE_ACCESS_MANAGER,
37
+ ROLE_UPGRADE_MANAGER,
38
+ ROLE_ACCESS_ROLES_MANAGER,
39
+ FULL_PRIVILEGES_MASK,
40
+ or,
41
+ not,
42
+ };
@@ -0,0 +1,315 @@
1
+ // Zeppelin test helpers
2
+ const {
3
+ BN,
4
+ constants,
5
+ expectEvent,
6
+ expectRevert,
7
+ } = require("@openzeppelin/test-helpers");
8
+ const {
9
+ assert,
10
+ expect,
11
+ } = require("chai");
12
+ const {
13
+ ZERO_ADDRESS,
14
+ ZERO_BYTES32,
15
+ MAX_UINT256,
16
+ } = constants;
17
+
18
+ // BN utils
19
+ const {
20
+ random_bn255,
21
+ random_bn256,
22
+ } = require("@lazy-sol/a-missing-jem/bn_utils");
23
+
24
+ // RBAC core features and roles
25
+ const {
26
+ not,
27
+ ROLE_ACCESS_MANAGER, FULL_PRIVILEGES_MASK,
28
+ } = require("./features_roles");
29
+
30
+ /**
31
+ * RBAC core behaviour
32
+ *
33
+ * @param deployment_fn RBAC contract deployment function
34
+ * @param a0 deployer/admin account
35
+ * @param a1 participant 1
36
+ * @param a2 participant 2
37
+ */
38
+ function behavesLikeRBAC(deployment_fn, a0, a1, a2) {
39
+ // define the "players"
40
+ const by = a1;
41
+ const to = a2;
42
+
43
+ describe("deployment and initial state", function() {
44
+ function deploy_and_check(owner, features) {
45
+ let access_control;
46
+ beforeEach(async function() {
47
+ access_control = await deployment_fn.call(this, a0, owner, features);
48
+ });
49
+ it('"RoleUpdated(owner)" event is emitted correctly', async function() {
50
+ await expectEvent.inConstruction(access_control, "RoleUpdated", {
51
+ operator: owner,
52
+ requested: FULL_PRIVILEGES_MASK,
53
+ assigned: FULL_PRIVILEGES_MASK,
54
+ });
55
+ });
56
+ it('"RoleUpdated(this)" event is emitted correctly', async function() {
57
+ await expectEvent.inConstruction(access_control, "RoleUpdated", {
58
+ operator: access_control.address,
59
+ requested: features,
60
+ assigned: features,
61
+ });
62
+ });
63
+ it("owners' role is set correctly", async function() {
64
+ expect(await access_control.getRole(owner)).to.be.bignumber.that.equals(FULL_PRIVILEGES_MASK);
65
+ });
66
+ it("features are set correctly", async function() {
67
+ expect(await access_control.features()).to.be.bignumber.that.equals(features);
68
+ });
69
+ }
70
+
71
+ describe("owner = 0, features = 0", function() {
72
+ deploy_and_check(ZERO_ADDRESS, new BN(0));
73
+ });
74
+ describe("owner = 0, features ≠ 0", function() {
75
+ deploy_and_check(ZERO_ADDRESS, random_bn256());
76
+ });
77
+ describe("owner ≠ 0, features = 0", function() {
78
+ deploy_and_check(a1, new BN(0));
79
+ });
80
+ describe("owner ≠ 0, features ≠ 0", function() {
81
+ deploy_and_check(a1, random_bn256());
82
+ });
83
+ });
84
+ describe("when deployed with not initial features", function() {
85
+ let access_control;
86
+ beforeEach(async function() {
87
+ access_control = await deployment_fn.call(this, a0);
88
+ });
89
+
90
+ function test_suite(write_fn, read_fn, check_fn, to_fn) {
91
+ describe("when performed by ACCESS_MANAGER", function() {
92
+ beforeEach(async function() {
93
+ await access_control.updateRole(by, ROLE_ACCESS_MANAGER, {from: a0});
94
+ });
95
+ describe("when ACCESS_MANAGER has full set of permissions", function() {
96
+ beforeEach(async function() {
97
+ await access_control.updateRole(by, MAX_UINT256, {from: a0});
98
+ });
99
+ describe("what you set", function() {
100
+ let receipt, set;
101
+ beforeEach(async function() {
102
+ // do not touch the highest permission bit (ACCESS_MANAGER permission)
103
+ set = random_bn255();
104
+ receipt = await write_fn(by, to, set);
105
+ });
106
+ describe("is what you get", function() {
107
+ it('"userRoles" value', async function() {
108
+ expect(await read_fn(to)).to.be.bignumber.that.equals(set);
109
+ });
110
+ it("role check (isOperatorInRole/isFeatureEnabled)", async function() {
111
+ expect(await check_fn(to, set)).to.be.true;
112
+ });
113
+ it('"RoleUpdated" event', async function() {
114
+ expectEvent(receipt, "RoleUpdated", {
115
+ operator: to_fn(to),
116
+ requested: set,
117
+ assigned: set,
118
+ });
119
+ });
120
+ });
121
+ });
122
+ describe("what you remove", function() {
123
+ let receipt, remove;
124
+ beforeEach(async function() {
125
+ // do not touch the highest permission bit (ACCESS_MANAGER permission)
126
+ remove = random_bn255();
127
+ receipt = await write_fn(by, to, not(remove));
128
+ });
129
+ describe("is what gets removed", function() {
130
+ it('"userRoles" value', async function() {
131
+ expect(await read_fn(to)).to.be.bignumber.that.equals(not(remove));
132
+ });
133
+ it("role check (isOperatorInRole/isFeatureEnabled)", async function() {
134
+ expect(await check_fn(to, not(remove))).to.be.true;
135
+ });
136
+ it('"RoleUpdated" event', async function() {
137
+ expectEvent(receipt, "RoleUpdated", {
138
+ operator: to_fn(to),
139
+ requested: not(remove),
140
+ assigned: not(remove),
141
+ });
142
+ });
143
+ });
144
+ });
145
+ });
146
+ describe("when ACCESS_MANAGER doesn't have any permissions", function() {
147
+ describe("what you get, independently of what you set", function() {
148
+ let receipt, set;
149
+ beforeEach(async function() {
150
+ // do not touch the highest permission bit (ACCESS_MANAGER permission)
151
+ set = random_bn255();
152
+ receipt = await write_fn(by, to, set);
153
+ });
154
+ describe("is always zero", function() {
155
+ it('"userRoles" value', async function() {
156
+ expect(await read_fn(to)).to.be.bignumber.that.is.zero;
157
+ });
158
+ it("role check (isOperatorInRole/isFeatureEnabled)", async function() {
159
+ expect(await check_fn(to, set)).to.be.false;
160
+ });
161
+ it('"RoleUpdated" event', async function() {
162
+ expectEvent(receipt, "RoleUpdated", {
163
+ operator: to_fn(to),
164
+ requested: set,
165
+ assigned: "0",
166
+ });
167
+ });
168
+ });
169
+ });
170
+ describe("what you get, independently of what you remove", function() {
171
+ let receipt, remove;
172
+ beforeEach(async function() {
173
+ // do not touch the highest permission bit (ACCESS_MANAGER permission)
174
+ remove = random_bn255();
175
+ await write_fn(a0, to, MAX_UINT256);
176
+ receipt = await write_fn(by, to, not(remove));
177
+ });
178
+ describe("is always what you had", function() {
179
+ it('"userRoles" value', async function() {
180
+ expect(await read_fn(to)).to.be.bignumber.that.equals(MAX_UINT256);
181
+ });
182
+ it("role check (isOperatorInRole/isFeatureEnabled)", async function() {
183
+ expect(await check_fn(to, MAX_UINT256)).to.be.true;
184
+ });
185
+ it('"RoleUpdated" event', async function() {
186
+ expectEvent(receipt, "RoleUpdated", {
187
+ operator: to_fn(to),
188
+ requested: not(remove),
189
+ assigned: MAX_UINT256,
190
+ });
191
+ });
192
+ });
193
+ });
194
+ });
195
+ describe("when ACCESS_MANAGER has some permissions", function() {
196
+ let role;
197
+ beforeEach(async function() {
198
+ // do not touch the highest permission bit (ACCESS_MANAGER permission)
199
+ role = random_bn255();
200
+ await access_control.updateRole(by, ROLE_ACCESS_MANAGER.or(role), {from: a0});
201
+ });
202
+ describe("what you get", function() {
203
+ let receipt, set;
204
+ beforeEach(async function() {
205
+ // do not touch the highest permission bit (ACCESS_MANAGER permission)
206
+ set = random_bn255();
207
+ receipt = await write_fn(by, to, set);
208
+ });
209
+ describe("is an intersection of what you set and what you have", function() {
210
+ it('"userRoles" value', async function() {
211
+ expect(await read_fn(to)).to.be.bignumber.that.equals(role.and(set));
212
+ });
213
+ it("role check (isOperatorInRole/isFeatureEnabled)", async function() {
214
+ expect(await check_fn(to, role.and(set))).to.be.true;
215
+ });
216
+ it('"RoleUpdated" event', async function() {
217
+ expectEvent(receipt, "RoleUpdated", {
218
+ operator: to_fn(to),
219
+ requested: set,
220
+ assigned: role.and(set),
221
+ });
222
+ });
223
+ });
224
+ });
225
+ describe("what you remove", function() {
226
+ let receipt, remove;
227
+ beforeEach(async function() {
228
+ // do not touch the highest permission bit (ACCESS_MANAGER permission)
229
+ remove = random_bn255();
230
+ await write_fn(a0, to, MAX_UINT256);
231
+ receipt = await write_fn(by, to, not(remove));
232
+ });
233
+ describe("is an intersection of what you tried to remove and what you have", function() {
234
+ it('"userRoles" value', async function() {
235
+ expect(await read_fn(to)).to.be.bignumber.that.equals(not(role.and(remove)));
236
+ });
237
+ it("role check (isOperatorInRole/isFeatureEnabled)", async function() {
238
+ expect(await check_fn(to, not(role.and(remove)))).to.be.true;
239
+ });
240
+ it('"RoleUpdated" event', async function() {
241
+ expectEvent(receipt, "RoleUpdated", {
242
+ operator: to_fn(to),
243
+ requested: not(remove),
244
+ assigned: not(role.and(remove)),
245
+ });
246
+ });
247
+ });
248
+ });
249
+ });
250
+ describe("ACCESS_MANAGER updates itself", function() {
251
+ beforeEach(async function() {
252
+ // do not touch the highest permission bit (ACCESS_MANAGER permission)
253
+ const role = random_bn255();
254
+ await access_control.updateRole(by, ROLE_ACCESS_MANAGER.or(role), {from: a0});
255
+ });
256
+ it("and degrades to zero with the 99.99% probability in 14 runs", async function() {
257
+ // randomly remove 255 bits of permissions
258
+ for(let i = 0; i < 14; i++) {
259
+ // do not touch the highest permission bit (ACCESS_MANAGER permission)
260
+ const role = random_bn255();
261
+ await access_control.updateRole(by, not(role), {from: by});
262
+ }
263
+ // this may fail with the probability 2^(-14) < 0.01%
264
+ expect(await access_control.getRole(by)).to.be.bignumber.that.equals(ROLE_ACCESS_MANAGER);
265
+ })
266
+ });
267
+ describe("when ACCESS_MANAGER grants ACCESS_MANAGER permission", function() {
268
+ beforeEach(async function() {
269
+ await access_control.updateRole(to, ROLE_ACCESS_MANAGER, {from: by});
270
+ });
271
+ it("operator becomes an ACCESS_MANAGER", async function() {
272
+ expect(await access_control.isOperatorInRole(to, ROLE_ACCESS_MANAGER), "operator").to.be.true;
273
+ expect(await access_control.isSenderInRole(ROLE_ACCESS_MANAGER, {from: to}), "sender").to.be.true;
274
+ });
275
+ });
276
+ describe("when ACCESS_MANAGER revokes ACCESS_MANAGER permission from itself", function() {
277
+ beforeEach(async function() {
278
+ await access_control.updateRole(by, 0, {from: by});
279
+ });
280
+ it("operator ceases to be an ACCESS_MANAGER", async function() {
281
+ expect(await access_control.isOperatorInRole(by, ROLE_ACCESS_MANAGER), "operator").to.be.false;
282
+ expect(await access_control.isSenderInRole(ROLE_ACCESS_MANAGER, {from: by}), "sender").to.be.false;
283
+ });
284
+ });
285
+ });
286
+ describe("otherwise (no ACCESS_MANAGER permission)", function() {
287
+ it("updateFeatures reverts", async function() {
288
+ await expectRevert(access_control.updateFeatures(1, {from: by}), "access denied");
289
+ });
290
+ it("updateRole reverts", async function() {
291
+ await expectRevert(access_control.updateRole(to, 1, {from: by}), "access denied");
292
+ });
293
+ });
294
+ }
295
+
296
+ // run two test suites to test get/set role and get/set features
297
+ test_suite(
298
+ async(by, to, set) => await access_control.updateRole(to, set, {from: by}),
299
+ async(op) => await access_control.getRole(op),
300
+ async(op, role) => await access_control.isOperatorInRole(op, role),
301
+ (to) => to
302
+ );
303
+ test_suite(
304
+ async(by, to, set) => await access_control.updateFeatures(set, {from: by}),
305
+ async(op) => await access_control.features(),
306
+ async(op, role) => await access_control.isFeatureEnabled(role),
307
+ (to) => access_control.address
308
+ );
309
+ });
310
+ }
311
+
312
+ // export the RBAC core behaviour
313
+ module.exports = {
314
+ behavesLikeRBAC,
315
+ }
@@ -0,0 +1,100 @@
1
+ // OwnableToAccessControlAdapter tests
2
+
3
+ // Zeppelin test helpers
4
+ const {
5
+ BN,
6
+ constants,
7
+ expectEvent,
8
+ expectRevert,
9
+ } = require("@openzeppelin/test-helpers");
10
+ const {
11
+ assert,
12
+ expect,
13
+ } = require("chai");
14
+ const {
15
+ ZERO_ADDRESS,
16
+ ZERO_BYTES32,
17
+ MAX_UINT256,
18
+ } = constants;
19
+
20
+ // deployment routines in use
21
+ const {
22
+ deploy_ownable_to_ac_adapter,
23
+ deploy_no_deps_ownable_to_ac_adapter,
24
+ } = require("./include/deployment_routines");
25
+
26
+ // run OwnableToAccessControlAdapter tests
27
+ contract("OwnableToAccessControlAdapter tests", function(accounts) {
28
+ // extract accounts to be used:
29
+ // A0 – special default zero account accounts[0] used by Truffle, reserved
30
+ // a0 – deployment account having all the permissions, reserved
31
+ // H0 – initial token holder account
32
+ // a1, a2,... – working accounts to perform tests on
33
+ const [A0, a0, H0, a1, a2, a3] = accounts;
34
+
35
+ it("Adapter won't deploy targeting to a zero address", async function() {
36
+ await expectRevert(deploy_no_deps_ownable_to_ac_adapter(a0, ZERO_ADDRESS), "zero address");
37
+ });
38
+ describe("after the Adapter is deployed and target Ownable ownership transferred to the Adapter", function() {
39
+ let target, adapter;
40
+ beforeEach(async function() {
41
+ ({target, adapter} = await deploy_ownable_to_ac_adapter(a0));
42
+ });
43
+
44
+ it("it is impossible to send ether to the non-payable target contract via the adapter", async function() {
45
+ await expectRevert(web3.eth.sendTransaction({
46
+ from: a0,
47
+ to: adapter.address,
48
+ value: 1_000_000_000, // 1 gwei
49
+ }), "execution failed");
50
+ });
51
+ it("it is impossible to execute transferOwnership function before its access role is configured", async function() {
52
+ await expectRevert(web3.eth.sendTransaction({
53
+ from: a0,
54
+ to: adapter.address,
55
+ data: target.contract.methods.transferOwnership(a2).encodeABI(),
56
+ }), "access role not set");
57
+ });
58
+ describe("once transferOwnership function access control is configured", function() {
59
+ const ROLE_OWNERSHIP_MANAGER = 0x00010000;
60
+ let receipt;
61
+ beforeEach(async function() {
62
+ receipt = await adapter.updateAccessRole("transferOwnership(address)", ROLE_OWNERSHIP_MANAGER, {from: a0});
63
+ });
64
+ it('"AccessRoleUpdated" event is emitted', async function() {
65
+ expectEvent(receipt, "AccessRoleUpdated", {
66
+ selector: web3.eth.abi.encodeFunctionSignature("transferOwnership(address)"),
67
+ role: "" + ROLE_OWNERSHIP_MANAGER,
68
+ });
69
+ });
70
+ it("it is impossible to execute transferOwnership function from unauthorized account", async function() {
71
+ await expectRevert(web3.eth.sendTransaction({
72
+ from: a1,
73
+ to: adapter.address,
74
+ data: target.contract.methods.transferOwnership(a2).encodeABI(),
75
+ }), "access denied");
76
+ });
77
+ describe("once an account has authorization to execute transferOwnership function", function() {
78
+ beforeEach(async function() {
79
+ await adapter.updateRole(a1, ROLE_OWNERSHIP_MANAGER, {from: a0});
80
+ });
81
+ it("execution of the transferOwnership function succeeds", async function() {
82
+ await web3.eth.sendTransaction({
83
+ from: a1,
84
+ to: adapter.address,
85
+ data: target.contract.methods.transferOwnership(a2).encodeABI(),
86
+ });
87
+ expect(await target.owner(), "wrong owner after ownership transfer").to.equal(a2);
88
+ });
89
+ it("execution of the transferOwnership non-payable function fails if ether is supplied", async function() {
90
+ await expectRevert(web3.eth.sendTransaction({
91
+ from: a1,
92
+ to: adapter.address,
93
+ data: target.contract.methods.transferOwnership(a2).encodeABI(),
94
+ value: 1_000_000_000, // 1 gwei
95
+ }), "execution failed");
96
+ });
97
+ });
98
+ });
99
+ });
100
+ });
@@ -0,0 +1,57 @@
1
+ // OwnableToAccessControlAdapter: RBAC tests
2
+
3
+ // Zeppelin test helpers
4
+ const {
5
+ BN,
6
+ constants,
7
+ expectEvent,
8
+ expectRevert,
9
+ } = require("@openzeppelin/test-helpers");
10
+ const {
11
+ assert,
12
+ expect,
13
+ } = require("chai");
14
+ const {
15
+ ZERO_ADDRESS,
16
+ ZERO_BYTES32,
17
+ MAX_UINT256,
18
+ } = constants;
19
+
20
+ // RBAC core features and roles
21
+ const {
22
+ not,
23
+ ROLE_ACCESS_ROLES_MANAGER,
24
+ } = require("./include/features_roles");
25
+
26
+ // deployment routines in use
27
+ const {
28
+ deploy_ownable_to_ac_adapter,
29
+ } = require("./include/deployment_routines");
30
+
31
+ // run OwnableToAccessControlAdapter: RBAC tests
32
+ contract("OwnableToAccessControlAdapter: RBAC tests", function(accounts) {
33
+ // extract accounts to be used:
34
+ // A0 – special default zero account accounts[0] used by Truffle, reserved
35
+ // a0 – deployment account having all the permissions, reserved
36
+ // H0 – initial token holder account
37
+ // a1, a2,... – working accounts to perform tests on
38
+ const [A0, a0, H0, a1, a2, a3] = accounts;
39
+
40
+ describe("after the Adapter is deployed and target Ownable ownership transferred to the Adapter", function() {
41
+ let target, adapter;
42
+ beforeEach(async function() {
43
+ ({target, adapter} = await deploy_ownable_to_ac_adapter(a0));
44
+ });
45
+
46
+ it("it is impossible to configure the access role from unauthorized account", async function() {
47
+ const operator = a1;
48
+ await adapter.updateRole(operator, not(ROLE_ACCESS_ROLES_MANAGER), {from: a0});
49
+ await expectRevert(adapter.updateAccessRole("1", 1, {from: operator}), "access denied");
50
+ });
51
+ it("it is possible to configure the access role from authorized account", async function() {
52
+ const operator = a1;
53
+ await adapter.updateRole(operator, ROLE_ACCESS_ROLES_MANAGER, {from: a0});
54
+ adapter.updateAccessRole("1", 1, {from: operator});
55
+ });
56
+ });
57
+ });
@@ -0,0 +1,24 @@
1
+ // AccessControl (RBAC) Core Tests
2
+
3
+ // import the core RBAC behaviour to use
4
+ const {
5
+ behavesLikeRBAC,
6
+ } = require("./include/rbac.behaviour");
7
+
8
+ // deployment routines in use
9
+ const {
10
+ deploy_access_control,
11
+ } = require("./include/deployment_routines");
12
+
13
+ // run AccessControl (RBAC) tests
14
+ contract("AccessControl (RBAC) Core tests", function(accounts) {
15
+ // extract accounts to be used:
16
+ // A0 – special default zero account accounts[0] used by Truffle, reserved
17
+ // a0 – deployment account having all the permissions, reserved
18
+ // H0 – initial token holder account
19
+ // a1, a2,... – working accounts to perform tests on
20
+ const [A0, a0, H0, a1, a2, a3] = accounts;
21
+
22
+ // run the core RBACs behaviour test
23
+ behavesLikeRBAC(deploy_access_control, a0, a1, a2);
24
+ });