@lazy-sol/access-control 1.0.3

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.
@@ -0,0 +1,240 @@
1
+ # Style Guides
2
+
3
+ A programming style guide is an opinionated guide of programming conventions, style, and best practices for a
4
+ team or project.
5
+
6
+ This section breaks into several subsections depending on the programming, scripting, and markup languages used.
7
+ When new language is added to the project, one should also add a corresponding style guide subsection to this section.
8
+
9
+ For each language we use, a style guide is based on one or more widely used style guides. When several reference
10
+ guides are used, we assume that the first one is a basic one, and next ones supplement it (contradicting rules
11
+ in the next ones are ignored).
12
+
13
+ There are always controversial rules leading to endless debates, these rules are more a matter of taste, than a
14
+ rational thing. One of the examples is a famous endless "tabs vs spaces debate".
15
+ For each style guide we maintain the list of these controversial rules together with overridden rules.
16
+
17
+ This is yet another element for encouraging people to lead a project.
18
+ You get a chance to demonstrate in practice how the rules you've chosen help the development, readability, maintainability, etc.
19
+
20
+ ## JavaScript
21
+
22
+ JavaScript is a non-class based object oriented programming language that is one of the core technologies of the
23
+ World Wide Web.
24
+ JavaScript was developed in September 1995 by a Netscape programmer Brandan Eich.
25
+ It was originally named Mocha, but quickly became known as LiveScript and, later, JavaScript.
26
+
27
+ JavaScript's syntax and naming conventions are similar to Java, for example both languages use camelCase to name
28
+ functions and variables, PascalCase for class names, UPPER_CASE for constants.
29
+ JavaScript, however, is not so strict: programs using snake_case instead of camelCase can also be seen widely.
30
+
31
+ We use [Airbnb Javascript Style Guide](https://github.com/airbnb/javascript) as a base.
32
+ Following rules are considered contentious (to be extended) and/or are overridden:
33
+
34
+ - [Whitespace](https://github.com/airbnb/javascript#whitespace)
35
+ - use of soft tabs (space character) set to 2 spaces (eslint: indent)
36
+ - **no** spaces inside curly braces (eslint: object-curly-spacing: **"never"**)
37
+ **reason:** monospace fonts have already enough spare space in braces, commas, dots, etc.
38
+ to make these symbols clearly distinguishable from the literals' symbols
39
+ - characters per line limit (eslint: max-len): **120**
40
+ **reason:**: most of the screens allow to easily see 120 characters in one line
41
+ - [Blocks](https://github.com/airbnb/javascript#blocks)
42
+ - `else` statements in an `if-else` construct, as well as `catch` and `finally`,
43
+ must be **on its own line** after the preceding closing brace (eslint: brace-style: **"stroustrup"**)
44
+ **reason:** this makes `if-else` blocks better distinguishable when statements inside are very short
45
+ - [Naming Conventions](https://github.com/airbnb/javascript#naming-conventions)
46
+ - camelCase naming for objects, functions, and instances (eslint: camelcase)
47
+
48
+ ## TypeScript
49
+
50
+ TypeScript is a strongly typed programming language that builds on JavaScript, developed by Microsoft, published
51
+ in 2012.
52
+
53
+ TypeScript style guide inherits from [JavaScript](#javascript) and is enriched with
54
+ [Google TypeScript Style Guide](https://google.github.io/styleguide/tsguide.html), which is used basically
55
+ to cover areas not covered in [Airbnb Javascript Style Guide](https://github.com/airbnb/javascript).
56
+
57
+ ## Solidity
58
+
59
+ Solidity is an object-oriented programming language for implementing smart contracts.
60
+ Solidity was proposed in August 2014 by Dr. Gavin Wood.
61
+ As specified by Dr. Gavin Wood, Solidity is designed around the JavaScript syntax to make it familiar for existing web
62
+ developers.
63
+
64
+ Solidity inherits its syntax and naming conventions from JavaScript. Both languages use camelCase naming for
65
+ functions and variables, PascalCase for class names, UPPER_CASE for constants.
66
+
67
+ We use [Official Solidity Style Guide](https://docs.soliditylang.org/en/v0.8.16/style-guide.html) as a base,
68
+ enriched with [Official Java Code Conventions](https://www.oracle.com/technetwork/java/codeconventions-150003.pdf)
69
+ (for example, Official Solidity Guide misses ideas on interface naming).
70
+ Following rules are considered contentious and/or are overridden:
71
+
72
+ - Tabs or Spaces: spaces are the preferred indentation method
73
+ - `else` statements in an `if-else` construct must be **on its own line** after the preceding closing brace
74
+
75
+ Prefer `Interface` naming to Zeppelin's `IInterface` one.
76
+ Name the interface by answering the question "what it is?", based on functional requirements. A `Truck`.
77
+ Name the implementation contract by answering the question "how it works?", or "what it looks like?",
78
+ based on non-functional requirements. A `RedTruck`.
79
+ ERC standards like ERC20, ERC721, and others are effectively interfaces already and do not require an "I" prefix.
80
+
81
+ Bad:
82
+
83
+ ```
84
+ interface IPriceOracle {
85
+ ...
86
+ }
87
+ contract PriceOracle is IPriceOracle {
88
+ ...
89
+ }
90
+ ```
91
+
92
+ Good:
93
+
94
+ ```
95
+ interface PriceOracle {
96
+ ...
97
+ }
98
+ contract PriceOracleV1 is PriceOracle {
99
+ ...
100
+ }
101
+ ```
102
+
103
+ Bad:
104
+
105
+ ```
106
+ interface IERC20 {
107
+ ...
108
+ }
109
+ contract Token is IERC20 {
110
+ ...
111
+ }
112
+ ```
113
+
114
+ Good:
115
+
116
+ ```
117
+ interface ERC20 {
118
+ ...
119
+ }
120
+ contract Token is ERC20 {
121
+ ...
122
+ }
123
+ ```
124
+
125
+ ## Markdown
126
+
127
+ Markdown is a lightweight markup language created by John Gruber and Aaron Swartz in 2004 with the goal to be
128
+ appealing to human readers in its source code form. Markdown was standardized in 2012-2016.
129
+
130
+ We use [Google Markdown Style Guide](https://google.github.io/styleguide/docguide/style.html) as a base,
131
+ enriched with [Matt Cone Markdown Style Guide](https://www.markdownguide.org/basic-syntax/).
132
+ Following rules are considered contentious and/or are overridden:
133
+
134
+ - [Trailing whitespace](https://google.github.io/styleguide/docguide/style.html#trailing-whitespace)
135
+ / [Line Breaks Best Practices](https://www.markdownguide.org/basic-syntax/#line-break-best-practices):
136
+ don't use the trailing backslash, use trailing whitespace and ensure .editorconfig has
137
+ `trim_trailing_whitespace = false` for `*.md` files
138
+
139
+ ## Automating Formatting Standards
140
+
141
+ The above standards can be more easily met by automating their implementation.
142
+ Many repositories will have a `.editorconfig` file, which tells editors how to interpret inputs, such as tab.
143
+ The EditorConfig file is read automatically by many IDEs, including WebStorm, IntellijIDEA and Visual Studio,
144
+ but is **not** picked up automatically by many even related tools including PHPStorm, Sublime, Eclipse,
145
+ and Visual Studio Code: a [supporting plugin](https://editorconfig.org/) should be used.
146
+ You should ensure your IDE setup supports these editor expectations.
147
+
148
+ Optionally you may additionally use Prettier or a similar formatter.
149
+ Prettier is an opinionated code formatter, which uses sensible defaults that can often (but not always)
150
+ be overridden in a `.prettierrc` file.
151
+ Prettier will also inspect `.editorconfig` files and use those settings as its defaults.
152
+ Note that Visual Studio Code includes Prettier formatter by default, and its Format command triggers it.
153
+ It can also be configured to trigger on-save.
154
+
155
+ Prettier should **not** be used on existing projects that already have an established standard.
156
+
157
+ Finally, a _linter_ such as eslint or solhint may be a good option to be used.
158
+ Linters dynamically inspect code and point out potential issues.
159
+ This can include style issues as above but also code quality issues like unused variables,
160
+ deprecated functions, unreachable code, etc.
161
+ Installing the solidity plugin for Visual Studio Code automatically installs a linter.
162
+
163
+ Note that the above tools can all be used together. EditorConfig works as you type, ensuring you meet standards,
164
+ Prettier formats your code after you write it, while linters highlight, but do not fix, potential quality issues.
165
+
166
+ ## Testing Standards and Style Guidelines
167
+
168
+ Testing smart contracts is of critical importance. Tests are used to validate security requirements,
169
+ and to confirm behaviour to be as expected and intended.
170
+ Proper testing of any software is a difficult skill that takes a long time to learn. Here are some important guides.
171
+
172
+ **Unit testing** is intended to test a single, specific behaviour, such as a function.
173
+ In the context of smart contracts this typically means to execute a function and then check the resulting state
174
+ and events emitted.
175
+
176
+ Unit testing forms the vast majority of test cases and requires large numbers of simple tests,
177
+ with each test verifying a single aspect of behaviour.
178
+ It should be possible for any failed test to immediately identify the error.
179
+
180
+ Unit tests are often built in a way phrased as _arrange-act-assert_.
181
+ Arrange is the process to set up the contract to a suitable initial state.
182
+ Act is executing the desired function.
183
+ Assert is verifying the state changes occurred and events emitted.
184
+
185
+ Arrange steps **do not belong to the test function** and should be implemented as part of a `beforeEach` or similar
186
+ hook which sets up the state for all the tests.
187
+ Use `describe` blocks to separate test functionality that has different state setup.
188
+
189
+ It is vitally important that tests are not an afterthought, but a key part of the development deliverable.
190
+ This means that the test should cover not just "the behaviour", but edge cases, error handling, permission checking,
191
+ bounds-checking and other similar difficulties. "Happy path" testing is of minimal value.
192
+
193
+ Some important points on unit tests:
194
+
195
+ - Only test one thing at a time - do not run compound tests
196
+ - Each test must be independent
197
+ - Consider making utility functions for things like state setup to ensure simplicity and consistency
198
+ - Separate contracts by a file and only test one contract per file
199
+ - Separate functionality areas with `describe` blocks, and note you can nest these blocks for sub-functionality
200
+ - Tests should be as small as possible, ideally only one line, or a few lines
201
+ - You can append `.only` to a test case while implementing it, to isolate that one test (not to run the whole suite
202
+ during the test development), though keep in mind that the entire suite must also work
203
+ - Do not add suite setup to `beforeEach`, as this will run before every test.
204
+ For example, getting all the accounts from the provider can be implemented either as global function, or if
205
+ using async mode - can be run in the `before` hook, which runs one single time.
206
+ - Ensure the test checks function execution constraints (contract state, function input params, access control), smart
207
+ contract state change(s), event emission(s)
208
+ - Favour constants (or TypeScript enums) for testing values, as they can convey meaning and be reused as the
209
+ assertion value
210
+
211
+ Many areas of functionality may also implement an end-to-end test, where multiple steps are undertaken in order
212
+ to ensure a cohesive and correct workflow.
213
+ These typically act as a "sanity check" to verify complex behaviours work as intended.
214
+ Such tests supplement, but do not replace, comprehensive unit tests.
215
+
216
+ Code Coverage reports can be generated with `npm run coverage`.
217
+ Reports show the coverage as a percentage of lines covered with tests.
218
+ It is important to ensure this is not reduced by your modifications.
219
+ It is also important the testing is not done **solely** to increase the test coverage percentage.
220
+ Instead, the code coverage outputs are used to highlight areas where tests are lacking.
221
+ The coverage reports generate output artifacts that show line-by-line where code is untested,
222
+ as well as summaries by files overall.
223
+
224
+ When beginning a new block of work you should ensure that you run the coverage report prior to starting
225
+ to ensure your changes do not lower the code coverage.
226
+
227
+ See also: [Gitlab Testing Standards](https://docs.gitlab.com/ee/development/testing_guide/)
228
+
229
+ ## References
230
+ 1. Srđan Popić, Gordana Velikić at al.
231
+ The Benefits of the Coding Standards Enforcement and it's Influence on the
232
+ Developers' Coding Behaviour: A Case Study on Two Small Projects
233
+ 2. [Coding standards: what are they, and why do you need
234
+ them](https://blog.codacy.com/coding-standards-what-are-they-and-why-do-you-need-them/)
235
+
236
+ ## About
237
+
238
+ Prepared by Basil Gorin
239
+
240
+ (c) 2017–2024 Basil Gorin
@@ -0,0 +1,359 @@
1
+ /**
2
+ * default Hardhat configuration which uses account mnemonic to derive accounts
3
+ * script expects following environment variables to be set:
4
+ * - P_KEY1 – mainnet private key, should start with 0x
5
+ * or
6
+ * - MNEMONIC1 – mainnet mnemonic, 12 words
7
+ *
8
+ * - P_KEY3 – ropsten private key, should start with 0x
9
+ * or
10
+ * - MNEMONIC3 – ropsten mnemonic, 12 words
11
+ *
12
+ * - P_KEY4 – rinkeby private key, should start with 0x
13
+ * or
14
+ * - MNEMONIC4 – rinkeby mnemonic, 12 words
15
+ *
16
+ * - P_KEY41 – kovan private key, should start with 0x
17
+ * or
18
+ * - MNEMONIC41 – kovan mnemonic, 12 words
19
+ *
20
+ * - P_KEY5 – goerli private key, should start with 0x
21
+ * or
22
+ * - MNEMONIC5 – goerli mnemonic, 12 words
23
+ *
24
+ * - P_KEY137 – polygon/matic private key, should start with 0x
25
+ * or
26
+ * - MNEMONIC137 – polygon/matic mnemonic, 12 words
27
+ *
28
+ * - P_KEY80001 – mumbai (polygon testnet) private key, should start with 0x
29
+ * or
30
+ * - MNEMONIC80001 – mumbai (polygon testnet) mnemonic, 12 words
31
+ *
32
+ * - P_KEY56 – Binance Smart Chain (BSC) mainnet private key, should start with 0x
33
+ * or
34
+ * - MNEMONIC56 – Binance Smart Chain (BSC) mainnet mnemonic, 12 words
35
+ *
36
+ * - P_KEY97 – Binance Smart Chain (BSC) testnet private key, should start with 0x
37
+ * or
38
+ * - MNEMONIC97 – Binance Smart Chain (BSC) testnet mnemonic, 12 words
39
+ *
40
+ * - ALCHEMY_KEY – Alchemy API key
41
+ * or
42
+ * - INFURA_KEY – Infura API key (Project ID)
43
+ *
44
+ * - ETHERSCAN_KEY – Etherscan API key
45
+ *
46
+ * - POLYSCAN_KEY – polygonscan API key
47
+ *
48
+ * - BSCSCAN_KEY – BscScan API key
49
+ *
50
+ * - REPORT_GAS - optional, set it to true to print gas usage info
51
+ */
52
+
53
+ // Enable Truffle 5 plugin for tests
54
+ // https://hardhat.org/guides/truffle-testing.html
55
+ require("@nomiclabs/hardhat-truffle5");
56
+
57
+ // enable Solidity-coverage
58
+ // https://hardhat.org/plugins/solidity-coverage.html
59
+ require("solidity-coverage");
60
+
61
+ // enable hardhat-gas-reporter
62
+ // https://github.com/cgewecke/hardhat-gas-reporter
63
+ require("hardhat-gas-reporter");
64
+
65
+ // adds a mechanism to deploy contracts to any network,
66
+ // keeping track of them and replicating the same environment for testing
67
+ // https://www.npmjs.com/package/hardhat-deploy
68
+ require("hardhat-deploy");
69
+
70
+ // verify environment setup, display warning if required, replace missing values with fakes
71
+ const FAKE_MNEMONIC = "test test test test test test test test test test test junk";
72
+ if(!process.env.MNEMONIC1 && !process.env.P_KEY1) {
73
+ console.warn("neither MNEMONIC1 nor P_KEY1 is not set. Mainnet deployments won't be available");
74
+ process.env.MNEMONIC1 = FAKE_MNEMONIC;
75
+ }
76
+ else if(process.env.P_KEY1 && !process.env.P_KEY1.startsWith("0x")) {
77
+ console.warn("P_KEY1 doesn't start with 0x. Appended 0x");
78
+ process.env.P_KEY1 = "0x" + process.env.P_KEY1;
79
+ }
80
+ if(!process.env.MNEMONIC3 && !process.env.P_KEY3) {
81
+ console.warn("neither MNEMONIC3 nor P_KEY3 is not set. Ropsten deployments won't be available");
82
+ process.env.MNEMONIC3 = FAKE_MNEMONIC;
83
+ }
84
+ else if(process.env.P_KEY3 && !process.env.P_KEY3.startsWith("0x")) {
85
+ console.warn("P_KEY3 doesn't start with 0x. Appended 0x");
86
+ process.env.P_KEY3 = "0x" + process.env.P_KEY3;
87
+ }
88
+ if(!process.env.MNEMONIC4 && !process.env.P_KEY4) {
89
+ console.warn("neither MNEMONIC4 nor P_KEY4 is not set. Rinkeby deployments won't be available");
90
+ process.env.MNEMONIC4 = FAKE_MNEMONIC;
91
+ }
92
+ else if(process.env.P_KEY4 && !process.env.P_KEY4.startsWith("0x")) {
93
+ console.warn("P_KEY4 doesn't start with 0x. Appended 0x");
94
+ process.env.P_KEY4 = "0x" + process.env.P_KEY4;
95
+ }
96
+ if(!process.env.MNEMONIC42 && !process.env.P_KEY42) {
97
+ console.warn("neither MNEMONIC42 nor P_KEY42 is not set. Kovan deployments won't be available");
98
+ process.env.MNEMONIC42 = FAKE_MNEMONIC;
99
+ }
100
+ else if(process.env.P_KEY42 && !process.env.P_KEY42.startsWith("0x")) {
101
+ console.warn("P_KEY42 doesn't start with 0x. Appended 0x");
102
+ process.env.P_KEY42 = "0x" + process.env.P_KEY42;
103
+ }
104
+ if(!process.env.MNEMONIC5 && !process.env.P_KEY5) {
105
+ console.warn("neither MNEMONIC5 nor P_KEY5 is not set. Goerli deployments won't be available");
106
+ process.env.MNEMONIC5 = FAKE_MNEMONIC;
107
+ }
108
+ else if(process.env.P_KEY5 && !process.env.P_KEY5.startsWith("0x")) {
109
+ console.warn("P_KEY5 doesn't start with 0x. Appended 0x");
110
+ process.env.P_KEY5 = "0x" + process.env.P_KEY5;
111
+ }
112
+ if(!process.env.MNEMONIC137 && !process.env.P_KEY137) {
113
+ console.warn("neither MNEMONIC137 nor P_KEY137 is not set. Polygon mainnet deployments won't be available");
114
+ process.env.MNEMONIC137 = FAKE_MNEMONIC;
115
+ }
116
+ else if(process.env.P_KEY137 && !process.env.P_KEY137.startsWith("0x")) {
117
+ console.warn("P_KEY137 doesn't start with 0x. Appended 0x");
118
+ process.env.P_KEY137 = "0x" + process.env.P_KEY137;
119
+ }
120
+ if(!process.env.MNEMONIC80001 && !process.env.P_KEY80001) {
121
+ console.warn("neither MNEMONIC80001 nor P_KEY80001 is not set. Mumbai (matic/polygon L2 testnet) deployments won't be available");
122
+ process.env.MNEMONIC80001 = FAKE_MNEMONIC;
123
+ }
124
+ else if(process.env.P_KEY80001 && !process.env.P_KEY80001.startsWith("0x")) {
125
+ console.warn("P_KEY80001 doesn't start with 0x. Appended 0x");
126
+ process.env.P_KEY80001 = "0x" + process.env.P_KEY80001;
127
+ }
128
+ if(!process.env.MNEMONIC56 && !process.env.P_KEY56) {
129
+ console.warn("neither MNEMONIC56 nor P_KEY56 is not set. Binance Smart Chain (BSC) mainnet deployments won't be available");
130
+ process.env.MNEMONIC56 = FAKE_MNEMONIC;
131
+ }
132
+ else if(process.env.P_KEY56 && !process.env.P_KEY56.startsWith("0x")) {
133
+ console.warn("P_KEY56 doesn't start with 0x. Appended 0x");
134
+ process.env.P_KEY56 = "0x" + process.env.P_KEY56;
135
+ }
136
+ if(!process.env.MNEMONIC97 && !process.env.P_KEY97) {
137
+ console.warn("neither MNEMONIC97 nor P_KEY97 is not set. Binance Smart Chain (BSC) testnet deployments won't be available");
138
+ process.env.MNEMONIC97 = FAKE_MNEMONIC;
139
+ }
140
+ else if(process.env.P_KEY97 && !process.env.P_KEY97.startsWith("0x")) {
141
+ console.warn("P_KEY97 doesn't start with 0x. Appended 0x");
142
+ process.env.P_KEY97 = "0x" + process.env.P_KEY97;
143
+ }
144
+ if(!process.env.INFURA_KEY && !process.env.ALCHEMY_KEY) {
145
+ console.warn("neither INFURA_KEY nor ALCHEMY_KEY is not set. Deployments may not be available");
146
+ process.env.INFURA_KEY = "";
147
+ process.env.ALCHEMY_KEY = "";
148
+ }
149
+ if(!process.env.ETHERSCAN_KEY) {
150
+ console.warn("ETHERSCAN_KEY is not set. Deployed smart contract code verification won't be available");
151
+ process.env.ETHERSCAN_KEY = "";
152
+ }
153
+ if(!process.env.POLYSCAN_KEY) {
154
+ console.warn("POLYSCAN_KEY is not set. Deployed smart contract code verification won't be available on polyscan");
155
+ process.env.POLYSCAN_KEY = "";
156
+ }
157
+ if(!process.env.BSCSCAN_KEY) {
158
+ console.warn("BSCSCAN_KEY is not set. Deployed smart contract code verification won't be available on BscScan");
159
+ process.env.BSCSCAN_KEY = "";
160
+ }
161
+
162
+ /**
163
+ * @type import('hardhat/config').HardhatUserConfig
164
+ */
165
+ module.exports = {
166
+ defaultNetwork: "hardhat",
167
+ networks: {
168
+ // https://hardhat.org/hardhat-network/
169
+ hardhat: {
170
+ // set networkId to 0xeeeb04de as for all local networks
171
+ chainId: 0xeeeb04de,
172
+ // set the gas price to one for convenient tx costs calculations in tests
173
+ // gasPrice: 1,
174
+ // London hard fork fix: impossible to set gas price lower than baseFeePerGas (875,000,000)
175
+ initialBaseFeePerGas: 0,
176
+ accounts: {
177
+ count: 35,
178
+ },
179
+ /*
180
+ forking: {
181
+ url: "https://mainnet.infura.io/v3/" + process.env.INFURA_KEY, // create a key: https://infura.io/
182
+ enabled: !!(process.env.HARDHAT_FORK),
183
+ },
184
+ */
185
+ },
186
+ // https://etherscan.io/
187
+ mainnet: {
188
+ url: get_endpoint_url("mainnet"),
189
+ accounts: get_accounts(process.env.P_KEY1, process.env.MNEMONIC1),
190
+ },
191
+ // https://ropsten.etherscan.io/
192
+ ropsten: {
193
+ url: get_endpoint_url("ropsten"),
194
+ accounts: get_accounts(process.env.P_KEY3, process.env.MNEMONIC3),
195
+ },
196
+ // https://rinkeby.etherscan.io/
197
+ rinkeby: {
198
+ url: get_endpoint_url("rinkeby"),
199
+ accounts: get_accounts(process.env.P_KEY4, process.env.MNEMONIC4),
200
+ },
201
+ // https://kovan.etherscan.io/
202
+ kovan: {
203
+ url: get_endpoint_url("kovan"),
204
+ accounts: get_accounts(process.env.P_KEY42, process.env.MNEMONIC42),
205
+ },
206
+ // https://goerli.etherscan.io/
207
+ goerli: {
208
+ url: get_endpoint_url("goerli"),
209
+ accounts: get_accounts(process.env.P_KEY5, process.env.MNEMONIC5),
210
+ },
211
+ // matic/polygon L2 mainnet
212
+ // https://polygonscan.com/
213
+ polygon: {
214
+ url: "https://polygon-rpc.com/",
215
+ accounts: get_accounts(process.env.P_KEY137, process.env.MNEMONIC137),
216
+ },
217
+ // matic/polygon L1 testnet – Mumbai
218
+ // https://mumbai.polygonscan.com/
219
+ mumbai: {
220
+ url: "https://rpc-mumbai.maticvigil.com",
221
+ accounts: get_accounts(process.env.P_KEY80001, process.env.MNEMONIC80001),
222
+ },
223
+ // Binance Smart Chain (BSC) L2 mainnet
224
+ binance: {
225
+ url: "https://bsc-dataseed1.binance.org/",
226
+ accounts: get_accounts(process.env.P_KEY56, process.env.MNEMONIC56),
227
+ },
228
+ // Binance Smart Chain (BSC) L2 testnet
229
+ binance_testnet: {
230
+ url: "https://data-seed-prebsc-1-s3.binance.org:8545/",
231
+ accounts: get_accounts(process.env.P_KEY97, process.env.MNEMONIC97),
232
+ },
233
+ },
234
+
235
+ // Configure Solidity compiler
236
+ solidity: {
237
+ // https://hardhat.org/guides/compile-contracts.html
238
+ compilers: [
239
+ {
240
+ version: "0.8.21",
241
+ settings: {
242
+ optimizer: {
243
+ enabled: true,
244
+ runs: 200
245
+ }
246
+ }
247
+ },
248
+ {
249
+ version: "0.6.2",
250
+ settings: {
251
+ optimizer: {
252
+ enabled: true,
253
+ runs: 200
254
+ }
255
+ }
256
+ },
257
+ {
258
+ version: "0.4.22",
259
+ settings: {
260
+ optimizer: {
261
+ enabled: true,
262
+ runs: 200
263
+ }
264
+ }
265
+ },
266
+ {
267
+ version: "0.4.11",
268
+ settings: {
269
+ optimizer: {
270
+ enabled: true,
271
+ runs: 200
272
+ }
273
+ }
274
+ },
275
+ ]
276
+ },
277
+
278
+ // Set default mocha options here, use special reporters etc.
279
+ mocha: {
280
+ // timeout: 100000,
281
+
282
+ // disable mocha timeouts:
283
+ // https://mochajs.org/api/mocha#enableTimeouts
284
+ enableTimeouts: false,
285
+ // https://github.com/mochajs/mocha/issues/3813
286
+ timeout: false,
287
+ },
288
+
289
+ // hardhat-gas-reporter will be disabled by default, use REPORT_GAS environment variable to enable it
290
+ // https://hardhat.org/plugins/hardhat-gas-reporter.html
291
+ gasReporter: {
292
+ enabled: !!(process.env.REPORT_GAS)
293
+ },
294
+ }
295
+
296
+ /**
297
+ * Determines a JSON-RPC endpoint to use to connect to the node
298
+ * based on the requested network name and environment variables set
299
+ *
300
+ * Tries to use custom RPC URL first (MAINNET_RPC_URL/ROPSTEN_RPC_URL/RINKEBY_RPC_URL/KOVAN_RPC_URL)
301
+ * Tries to use alchemy RPC URL next (if ALCHEMY_KEY is set)
302
+ * Fallbacks to infura RPC URL
303
+ *
304
+ * @param network_name one of mainnet/ropsten/rinkeby/kovan
305
+ * @return JSON-RPC endpoint URL
306
+ */
307
+ function get_endpoint_url(network_name) {
308
+ // try custom RPC endpoint first (private node, quicknode, etc.)
309
+ // create a quicknode key: https://www.quicknode.com/
310
+ if(process.env.MAINNET_RPC_URL && network_name === "mainnet") {
311
+ return process.env.MAINNET_RPC_URL;
312
+ }
313
+ if(process.env.ROPSTEN_RPC_URL && network_name === "ropsten") {
314
+ return process.env.ROPSTEN_RPC_URL;
315
+ }
316
+ if(process.env.RINKEBY_RPC_URL && network_name === "rinkeby") {
317
+ return process.env.RINKEBY_RPC_URL;
318
+ }
319
+ if(process.env.KOVAN_RPC_URL && network_name === "kovan") {
320
+ return process.env.KOVAN_RPC_URL;
321
+ }
322
+ if(process.env.GOERLI_RPC_URL && network_name === "goerli") {
323
+ return process.env.GOERLI_RPC_URL;
324
+ }
325
+
326
+ // try the alchemy next
327
+ // create a key: https://www.alchemy.com/
328
+ if(process.env.ALCHEMY_KEY) {
329
+ switch(network_name) {
330
+ case "mainnet": return "https://eth-mainnet.alchemyapi.io/v2/" + process.env.ALCHEMY_KEY;
331
+ case "ropsten": return "https://eth-ropsten.alchemyapi.io/v2/" + process.env.ALCHEMY_KEY;
332
+ case "rinkeby": return "https://eth-rinkeby.alchemyapi.io/v2/" + process.env.ALCHEMY_KEY;
333
+ case "kovan": return "https://eth-kovan.alchemyapi.io/v2/" + process.env.ALCHEMY_KEY;
334
+ case "goerli": return "https://eth-goerli.alchemyapi.io/v2/" + process.env.ALCHEMY_KEY;
335
+ }
336
+ }
337
+
338
+ // fallback to infura
339
+ // create a key: https://infura.io/
340
+ switch(network_name) {
341
+ case "mainnet": return "https://mainnet.infura.io/v3/" + process.env.INFURA_KEY;
342
+ case "ropsten": return "https://ropsten.infura.io/v3/" + process.env.INFURA_KEY;
343
+ case "rinkeby": return "https://rinkeby.infura.io/v3/" + process.env.INFURA_KEY;
344
+ case "kovan": return "https://kovan.infura.io/v3/" + process.env.INFURA_KEY;
345
+ case "goerli": return "https://goerli.infura.io/v3/" + process.env.INFURA_KEY;
346
+ }
347
+ }
348
+
349
+ /**
350
+ * Depending on which of the inputs are available (private key or mnemonic),
351
+ * constructs an account object for use in the hardhat config
352
+ *
353
+ * @param p_key account private key, export private key from mnemonic: https://metamask.io/
354
+ * @param mnemonic 12 words mnemonic, create 12 words: https://metamask.io/
355
+ * @return either [p_key] if p_key is defined, or {mnemonic} if mnemonic is defined
356
+ */
357
+ function get_accounts(p_key, mnemonic) {
358
+ return p_key? [p_key]: mnemonic? {mnemonic, initialIndex: 0}: undefined;
359
+ }
package/package.json ADDED
@@ -0,0 +1,39 @@
1
+ {
2
+ "name": "@lazy-sol/access-control",
3
+ "version": "1.0.3",
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
+ "main": "index.js",
6
+ "scripts": {
7
+ "clean": "hardhat clean",
8
+ "compile": "hardhat compile",
9
+ "test": "hardhat test",
10
+ "coverage": "hardhat coverage",
11
+ "deploy": "hardhat deploy"
12
+ },
13
+ "engines": {
14
+ "node": ">=16.0.0"
15
+ },
16
+ "keywords": [
17
+ "RBAC",
18
+ "Solidity",
19
+ "access control",
20
+ "modular architecture"
21
+ ],
22
+ "author": "Basil Gorin",
23
+ "license": "MIT",
24
+ "dependencies": {
25
+ "@lazy-sol/a-missing-gem": "^1.0.0",
26
+ "@nomiclabs/hardhat-truffle5": "^2.0.7",
27
+ "hardhat": "^2.16.0",
28
+ "hardhat-deploy": "^0.11.45"
29
+ },
30
+ "devDependencies": {
31
+ "@lazy-sol/zeppelin-test-helpers": "^1.0.0",
32
+ "hardhat-gas-reporter": "^1.0.10",
33
+ "solidity-coverage": "^0.8.10"
34
+ },
35
+ "overrides": {
36
+ "tough-cookie": "^4.1.3",
37
+ "yargs-parser": "^5.0.1"
38
+ }
39
+ }
@@ -0,0 +1,54 @@
1
+ // AdapterFactory 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_usdt,
23
+ deploy_adapter_factory,
24
+ factory_deploy_ownable_to_ac_adapter,
25
+ } = require("./include/deployment_routines");
26
+
27
+ // run AdapterFactory tests
28
+ contract("AdapterFactory tests", function(accounts) {
29
+ // extract accounts to be used:
30
+ // A0 – special default zero account accounts[0] used by Truffle, reserved
31
+ // a0 – deployment account having all the permissions, reserved
32
+ // H0 – initial token holder account
33
+ // a1, a2,... – working accounts to perform tests on
34
+ const [A0, a0, H0, a1, a2, a3] = accounts;
35
+
36
+ let usdt, factory;
37
+ beforeEach(async function() {
38
+ usdt = await deploy_usdt(a1);
39
+ factory = await deploy_adapter_factory();
40
+ });
41
+
42
+ it("adapter deployment fails if executed not by the ownable owner", async function() {
43
+ await expectRevert(factory_deploy_ownable_to_ac_adapter(a2, factory, usdt), "not an owner");
44
+ });
45
+ describe("adapter deployment succeeds if executed by the ownable owner", async function() {
46
+ let adapter;
47
+ beforeEach(async function() {
48
+ ({adapter} = await factory_deploy_ownable_to_ac_adapter(a1, factory, usdt));
49
+ });
50
+ it("adapter's target is set correctly", async function() {
51
+ expect(await adapter.target()).to.be.equal(usdt.address);
52
+ });
53
+ });
54
+ });