Compare commits
419 Commits
v2.0.0-rc.
...
v2.2.1
| Author | SHA1 | Date | |
|---|---|---|---|
| 41e79d7887 | |||
| f245f233b3 | |||
| 7ac0502c50 | |||
| dee9a2b897 | |||
| 64cf73d646 | |||
| c4ccdc182f | |||
| e592627578 | |||
| 24416fc208 | |||
| 09dee513ed | |||
| 906b18f144 | |||
| eb6b5b6631 | |||
| 7d0c6280f3 | |||
| 56b7d0713b | |||
| a7d5c72fdc | |||
| 7050b73a89 | |||
| 2b9dc9ae87 | |||
| 9ed1b44865 | |||
| 7aaf15be59 | |||
| 1e5295d304 | |||
| 61c4318c33 | |||
| 79dd498b16 | |||
| 547a5f242a | |||
| 352ec94579 | |||
| 3772233cf5 | |||
| 7f54542172 | |||
| 3ff2e24518 | |||
| 0c617b755e | |||
| 8cc3349d1f | |||
| 41aa39afbc | |||
| 0dded493a0 | |||
| a1f168be96 | |||
| 5b93137c26 | |||
| f5ba7e7f0d | |||
| 5a64eb2e14 | |||
| 2648206394 | |||
| 77d569d8fa | |||
| 634883ce8e | |||
| de90f4458a | |||
| a39bea230e | |||
| 8d0937c54c | |||
| d6c47c4b7c | |||
| 3111291b4a | |||
| 14ec984cc4 | |||
| b14c9f4b68 | |||
| fc17a1d9f5 | |||
| c44e40c293 | |||
| 2fc0aaabb3 | |||
| ae41195863 | |||
| 99a07493f2 | |||
| 328d03a7f4 | |||
| 530c90d438 | |||
| 3654150d0c | |||
| 9cf68279c1 | |||
| 039e5b9602 | |||
| cab777b820 | |||
| 7ed22bbded | |||
| 889af764e2 | |||
| f18fd17355 | |||
| 3dbf651b8e | |||
| 6bf2ae8229 | |||
| 644b121677 | |||
| 40d15146c4 | |||
| 453e3dd454 | |||
| e8e6dd52a5 | |||
| 105b927b62 | |||
| 2c34cfbe0e | |||
| 0b1e1810b1 | |||
| 2eb0de4cd2 | |||
| 3fd5195573 | |||
| 491fb5acd9 | |||
| 05c7d8c861 | |||
| d032ca62e2 | |||
| b306c41525 | |||
| 8dd92fd6ca | |||
| 1fd993bc01 | |||
| b39f3c2055 | |||
| 4e026cd4c7 | |||
| c08d63c118 | |||
| e357592208 | |||
| f3635e1517 | |||
| a09cf147ea | |||
| 04186e2cf6 | |||
| cff2509c63 | |||
| dd433c41bb | |||
| 4952240620 | |||
| 00f7c19d02 | |||
| 5eafd1dec2 | |||
| f80c65ff67 | |||
| 07603d5875 | |||
| 3a5da75876 | |||
| f84278433d | |||
| 73a34f96a7 | |||
| 877f07f0a9 | |||
| e808a64649 | |||
| e1f40e7e23 | |||
| 8617c4b4c8 | |||
| 96432bf28e | |||
| a221c17fb2 | |||
| 1a9cb0786d | |||
| fd808b3ff8 | |||
| 6a658f2ac8 | |||
| d9a8cd2bef | |||
| bce2d68e7f | |||
| b7d60f2f9a | |||
| 7fb90a1566 | |||
| e5b94c1481 | |||
| 79145fa53a | |||
| 3e82db2f6f | |||
| 089f14aa06 | |||
| ae02103e47 | |||
| ba83239dd8 | |||
| 14a59b2903 | |||
| 4f5715bbd7 | |||
| 312a2584e8 | |||
| c23b7ffbad | |||
| 6aa88e2b7d | |||
| 76abd1a41e | |||
| 35d70397b6 | |||
| a5b14f262e | |||
| 350aae09d2 | |||
| 63ce358f30 | |||
| 40f08a8c0b | |||
| 8c20d53789 | |||
| 576b020384 | |||
| 13eff70112 | |||
| daa301fef0 | |||
| 4b8fcbcee1 | |||
| 7361ffd26b | |||
| be5ed7364b | |||
| 73cbad2f78 | |||
| 02f9727dd8 | |||
| 503674167d | |||
| 54ceedbb1f | |||
| d17ae0b806 | |||
| fad30c3d2c | |||
| 8056433c44 | |||
| 12533bcb2b | |||
| 2da19eebd3 | |||
| a99b9da3d4 | |||
| 7142e25e78 | |||
| dd2e947976 | |||
| 357fded2b5 | |||
| 70e616db7c | |||
| 70fd243e3b | |||
| 5caecf548c | |||
| b7d56d5471 | |||
| 41c540fb1e | |||
| e7d6e86395 | |||
| c0bda4db88 | |||
| 88e8c7c94b | |||
| 9faebb5365 | |||
| 714ab21a6e | |||
| 8dae261d20 | |||
| 6fd0010325 | |||
| 7ef2730506 | |||
| 6407d7818d | |||
| c2de8ffd14 | |||
| f0e12d5301 | |||
| 21ed6bee25 | |||
| b9793abec6 | |||
| 5471fc808a | |||
| 281338409b | |||
| a833c4b4ee | |||
| bb6a24e6aa | |||
| 83bc045a56 | |||
| 6363a776f7 | |||
| f72c79d54a | |||
| 32bc7a6fe5 | |||
| 1186520617 | |||
| b5892a2b5e | |||
| 4f356e35a9 | |||
| 79eb94d3cd | |||
| 18552a8d5f | |||
| b047d28476 | |||
| 06e265b38d | |||
| 80458ebc72 | |||
| 6d415c508b | |||
| a936cbf5fb | |||
| 1ac1ac984e | |||
| 54268bfeed | |||
| 8204f6a71f | |||
| bbe804a14b | |||
| 28cf567e41 | |||
| 5bb865218f | |||
| 94692acb14 | |||
| 384dff9abe | |||
| 5bf3907862 | |||
| c8220aeea8 | |||
| 9155bfe27f | |||
| 1c5f16ae26 | |||
| d9fdffe88e | |||
| 0c05ce0eb1 | |||
| f28a4427a2 | |||
| e5ba8666de | |||
| 2fa3176399 | |||
| d1f2b19e6e | |||
| a8a3e0be05 | |||
| f38ff1bdbd | |||
| 34fdb0fe23 | |||
| 793de306cf | |||
| 0720923115 | |||
| 95666637b6 | |||
| 315f426f5c | |||
| 67dac7ae99 | |||
| a07499796a | |||
| fcab9c89f2 | |||
| cbe414864f | |||
| 0231fac514 | |||
| ff0c048ad9 | |||
| 96d6103e0b | |||
| 0ae92d78eb | |||
| 5e69036bbc | |||
| 6395ddac2c | |||
| df3c113711 | |||
| f3df2dab3d | |||
| cfef58361f | |||
| d8ab8a00f2 | |||
| 2733cb4a41 | |||
| a2a28b02e8 | |||
| 03765e08b9 | |||
| 9be0f100c4 | |||
| a3e312d133 | |||
| 3341dd8899 | |||
| 3bd30f7382 | |||
| 844a96d0b9 | |||
| 84a37e1460 | |||
| 36043ecc3e | |||
| d75ba16223 | |||
| 03dfb2965c | |||
| 9f822906b8 | |||
| eb92fd1f48 | |||
| 076cb7decd | |||
| 1961032592 | |||
| da67e435b1 | |||
| fffa406aa4 | |||
| 488c3de389 | |||
| 45747144ff | |||
| bc7ba69f9b | |||
| 423c6523ba | |||
| ecd6c57faa | |||
| 19de09afe1 | |||
| b0da0fded0 | |||
| 58a42443df | |||
| af42c39e6c | |||
| 3acc2b4216 | |||
| 932a39f5fd | |||
| 6956b935b3 | |||
| 7bdefbeb9a | |||
| 6fe9b340b4 | |||
| b25e8b91a5 | |||
| f7e53d90fa | |||
| 41f84f8b40 | |||
| b17de011dc | |||
| 14dd3f6610 | |||
| 716efc4b51 | |||
| 143ccf7a74 | |||
| dd750bc094 | |||
| ef83f895b9 | |||
| cd3be5fb02 | |||
| f29e98f772 | |||
| 308e5e9cc0 | |||
| 744f567f40 | |||
| b41b125c15 | |||
| 3df0a786e4 | |||
| fd4de77651 | |||
| ace14d3ad7 | |||
| 5c228805ad | |||
| 3c4528b8f4 | |||
| c87433e0c2 | |||
| f3888bb0b0 | |||
| 43ebb4fc43 | |||
| 94a7abcebc | |||
| f4d6f40442 | |||
| 269981ee6a | |||
| 34bc709bc2 | |||
| 32d0f6770c | |||
| caa0db9fa9 | |||
| 6ae041bca6 | |||
| fa1dfbd113 | |||
| a6889776f4 | |||
| 621d4b30da | |||
| 693907d3c8 | |||
| 2108641a37 | |||
| 418b6f7cb3 | |||
| 1a4e5346ed | |||
| ed200a0219 | |||
| c4487ba836 | |||
| 2c2d80d9a0 | |||
| 6247a7bf7c | |||
| 22f8660c8e | |||
| 175e2c7254 | |||
| 536262f2ec | |||
| a0a3187b30 | |||
| f3b5f9e8f0 | |||
| e6d5379e39 | |||
| 8bf7356f38 | |||
| d7b7644e68 | |||
| 8dd0739072 | |||
| 838509c0a4 | |||
| e6252d511c | |||
| e2e05294b0 | |||
| 3130a3f3de | |||
| 884d5e0132 | |||
| 8d28bd445a | |||
| 75c0a59bb4 | |||
| d643caf8fe | |||
| a010d88def | |||
| d3116fcea8 | |||
| 947de54cee | |||
| cda2866e7c | |||
| ae109f69cc | |||
| 5fdeaa81d5 | |||
| db2e1d2c74 | |||
| 396680b856 | |||
| 21198bf1c1 | |||
| aa6a44bb20 | |||
| 10642d14ea | |||
| 6ac45333fe | |||
| 0962b9e5e6 | |||
| c630cb4016 | |||
| 21e016378c | |||
| 7cee6df3f7 | |||
| 57325f51ff | |||
| 20a2aa4274 | |||
| 5c1c43d2e1 | |||
| f3a0a6a463 | |||
| 416c4ced2c | |||
| 3f51d342d1 | |||
| 1f54c72d1d | |||
| f90fd5330e | |||
| 653b154b0e | |||
| 6e0ace1914 | |||
| 5b8d5eb5e9 | |||
| 3a3d2b154f | |||
| f3606e3e21 | |||
| 9c16ffcaf4 | |||
| 4c319a1072 | |||
| 9b37104655 | |||
| 3e55408cb5 | |||
| 4b21fcf5af | |||
| d062352de7 | |||
| b4f87bb8fc | |||
| 225b492109 | |||
| 7825caa1fd | |||
| b79196f911 | |||
| d8cbd5554f | |||
| 5f7e43f170 | |||
| b644c72eb0 | |||
| 0b8296e525 | |||
| 651f6d8b57 | |||
| 13b19612d6 | |||
| c12a1c6898 | |||
| a23d42fc04 | |||
| 2a2519414b | |||
| c46f0353d1 | |||
| 8f4610e007 | |||
| 63ca200016 | |||
| d87e833310 | |||
| 198dbf348c | |||
| 094677f179 | |||
| e6167f1c0b | |||
| 23ddc9db2a | |||
| 8443df3826 | |||
| 6e5596e80c | |||
| f00d13125b | |||
| 3af2f8ad7c | |||
| 59afaca753 | |||
| f35eeed0eb | |||
| 8b19e3c215 | |||
| dca62efba9 | |||
| 923bbb44a8 | |||
| d4c455c180 | |||
| 5ac618681a | |||
| d191247505 | |||
| 9b55e96fa0 | |||
| 8868c0b6d3 | |||
| 534ff92ba5 | |||
| 31ec824aef | |||
| b732b6417e | |||
| 998b5f43fb | |||
| ff31995104 | |||
| 48a7cd4e60 | |||
| acd34a9372 | |||
| 2ce67a25ef | |||
| 700b811813 | |||
| 16f04b13d7 | |||
| e3ad4a5e14 | |||
| 579446d5d9 | |||
| fc07f7a0ff | |||
| dd6054efeb | |||
| 27a6a15d66 | |||
| 32e93579fa | |||
| c8719ce418 | |||
| 39fe05dfad | |||
| be101154fa | |||
| c329fc0a5f | |||
| e55dbc9681 | |||
| 6f1c67af0d | |||
| 5284a6df88 | |||
| 8bce0a4f2e | |||
| 11d2bbc092 | |||
| ff69c54497 | |||
| 6669f3fcee | |||
| 18e16a5db0 | |||
| 95fdc7bd8a | |||
| 27d696aa7d | |||
| ff6a565452 | |||
| 5f079c8605 | |||
| ea335ebc64 | |||
| b1a801566c | |||
| 2eac2a79b7 | |||
| f9fc8d2e96 | |||
| 89c32f5dd7 | |||
| eff3d7ca8e | |||
| 85225ef6ae | |||
| 2010c6b464 | |||
| 03891b00a7 | |||
| d0ec491b1f | |||
| 38536f42f4 |
@ -1,5 +0,0 @@
|
||||
# configure your infura api key (not technically required)
|
||||
INFURA_API_KEY=
|
||||
|
||||
# change the mnemonic that your hd wallet is seeded with
|
||||
MNEMONIC=
|
||||
11
.eslintrc
11
.eslintrc
@ -1,22 +1,23 @@
|
||||
{
|
||||
"extends" : [
|
||||
"standard",
|
||||
"plugin:promise/recommended"
|
||||
"plugin:promise/recommended",
|
||||
],
|
||||
"plugins": [
|
||||
"promise"
|
||||
"mocha-no-only",
|
||||
"promise",
|
||||
],
|
||||
"env": {
|
||||
"browser" : true,
|
||||
"node" : true,
|
||||
"mocha" : true,
|
||||
"jest" : true
|
||||
"jest" : true,
|
||||
},
|
||||
"globals" : {
|
||||
"artifacts": false,
|
||||
"contract": false,
|
||||
"assert": false,
|
||||
"web3": false
|
||||
"web3": false,
|
||||
},
|
||||
"rules": {
|
||||
|
||||
@ -49,6 +50,8 @@
|
||||
"semi": ["error", "always"],
|
||||
"space-before-function-paren": ["error", "always"],
|
||||
|
||||
"mocha-no-only/mocha-no-only": ["error"],
|
||||
|
||||
"promise/always-return": "off",
|
||||
"promise/avoid-new": "off",
|
||||
}
|
||||
|
||||
34
.github/ISSUE_TEMPLATE.md
vendored
34
.github/ISSUE_TEMPLATE.md
vendored
@ -1,34 +0,0 @@
|
||||
## 🎉 Description
|
||||
|
||||
<!-- Briefly describe the issue you are experiencing (or the feature you want to see added to OpenZeppelin). Tell us what you were trying to do and what happened instead. **Remember, this is _not_ a place to ask for help debugging code; for that, we welcome you in the [OpenZeppelin Slack Channel](https://slack.openzeppelin.org/).** -->
|
||||
|
||||
- [ ] 🐛 This is a bug report.
|
||||
- [ ] 📈 This is a feature request.
|
||||
|
||||
<!-- Please check one of the above by placing an x in the box. -->
|
||||
|
||||
## 💻 Environment
|
||||
|
||||
Next, we need to know what your environment looks like.
|
||||
|
||||
- Which version of OpenZeppelin are you using?
|
||||
- What network are you deploying to? Ganache? Ropsten?
|
||||
- How are you deploying your OpenZeppelin-backed contracts? truffle? Remix? Let us know!
|
||||
|
||||
## 📝 Details
|
||||
|
||||
Describe the problem you have been experiencing in more detail. Include as much information as you think is relevant. Keep in mind that transactions can fail for many reasons; context is key here.
|
||||
|
||||
## 🔢 Code To Reproduce Issue [ Good To Have ]
|
||||
|
||||
Please remember that with sample code it's easier to reproduce the bug and it's much faster to fix it.
|
||||
|
||||
```
|
||||
insert short code snippets here
|
||||
```
|
||||
|
||||
<!-- If your code is larger, consider linking us to a repo illustrating your issue. -->
|
||||
|
||||
## 👍 Other Information
|
||||
|
||||
<!-- List any other information that is relevant to your issue. Error logs, related issues, suggestions on how to fix, Stack Overflow links, forum links, etc. -->
|
||||
21
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
21
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Report a bug in OpenZeppelin
|
||||
|
||||
---
|
||||
|
||||
<!-- Briefly describe the issue you're experiencing. Tell us what you were trying to do and what happened instead. -->
|
||||
|
||||
<!-- Remember, this is not a place to ask for help debugging code. For that, we welcome you in the OpenZeppelin Slack channel: https://slack.openzeppelin.org/. -->
|
||||
|
||||
**💻 Environment**
|
||||
|
||||
<!-- Tell us what version of OpenZeppelin you're using, and how you're using it: Truffle, Remix, etc. -->
|
||||
|
||||
**📝 Details**
|
||||
|
||||
<!-- Describe the problem you have been experiencing in more detail. Include as much information as you think is relevant. Keep in mind that transactions can fail for many reasons; context is key here. -->
|
||||
|
||||
**🔢 Code to reproduce bug**
|
||||
|
||||
<!-- We will be able to better help if you provide a minimal example that triggers the bug. -->
|
||||
14
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
14
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
---
|
||||
name: Feature request
|
||||
about: Suggest an idea for OpenZeppelin
|
||||
|
||||
---
|
||||
|
||||
**🧐 Motivation**
|
||||
<!-- Is your feature request related to a specific problem? Is it just a crazy idea? Tell us about it! -->
|
||||
|
||||
**📝 Details**
|
||||
<!-- Please describe your feature request in detail. -->
|
||||
|
||||
<!-- Make sure that you have reviewed the OpenZeppelin Contributor Guidelines. -->
|
||||
<!-- https://github.com/OpenZeppelin/openzeppelin-solidity/blob/master/CONTRIBUTING.md -->
|
||||
25
.github/PULL_REQUEST_TEMPLATE.md
vendored
25
.github/PULL_REQUEST_TEMPLATE.md
vendored
@ -1,17 +1,22 @@
|
||||
<!-- 0. 🎉 Thank you for submitting a PR! -->
|
||||
|
||||
<!-- 1. **Does this close any open issues?** If so, list them here. If not, remove the `Fixes #` line. -->
|
||||
<!-- 1. Does this close any open issues? Please list them below. -->
|
||||
|
||||
<!-- Keep in mind that new features have a better chance of being merged fast if
|
||||
they were first discussed and designed with the maintainers. If there is no
|
||||
corresponding issue, please consider opening one for discussion first! -->
|
||||
|
||||
Fixes #
|
||||
|
||||
# 🚀 Description
|
||||
|
||||
<!-- 2. Describe the changes introduced in this pull request -->
|
||||
<!-- 2. Describe the changes introduced in this pull request. -->
|
||||
<!-- Include any context necessary for understanding the PR's purpose. -->
|
||||
|
||||
<!-- 3. Before submitting, please review the following checklist: -->
|
||||
|
||||
- [ ] 📘 I've reviewed the [OpenZeppelin Contributor Guidelines](../blob/master/CONTRIBUTING.md)
|
||||
- [ ] ✅ I've added tests where applicable to test my new functionality.
|
||||
- [ ] 📖 I've made sure that my contracts are well-documented.
|
||||
- [ ] 🎨 I've run the JS/Solidity linters and fixed any issues (`npm run lint:fix`).
|
||||
<!-- 3. Before submitting, please make sure that you have:
|
||||
- reviewed the OpenZeppelin Contributor Guidelines
|
||||
(https://github.com/OpenZeppelin/openzeppelin-solidity/blob/master/CONTRIBUTING.md),
|
||||
- added tests where applicable to test new functionality,
|
||||
- made sure that your contracts are well-documented,
|
||||
- run the Solidity linter (`npm run lint:sol`) and fixed any issues,
|
||||
- run the JS linter and fixed any issues (`npm run lint:fix`), and
|
||||
- updated the changelog, if applicable.
|
||||
-->
|
||||
|
||||
9
.gitignore
vendored
9
.gitignore
vendored
@ -32,8 +32,13 @@ npm-debug.log
|
||||
# truffle build directory
|
||||
build/
|
||||
|
||||
# lol macs
|
||||
.DS_Store/
|
||||
# macOS
|
||||
.DS_Store
|
||||
|
||||
# truffle
|
||||
.node-xmlhttprequest-*
|
||||
|
||||
.openzeppelin/.session
|
||||
|
||||
# IntelliJ IDE
|
||||
.idea
|
||||
|
||||
@ -1 +0,0 @@
|
||||
v8.9.1
|
||||
945
.openzeppelin/kovan.json
Normal file
945
.openzeppelin/kovan.json
Normal file
@ -0,0 +1,945 @@
|
||||
{
|
||||
"contracts": {
|
||||
"TokenVesting": {
|
||||
"address": "0x17d2e73611a9ec10ab4751c514a539ec820b953c",
|
||||
"constructorCode": "608060405234801561001057600080fd5b50611c6c806100206000396000f3fe",
|
||||
"bodyBytecodeHash": "ba0eade6a19e4b485aca3478c8755d2a6041a2b39a7aa1a0a73253a782c4a065",
|
||||
"localBytecodeHash": "94b5eed89a6bab268326a5010e52000ff74d40d96c83811c9d455d7c8b54f447",
|
||||
"deployedBytecodeHash": "94b5eed89a6bab268326a5010e52000ff74d40d96c83811c9d455d7c8b54f447",
|
||||
"types": {
|
||||
"t_bool": {
|
||||
"id": "t_bool",
|
||||
"kind": "elementary",
|
||||
"label": "bool"
|
||||
},
|
||||
"t_uint256": {
|
||||
"id": "t_uint256",
|
||||
"kind": "elementary",
|
||||
"label": "uint256"
|
||||
},
|
||||
"t_array:50<t_uint256>": {
|
||||
"id": "t_array:50<t_uint256>",
|
||||
"valueType": "t_uint256",
|
||||
"length": "50",
|
||||
"kind": "array",
|
||||
"label": "uint256[50]"
|
||||
},
|
||||
"t_address": {
|
||||
"id": "t_address",
|
||||
"kind": "elementary",
|
||||
"label": "address"
|
||||
},
|
||||
"t_mapping<t_uint256>": {
|
||||
"id": "t_mapping<t_uint256>",
|
||||
"valueType": "t_uint256",
|
||||
"label": "mapping(key => uint256)",
|
||||
"kind": "mapping"
|
||||
},
|
||||
"t_mapping<t_bool>": {
|
||||
"id": "t_mapping<t_bool>",
|
||||
"valueType": "t_bool",
|
||||
"label": "mapping(key => bool)",
|
||||
"kind": "mapping"
|
||||
}
|
||||
},
|
||||
"storage": [
|
||||
{
|
||||
"contract": "Initializable",
|
||||
"path": "@openzeppelin/upgrades/contracts/Initializable.sol",
|
||||
"label": "initialized",
|
||||
"astId": 13503,
|
||||
"type": "t_bool",
|
||||
"src": "757:24:147"
|
||||
},
|
||||
{
|
||||
"contract": "Initializable",
|
||||
"path": "@openzeppelin/upgrades/contracts/Initializable.sol",
|
||||
"label": "initializing",
|
||||
"astId": 13505,
|
||||
"type": "t_bool",
|
||||
"src": "876:25:147"
|
||||
},
|
||||
{
|
||||
"contract": "Initializable",
|
||||
"path": "@openzeppelin/upgrades/contracts/Initializable.sol",
|
||||
"label": "______gap",
|
||||
"astId": 13554,
|
||||
"type": "t_array:50<t_uint256>",
|
||||
"src": "1891:29:147"
|
||||
},
|
||||
{
|
||||
"contract": "Ownable",
|
||||
"path": "contracts/ownership/Ownable.sol",
|
||||
"label": "_owner",
|
||||
"astId": 8198,
|
||||
"type": "t_address",
|
||||
"src": "472:22:108"
|
||||
},
|
||||
{
|
||||
"contract": "Ownable",
|
||||
"path": "contracts/ownership/Ownable.sol",
|
||||
"label": "______gap",
|
||||
"astId": 8311,
|
||||
"type": "t_array:50<t_uint256>",
|
||||
"src": "2415:29:108"
|
||||
},
|
||||
{
|
||||
"contract": "TokenVesting",
|
||||
"path": "contracts/drafts/TokenVesting.sol",
|
||||
"label": "_beneficiary",
|
||||
"astId": 3576,
|
||||
"type": "t_address",
|
||||
"src": "1133:28:28"
|
||||
},
|
||||
{
|
||||
"contract": "TokenVesting",
|
||||
"path": "contracts/drafts/TokenVesting.sol",
|
||||
"label": "_cliff",
|
||||
"astId": 3578,
|
||||
"type": "t_uint256",
|
||||
"src": "1263:22:28"
|
||||
},
|
||||
{
|
||||
"contract": "TokenVesting",
|
||||
"path": "contracts/drafts/TokenVesting.sol",
|
||||
"label": "_start",
|
||||
"astId": 3580,
|
||||
"type": "t_uint256",
|
||||
"src": "1291:22:28"
|
||||
},
|
||||
{
|
||||
"contract": "TokenVesting",
|
||||
"path": "contracts/drafts/TokenVesting.sol",
|
||||
"label": "_duration",
|
||||
"astId": 3582,
|
||||
"type": "t_uint256",
|
||||
"src": "1319:25:28"
|
||||
},
|
||||
{
|
||||
"contract": "TokenVesting",
|
||||
"path": "contracts/drafts/TokenVesting.sol",
|
||||
"label": "_revocable",
|
||||
"astId": 3584,
|
||||
"type": "t_bool",
|
||||
"src": "1351:23:28"
|
||||
},
|
||||
{
|
||||
"contract": "TokenVesting",
|
||||
"path": "contracts/drafts/TokenVesting.sol",
|
||||
"label": "_released",
|
||||
"astId": 3588,
|
||||
"type": "t_mapping<t_uint256>",
|
||||
"src": "1381:46:28"
|
||||
},
|
||||
{
|
||||
"contract": "TokenVesting",
|
||||
"path": "contracts/drafts/TokenVesting.sol",
|
||||
"label": "_revoked",
|
||||
"astId": 3592,
|
||||
"type": "t_mapping<t_bool>",
|
||||
"src": "1433:42:28"
|
||||
},
|
||||
{
|
||||
"contract": "TokenVesting",
|
||||
"path": "contracts/drafts/TokenVesting.sol",
|
||||
"label": "______gap",
|
||||
"astId": 3941,
|
||||
"type": "t_array:50<t_uint256>",
|
||||
"src": "6226:29:28"
|
||||
}
|
||||
],
|
||||
"warnings": {
|
||||
"hasConstructor": false,
|
||||
"hasSelfDestruct": false,
|
||||
"hasDelegateCall": false,
|
||||
"hasInitialValuesInDeclarations": false,
|
||||
"uninitializedBaseContracts": [],
|
||||
"storageUncheckedVars": [],
|
||||
"storageDiff": []
|
||||
}
|
||||
},
|
||||
"PaymentSplitter": {
|
||||
"address": "0xf1e274980871d7c4aaab8d646c17728ed263e747",
|
||||
"constructorCode": "608060405234801561001057600080fd5b506110a4806100206000396000f3fe",
|
||||
"bodyBytecodeHash": "fe0f9da480efb9ef366284126f8d9dccff6f19f8ee0183449035b37c1f5103d8",
|
||||
"localBytecodeHash": "d9901040952d3add936b2939fb694875bdfd7b513c877bc1942d36a5e4190873",
|
||||
"deployedBytecodeHash": "d9901040952d3add936b2939fb694875bdfd7b513c877bc1942d36a5e4190873",
|
||||
"types": {
|
||||
"t_bool": {
|
||||
"id": "t_bool",
|
||||
"kind": "elementary",
|
||||
"label": "bool"
|
||||
},
|
||||
"t_uint256": {
|
||||
"id": "t_uint256",
|
||||
"kind": "elementary",
|
||||
"label": "uint256"
|
||||
},
|
||||
"t_array:50<t_uint256>": {
|
||||
"id": "t_array:50<t_uint256>",
|
||||
"valueType": "t_uint256",
|
||||
"length": "50",
|
||||
"kind": "array",
|
||||
"label": "uint256[50]"
|
||||
},
|
||||
"t_mapping<t_uint256>": {
|
||||
"id": "t_mapping<t_uint256>",
|
||||
"valueType": "t_uint256",
|
||||
"label": "mapping(key => uint256)",
|
||||
"kind": "mapping"
|
||||
},
|
||||
"t_address": {
|
||||
"id": "t_address",
|
||||
"kind": "elementary",
|
||||
"label": "address"
|
||||
},
|
||||
"t_array:dyn<t_address>": {
|
||||
"id": "t_array:dyn<t_address>",
|
||||
"valueType": "t_address",
|
||||
"length": "dyn",
|
||||
"kind": "array",
|
||||
"label": "address[]"
|
||||
}
|
||||
},
|
||||
"storage": [
|
||||
{
|
||||
"contract": "Initializable",
|
||||
"path": "@openzeppelin/upgrades/contracts/Initializable.sol",
|
||||
"label": "initialized",
|
||||
"astId": 13503,
|
||||
"type": "t_bool",
|
||||
"src": "757:24:147"
|
||||
},
|
||||
{
|
||||
"contract": "Initializable",
|
||||
"path": "@openzeppelin/upgrades/contracts/Initializable.sol",
|
||||
"label": "initializing",
|
||||
"astId": 13505,
|
||||
"type": "t_bool",
|
||||
"src": "876:25:147"
|
||||
},
|
||||
{
|
||||
"contract": "Initializable",
|
||||
"path": "@openzeppelin/upgrades/contracts/Initializable.sol",
|
||||
"label": "______gap",
|
||||
"astId": 13554,
|
||||
"type": "t_array:50<t_uint256>",
|
||||
"src": "1891:29:147"
|
||||
},
|
||||
{
|
||||
"contract": "PaymentSplitter",
|
||||
"path": "contracts/payment/PaymentSplitter.sol",
|
||||
"label": "_totalShares",
|
||||
"astId": 8418,
|
||||
"type": "t_uint256",
|
||||
"src": "1176:28:110"
|
||||
},
|
||||
{
|
||||
"contract": "PaymentSplitter",
|
||||
"path": "contracts/payment/PaymentSplitter.sol",
|
||||
"label": "_totalReleased",
|
||||
"astId": 8420,
|
||||
"type": "t_uint256",
|
||||
"src": "1210:30:110"
|
||||
},
|
||||
{
|
||||
"contract": "PaymentSplitter",
|
||||
"path": "contracts/payment/PaymentSplitter.sol",
|
||||
"label": "_shares",
|
||||
"astId": 8424,
|
||||
"type": "t_mapping<t_uint256>",
|
||||
"src": "1247:43:110"
|
||||
},
|
||||
{
|
||||
"contract": "PaymentSplitter",
|
||||
"path": "contracts/payment/PaymentSplitter.sol",
|
||||
"label": "_released",
|
||||
"astId": 8428,
|
||||
"type": "t_mapping<t_uint256>",
|
||||
"src": "1296:45:110"
|
||||
},
|
||||
{
|
||||
"contract": "PaymentSplitter",
|
||||
"path": "contracts/payment/PaymentSplitter.sol",
|
||||
"label": "_payees",
|
||||
"astId": 8431,
|
||||
"type": "t_array:dyn<t_address>",
|
||||
"src": "1347:25:110"
|
||||
},
|
||||
{
|
||||
"contract": "PaymentSplitter",
|
||||
"path": "contracts/payment/PaymentSplitter.sol",
|
||||
"label": "______gap",
|
||||
"astId": 8684,
|
||||
"type": "t_array:50<t_uint256>",
|
||||
"src": "5158:29:110"
|
||||
}
|
||||
],
|
||||
"warnings": {
|
||||
"hasConstructor": false,
|
||||
"hasSelfDestruct": false,
|
||||
"hasDelegateCall": false,
|
||||
"hasInitialValuesInDeclarations": false,
|
||||
"uninitializedBaseContracts": [],
|
||||
"storageUncheckedVars": [],
|
||||
"storageDiff": []
|
||||
}
|
||||
},
|
||||
"StandaloneERC20": {
|
||||
"address": "0x2a79d89665d22ee56cc0efd102169fa41f27b065",
|
||||
"constructorCode": "608060405234801561001057600080fd5b50613153806100206000396000f3fe",
|
||||
"bodyBytecodeHash": "ad8d45945d6a4f088a61fd605c38cdf2f40171624bca2a7c3b2d4e95b068eb3d",
|
||||
"localBytecodeHash": "bca15bc1a7aa87c603c9b185aab38e0d72b8adc6347426bb66954cef39e88a74",
|
||||
"deployedBytecodeHash": "bca15bc1a7aa87c603c9b185aab38e0d72b8adc6347426bb66954cef39e88a74",
|
||||
"types": {
|
||||
"t_bool": {
|
||||
"id": "t_bool",
|
||||
"kind": "elementary",
|
||||
"label": "bool"
|
||||
},
|
||||
"t_uint256": {
|
||||
"id": "t_uint256",
|
||||
"kind": "elementary",
|
||||
"label": "uint256"
|
||||
},
|
||||
"t_array:50<t_uint256>": {
|
||||
"id": "t_array:50<t_uint256>",
|
||||
"valueType": "t_uint256",
|
||||
"length": "50",
|
||||
"kind": "array",
|
||||
"label": "uint256[50]"
|
||||
},
|
||||
"t_string": {
|
||||
"id": "t_string",
|
||||
"kind": "elementary",
|
||||
"label": "string"
|
||||
},
|
||||
"t_uint8": {
|
||||
"id": "t_uint8",
|
||||
"kind": "elementary",
|
||||
"label": "uint8"
|
||||
},
|
||||
"t_mapping<t_uint256>": {
|
||||
"id": "t_mapping<t_uint256>",
|
||||
"valueType": "t_uint256",
|
||||
"label": "mapping(key => uint256)",
|
||||
"kind": "mapping"
|
||||
},
|
||||
"t_struct<Roles.Role>": {
|
||||
"id": "t_struct<Roles.Role>",
|
||||
"kind": "struct",
|
||||
"label": "Roles.Role",
|
||||
"members": [
|
||||
{
|
||||
"label": "bearer",
|
||||
"astId": 5,
|
||||
"type": "t_mapping<t_bool>",
|
||||
"src": "150:32:0"
|
||||
}
|
||||
]
|
||||
},
|
||||
"t_mapping<t_bool>": {
|
||||
"id": "t_mapping<t_bool>",
|
||||
"valueType": "t_bool",
|
||||
"label": "mapping(key => bool)",
|
||||
"kind": "mapping"
|
||||
}
|
||||
},
|
||||
"storage": [
|
||||
{
|
||||
"contract": "Initializable",
|
||||
"path": "@openzeppelin/upgrades/contracts/Initializable.sol",
|
||||
"label": "initialized",
|
||||
"astId": 13503,
|
||||
"type": "t_bool",
|
||||
"src": "757:24:147"
|
||||
},
|
||||
{
|
||||
"contract": "Initializable",
|
||||
"path": "@openzeppelin/upgrades/contracts/Initializable.sol",
|
||||
"label": "initializing",
|
||||
"astId": 13505,
|
||||
"type": "t_bool",
|
||||
"src": "876:25:147"
|
||||
},
|
||||
{
|
||||
"contract": "Initializable",
|
||||
"path": "@openzeppelin/upgrades/contracts/Initializable.sol",
|
||||
"label": "______gap",
|
||||
"astId": 13554,
|
||||
"type": "t_array:50<t_uint256>",
|
||||
"src": "1891:29:147"
|
||||
},
|
||||
{
|
||||
"contract": "ERC20Detailed",
|
||||
"path": "contracts/token/ERC20/ERC20Detailed.sol",
|
||||
"label": "_name",
|
||||
"astId": 9641,
|
||||
"type": "t_string",
|
||||
"src": "209:20:118"
|
||||
},
|
||||
{
|
||||
"contract": "ERC20Detailed",
|
||||
"path": "contracts/token/ERC20/ERC20Detailed.sol",
|
||||
"label": "_symbol",
|
||||
"astId": 9643,
|
||||
"type": "t_string",
|
||||
"src": "235:22:118"
|
||||
},
|
||||
{
|
||||
"contract": "ERC20Detailed",
|
||||
"path": "contracts/token/ERC20/ERC20Detailed.sol",
|
||||
"label": "_decimals",
|
||||
"astId": 9645,
|
||||
"type": "t_uint8",
|
||||
"src": "263:23:118"
|
||||
},
|
||||
{
|
||||
"contract": "ERC20Detailed",
|
||||
"path": "contracts/token/ERC20/ERC20Detailed.sol",
|
||||
"label": "______gap",
|
||||
"astId": 9697,
|
||||
"type": "t_array:50<t_uint256>",
|
||||
"src": "1645:29:118"
|
||||
},
|
||||
{
|
||||
"contract": "ERC20",
|
||||
"path": "contracts/token/ERC20/ERC20.sol",
|
||||
"label": "_balances",
|
||||
"astId": 9129,
|
||||
"type": "t_mapping<t_uint256>",
|
||||
"src": "1357:46:115"
|
||||
},
|
||||
{
|
||||
"contract": "ERC20",
|
||||
"path": "contracts/token/ERC20/ERC20.sol",
|
||||
"label": "_allowances",
|
||||
"astId": 9135,
|
||||
"type": "t_mapping<t_uint256>",
|
||||
"src": "1410:69:115"
|
||||
},
|
||||
{
|
||||
"contract": "ERC20",
|
||||
"path": "contracts/token/ERC20/ERC20.sol",
|
||||
"label": "_totalSupply",
|
||||
"astId": 9137,
|
||||
"type": "t_uint256",
|
||||
"src": "1486:28:115"
|
||||
},
|
||||
{
|
||||
"contract": "ERC20",
|
||||
"path": "contracts/token/ERC20/ERC20.sol",
|
||||
"label": "______gap",
|
||||
"astId": 9516,
|
||||
"type": "t_array:50<t_uint256>",
|
||||
"src": "7875:29:115"
|
||||
},
|
||||
{
|
||||
"contract": "MinterRole",
|
||||
"path": "contracts/access/roles/MinterRole.sol",
|
||||
"label": "_minters",
|
||||
"astId": 219,
|
||||
"type": "t_struct<Roles.Role>",
|
||||
"src": "271:27:2"
|
||||
},
|
||||
{
|
||||
"contract": "MinterRole",
|
||||
"path": "contracts/access/roles/MinterRole.sol",
|
||||
"label": "______gap",
|
||||
"astId": 319,
|
||||
"type": "t_array:50<t_uint256>",
|
||||
"src": "1133:29:2"
|
||||
},
|
||||
{
|
||||
"contract": "ERC20Mintable",
|
||||
"path": "contracts/token/ERC20/ERC20Mintable.sol",
|
||||
"label": "______gap",
|
||||
"astId": 9746,
|
||||
"type": "t_array:50<t_uint256>",
|
||||
"src": "816:29:119"
|
||||
},
|
||||
{
|
||||
"contract": "PauserRole",
|
||||
"path": "contracts/access/roles/PauserRole.sol",
|
||||
"label": "_pausers",
|
||||
"astId": 339,
|
||||
"type": "t_struct<Roles.Role>",
|
||||
"src": "271:27:3"
|
||||
},
|
||||
{
|
||||
"contract": "PauserRole",
|
||||
"path": "contracts/access/roles/PauserRole.sol",
|
||||
"label": "______gap",
|
||||
"astId": 439,
|
||||
"type": "t_array:50<t_uint256>",
|
||||
"src": "1133:29:3"
|
||||
},
|
||||
{
|
||||
"contract": "Pausable",
|
||||
"path": "contracts/lifecycle/Pausable.sol",
|
||||
"label": "_paused",
|
||||
"astId": 4481,
|
||||
"type": "t_bool",
|
||||
"src": "855:20:37"
|
||||
},
|
||||
{
|
||||
"contract": "Pausable",
|
||||
"path": "contracts/lifecycle/Pausable.sol",
|
||||
"label": "______gap",
|
||||
"astId": 4564,
|
||||
"type": "t_array:50<t_uint256>",
|
||||
"src": "2105:29:37"
|
||||
},
|
||||
{
|
||||
"contract": "ERC20Pausable",
|
||||
"path": "contracts/token/ERC20/ERC20Pausable.sol",
|
||||
"label": "______gap",
|
||||
"astId": 9869,
|
||||
"type": "t_array:50<t_uint256>",
|
||||
"src": "1178:29:120"
|
||||
}
|
||||
],
|
||||
"warnings": {
|
||||
"hasConstructor": false,
|
||||
"hasSelfDestruct": false,
|
||||
"hasDelegateCall": false,
|
||||
"hasInitialValuesInDeclarations": false,
|
||||
"uninitializedBaseContracts": [],
|
||||
"storageUncheckedVars": [
|
||||
{
|
||||
"contract": "MinterRole",
|
||||
"path": "contracts/access/roles/MinterRole.sol",
|
||||
"label": "_minters",
|
||||
"astId": 219,
|
||||
"type": "t_struct<Roles.Role>",
|
||||
"src": "271:27:2"
|
||||
},
|
||||
{
|
||||
"contract": "PauserRole",
|
||||
"path": "contracts/access/roles/PauserRole.sol",
|
||||
"label": "_pausers",
|
||||
"astId": 339,
|
||||
"type": "t_struct<Roles.Role>",
|
||||
"src": "271:27:3"
|
||||
}
|
||||
],
|
||||
"storageDiff": [
|
||||
{
|
||||
"action": "rename",
|
||||
"updated": {
|
||||
"index": 8,
|
||||
"contract": "ERC20",
|
||||
"path": "contracts/token/ERC20/ERC20.sol",
|
||||
"label": "_allowances",
|
||||
"astId": 9135,
|
||||
"type": "t_mapping<t_uint256>",
|
||||
"src": "1410:69:115"
|
||||
},
|
||||
"original": {
|
||||
"index": 8,
|
||||
"contract": "ERC20",
|
||||
"path": "contracts/token/ERC20/ERC20.sol",
|
||||
"label": "_allowed",
|
||||
"astId": 8173,
|
||||
"type": "t_mapping<t_uint256>",
|
||||
"src": "827:66:110"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"StandaloneERC721": {
|
||||
"address": "0x61e5b805911ba82de487e13de1e375a6130004f0",
|
||||
"constructorCode": "608060405234801561001057600080fd5b50614299806100206000396000f3fe",
|
||||
"bodyBytecodeHash": "9113153cb4b2b62f720cb12960ba3b4a7b9a5f3329e34a4a3ece0212d130ae53",
|
||||
"localBytecodeHash": "5dca693db1fee9a4ce973e49d6665a8770b823c36ba2c7e64f37d81046672074",
|
||||
"deployedBytecodeHash": "5dca693db1fee9a4ce973e49d6665a8770b823c36ba2c7e64f37d81046672074",
|
||||
"types": {
|
||||
"t_bool": {
|
||||
"id": "t_bool",
|
||||
"kind": "elementary",
|
||||
"label": "bool"
|
||||
},
|
||||
"t_uint256": {
|
||||
"id": "t_uint256",
|
||||
"kind": "elementary",
|
||||
"label": "uint256"
|
||||
},
|
||||
"t_array:50<t_uint256>": {
|
||||
"id": "t_array:50<t_uint256>",
|
||||
"valueType": "t_uint256",
|
||||
"length": "50",
|
||||
"kind": "array",
|
||||
"label": "uint256[50]"
|
||||
},
|
||||
"t_mapping<t_bool>": {
|
||||
"id": "t_mapping<t_bool>",
|
||||
"valueType": "t_bool",
|
||||
"label": "mapping(key => bool)",
|
||||
"kind": "mapping"
|
||||
},
|
||||
"t_address": {
|
||||
"id": "t_address",
|
||||
"kind": "elementary",
|
||||
"label": "address"
|
||||
},
|
||||
"t_mapping<t_address>": {
|
||||
"id": "t_mapping<t_address>",
|
||||
"valueType": "t_address",
|
||||
"label": "mapping(key => address)",
|
||||
"kind": "mapping"
|
||||
},
|
||||
"t_struct<Counters.Counter>": {
|
||||
"id": "t_struct<Counters.Counter>",
|
||||
"kind": "struct",
|
||||
"label": "Counters.Counter",
|
||||
"members": [
|
||||
{
|
||||
"label": "_value",
|
||||
"astId": 2533,
|
||||
"type": "t_uint256",
|
||||
"src": "1022:14:22"
|
||||
}
|
||||
]
|
||||
},
|
||||
"t_mapping<t_struct<Counters.Counter>>": {
|
||||
"id": "t_mapping<t_struct<Counters.Counter>>",
|
||||
"valueType": "t_struct<Counters.Counter>",
|
||||
"label": "mapping(key => Counters.Counter)",
|
||||
"kind": "mapping"
|
||||
},
|
||||
"t_array:dyn<t_uint256>": {
|
||||
"id": "t_array:dyn<t_uint256>",
|
||||
"valueType": "t_uint256",
|
||||
"length": "dyn",
|
||||
"kind": "array",
|
||||
"label": "uint256[]"
|
||||
},
|
||||
"t_mapping<t_array:dyn<t_uint256>>": {
|
||||
"id": "t_mapping<t_array:dyn<t_uint256>>",
|
||||
"valueType": "t_array:dyn<t_uint256>",
|
||||
"label": "mapping(key => uint256[])",
|
||||
"kind": "mapping"
|
||||
},
|
||||
"t_mapping<t_uint256>": {
|
||||
"id": "t_mapping<t_uint256>",
|
||||
"valueType": "t_uint256",
|
||||
"label": "mapping(key => uint256)",
|
||||
"kind": "mapping"
|
||||
},
|
||||
"t_string": {
|
||||
"id": "t_string",
|
||||
"kind": "elementary",
|
||||
"label": "string"
|
||||
},
|
||||
"t_mapping<t_string>": {
|
||||
"id": "t_mapping<t_string>",
|
||||
"valueType": "t_string",
|
||||
"label": "mapping(key => string)",
|
||||
"kind": "mapping"
|
||||
},
|
||||
"t_struct<Roles.Role>": {
|
||||
"id": "t_struct<Roles.Role>",
|
||||
"kind": "struct",
|
||||
"label": "Roles.Role",
|
||||
"members": [
|
||||
{
|
||||
"label": "bearer",
|
||||
"astId": 5,
|
||||
"type": "t_mapping<t_bool>",
|
||||
"src": "150:32:0"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"storage": [
|
||||
{
|
||||
"contract": "Initializable",
|
||||
"path": "@openzeppelin/upgrades/contracts/Initializable.sol",
|
||||
"label": "initialized",
|
||||
"astId": 13503,
|
||||
"type": "t_bool",
|
||||
"src": "757:24:147"
|
||||
},
|
||||
{
|
||||
"contract": "Initializable",
|
||||
"path": "@openzeppelin/upgrades/contracts/Initializable.sol",
|
||||
"label": "initializing",
|
||||
"astId": 13505,
|
||||
"type": "t_bool",
|
||||
"src": "876:25:147"
|
||||
},
|
||||
{
|
||||
"contract": "Initializable",
|
||||
"path": "@openzeppelin/upgrades/contracts/Initializable.sol",
|
||||
"label": "______gap",
|
||||
"astId": 13554,
|
||||
"type": "t_array:50<t_uint256>",
|
||||
"src": "1891:29:147"
|
||||
},
|
||||
{
|
||||
"contract": "ERC165",
|
||||
"path": "contracts/introspection/ERC165.sol",
|
||||
"label": "_supportedInterfaces",
|
||||
"astId": 4117,
|
||||
"type": "t_mapping<t_bool>",
|
||||
"src": "550:52:31"
|
||||
},
|
||||
{
|
||||
"contract": "ERC165",
|
||||
"path": "contracts/introspection/ERC165.sol",
|
||||
"label": "______gap",
|
||||
"astId": 4162,
|
||||
"type": "t_array:50<t_uint256>",
|
||||
"src": "1714:29:31"
|
||||
},
|
||||
{
|
||||
"contract": "ERC721",
|
||||
"path": "contracts/token/ERC721/ERC721.sol",
|
||||
"label": "_tokenOwner",
|
||||
"astId": 10508,
|
||||
"type": "t_mapping<t_address>",
|
||||
"src": "829:48:125"
|
||||
},
|
||||
{
|
||||
"contract": "ERC721",
|
||||
"path": "contracts/token/ERC721/ERC721.sol",
|
||||
"label": "_tokenApprovals",
|
||||
"astId": 10512,
|
||||
"type": "t_mapping<t_address>",
|
||||
"src": "933:52:125"
|
||||
},
|
||||
{
|
||||
"contract": "ERC721",
|
||||
"path": "contracts/token/ERC721/ERC721.sol",
|
||||
"label": "_ownedTokensCount",
|
||||
"astId": 10516,
|
||||
"type": "t_mapping<t_struct<Counters.Counter>>",
|
||||
"src": "1043:63:125"
|
||||
},
|
||||
{
|
||||
"contract": "ERC721",
|
||||
"path": "contracts/token/ERC721/ERC721.sol",
|
||||
"label": "_operatorApprovals",
|
||||
"astId": 10522,
|
||||
"type": "t_mapping<t_bool>",
|
||||
"src": "1161:73:125"
|
||||
},
|
||||
{
|
||||
"contract": "ERC721",
|
||||
"path": "contracts/token/ERC721/ERC721.sol",
|
||||
"label": "______gap",
|
||||
"astId": 11065,
|
||||
"type": "t_array:50<t_uint256>",
|
||||
"src": "12696:29:125"
|
||||
},
|
||||
{
|
||||
"contract": "ERC721Enumerable",
|
||||
"path": "contracts/token/ERC721/ERC721Enumerable.sol",
|
||||
"label": "_ownedTokens",
|
||||
"astId": 11117,
|
||||
"type": "t_mapping<t_array:dyn<t_uint256>>",
|
||||
"src": "445:50:127"
|
||||
},
|
||||
{
|
||||
"contract": "ERC721Enumerable",
|
||||
"path": "contracts/token/ERC721/ERC721Enumerable.sol",
|
||||
"label": "_ownedTokensIndex",
|
||||
"astId": 11121,
|
||||
"type": "t_mapping<t_uint256>",
|
||||
"src": "565:53:127"
|
||||
},
|
||||
{
|
||||
"contract": "ERC721Enumerable",
|
||||
"path": "contracts/token/ERC721/ERC721Enumerable.sol",
|
||||
"label": "_allTokens",
|
||||
"astId": 11124,
|
||||
"type": "t_array:dyn<t_uint256>",
|
||||
"src": "679:28:127"
|
||||
},
|
||||
{
|
||||
"contract": "ERC721Enumerable",
|
||||
"path": "contracts/token/ERC721/ERC721Enumerable.sol",
|
||||
"label": "_allTokensIndex",
|
||||
"astId": 11128,
|
||||
"type": "t_mapping<t_uint256>",
|
||||
"src": "778:51:127"
|
||||
},
|
||||
{
|
||||
"contract": "ERC721Enumerable",
|
||||
"path": "contracts/token/ERC721/ERC721Enumerable.sol",
|
||||
"label": "______gap",
|
||||
"astId": 11459,
|
||||
"type": "t_array:50<t_uint256>",
|
||||
"src": "8994:29:127"
|
||||
},
|
||||
{
|
||||
"contract": "ERC721Metadata",
|
||||
"path": "contracts/token/ERC721/ERC721Metadata.sol",
|
||||
"label": "_name",
|
||||
"astId": 11526,
|
||||
"type": "t_string",
|
||||
"src": "266:20:130"
|
||||
},
|
||||
{
|
||||
"contract": "ERC721Metadata",
|
||||
"path": "contracts/token/ERC721/ERC721Metadata.sol",
|
||||
"label": "_symbol",
|
||||
"astId": 11528,
|
||||
"type": "t_string",
|
||||
"src": "313:22:130"
|
||||
},
|
||||
{
|
||||
"contract": "ERC721Metadata",
|
||||
"path": "contracts/token/ERC721/ERC721Metadata.sol",
|
||||
"label": "_tokenURIs",
|
||||
"astId": 11532,
|
||||
"type": "t_mapping<t_string>",
|
||||
"src": "381:45:130"
|
||||
},
|
||||
{
|
||||
"contract": "ERC721Metadata",
|
||||
"path": "contracts/token/ERC721/ERC721Metadata.sol",
|
||||
"label": "______gap",
|
||||
"astId": 11663,
|
||||
"type": "t_array:50<t_uint256>",
|
||||
"src": "3029:29:130"
|
||||
},
|
||||
{
|
||||
"contract": "MinterRole",
|
||||
"path": "contracts/access/roles/MinterRole.sol",
|
||||
"label": "_minters",
|
||||
"astId": 219,
|
||||
"type": "t_struct<Roles.Role>",
|
||||
"src": "271:27:2"
|
||||
},
|
||||
{
|
||||
"contract": "MinterRole",
|
||||
"path": "contracts/access/roles/MinterRole.sol",
|
||||
"label": "______gap",
|
||||
"astId": 319,
|
||||
"type": "t_array:50<t_uint256>",
|
||||
"src": "1133:29:2"
|
||||
},
|
||||
{
|
||||
"contract": "ERC721MetadataMintable",
|
||||
"path": "contracts/token/ERC721/ERC721MetadataMintable.sol",
|
||||
"label": "______gap",
|
||||
"astId": 11733,
|
||||
"type": "t_array:50<t_uint256>",
|
||||
"src": "1042:29:131"
|
||||
},
|
||||
{
|
||||
"contract": "PauserRole",
|
||||
"path": "contracts/access/roles/PauserRole.sol",
|
||||
"label": "_pausers",
|
||||
"astId": 339,
|
||||
"type": "t_struct<Roles.Role>",
|
||||
"src": "271:27:3"
|
||||
},
|
||||
{
|
||||
"contract": "PauserRole",
|
||||
"path": "contracts/access/roles/PauserRole.sol",
|
||||
"label": "______gap",
|
||||
"astId": 439,
|
||||
"type": "t_array:50<t_uint256>",
|
||||
"src": "1133:29:3"
|
||||
},
|
||||
{
|
||||
"contract": "Pausable",
|
||||
"path": "contracts/lifecycle/Pausable.sol",
|
||||
"label": "_paused",
|
||||
"astId": 4481,
|
||||
"type": "t_bool",
|
||||
"src": "855:20:37"
|
||||
},
|
||||
{
|
||||
"contract": "Pausable",
|
||||
"path": "contracts/lifecycle/Pausable.sol",
|
||||
"label": "______gap",
|
||||
"astId": 4564,
|
||||
"type": "t_array:50<t_uint256>",
|
||||
"src": "2105:29:37"
|
||||
},
|
||||
{
|
||||
"contract": "ERC721Pausable",
|
||||
"path": "contracts/token/ERC721/ERC721Pausable.sol",
|
||||
"label": "______gap",
|
||||
"astId": 11878,
|
||||
"type": "t_array:50<t_uint256>",
|
||||
"src": "850:29:133"
|
||||
}
|
||||
],
|
||||
"warnings": {
|
||||
"hasConstructor": false,
|
||||
"hasSelfDestruct": false,
|
||||
"hasDelegateCall": false,
|
||||
"hasInitialValuesInDeclarations": false,
|
||||
"uninitializedBaseContracts": [],
|
||||
"storageUncheckedVars": [
|
||||
{
|
||||
"contract": "ERC721",
|
||||
"path": "contracts/token/ERC721/ERC721.sol",
|
||||
"label": "_ownedTokensCount",
|
||||
"astId": 10516,
|
||||
"type": "t_mapping<t_struct<Counters.Counter>>",
|
||||
"src": "1043:63:125"
|
||||
},
|
||||
{
|
||||
"contract": "MinterRole",
|
||||
"path": "contracts/access/roles/MinterRole.sol",
|
||||
"label": "_minters",
|
||||
"astId": 219,
|
||||
"type": "t_struct<Roles.Role>",
|
||||
"src": "271:27:2"
|
||||
},
|
||||
{
|
||||
"contract": "PauserRole",
|
||||
"path": "contracts/access/roles/PauserRole.sol",
|
||||
"label": "_pausers",
|
||||
"astId": 339,
|
||||
"type": "t_struct<Roles.Role>",
|
||||
"src": "271:27:3"
|
||||
}
|
||||
],
|
||||
"storageDiff": [
|
||||
{
|
||||
"action": "typechange",
|
||||
"updated": {
|
||||
"index": 7,
|
||||
"contract": "ERC721",
|
||||
"path": "contracts/token/ERC721/ERC721.sol",
|
||||
"label": "_ownedTokensCount",
|
||||
"astId": 10516,
|
||||
"type": "t_mapping<t_struct<Counters.Counter>>",
|
||||
"src": "1043:63:125"
|
||||
},
|
||||
"original": {
|
||||
"index": 7,
|
||||
"contract": "ERC721",
|
||||
"path": "contracts/token/ERC721/ERC721.sol",
|
||||
"label": "_ownedTokensCount",
|
||||
"astId": 9505,
|
||||
"type": "t_mapping<t_uint256>",
|
||||
"src": "988:54:120"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"solidityLibs": {},
|
||||
"proxies": {},
|
||||
"manifestVersion": "2.2",
|
||||
"frozen": true,
|
||||
"app": {
|
||||
"address": "0xf5829d56998ccc1405b7eabccac78164af270d39"
|
||||
},
|
||||
"package": {
|
||||
"address": "0xb6f8f11b166d526932ee04ffe4d25b810f619e34"
|
||||
},
|
||||
"provider": {
|
||||
"address": "0x200194fd3013c88ab2b3c84e2c885aba42a3df5d"
|
||||
},
|
||||
"version": "2.2.0"
|
||||
}
|
||||
851
.openzeppelin/mainnet.json
Normal file
851
.openzeppelin/mainnet.json
Normal file
@ -0,0 +1,851 @@
|
||||
{
|
||||
"contracts": {
|
||||
"StandaloneERC721": {
|
||||
"address": "0x8c9900276e5eD54C104d743a6E01B7041acab40f",
|
||||
"constructorCode": "608060405234801561001057600080fd5b506136c6806100206000396000f3fe",
|
||||
"bodyBytecodeHash": "1f3ce589a0ba1fad4f98754bd97f051852e7dbb5522d49a7185defb3e377d347",
|
||||
"localBytecodeHash": "84a5a6731b4686c34ef5acfcf4474af2e61b3e4e0b10ea96418e4b7bd1074cbc",
|
||||
"deployedBytecodeHash": "84a5a6731b4686c34ef5acfcf4474af2e61b3e4e0b10ea96418e4b7bd1074cbc",
|
||||
"types": {
|
||||
"t_bool": {
|
||||
"id": "t_bool",
|
||||
"kind": "elementary",
|
||||
"label": "bool"
|
||||
},
|
||||
"t_uint256": {
|
||||
"id": "t_uint256",
|
||||
"kind": "elementary",
|
||||
"label": "uint256"
|
||||
},
|
||||
"t_array:50<t_uint256>": {
|
||||
"id": "t_array:50<t_uint256>",
|
||||
"valueType": "t_uint256",
|
||||
"length": "50",
|
||||
"kind": "array",
|
||||
"label": "uint256[50]"
|
||||
},
|
||||
"t_mapping<t_bool>": {
|
||||
"id": "t_mapping<t_bool>",
|
||||
"valueType": "t_bool",
|
||||
"label": "mapping(key => bool)",
|
||||
"kind": "mapping"
|
||||
},
|
||||
"t_address": {
|
||||
"id": "t_address",
|
||||
"kind": "elementary",
|
||||
"label": "address"
|
||||
},
|
||||
"t_mapping<t_address>": {
|
||||
"id": "t_mapping<t_address>",
|
||||
"valueType": "t_address",
|
||||
"label": "mapping(key => address)",
|
||||
"kind": "mapping"
|
||||
},
|
||||
"t_struct<Counters.Counter>": {
|
||||
"id": "t_struct<Counters.Counter>",
|
||||
"kind": "struct",
|
||||
"label": "Counters.Counter",
|
||||
"members": [
|
||||
{
|
||||
"label": "_value",
|
||||
"astId": 2415,
|
||||
"type": "t_uint256",
|
||||
"src": "1021:14:22"
|
||||
}
|
||||
]
|
||||
},
|
||||
"t_mapping<t_struct<Counters.Counter>>": {
|
||||
"id": "t_mapping<t_struct<Counters.Counter>>",
|
||||
"valueType": "t_struct<Counters.Counter>",
|
||||
"label": "mapping(key => Counters.Counter)",
|
||||
"kind": "mapping"
|
||||
},
|
||||
"t_array:dyn<t_uint256>": {
|
||||
"id": "t_array:dyn<t_uint256>",
|
||||
"valueType": "t_uint256",
|
||||
"length": "dyn",
|
||||
"kind": "array",
|
||||
"label": "uint256[]"
|
||||
},
|
||||
"t_mapping<t_array:dyn<t_uint256>>": {
|
||||
"id": "t_mapping<t_array:dyn<t_uint256>>",
|
||||
"valueType": "t_array:dyn<t_uint256>",
|
||||
"label": "mapping(key => uint256[])",
|
||||
"kind": "mapping"
|
||||
},
|
||||
"t_mapping<t_uint256>": {
|
||||
"id": "t_mapping<t_uint256>",
|
||||
"valueType": "t_uint256",
|
||||
"label": "mapping(key => uint256)",
|
||||
"kind": "mapping"
|
||||
},
|
||||
"t_string": {
|
||||
"id": "t_string",
|
||||
"kind": "elementary",
|
||||
"label": "string"
|
||||
},
|
||||
"t_mapping<t_string>": {
|
||||
"id": "t_mapping<t_string>",
|
||||
"valueType": "t_string",
|
||||
"label": "mapping(key => string)",
|
||||
"kind": "mapping"
|
||||
},
|
||||
"t_struct<Roles.Role>": {
|
||||
"id": "t_struct<Roles.Role>",
|
||||
"kind": "struct",
|
||||
"label": "Roles.Role",
|
||||
"members": [
|
||||
{
|
||||
"label": "bearer",
|
||||
"astId": 5,
|
||||
"type": "t_mapping<t_bool>",
|
||||
"src": "150:32:0"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"storage": [
|
||||
{
|
||||
"contract": "Initializable",
|
||||
"path": "@openzeppelin/upgrades/contracts/Initializable.sol",
|
||||
"label": "initialized",
|
||||
"astId": 11836,
|
||||
"type": "t_bool",
|
||||
"src": "757:24:140"
|
||||
},
|
||||
{
|
||||
"contract": "Initializable",
|
||||
"path": "@openzeppelin/upgrades/contracts/Initializable.sol",
|
||||
"label": "initializing",
|
||||
"astId": 11838,
|
||||
"type": "t_bool",
|
||||
"src": "876:25:140"
|
||||
},
|
||||
{
|
||||
"contract": "Initializable",
|
||||
"path": "@openzeppelin/upgrades/contracts/Initializable.sol",
|
||||
"label": "______gap",
|
||||
"astId": 11887,
|
||||
"type": "t_array:50<t_uint256>",
|
||||
"src": "1891:29:140"
|
||||
},
|
||||
{
|
||||
"contract": "ERC165",
|
||||
"path": "contracts/introspection/ERC165.sol",
|
||||
"label": "_supportedInterfaces",
|
||||
"astId": 3974,
|
||||
"type": "t_mapping<t_bool>",
|
||||
"src": "496:52:31"
|
||||
},
|
||||
{
|
||||
"contract": "ERC165",
|
||||
"path": "contracts/introspection/ERC165.sol",
|
||||
"label": "______gap",
|
||||
"astId": 4018,
|
||||
"type": "t_array:50<t_uint256>",
|
||||
"src": "1229:29:31"
|
||||
},
|
||||
{
|
||||
"contract": "ERC721",
|
||||
"path": "contracts/token/ERC721/ERC721.sol",
|
||||
"label": "_tokenOwner",
|
||||
"astId": 10031,
|
||||
"type": "t_mapping<t_address>",
|
||||
"src": "829:48:122"
|
||||
},
|
||||
{
|
||||
"contract": "ERC721",
|
||||
"path": "contracts/token/ERC721/ERC721.sol",
|
||||
"label": "_tokenApprovals",
|
||||
"astId": 10035,
|
||||
"type": "t_mapping<t_address>",
|
||||
"src": "933:52:122"
|
||||
},
|
||||
{
|
||||
"contract": "ERC721",
|
||||
"path": "contracts/token/ERC721/ERC721.sol",
|
||||
"label": "_ownedTokensCount",
|
||||
"astId": 10039,
|
||||
"type": "t_mapping<t_struct<Counters.Counter>>",
|
||||
"src": "1043:63:122"
|
||||
},
|
||||
{
|
||||
"contract": "ERC721",
|
||||
"path": "contracts/token/ERC721/ERC721.sol",
|
||||
"label": "_operatorApprovals",
|
||||
"astId": 10045,
|
||||
"type": "t_mapping<t_bool>",
|
||||
"src": "1161:73:122"
|
||||
},
|
||||
{
|
||||
"contract": "ERC721",
|
||||
"path": "contracts/token/ERC721/ERC721.sol",
|
||||
"label": "______gap",
|
||||
"astId": 10568,
|
||||
"type": "t_array:50<t_uint256>",
|
||||
"src": "11658:29:122"
|
||||
},
|
||||
{
|
||||
"contract": "ERC721Enumerable",
|
||||
"path": "contracts/token/ERC721/ERC721Enumerable.sol",
|
||||
"label": "_ownedTokens",
|
||||
"astId": 10619,
|
||||
"type": "t_mapping<t_array:dyn<t_uint256>>",
|
||||
"src": "445:50:124"
|
||||
},
|
||||
{
|
||||
"contract": "ERC721Enumerable",
|
||||
"path": "contracts/token/ERC721/ERC721Enumerable.sol",
|
||||
"label": "_ownedTokensIndex",
|
||||
"astId": 10623,
|
||||
"type": "t_mapping<t_uint256>",
|
||||
"src": "565:53:124"
|
||||
},
|
||||
{
|
||||
"contract": "ERC721Enumerable",
|
||||
"path": "contracts/token/ERC721/ERC721Enumerable.sol",
|
||||
"label": "_allTokens",
|
||||
"astId": 10626,
|
||||
"type": "t_array:dyn<t_uint256>",
|
||||
"src": "679:28:124"
|
||||
},
|
||||
{
|
||||
"contract": "ERC721Enumerable",
|
||||
"path": "contracts/token/ERC721/ERC721Enumerable.sol",
|
||||
"label": "_allTokensIndex",
|
||||
"astId": 10630,
|
||||
"type": "t_mapping<t_uint256>",
|
||||
"src": "778:51:124"
|
||||
},
|
||||
{
|
||||
"contract": "ERC721Enumerable",
|
||||
"path": "contracts/token/ERC721/ERC721Enumerable.sol",
|
||||
"label": "______gap",
|
||||
"astId": 10959,
|
||||
"type": "t_array:50<t_uint256>",
|
||||
"src": "8801:29:124"
|
||||
},
|
||||
{
|
||||
"contract": "ERC721Metadata",
|
||||
"path": "contracts/token/ERC721/ERC721Metadata.sol",
|
||||
"label": "_name",
|
||||
"astId": 11026,
|
||||
"type": "t_string",
|
||||
"src": "266:20:127"
|
||||
},
|
||||
{
|
||||
"contract": "ERC721Metadata",
|
||||
"path": "contracts/token/ERC721/ERC721Metadata.sol",
|
||||
"label": "_symbol",
|
||||
"astId": 11028,
|
||||
"type": "t_string",
|
||||
"src": "313:22:127"
|
||||
},
|
||||
{
|
||||
"contract": "ERC721Metadata",
|
||||
"path": "contracts/token/ERC721/ERC721Metadata.sol",
|
||||
"label": "_tokenURIs",
|
||||
"astId": 11032,
|
||||
"type": "t_mapping<t_string>",
|
||||
"src": "381:45:127"
|
||||
},
|
||||
{
|
||||
"contract": "ERC721Metadata",
|
||||
"path": "contracts/token/ERC721/ERC721Metadata.sol",
|
||||
"label": "______gap",
|
||||
"astId": 11161,
|
||||
"type": "t_array:50<t_uint256>",
|
||||
"src": "2834:29:127"
|
||||
},
|
||||
{
|
||||
"contract": "MinterRole",
|
||||
"path": "contracts/access/roles/MinterRole.sol",
|
||||
"label": "_minters",
|
||||
"astId": 231,
|
||||
"type": "t_struct<Roles.Role>",
|
||||
"src": "271:27:2"
|
||||
},
|
||||
{
|
||||
"contract": "MinterRole",
|
||||
"path": "contracts/access/roles/MinterRole.sol",
|
||||
"label": "______gap",
|
||||
"astId": 330,
|
||||
"type": "t_array:50<t_uint256>",
|
||||
"src": "1081:29:2"
|
||||
},
|
||||
{
|
||||
"contract": "ERC721MetadataMintable",
|
||||
"path": "contracts/token/ERC721/ERC721MetadataMintable.sol",
|
||||
"label": "______gap",
|
||||
"astId": 11231,
|
||||
"type": "t_array:50<t_uint256>",
|
||||
"src": "1040:29:128"
|
||||
},
|
||||
{
|
||||
"contract": "PauserRole",
|
||||
"path": "contracts/access/roles/PauserRole.sol",
|
||||
"label": "_pausers",
|
||||
"astId": 350,
|
||||
"type": "t_struct<Roles.Role>",
|
||||
"src": "271:27:3"
|
||||
},
|
||||
{
|
||||
"contract": "PauserRole",
|
||||
"path": "contracts/access/roles/PauserRole.sol",
|
||||
"label": "______gap",
|
||||
"astId": 449,
|
||||
"type": "t_array:50<t_uint256>",
|
||||
"src": "1081:29:3"
|
||||
},
|
||||
{
|
||||
"contract": "Pausable",
|
||||
"path": "contracts/lifecycle/Pausable.sol",
|
||||
"label": "_paused",
|
||||
"astId": 4184,
|
||||
"type": "t_bool",
|
||||
"src": "352:20:34"
|
||||
},
|
||||
{
|
||||
"contract": "Pausable",
|
||||
"path": "contracts/lifecycle/Pausable.sol",
|
||||
"label": "______gap",
|
||||
"astId": 4265,
|
||||
"type": "t_array:50<t_uint256>",
|
||||
"src": "1429:29:34"
|
||||
},
|
||||
{
|
||||
"contract": "ERC721Pausable",
|
||||
"path": "contracts/token/ERC721/ERC721Pausable.sol",
|
||||
"label": "______gap",
|
||||
"astId": 11376,
|
||||
"type": "t_array:50<t_uint256>",
|
||||
"src": "850:29:130"
|
||||
}
|
||||
],
|
||||
"warnings": {
|
||||
"hasConstructor": false,
|
||||
"hasSelfDestruct": false,
|
||||
"hasDelegateCall": false,
|
||||
"hasInitialValuesInDeclarations": false,
|
||||
"uninitializedBaseContracts": []
|
||||
}
|
||||
},
|
||||
"StandaloneERC20": {
|
||||
"address": "0xe95Ca7dE499b425FBbdFD08C4021448FAB91cB0D",
|
||||
"constructorCode": "608060405234801561001057600080fd5b50612904806100206000396000f3fe",
|
||||
"bodyBytecodeHash": "68b813a3c2b5407b02238fdd29abedd7efa8d2e88e3aecea30ca59ad3cafa465",
|
||||
"localBytecodeHash": "ffcdfe04a4bf5020bb4661355d65a2d6da2938f1070399f417f8fc8d301ea692",
|
||||
"deployedBytecodeHash": "ffcdfe04a4bf5020bb4661355d65a2d6da2938f1070399f417f8fc8d301ea692",
|
||||
"types": {
|
||||
"t_bool": {
|
||||
"id": "t_bool",
|
||||
"kind": "elementary",
|
||||
"label": "bool"
|
||||
},
|
||||
"t_uint256": {
|
||||
"id": "t_uint256",
|
||||
"kind": "elementary",
|
||||
"label": "uint256"
|
||||
},
|
||||
"t_array:50<t_uint256>": {
|
||||
"id": "t_array:50<t_uint256>",
|
||||
"valueType": "t_uint256",
|
||||
"length": "50",
|
||||
"kind": "array",
|
||||
"label": "uint256[50]"
|
||||
},
|
||||
"t_string": {
|
||||
"id": "t_string",
|
||||
"kind": "elementary",
|
||||
"label": "string"
|
||||
},
|
||||
"t_uint8": {
|
||||
"id": "t_uint8",
|
||||
"kind": "elementary",
|
||||
"label": "uint8"
|
||||
},
|
||||
"t_mapping<t_uint256>": {
|
||||
"id": "t_mapping<t_uint256>",
|
||||
"valueType": "t_uint256",
|
||||
"label": "mapping(key => uint256)",
|
||||
"kind": "mapping"
|
||||
},
|
||||
"t_struct<Roles.Role>": {
|
||||
"id": "t_struct<Roles.Role>",
|
||||
"kind": "struct",
|
||||
"label": "Roles.Role",
|
||||
"members": [
|
||||
{
|
||||
"label": "bearer",
|
||||
"astId": 5,
|
||||
"type": "t_mapping<t_bool>",
|
||||
"src": "150:32:0"
|
||||
}
|
||||
]
|
||||
},
|
||||
"t_mapping<t_bool>": {
|
||||
"id": "t_mapping<t_bool>",
|
||||
"valueType": "t_bool",
|
||||
"label": "mapping(key => bool)",
|
||||
"kind": "mapping"
|
||||
}
|
||||
},
|
||||
"storage": [
|
||||
{
|
||||
"contract": "Initializable",
|
||||
"path": "@openzeppelin/upgrades/contracts/Initializable.sol",
|
||||
"label": "initialized",
|
||||
"astId": 11836,
|
||||
"type": "t_bool",
|
||||
"src": "757:24:140"
|
||||
},
|
||||
{
|
||||
"contract": "Initializable",
|
||||
"path": "@openzeppelin/upgrades/contracts/Initializable.sol",
|
||||
"label": "initializing",
|
||||
"astId": 11838,
|
||||
"type": "t_bool",
|
||||
"src": "876:25:140"
|
||||
},
|
||||
{
|
||||
"contract": "Initializable",
|
||||
"path": "@openzeppelin/upgrades/contracts/Initializable.sol",
|
||||
"label": "______gap",
|
||||
"astId": 11887,
|
||||
"type": "t_array:50<t_uint256>",
|
||||
"src": "1891:29:140"
|
||||
},
|
||||
{
|
||||
"contract": "ERC20Detailed",
|
||||
"path": "contracts/token/ERC20/ERC20Detailed.sol",
|
||||
"label": "_name",
|
||||
"astId": 9171,
|
||||
"type": "t_string",
|
||||
"src": "382:20:115"
|
||||
},
|
||||
{
|
||||
"contract": "ERC20Detailed",
|
||||
"path": "contracts/token/ERC20/ERC20Detailed.sol",
|
||||
"label": "_symbol",
|
||||
"astId": 9173,
|
||||
"type": "t_string",
|
||||
"src": "408:22:115"
|
||||
},
|
||||
{
|
||||
"contract": "ERC20Detailed",
|
||||
"path": "contracts/token/ERC20/ERC20Detailed.sol",
|
||||
"label": "_decimals",
|
||||
"astId": 9175,
|
||||
"type": "t_uint8",
|
||||
"src": "436:23:115"
|
||||
},
|
||||
{
|
||||
"contract": "ERC20Detailed",
|
||||
"path": "contracts/token/ERC20/ERC20Detailed.sol",
|
||||
"label": "______gap",
|
||||
"astId": 9227,
|
||||
"type": "t_array:50<t_uint256>",
|
||||
"src": "1097:29:115"
|
||||
},
|
||||
{
|
||||
"contract": "ERC20",
|
||||
"path": "contracts/token/ERC20/ERC20.sol",
|
||||
"label": "_balances",
|
||||
"astId": 8675,
|
||||
"type": "t_mapping<t_uint256>",
|
||||
"src": "752:46:112"
|
||||
},
|
||||
{
|
||||
"contract": "ERC20",
|
||||
"path": "contracts/token/ERC20/ERC20.sol",
|
||||
"label": "_allowed",
|
||||
"astId": 8681,
|
||||
"type": "t_mapping<t_uint256>",
|
||||
"src": "805:66:112"
|
||||
},
|
||||
{
|
||||
"contract": "ERC20",
|
||||
"path": "contracts/token/ERC20/ERC20.sol",
|
||||
"label": "_totalSupply",
|
||||
"astId": 8683,
|
||||
"type": "t_uint256",
|
||||
"src": "878:28:112"
|
||||
},
|
||||
{
|
||||
"contract": "ERC20",
|
||||
"path": "contracts/token/ERC20/ERC20.sol",
|
||||
"label": "______gap",
|
||||
"astId": 9048,
|
||||
"type": "t_array:50<t_uint256>",
|
||||
"src": "7714:29:112"
|
||||
},
|
||||
{
|
||||
"contract": "MinterRole",
|
||||
"path": "contracts/access/roles/MinterRole.sol",
|
||||
"label": "_minters",
|
||||
"astId": 231,
|
||||
"type": "t_struct<Roles.Role>",
|
||||
"src": "271:27:2"
|
||||
},
|
||||
{
|
||||
"contract": "MinterRole",
|
||||
"path": "contracts/access/roles/MinterRole.sol",
|
||||
"label": "______gap",
|
||||
"astId": 330,
|
||||
"type": "t_array:50<t_uint256>",
|
||||
"src": "1081:29:2"
|
||||
},
|
||||
{
|
||||
"contract": "ERC20Mintable",
|
||||
"path": "contracts/token/ERC20/ERC20Mintable.sol",
|
||||
"label": "______gap",
|
||||
"astId": 9276,
|
||||
"type": "t_array:50<t_uint256>",
|
||||
"src": "745:29:116"
|
||||
},
|
||||
{
|
||||
"contract": "PauserRole",
|
||||
"path": "contracts/access/roles/PauserRole.sol",
|
||||
"label": "_pausers",
|
||||
"astId": 350,
|
||||
"type": "t_struct<Roles.Role>",
|
||||
"src": "271:27:3"
|
||||
},
|
||||
{
|
||||
"contract": "PauserRole",
|
||||
"path": "contracts/access/roles/PauserRole.sol",
|
||||
"label": "______gap",
|
||||
"astId": 449,
|
||||
"type": "t_array:50<t_uint256>",
|
||||
"src": "1081:29:3"
|
||||
},
|
||||
{
|
||||
"contract": "Pausable",
|
||||
"path": "contracts/lifecycle/Pausable.sol",
|
||||
"label": "_paused",
|
||||
"astId": 4184,
|
||||
"type": "t_bool",
|
||||
"src": "352:20:34"
|
||||
},
|
||||
{
|
||||
"contract": "Pausable",
|
||||
"path": "contracts/lifecycle/Pausable.sol",
|
||||
"label": "______gap",
|
||||
"astId": 4265,
|
||||
"type": "t_array:50<t_uint256>",
|
||||
"src": "1429:29:34"
|
||||
},
|
||||
{
|
||||
"contract": "ERC20Pausable",
|
||||
"path": "contracts/token/ERC20/ERC20Pausable.sol",
|
||||
"label": "______gap",
|
||||
"astId": 9399,
|
||||
"type": "t_array:50<t_uint256>",
|
||||
"src": "1194:29:117"
|
||||
}
|
||||
],
|
||||
"warnings": {
|
||||
"hasConstructor": false,
|
||||
"hasSelfDestruct": false,
|
||||
"hasDelegateCall": false,
|
||||
"hasInitialValuesInDeclarations": false,
|
||||
"uninitializedBaseContracts": []
|
||||
}
|
||||
},
|
||||
"PaymentSplitter": {
|
||||
"address": "0xb3E46068440Ebd9AD43A3347eDFfC63697B84544",
|
||||
"constructorCode": "608060405234801561001057600080fd5b50610c17806100206000396000f3fe",
|
||||
"bodyBytecodeHash": "34c5c6011ba90548e55bf061f25c0847894d8882e4fa691726bf5d70bfadfd70",
|
||||
"localBytecodeHash": "d2ee04ff44581e396d308fb7e8f6ff66680f1eda86ee165873c4c16a65b4269d",
|
||||
"deployedBytecodeHash": "d2ee04ff44581e396d308fb7e8f6ff66680f1eda86ee165873c4c16a65b4269d",
|
||||
"types": {
|
||||
"t_bool": {
|
||||
"id": "t_bool",
|
||||
"kind": "elementary",
|
||||
"label": "bool"
|
||||
},
|
||||
"t_uint256": {
|
||||
"id": "t_uint256",
|
||||
"kind": "elementary",
|
||||
"label": "uint256"
|
||||
},
|
||||
"t_array:50<t_uint256>": {
|
||||
"id": "t_array:50<t_uint256>",
|
||||
"valueType": "t_uint256",
|
||||
"length": "50",
|
||||
"kind": "array",
|
||||
"label": "uint256[50]"
|
||||
},
|
||||
"t_mapping<t_uint256>": {
|
||||
"id": "t_mapping<t_uint256>",
|
||||
"valueType": "t_uint256",
|
||||
"label": "mapping(key => uint256)",
|
||||
"kind": "mapping"
|
||||
},
|
||||
"t_address": {
|
||||
"id": "t_address",
|
||||
"kind": "elementary",
|
||||
"label": "address"
|
||||
},
|
||||
"t_array:dyn<t_address>": {
|
||||
"id": "t_array:dyn<t_address>",
|
||||
"valueType": "t_address",
|
||||
"length": "dyn",
|
||||
"kind": "array",
|
||||
"label": "address[]"
|
||||
}
|
||||
},
|
||||
"storage": [
|
||||
{
|
||||
"contract": "Initializable",
|
||||
"path": "@openzeppelin/upgrades/contracts/Initializable.sol",
|
||||
"label": "initialized",
|
||||
"astId": 11836,
|
||||
"type": "t_bool",
|
||||
"src": "757:24:140"
|
||||
},
|
||||
{
|
||||
"contract": "Initializable",
|
||||
"path": "@openzeppelin/upgrades/contracts/Initializable.sol",
|
||||
"label": "initializing",
|
||||
"astId": 11838,
|
||||
"type": "t_bool",
|
||||
"src": "876:25:140"
|
||||
},
|
||||
{
|
||||
"contract": "Initializable",
|
||||
"path": "@openzeppelin/upgrades/contracts/Initializable.sol",
|
||||
"label": "______gap",
|
||||
"astId": 11887,
|
||||
"type": "t_array:50<t_uint256>",
|
||||
"src": "1891:29:140"
|
||||
},
|
||||
{
|
||||
"contract": "PaymentSplitter",
|
||||
"path": "contracts/payment/PaymentSplitter.sol",
|
||||
"label": "_totalShares",
|
||||
"astId": 7977,
|
||||
"type": "t_uint256",
|
||||
"src": "540:28:107"
|
||||
},
|
||||
{
|
||||
"contract": "PaymentSplitter",
|
||||
"path": "contracts/payment/PaymentSplitter.sol",
|
||||
"label": "_totalReleased",
|
||||
"astId": 7979,
|
||||
"type": "t_uint256",
|
||||
"src": "574:30:107"
|
||||
},
|
||||
{
|
||||
"contract": "PaymentSplitter",
|
||||
"path": "contracts/payment/PaymentSplitter.sol",
|
||||
"label": "_shares",
|
||||
"astId": 7983,
|
||||
"type": "t_mapping<t_uint256>",
|
||||
"src": "611:43:107"
|
||||
},
|
||||
{
|
||||
"contract": "PaymentSplitter",
|
||||
"path": "contracts/payment/PaymentSplitter.sol",
|
||||
"label": "_released",
|
||||
"astId": 7987,
|
||||
"type": "t_mapping<t_uint256>",
|
||||
"src": "660:45:107"
|
||||
},
|
||||
{
|
||||
"contract": "PaymentSplitter",
|
||||
"path": "contracts/payment/PaymentSplitter.sol",
|
||||
"label": "_payees",
|
||||
"astId": 7990,
|
||||
"type": "t_array:dyn<t_address>",
|
||||
"src": "711:25:107"
|
||||
},
|
||||
{
|
||||
"contract": "PaymentSplitter",
|
||||
"path": "contracts/payment/PaymentSplitter.sol",
|
||||
"label": "______gap",
|
||||
"astId": 8236,
|
||||
"type": "t_array:50<t_uint256>",
|
||||
"src": "3236:29:107"
|
||||
}
|
||||
],
|
||||
"warnings": {
|
||||
"hasConstructor": false,
|
||||
"hasSelfDestruct": false,
|
||||
"hasDelegateCall": false,
|
||||
"hasInitialValuesInDeclarations": false,
|
||||
"uninitializedBaseContracts": []
|
||||
}
|
||||
},
|
||||
"TokenVesting": {
|
||||
"address": "0xF0fcf1a5aaf25CDe77cb6ef95717323FAEfE492d",
|
||||
"constructorCode": "608060405234801561001057600080fd5b50611559806100206000396000f3fe",
|
||||
"bodyBytecodeHash": "01f22f428367f86242e342322247e732d645b5cfdd40a9411cb3a10842ee2bac",
|
||||
"localBytecodeHash": "f5eb9bf4cd80d75f1e0928674f0436601837641bdbc0196a89f8ea392097a282",
|
||||
"deployedBytecodeHash": "f5eb9bf4cd80d75f1e0928674f0436601837641bdbc0196a89f8ea392097a282",
|
||||
"types": {
|
||||
"t_bool": {
|
||||
"id": "t_bool",
|
||||
"kind": "elementary",
|
||||
"label": "bool"
|
||||
},
|
||||
"t_uint256": {
|
||||
"id": "t_uint256",
|
||||
"kind": "elementary",
|
||||
"label": "uint256"
|
||||
},
|
||||
"t_array:50<t_uint256>": {
|
||||
"id": "t_array:50<t_uint256>",
|
||||
"valueType": "t_uint256",
|
||||
"length": "50",
|
||||
"kind": "array",
|
||||
"label": "uint256[50]"
|
||||
},
|
||||
"t_address": {
|
||||
"id": "t_address",
|
||||
"kind": "elementary",
|
||||
"label": "address"
|
||||
},
|
||||
"t_mapping<t_uint256>": {
|
||||
"id": "t_mapping<t_uint256>",
|
||||
"valueType": "t_uint256",
|
||||
"label": "mapping(key => uint256)",
|
||||
"kind": "mapping"
|
||||
},
|
||||
"t_mapping<t_bool>": {
|
||||
"id": "t_mapping<t_bool>",
|
||||
"valueType": "t_bool",
|
||||
"label": "mapping(key => bool)",
|
||||
"kind": "mapping"
|
||||
}
|
||||
},
|
||||
"storage": [
|
||||
{
|
||||
"contract": "Initializable",
|
||||
"path": "@openzeppelin/upgrades/contracts/Initializable.sol",
|
||||
"label": "initialized",
|
||||
"astId": 11836,
|
||||
"type": "t_bool",
|
||||
"src": "757:24:140"
|
||||
},
|
||||
{
|
||||
"contract": "Initializable",
|
||||
"path": "@openzeppelin/upgrades/contracts/Initializable.sol",
|
||||
"label": "initializing",
|
||||
"astId": 11838,
|
||||
"type": "t_bool",
|
||||
"src": "876:25:140"
|
||||
},
|
||||
{
|
||||
"contract": "Initializable",
|
||||
"path": "@openzeppelin/upgrades/contracts/Initializable.sol",
|
||||
"label": "______gap",
|
||||
"astId": 11887,
|
||||
"type": "t_array:50<t_uint256>",
|
||||
"src": "1891:29:140"
|
||||
},
|
||||
{
|
||||
"contract": "Ownable",
|
||||
"path": "contracts/ownership/Ownable.sol",
|
||||
"label": "_owner",
|
||||
"astId": 7761,
|
||||
"type": "t_address",
|
||||
"src": "302:22:105"
|
||||
},
|
||||
{
|
||||
"contract": "Ownable",
|
||||
"path": "contracts/ownership/Ownable.sol",
|
||||
"label": "______gap",
|
||||
"astId": 7872,
|
||||
"type": "t_array:50<t_uint256>",
|
||||
"src": "2262:29:105"
|
||||
},
|
||||
{
|
||||
"contract": "TokenVesting",
|
||||
"path": "contracts/drafts/TokenVesting.sol",
|
||||
"label": "_beneficiary",
|
||||
"astId": 3441,
|
||||
"type": "t_address",
|
||||
"src": "1133:28:28"
|
||||
},
|
||||
{
|
||||
"contract": "TokenVesting",
|
||||
"path": "contracts/drafts/TokenVesting.sol",
|
||||
"label": "_cliff",
|
||||
"astId": 3443,
|
||||
"type": "t_uint256",
|
||||
"src": "1263:22:28"
|
||||
},
|
||||
{
|
||||
"contract": "TokenVesting",
|
||||
"path": "contracts/drafts/TokenVesting.sol",
|
||||
"label": "_start",
|
||||
"astId": 3445,
|
||||
"type": "t_uint256",
|
||||
"src": "1291:22:28"
|
||||
},
|
||||
{
|
||||
"contract": "TokenVesting",
|
||||
"path": "contracts/drafts/TokenVesting.sol",
|
||||
"label": "_duration",
|
||||
"astId": 3447,
|
||||
"type": "t_uint256",
|
||||
"src": "1319:25:28"
|
||||
},
|
||||
{
|
||||
"contract": "TokenVesting",
|
||||
"path": "contracts/drafts/TokenVesting.sol",
|
||||
"label": "_revocable",
|
||||
"astId": 3449,
|
||||
"type": "t_bool",
|
||||
"src": "1351:23:28"
|
||||
},
|
||||
{
|
||||
"contract": "TokenVesting",
|
||||
"path": "contracts/drafts/TokenVesting.sol",
|
||||
"label": "_released",
|
||||
"astId": 3453,
|
||||
"type": "t_mapping<t_uint256>",
|
||||
"src": "1381:46:28"
|
||||
},
|
||||
{
|
||||
"contract": "TokenVesting",
|
||||
"path": "contracts/drafts/TokenVesting.sol",
|
||||
"label": "_revoked",
|
||||
"astId": 3457,
|
||||
"type": "t_mapping<t_bool>",
|
||||
"src": "1433:42:28"
|
||||
},
|
||||
{
|
||||
"contract": "TokenVesting",
|
||||
"path": "contracts/drafts/TokenVesting.sol",
|
||||
"label": "______gap",
|
||||
"astId": 3799,
|
||||
"type": "t_array:50<t_uint256>",
|
||||
"src": "5837:29:28"
|
||||
}
|
||||
],
|
||||
"warnings": {
|
||||
"hasConstructor": false,
|
||||
"hasSelfDestruct": false,
|
||||
"hasDelegateCall": false,
|
||||
"hasInitialValuesInDeclarations": false,
|
||||
"uninitializedBaseContracts": []
|
||||
}
|
||||
}
|
||||
},
|
||||
"solidityLibs": {},
|
||||
"proxies": {},
|
||||
"manifestVersion": "2.2",
|
||||
"frozen": true,
|
||||
"app": {
|
||||
"address": "0x2Ba1a8C7352a5B5Ea3ea3408F89e1bA7920d36CE"
|
||||
},
|
||||
"package": {
|
||||
"address": "0x778dddF23Ec1B5Cb18394c6C110480CaaDB3B0f6"
|
||||
},
|
||||
"provider": {
|
||||
"address": "0xdd3e0B83e5462FD4Ba012FF05A57f709FA050458"
|
||||
},
|
||||
"version": "2.2.0"
|
||||
}
|
||||
12
.openzeppelin/project.json
Normal file
12
.openzeppelin/project.json
Normal file
@ -0,0 +1,12 @@
|
||||
{
|
||||
"manifestVersion": "2.2",
|
||||
"name": "@openzeppelin/contracts-ethereum-package",
|
||||
"publish": true,
|
||||
"version": "2.2.0",
|
||||
"contracts": {
|
||||
"StandaloneERC20": "StandaloneERC20",
|
||||
"StandaloneERC721": "StandaloneERC721",
|
||||
"TokenVesting": "TokenVesting",
|
||||
"PaymentSplitter": "PaymentSplitter"
|
||||
}
|
||||
}
|
||||
945
.openzeppelin/rinkeby.json
Normal file
945
.openzeppelin/rinkeby.json
Normal file
@ -0,0 +1,945 @@
|
||||
{
|
||||
"contracts": {
|
||||
"PaymentSplitter": {
|
||||
"address": "0x29d58ac2407f62caf9b1e00f0d7088d8c8590703",
|
||||
"constructorCode": "608060405234801561001057600080fd5b506110a4806100206000396000f3fe",
|
||||
"bodyBytecodeHash": "fe0f9da480efb9ef366284126f8d9dccff6f19f8ee0183449035b37c1f5103d8",
|
||||
"localBytecodeHash": "d9901040952d3add936b2939fb694875bdfd7b513c877bc1942d36a5e4190873",
|
||||
"deployedBytecodeHash": "d9901040952d3add936b2939fb694875bdfd7b513c877bc1942d36a5e4190873",
|
||||
"types": {
|
||||
"t_bool": {
|
||||
"id": "t_bool",
|
||||
"kind": "elementary",
|
||||
"label": "bool"
|
||||
},
|
||||
"t_uint256": {
|
||||
"id": "t_uint256",
|
||||
"kind": "elementary",
|
||||
"label": "uint256"
|
||||
},
|
||||
"t_array:50<t_uint256>": {
|
||||
"id": "t_array:50<t_uint256>",
|
||||
"valueType": "t_uint256",
|
||||
"length": "50",
|
||||
"kind": "array",
|
||||
"label": "uint256[50]"
|
||||
},
|
||||
"t_mapping<t_uint256>": {
|
||||
"id": "t_mapping<t_uint256>",
|
||||
"valueType": "t_uint256",
|
||||
"label": "mapping(key => uint256)",
|
||||
"kind": "mapping"
|
||||
},
|
||||
"t_address": {
|
||||
"id": "t_address",
|
||||
"kind": "elementary",
|
||||
"label": "address"
|
||||
},
|
||||
"t_array:dyn<t_address>": {
|
||||
"id": "t_array:dyn<t_address>",
|
||||
"valueType": "t_address",
|
||||
"length": "dyn",
|
||||
"kind": "array",
|
||||
"label": "address[]"
|
||||
}
|
||||
},
|
||||
"storage": [
|
||||
{
|
||||
"contract": "Initializable",
|
||||
"path": "@openzeppelin/upgrades/contracts/Initializable.sol",
|
||||
"label": "initialized",
|
||||
"astId": 13503,
|
||||
"type": "t_bool",
|
||||
"src": "757:24:147"
|
||||
},
|
||||
{
|
||||
"contract": "Initializable",
|
||||
"path": "@openzeppelin/upgrades/contracts/Initializable.sol",
|
||||
"label": "initializing",
|
||||
"astId": 13505,
|
||||
"type": "t_bool",
|
||||
"src": "876:25:147"
|
||||
},
|
||||
{
|
||||
"contract": "Initializable",
|
||||
"path": "@openzeppelin/upgrades/contracts/Initializable.sol",
|
||||
"label": "______gap",
|
||||
"astId": 13554,
|
||||
"type": "t_array:50<t_uint256>",
|
||||
"src": "1891:29:147"
|
||||
},
|
||||
{
|
||||
"contract": "PaymentSplitter",
|
||||
"path": "contracts/payment/PaymentSplitter.sol",
|
||||
"label": "_totalShares",
|
||||
"astId": 8418,
|
||||
"type": "t_uint256",
|
||||
"src": "1176:28:110"
|
||||
},
|
||||
{
|
||||
"contract": "PaymentSplitter",
|
||||
"path": "contracts/payment/PaymentSplitter.sol",
|
||||
"label": "_totalReleased",
|
||||
"astId": 8420,
|
||||
"type": "t_uint256",
|
||||
"src": "1210:30:110"
|
||||
},
|
||||
{
|
||||
"contract": "PaymentSplitter",
|
||||
"path": "contracts/payment/PaymentSplitter.sol",
|
||||
"label": "_shares",
|
||||
"astId": 8424,
|
||||
"type": "t_mapping<t_uint256>",
|
||||
"src": "1247:43:110"
|
||||
},
|
||||
{
|
||||
"contract": "PaymentSplitter",
|
||||
"path": "contracts/payment/PaymentSplitter.sol",
|
||||
"label": "_released",
|
||||
"astId": 8428,
|
||||
"type": "t_mapping<t_uint256>",
|
||||
"src": "1296:45:110"
|
||||
},
|
||||
{
|
||||
"contract": "PaymentSplitter",
|
||||
"path": "contracts/payment/PaymentSplitter.sol",
|
||||
"label": "_payees",
|
||||
"astId": 8431,
|
||||
"type": "t_array:dyn<t_address>",
|
||||
"src": "1347:25:110"
|
||||
},
|
||||
{
|
||||
"contract": "PaymentSplitter",
|
||||
"path": "contracts/payment/PaymentSplitter.sol",
|
||||
"label": "______gap",
|
||||
"astId": 8684,
|
||||
"type": "t_array:50<t_uint256>",
|
||||
"src": "5158:29:110"
|
||||
}
|
||||
],
|
||||
"warnings": {
|
||||
"hasConstructor": false,
|
||||
"hasSelfDestruct": false,
|
||||
"hasDelegateCall": false,
|
||||
"hasInitialValuesInDeclarations": false,
|
||||
"uninitializedBaseContracts": [],
|
||||
"storageUncheckedVars": [],
|
||||
"storageDiff": []
|
||||
}
|
||||
},
|
||||
"TokenVesting": {
|
||||
"address": "0x142e4ad09777e6f3068e630a085a4739614d1e76",
|
||||
"constructorCode": "608060405234801561001057600080fd5b50611c6c806100206000396000f3fe",
|
||||
"bodyBytecodeHash": "ba0eade6a19e4b485aca3478c8755d2a6041a2b39a7aa1a0a73253a782c4a065",
|
||||
"localBytecodeHash": "94b5eed89a6bab268326a5010e52000ff74d40d96c83811c9d455d7c8b54f447",
|
||||
"deployedBytecodeHash": "94b5eed89a6bab268326a5010e52000ff74d40d96c83811c9d455d7c8b54f447",
|
||||
"types": {
|
||||
"t_bool": {
|
||||
"id": "t_bool",
|
||||
"kind": "elementary",
|
||||
"label": "bool"
|
||||
},
|
||||
"t_uint256": {
|
||||
"id": "t_uint256",
|
||||
"kind": "elementary",
|
||||
"label": "uint256"
|
||||
},
|
||||
"t_array:50<t_uint256>": {
|
||||
"id": "t_array:50<t_uint256>",
|
||||
"valueType": "t_uint256",
|
||||
"length": "50",
|
||||
"kind": "array",
|
||||
"label": "uint256[50]"
|
||||
},
|
||||
"t_address": {
|
||||
"id": "t_address",
|
||||
"kind": "elementary",
|
||||
"label": "address"
|
||||
},
|
||||
"t_mapping<t_uint256>": {
|
||||
"id": "t_mapping<t_uint256>",
|
||||
"valueType": "t_uint256",
|
||||
"label": "mapping(key => uint256)",
|
||||
"kind": "mapping"
|
||||
},
|
||||
"t_mapping<t_bool>": {
|
||||
"id": "t_mapping<t_bool>",
|
||||
"valueType": "t_bool",
|
||||
"label": "mapping(key => bool)",
|
||||
"kind": "mapping"
|
||||
}
|
||||
},
|
||||
"storage": [
|
||||
{
|
||||
"contract": "Initializable",
|
||||
"path": "@openzeppelin/upgrades/contracts/Initializable.sol",
|
||||
"label": "initialized",
|
||||
"astId": 13503,
|
||||
"type": "t_bool",
|
||||
"src": "757:24:147"
|
||||
},
|
||||
{
|
||||
"contract": "Initializable",
|
||||
"path": "@openzeppelin/upgrades/contracts/Initializable.sol",
|
||||
"label": "initializing",
|
||||
"astId": 13505,
|
||||
"type": "t_bool",
|
||||
"src": "876:25:147"
|
||||
},
|
||||
{
|
||||
"contract": "Initializable",
|
||||
"path": "@openzeppelin/upgrades/contracts/Initializable.sol",
|
||||
"label": "______gap",
|
||||
"astId": 13554,
|
||||
"type": "t_array:50<t_uint256>",
|
||||
"src": "1891:29:147"
|
||||
},
|
||||
{
|
||||
"contract": "Ownable",
|
||||
"path": "contracts/ownership/Ownable.sol",
|
||||
"label": "_owner",
|
||||
"astId": 8198,
|
||||
"type": "t_address",
|
||||
"src": "472:22:108"
|
||||
},
|
||||
{
|
||||
"contract": "Ownable",
|
||||
"path": "contracts/ownership/Ownable.sol",
|
||||
"label": "______gap",
|
||||
"astId": 8311,
|
||||
"type": "t_array:50<t_uint256>",
|
||||
"src": "2415:29:108"
|
||||
},
|
||||
{
|
||||
"contract": "TokenVesting",
|
||||
"path": "contracts/drafts/TokenVesting.sol",
|
||||
"label": "_beneficiary",
|
||||
"astId": 3576,
|
||||
"type": "t_address",
|
||||
"src": "1133:28:28"
|
||||
},
|
||||
{
|
||||
"contract": "TokenVesting",
|
||||
"path": "contracts/drafts/TokenVesting.sol",
|
||||
"label": "_cliff",
|
||||
"astId": 3578,
|
||||
"type": "t_uint256",
|
||||
"src": "1263:22:28"
|
||||
},
|
||||
{
|
||||
"contract": "TokenVesting",
|
||||
"path": "contracts/drafts/TokenVesting.sol",
|
||||
"label": "_start",
|
||||
"astId": 3580,
|
||||
"type": "t_uint256",
|
||||
"src": "1291:22:28"
|
||||
},
|
||||
{
|
||||
"contract": "TokenVesting",
|
||||
"path": "contracts/drafts/TokenVesting.sol",
|
||||
"label": "_duration",
|
||||
"astId": 3582,
|
||||
"type": "t_uint256",
|
||||
"src": "1319:25:28"
|
||||
},
|
||||
{
|
||||
"contract": "TokenVesting",
|
||||
"path": "contracts/drafts/TokenVesting.sol",
|
||||
"label": "_revocable",
|
||||
"astId": 3584,
|
||||
"type": "t_bool",
|
||||
"src": "1351:23:28"
|
||||
},
|
||||
{
|
||||
"contract": "TokenVesting",
|
||||
"path": "contracts/drafts/TokenVesting.sol",
|
||||
"label": "_released",
|
||||
"astId": 3588,
|
||||
"type": "t_mapping<t_uint256>",
|
||||
"src": "1381:46:28"
|
||||
},
|
||||
{
|
||||
"contract": "TokenVesting",
|
||||
"path": "contracts/drafts/TokenVesting.sol",
|
||||
"label": "_revoked",
|
||||
"astId": 3592,
|
||||
"type": "t_mapping<t_bool>",
|
||||
"src": "1433:42:28"
|
||||
},
|
||||
{
|
||||
"contract": "TokenVesting",
|
||||
"path": "contracts/drafts/TokenVesting.sol",
|
||||
"label": "______gap",
|
||||
"astId": 3941,
|
||||
"type": "t_array:50<t_uint256>",
|
||||
"src": "6226:29:28"
|
||||
}
|
||||
],
|
||||
"warnings": {
|
||||
"hasConstructor": false,
|
||||
"hasSelfDestruct": false,
|
||||
"hasDelegateCall": false,
|
||||
"hasInitialValuesInDeclarations": false,
|
||||
"uninitializedBaseContracts": [],
|
||||
"storageUncheckedVars": [],
|
||||
"storageDiff": []
|
||||
}
|
||||
},
|
||||
"StandaloneERC20": {
|
||||
"address": "0xa17887b5aacc4d3b04ae375178d8e0971d84434a",
|
||||
"constructorCode": "608060405234801561001057600080fd5b50613153806100206000396000f3fe",
|
||||
"bodyBytecodeHash": "ad8d45945d6a4f088a61fd605c38cdf2f40171624bca2a7c3b2d4e95b068eb3d",
|
||||
"localBytecodeHash": "bca15bc1a7aa87c603c9b185aab38e0d72b8adc6347426bb66954cef39e88a74",
|
||||
"deployedBytecodeHash": "bca15bc1a7aa87c603c9b185aab38e0d72b8adc6347426bb66954cef39e88a74",
|
||||
"types": {
|
||||
"t_bool": {
|
||||
"id": "t_bool",
|
||||
"kind": "elementary",
|
||||
"label": "bool"
|
||||
},
|
||||
"t_uint256": {
|
||||
"id": "t_uint256",
|
||||
"kind": "elementary",
|
||||
"label": "uint256"
|
||||
},
|
||||
"t_array:50<t_uint256>": {
|
||||
"id": "t_array:50<t_uint256>",
|
||||
"valueType": "t_uint256",
|
||||
"length": "50",
|
||||
"kind": "array",
|
||||
"label": "uint256[50]"
|
||||
},
|
||||
"t_string": {
|
||||
"id": "t_string",
|
||||
"kind": "elementary",
|
||||
"label": "string"
|
||||
},
|
||||
"t_uint8": {
|
||||
"id": "t_uint8",
|
||||
"kind": "elementary",
|
||||
"label": "uint8"
|
||||
},
|
||||
"t_mapping<t_uint256>": {
|
||||
"id": "t_mapping<t_uint256>",
|
||||
"valueType": "t_uint256",
|
||||
"label": "mapping(key => uint256)",
|
||||
"kind": "mapping"
|
||||
},
|
||||
"t_struct<Roles.Role>": {
|
||||
"id": "t_struct<Roles.Role>",
|
||||
"kind": "struct",
|
||||
"label": "Roles.Role",
|
||||
"members": [
|
||||
{
|
||||
"label": "bearer",
|
||||
"astId": 5,
|
||||
"type": "t_mapping<t_bool>",
|
||||
"src": "150:32:0"
|
||||
}
|
||||
]
|
||||
},
|
||||
"t_mapping<t_bool>": {
|
||||
"id": "t_mapping<t_bool>",
|
||||
"valueType": "t_bool",
|
||||
"label": "mapping(key => bool)",
|
||||
"kind": "mapping"
|
||||
}
|
||||
},
|
||||
"storage": [
|
||||
{
|
||||
"contract": "Initializable",
|
||||
"path": "@openzeppelin/upgrades/contracts/Initializable.sol",
|
||||
"label": "initialized",
|
||||
"astId": 13503,
|
||||
"type": "t_bool",
|
||||
"src": "757:24:147"
|
||||
},
|
||||
{
|
||||
"contract": "Initializable",
|
||||
"path": "@openzeppelin/upgrades/contracts/Initializable.sol",
|
||||
"label": "initializing",
|
||||
"astId": 13505,
|
||||
"type": "t_bool",
|
||||
"src": "876:25:147"
|
||||
},
|
||||
{
|
||||
"contract": "Initializable",
|
||||
"path": "@openzeppelin/upgrades/contracts/Initializable.sol",
|
||||
"label": "______gap",
|
||||
"astId": 13554,
|
||||
"type": "t_array:50<t_uint256>",
|
||||
"src": "1891:29:147"
|
||||
},
|
||||
{
|
||||
"contract": "ERC20Detailed",
|
||||
"path": "contracts/token/ERC20/ERC20Detailed.sol",
|
||||
"label": "_name",
|
||||
"astId": 9641,
|
||||
"type": "t_string",
|
||||
"src": "209:20:118"
|
||||
},
|
||||
{
|
||||
"contract": "ERC20Detailed",
|
||||
"path": "contracts/token/ERC20/ERC20Detailed.sol",
|
||||
"label": "_symbol",
|
||||
"astId": 9643,
|
||||
"type": "t_string",
|
||||
"src": "235:22:118"
|
||||
},
|
||||
{
|
||||
"contract": "ERC20Detailed",
|
||||
"path": "contracts/token/ERC20/ERC20Detailed.sol",
|
||||
"label": "_decimals",
|
||||
"astId": 9645,
|
||||
"type": "t_uint8",
|
||||
"src": "263:23:118"
|
||||
},
|
||||
{
|
||||
"contract": "ERC20Detailed",
|
||||
"path": "contracts/token/ERC20/ERC20Detailed.sol",
|
||||
"label": "______gap",
|
||||
"astId": 9697,
|
||||
"type": "t_array:50<t_uint256>",
|
||||
"src": "1645:29:118"
|
||||
},
|
||||
{
|
||||
"contract": "ERC20",
|
||||
"path": "contracts/token/ERC20/ERC20.sol",
|
||||
"label": "_balances",
|
||||
"astId": 9129,
|
||||
"type": "t_mapping<t_uint256>",
|
||||
"src": "1357:46:115"
|
||||
},
|
||||
{
|
||||
"contract": "ERC20",
|
||||
"path": "contracts/token/ERC20/ERC20.sol",
|
||||
"label": "_allowances",
|
||||
"astId": 9135,
|
||||
"type": "t_mapping<t_uint256>",
|
||||
"src": "1410:69:115"
|
||||
},
|
||||
{
|
||||
"contract": "ERC20",
|
||||
"path": "contracts/token/ERC20/ERC20.sol",
|
||||
"label": "_totalSupply",
|
||||
"astId": 9137,
|
||||
"type": "t_uint256",
|
||||
"src": "1486:28:115"
|
||||
},
|
||||
{
|
||||
"contract": "ERC20",
|
||||
"path": "contracts/token/ERC20/ERC20.sol",
|
||||
"label": "______gap",
|
||||
"astId": 9516,
|
||||
"type": "t_array:50<t_uint256>",
|
||||
"src": "7875:29:115"
|
||||
},
|
||||
{
|
||||
"contract": "MinterRole",
|
||||
"path": "contracts/access/roles/MinterRole.sol",
|
||||
"label": "_minters",
|
||||
"astId": 219,
|
||||
"type": "t_struct<Roles.Role>",
|
||||
"src": "271:27:2"
|
||||
},
|
||||
{
|
||||
"contract": "MinterRole",
|
||||
"path": "contracts/access/roles/MinterRole.sol",
|
||||
"label": "______gap",
|
||||
"astId": 319,
|
||||
"type": "t_array:50<t_uint256>",
|
||||
"src": "1133:29:2"
|
||||
},
|
||||
{
|
||||
"contract": "ERC20Mintable",
|
||||
"path": "contracts/token/ERC20/ERC20Mintable.sol",
|
||||
"label": "______gap",
|
||||
"astId": 9746,
|
||||
"type": "t_array:50<t_uint256>",
|
||||
"src": "816:29:119"
|
||||
},
|
||||
{
|
||||
"contract": "PauserRole",
|
||||
"path": "contracts/access/roles/PauserRole.sol",
|
||||
"label": "_pausers",
|
||||
"astId": 339,
|
||||
"type": "t_struct<Roles.Role>",
|
||||
"src": "271:27:3"
|
||||
},
|
||||
{
|
||||
"contract": "PauserRole",
|
||||
"path": "contracts/access/roles/PauserRole.sol",
|
||||
"label": "______gap",
|
||||
"astId": 439,
|
||||
"type": "t_array:50<t_uint256>",
|
||||
"src": "1133:29:3"
|
||||
},
|
||||
{
|
||||
"contract": "Pausable",
|
||||
"path": "contracts/lifecycle/Pausable.sol",
|
||||
"label": "_paused",
|
||||
"astId": 4481,
|
||||
"type": "t_bool",
|
||||
"src": "855:20:37"
|
||||
},
|
||||
{
|
||||
"contract": "Pausable",
|
||||
"path": "contracts/lifecycle/Pausable.sol",
|
||||
"label": "______gap",
|
||||
"astId": 4564,
|
||||
"type": "t_array:50<t_uint256>",
|
||||
"src": "2105:29:37"
|
||||
},
|
||||
{
|
||||
"contract": "ERC20Pausable",
|
||||
"path": "contracts/token/ERC20/ERC20Pausable.sol",
|
||||
"label": "______gap",
|
||||
"astId": 9869,
|
||||
"type": "t_array:50<t_uint256>",
|
||||
"src": "1178:29:120"
|
||||
}
|
||||
],
|
||||
"warnings": {
|
||||
"hasConstructor": false,
|
||||
"hasSelfDestruct": false,
|
||||
"hasDelegateCall": false,
|
||||
"hasInitialValuesInDeclarations": false,
|
||||
"uninitializedBaseContracts": [],
|
||||
"storageUncheckedVars": [
|
||||
{
|
||||
"contract": "MinterRole",
|
||||
"path": "contracts/access/roles/MinterRole.sol",
|
||||
"label": "_minters",
|
||||
"astId": 219,
|
||||
"type": "t_struct<Roles.Role>",
|
||||
"src": "271:27:2"
|
||||
},
|
||||
{
|
||||
"contract": "PauserRole",
|
||||
"path": "contracts/access/roles/PauserRole.sol",
|
||||
"label": "_pausers",
|
||||
"astId": 339,
|
||||
"type": "t_struct<Roles.Role>",
|
||||
"src": "271:27:3"
|
||||
}
|
||||
],
|
||||
"storageDiff": [
|
||||
{
|
||||
"action": "rename",
|
||||
"updated": {
|
||||
"index": 8,
|
||||
"contract": "ERC20",
|
||||
"path": "contracts/token/ERC20/ERC20.sol",
|
||||
"label": "_allowances",
|
||||
"astId": 9135,
|
||||
"type": "t_mapping<t_uint256>",
|
||||
"src": "1410:69:115"
|
||||
},
|
||||
"original": {
|
||||
"index": 8,
|
||||
"contract": "ERC20",
|
||||
"path": "contracts/token/ERC20/ERC20.sol",
|
||||
"label": "_allowed",
|
||||
"astId": 8173,
|
||||
"type": "t_mapping<t_uint256>",
|
||||
"src": "827:66:110"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"StandaloneERC721": {
|
||||
"address": "0x27787a3b782897021eaffb8f1d52e71d74cea0b0",
|
||||
"constructorCode": "608060405234801561001057600080fd5b50614299806100206000396000f3fe",
|
||||
"bodyBytecodeHash": "9113153cb4b2b62f720cb12960ba3b4a7b9a5f3329e34a4a3ece0212d130ae53",
|
||||
"localBytecodeHash": "5dca693db1fee9a4ce973e49d6665a8770b823c36ba2c7e64f37d81046672074",
|
||||
"deployedBytecodeHash": "5dca693db1fee9a4ce973e49d6665a8770b823c36ba2c7e64f37d81046672074",
|
||||
"types": {
|
||||
"t_bool": {
|
||||
"id": "t_bool",
|
||||
"kind": "elementary",
|
||||
"label": "bool"
|
||||
},
|
||||
"t_uint256": {
|
||||
"id": "t_uint256",
|
||||
"kind": "elementary",
|
||||
"label": "uint256"
|
||||
},
|
||||
"t_array:50<t_uint256>": {
|
||||
"id": "t_array:50<t_uint256>",
|
||||
"valueType": "t_uint256",
|
||||
"length": "50",
|
||||
"kind": "array",
|
||||
"label": "uint256[50]"
|
||||
},
|
||||
"t_mapping<t_bool>": {
|
||||
"id": "t_mapping<t_bool>",
|
||||
"valueType": "t_bool",
|
||||
"label": "mapping(key => bool)",
|
||||
"kind": "mapping"
|
||||
},
|
||||
"t_address": {
|
||||
"id": "t_address",
|
||||
"kind": "elementary",
|
||||
"label": "address"
|
||||
},
|
||||
"t_mapping<t_address>": {
|
||||
"id": "t_mapping<t_address>",
|
||||
"valueType": "t_address",
|
||||
"label": "mapping(key => address)",
|
||||
"kind": "mapping"
|
||||
},
|
||||
"t_struct<Counters.Counter>": {
|
||||
"id": "t_struct<Counters.Counter>",
|
||||
"kind": "struct",
|
||||
"label": "Counters.Counter",
|
||||
"members": [
|
||||
{
|
||||
"label": "_value",
|
||||
"astId": 2533,
|
||||
"type": "t_uint256",
|
||||
"src": "1022:14:22"
|
||||
}
|
||||
]
|
||||
},
|
||||
"t_mapping<t_struct<Counters.Counter>>": {
|
||||
"id": "t_mapping<t_struct<Counters.Counter>>",
|
||||
"valueType": "t_struct<Counters.Counter>",
|
||||
"label": "mapping(key => Counters.Counter)",
|
||||
"kind": "mapping"
|
||||
},
|
||||
"t_array:dyn<t_uint256>": {
|
||||
"id": "t_array:dyn<t_uint256>",
|
||||
"valueType": "t_uint256",
|
||||
"length": "dyn",
|
||||
"kind": "array",
|
||||
"label": "uint256[]"
|
||||
},
|
||||
"t_mapping<t_array:dyn<t_uint256>>": {
|
||||
"id": "t_mapping<t_array:dyn<t_uint256>>",
|
||||
"valueType": "t_array:dyn<t_uint256>",
|
||||
"label": "mapping(key => uint256[])",
|
||||
"kind": "mapping"
|
||||
},
|
||||
"t_mapping<t_uint256>": {
|
||||
"id": "t_mapping<t_uint256>",
|
||||
"valueType": "t_uint256",
|
||||
"label": "mapping(key => uint256)",
|
||||
"kind": "mapping"
|
||||
},
|
||||
"t_string": {
|
||||
"id": "t_string",
|
||||
"kind": "elementary",
|
||||
"label": "string"
|
||||
},
|
||||
"t_mapping<t_string>": {
|
||||
"id": "t_mapping<t_string>",
|
||||
"valueType": "t_string",
|
||||
"label": "mapping(key => string)",
|
||||
"kind": "mapping"
|
||||
},
|
||||
"t_struct<Roles.Role>": {
|
||||
"id": "t_struct<Roles.Role>",
|
||||
"kind": "struct",
|
||||
"label": "Roles.Role",
|
||||
"members": [
|
||||
{
|
||||
"label": "bearer",
|
||||
"astId": 5,
|
||||
"type": "t_mapping<t_bool>",
|
||||
"src": "150:32:0"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"storage": [
|
||||
{
|
||||
"contract": "Initializable",
|
||||
"path": "@openzeppelin/upgrades/contracts/Initializable.sol",
|
||||
"label": "initialized",
|
||||
"astId": 13503,
|
||||
"type": "t_bool",
|
||||
"src": "757:24:147"
|
||||
},
|
||||
{
|
||||
"contract": "Initializable",
|
||||
"path": "@openzeppelin/upgrades/contracts/Initializable.sol",
|
||||
"label": "initializing",
|
||||
"astId": 13505,
|
||||
"type": "t_bool",
|
||||
"src": "876:25:147"
|
||||
},
|
||||
{
|
||||
"contract": "Initializable",
|
||||
"path": "@openzeppelin/upgrades/contracts/Initializable.sol",
|
||||
"label": "______gap",
|
||||
"astId": 13554,
|
||||
"type": "t_array:50<t_uint256>",
|
||||
"src": "1891:29:147"
|
||||
},
|
||||
{
|
||||
"contract": "ERC165",
|
||||
"path": "contracts/introspection/ERC165.sol",
|
||||
"label": "_supportedInterfaces",
|
||||
"astId": 4117,
|
||||
"type": "t_mapping<t_bool>",
|
||||
"src": "550:52:31"
|
||||
},
|
||||
{
|
||||
"contract": "ERC165",
|
||||
"path": "contracts/introspection/ERC165.sol",
|
||||
"label": "______gap",
|
||||
"astId": 4162,
|
||||
"type": "t_array:50<t_uint256>",
|
||||
"src": "1714:29:31"
|
||||
},
|
||||
{
|
||||
"contract": "ERC721",
|
||||
"path": "contracts/token/ERC721/ERC721.sol",
|
||||
"label": "_tokenOwner",
|
||||
"astId": 10508,
|
||||
"type": "t_mapping<t_address>",
|
||||
"src": "829:48:125"
|
||||
},
|
||||
{
|
||||
"contract": "ERC721",
|
||||
"path": "contracts/token/ERC721/ERC721.sol",
|
||||
"label": "_tokenApprovals",
|
||||
"astId": 10512,
|
||||
"type": "t_mapping<t_address>",
|
||||
"src": "933:52:125"
|
||||
},
|
||||
{
|
||||
"contract": "ERC721",
|
||||
"path": "contracts/token/ERC721/ERC721.sol",
|
||||
"label": "_ownedTokensCount",
|
||||
"astId": 10516,
|
||||
"type": "t_mapping<t_struct<Counters.Counter>>",
|
||||
"src": "1043:63:125"
|
||||
},
|
||||
{
|
||||
"contract": "ERC721",
|
||||
"path": "contracts/token/ERC721/ERC721.sol",
|
||||
"label": "_operatorApprovals",
|
||||
"astId": 10522,
|
||||
"type": "t_mapping<t_bool>",
|
||||
"src": "1161:73:125"
|
||||
},
|
||||
{
|
||||
"contract": "ERC721",
|
||||
"path": "contracts/token/ERC721/ERC721.sol",
|
||||
"label": "______gap",
|
||||
"astId": 11065,
|
||||
"type": "t_array:50<t_uint256>",
|
||||
"src": "12696:29:125"
|
||||
},
|
||||
{
|
||||
"contract": "ERC721Enumerable",
|
||||
"path": "contracts/token/ERC721/ERC721Enumerable.sol",
|
||||
"label": "_ownedTokens",
|
||||
"astId": 11117,
|
||||
"type": "t_mapping<t_array:dyn<t_uint256>>",
|
||||
"src": "445:50:127"
|
||||
},
|
||||
{
|
||||
"contract": "ERC721Enumerable",
|
||||
"path": "contracts/token/ERC721/ERC721Enumerable.sol",
|
||||
"label": "_ownedTokensIndex",
|
||||
"astId": 11121,
|
||||
"type": "t_mapping<t_uint256>",
|
||||
"src": "565:53:127"
|
||||
},
|
||||
{
|
||||
"contract": "ERC721Enumerable",
|
||||
"path": "contracts/token/ERC721/ERC721Enumerable.sol",
|
||||
"label": "_allTokens",
|
||||
"astId": 11124,
|
||||
"type": "t_array:dyn<t_uint256>",
|
||||
"src": "679:28:127"
|
||||
},
|
||||
{
|
||||
"contract": "ERC721Enumerable",
|
||||
"path": "contracts/token/ERC721/ERC721Enumerable.sol",
|
||||
"label": "_allTokensIndex",
|
||||
"astId": 11128,
|
||||
"type": "t_mapping<t_uint256>",
|
||||
"src": "778:51:127"
|
||||
},
|
||||
{
|
||||
"contract": "ERC721Enumerable",
|
||||
"path": "contracts/token/ERC721/ERC721Enumerable.sol",
|
||||
"label": "______gap",
|
||||
"astId": 11459,
|
||||
"type": "t_array:50<t_uint256>",
|
||||
"src": "8994:29:127"
|
||||
},
|
||||
{
|
||||
"contract": "ERC721Metadata",
|
||||
"path": "contracts/token/ERC721/ERC721Metadata.sol",
|
||||
"label": "_name",
|
||||
"astId": 11526,
|
||||
"type": "t_string",
|
||||
"src": "266:20:130"
|
||||
},
|
||||
{
|
||||
"contract": "ERC721Metadata",
|
||||
"path": "contracts/token/ERC721/ERC721Metadata.sol",
|
||||
"label": "_symbol",
|
||||
"astId": 11528,
|
||||
"type": "t_string",
|
||||
"src": "313:22:130"
|
||||
},
|
||||
{
|
||||
"contract": "ERC721Metadata",
|
||||
"path": "contracts/token/ERC721/ERC721Metadata.sol",
|
||||
"label": "_tokenURIs",
|
||||
"astId": 11532,
|
||||
"type": "t_mapping<t_string>",
|
||||
"src": "381:45:130"
|
||||
},
|
||||
{
|
||||
"contract": "ERC721Metadata",
|
||||
"path": "contracts/token/ERC721/ERC721Metadata.sol",
|
||||
"label": "______gap",
|
||||
"astId": 11663,
|
||||
"type": "t_array:50<t_uint256>",
|
||||
"src": "3029:29:130"
|
||||
},
|
||||
{
|
||||
"contract": "MinterRole",
|
||||
"path": "contracts/access/roles/MinterRole.sol",
|
||||
"label": "_minters",
|
||||
"astId": 219,
|
||||
"type": "t_struct<Roles.Role>",
|
||||
"src": "271:27:2"
|
||||
},
|
||||
{
|
||||
"contract": "MinterRole",
|
||||
"path": "contracts/access/roles/MinterRole.sol",
|
||||
"label": "______gap",
|
||||
"astId": 319,
|
||||
"type": "t_array:50<t_uint256>",
|
||||
"src": "1133:29:2"
|
||||
},
|
||||
{
|
||||
"contract": "ERC721MetadataMintable",
|
||||
"path": "contracts/token/ERC721/ERC721MetadataMintable.sol",
|
||||
"label": "______gap",
|
||||
"astId": 11733,
|
||||
"type": "t_array:50<t_uint256>",
|
||||
"src": "1042:29:131"
|
||||
},
|
||||
{
|
||||
"contract": "PauserRole",
|
||||
"path": "contracts/access/roles/PauserRole.sol",
|
||||
"label": "_pausers",
|
||||
"astId": 339,
|
||||
"type": "t_struct<Roles.Role>",
|
||||
"src": "271:27:3"
|
||||
},
|
||||
{
|
||||
"contract": "PauserRole",
|
||||
"path": "contracts/access/roles/PauserRole.sol",
|
||||
"label": "______gap",
|
||||
"astId": 439,
|
||||
"type": "t_array:50<t_uint256>",
|
||||
"src": "1133:29:3"
|
||||
},
|
||||
{
|
||||
"contract": "Pausable",
|
||||
"path": "contracts/lifecycle/Pausable.sol",
|
||||
"label": "_paused",
|
||||
"astId": 4481,
|
||||
"type": "t_bool",
|
||||
"src": "855:20:37"
|
||||
},
|
||||
{
|
||||
"contract": "Pausable",
|
||||
"path": "contracts/lifecycle/Pausable.sol",
|
||||
"label": "______gap",
|
||||
"astId": 4564,
|
||||
"type": "t_array:50<t_uint256>",
|
||||
"src": "2105:29:37"
|
||||
},
|
||||
{
|
||||
"contract": "ERC721Pausable",
|
||||
"path": "contracts/token/ERC721/ERC721Pausable.sol",
|
||||
"label": "______gap",
|
||||
"astId": 11878,
|
||||
"type": "t_array:50<t_uint256>",
|
||||
"src": "850:29:133"
|
||||
}
|
||||
],
|
||||
"warnings": {
|
||||
"hasConstructor": false,
|
||||
"hasSelfDestruct": false,
|
||||
"hasDelegateCall": false,
|
||||
"hasInitialValuesInDeclarations": false,
|
||||
"uninitializedBaseContracts": [],
|
||||
"storageUncheckedVars": [
|
||||
{
|
||||
"contract": "ERC721",
|
||||
"path": "contracts/token/ERC721/ERC721.sol",
|
||||
"label": "_ownedTokensCount",
|
||||
"astId": 10516,
|
||||
"type": "t_mapping<t_struct<Counters.Counter>>",
|
||||
"src": "1043:63:125"
|
||||
},
|
||||
{
|
||||
"contract": "MinterRole",
|
||||
"path": "contracts/access/roles/MinterRole.sol",
|
||||
"label": "_minters",
|
||||
"astId": 219,
|
||||
"type": "t_struct<Roles.Role>",
|
||||
"src": "271:27:2"
|
||||
},
|
||||
{
|
||||
"contract": "PauserRole",
|
||||
"path": "contracts/access/roles/PauserRole.sol",
|
||||
"label": "_pausers",
|
||||
"astId": 339,
|
||||
"type": "t_struct<Roles.Role>",
|
||||
"src": "271:27:3"
|
||||
}
|
||||
],
|
||||
"storageDiff": [
|
||||
{
|
||||
"action": "typechange",
|
||||
"updated": {
|
||||
"index": 7,
|
||||
"contract": "ERC721",
|
||||
"path": "contracts/token/ERC721/ERC721.sol",
|
||||
"label": "_ownedTokensCount",
|
||||
"astId": 10516,
|
||||
"type": "t_mapping<t_struct<Counters.Counter>>",
|
||||
"src": "1043:63:125"
|
||||
},
|
||||
"original": {
|
||||
"index": 7,
|
||||
"contract": "ERC721",
|
||||
"path": "contracts/token/ERC721/ERC721.sol",
|
||||
"label": "_ownedTokensCount",
|
||||
"astId": 9505,
|
||||
"type": "t_mapping<t_uint256>",
|
||||
"src": "988:54:120"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"solidityLibs": {},
|
||||
"proxies": {},
|
||||
"manifestVersion": "2.2",
|
||||
"frozen": true,
|
||||
"app": {
|
||||
"address": "0x291439e6444daec9e47ae359aa79fd1811a42679"
|
||||
},
|
||||
"package": {
|
||||
"address": "0xa44bb80b290de8a465d17b14269df53cf0b9bf4f"
|
||||
},
|
||||
"provider": {
|
||||
"address": "0x20b96704e5cab368fc05d8729b9d2c4c830f9338"
|
||||
},
|
||||
"version": "2.2.0"
|
||||
}
|
||||
851
.openzeppelin/ropsten.json
Normal file
851
.openzeppelin/ropsten.json
Normal file
@ -0,0 +1,851 @@
|
||||
{
|
||||
"contracts": {
|
||||
"TokenVesting": {
|
||||
"address": "0x37b52342e1e8eca924c69e49797e8b1a80251a88",
|
||||
"constructorCode": "608060405234801561001057600080fd5b50611c6c806100206000396000f3fe",
|
||||
"bodyBytecodeHash": "ba0eade6a19e4b485aca3478c8755d2a6041a2b39a7aa1a0a73253a782c4a065",
|
||||
"localBytecodeHash": "94b5eed89a6bab268326a5010e52000ff74d40d96c83811c9d455d7c8b54f447",
|
||||
"deployedBytecodeHash": "94b5eed89a6bab268326a5010e52000ff74d40d96c83811c9d455d7c8b54f447",
|
||||
"types": {
|
||||
"t_bool": {
|
||||
"id": "t_bool",
|
||||
"kind": "elementary",
|
||||
"label": "bool"
|
||||
},
|
||||
"t_uint256": {
|
||||
"id": "t_uint256",
|
||||
"kind": "elementary",
|
||||
"label": "uint256"
|
||||
},
|
||||
"t_array:50<t_uint256>": {
|
||||
"id": "t_array:50<t_uint256>",
|
||||
"valueType": "t_uint256",
|
||||
"length": "50",
|
||||
"kind": "array",
|
||||
"label": "uint256[50]"
|
||||
},
|
||||
"t_address": {
|
||||
"id": "t_address",
|
||||
"kind": "elementary",
|
||||
"label": "address"
|
||||
},
|
||||
"t_mapping<t_uint256>": {
|
||||
"id": "t_mapping<t_uint256>",
|
||||
"valueType": "t_uint256",
|
||||
"label": "mapping(key => uint256)",
|
||||
"kind": "mapping"
|
||||
},
|
||||
"t_mapping<t_bool>": {
|
||||
"id": "t_mapping<t_bool>",
|
||||
"valueType": "t_bool",
|
||||
"label": "mapping(key => bool)",
|
||||
"kind": "mapping"
|
||||
}
|
||||
},
|
||||
"storage": [
|
||||
{
|
||||
"contract": "Initializable",
|
||||
"path": "@openzeppelin/upgrades/contracts/Initializable.sol",
|
||||
"label": "initialized",
|
||||
"astId": 13503,
|
||||
"type": "t_bool",
|
||||
"src": "757:24:147"
|
||||
},
|
||||
{
|
||||
"contract": "Initializable",
|
||||
"path": "@openzeppelin/upgrades/contracts/Initializable.sol",
|
||||
"label": "initializing",
|
||||
"astId": 13505,
|
||||
"type": "t_bool",
|
||||
"src": "876:25:147"
|
||||
},
|
||||
{
|
||||
"contract": "Initializable",
|
||||
"path": "@openzeppelin/upgrades/contracts/Initializable.sol",
|
||||
"label": "______gap",
|
||||
"astId": 13554,
|
||||
"type": "t_array:50<t_uint256>",
|
||||
"src": "1891:29:147"
|
||||
},
|
||||
{
|
||||
"contract": "Ownable",
|
||||
"path": "contracts/ownership/Ownable.sol",
|
||||
"label": "_owner",
|
||||
"astId": 8198,
|
||||
"type": "t_address",
|
||||
"src": "472:22:108"
|
||||
},
|
||||
{
|
||||
"contract": "Ownable",
|
||||
"path": "contracts/ownership/Ownable.sol",
|
||||
"label": "______gap",
|
||||
"astId": 8311,
|
||||
"type": "t_array:50<t_uint256>",
|
||||
"src": "2415:29:108"
|
||||
},
|
||||
{
|
||||
"contract": "TokenVesting",
|
||||
"path": "contracts/drafts/TokenVesting.sol",
|
||||
"label": "_beneficiary",
|
||||
"astId": 3576,
|
||||
"type": "t_address",
|
||||
"src": "1133:28:28"
|
||||
},
|
||||
{
|
||||
"contract": "TokenVesting",
|
||||
"path": "contracts/drafts/TokenVesting.sol",
|
||||
"label": "_cliff",
|
||||
"astId": 3578,
|
||||
"type": "t_uint256",
|
||||
"src": "1263:22:28"
|
||||
},
|
||||
{
|
||||
"contract": "TokenVesting",
|
||||
"path": "contracts/drafts/TokenVesting.sol",
|
||||
"label": "_start",
|
||||
"astId": 3580,
|
||||
"type": "t_uint256",
|
||||
"src": "1291:22:28"
|
||||
},
|
||||
{
|
||||
"contract": "TokenVesting",
|
||||
"path": "contracts/drafts/TokenVesting.sol",
|
||||
"label": "_duration",
|
||||
"astId": 3582,
|
||||
"type": "t_uint256",
|
||||
"src": "1319:25:28"
|
||||
},
|
||||
{
|
||||
"contract": "TokenVesting",
|
||||
"path": "contracts/drafts/TokenVesting.sol",
|
||||
"label": "_revocable",
|
||||
"astId": 3584,
|
||||
"type": "t_bool",
|
||||
"src": "1351:23:28"
|
||||
},
|
||||
{
|
||||
"contract": "TokenVesting",
|
||||
"path": "contracts/drafts/TokenVesting.sol",
|
||||
"label": "_released",
|
||||
"astId": 3588,
|
||||
"type": "t_mapping<t_uint256>",
|
||||
"src": "1381:46:28"
|
||||
},
|
||||
{
|
||||
"contract": "TokenVesting",
|
||||
"path": "contracts/drafts/TokenVesting.sol",
|
||||
"label": "_revoked",
|
||||
"astId": 3592,
|
||||
"type": "t_mapping<t_bool>",
|
||||
"src": "1433:42:28"
|
||||
},
|
||||
{
|
||||
"contract": "TokenVesting",
|
||||
"path": "contracts/drafts/TokenVesting.sol",
|
||||
"label": "______gap",
|
||||
"astId": 3941,
|
||||
"type": "t_array:50<t_uint256>",
|
||||
"src": "6226:29:28"
|
||||
}
|
||||
],
|
||||
"warnings": {
|
||||
"hasConstructor": false,
|
||||
"hasSelfDestruct": false,
|
||||
"hasDelegateCall": false,
|
||||
"hasInitialValuesInDeclarations": false,
|
||||
"uninitializedBaseContracts": []
|
||||
}
|
||||
},
|
||||
"PaymentSplitter": {
|
||||
"address": "0xee1ff7edb4d1dee795497dc715a8173c9ddda440",
|
||||
"constructorCode": "608060405234801561001057600080fd5b506110a4806100206000396000f3fe",
|
||||
"bodyBytecodeHash": "fe0f9da480efb9ef366284126f8d9dccff6f19f8ee0183449035b37c1f5103d8",
|
||||
"localBytecodeHash": "d9901040952d3add936b2939fb694875bdfd7b513c877bc1942d36a5e4190873",
|
||||
"deployedBytecodeHash": "d9901040952d3add936b2939fb694875bdfd7b513c877bc1942d36a5e4190873",
|
||||
"types": {
|
||||
"t_bool": {
|
||||
"id": "t_bool",
|
||||
"kind": "elementary",
|
||||
"label": "bool"
|
||||
},
|
||||
"t_uint256": {
|
||||
"id": "t_uint256",
|
||||
"kind": "elementary",
|
||||
"label": "uint256"
|
||||
},
|
||||
"t_array:50<t_uint256>": {
|
||||
"id": "t_array:50<t_uint256>",
|
||||
"valueType": "t_uint256",
|
||||
"length": "50",
|
||||
"kind": "array",
|
||||
"label": "uint256[50]"
|
||||
},
|
||||
"t_mapping<t_uint256>": {
|
||||
"id": "t_mapping<t_uint256>",
|
||||
"valueType": "t_uint256",
|
||||
"label": "mapping(key => uint256)",
|
||||
"kind": "mapping"
|
||||
},
|
||||
"t_address": {
|
||||
"id": "t_address",
|
||||
"kind": "elementary",
|
||||
"label": "address"
|
||||
},
|
||||
"t_array:dyn<t_address>": {
|
||||
"id": "t_array:dyn<t_address>",
|
||||
"valueType": "t_address",
|
||||
"length": "dyn",
|
||||
"kind": "array",
|
||||
"label": "address[]"
|
||||
}
|
||||
},
|
||||
"storage": [
|
||||
{
|
||||
"contract": "Initializable",
|
||||
"path": "@openzeppelin/upgrades/contracts/Initializable.sol",
|
||||
"label": "initialized",
|
||||
"astId": 13503,
|
||||
"type": "t_bool",
|
||||
"src": "757:24:147"
|
||||
},
|
||||
{
|
||||
"contract": "Initializable",
|
||||
"path": "@openzeppelin/upgrades/contracts/Initializable.sol",
|
||||
"label": "initializing",
|
||||
"astId": 13505,
|
||||
"type": "t_bool",
|
||||
"src": "876:25:147"
|
||||
},
|
||||
{
|
||||
"contract": "Initializable",
|
||||
"path": "@openzeppelin/upgrades/contracts/Initializable.sol",
|
||||
"label": "______gap",
|
||||
"astId": 13554,
|
||||
"type": "t_array:50<t_uint256>",
|
||||
"src": "1891:29:147"
|
||||
},
|
||||
{
|
||||
"contract": "PaymentSplitter",
|
||||
"path": "contracts/payment/PaymentSplitter.sol",
|
||||
"label": "_totalShares",
|
||||
"astId": 8418,
|
||||
"type": "t_uint256",
|
||||
"src": "1176:28:110"
|
||||
},
|
||||
{
|
||||
"contract": "PaymentSplitter",
|
||||
"path": "contracts/payment/PaymentSplitter.sol",
|
||||
"label": "_totalReleased",
|
||||
"astId": 8420,
|
||||
"type": "t_uint256",
|
||||
"src": "1210:30:110"
|
||||
},
|
||||
{
|
||||
"contract": "PaymentSplitter",
|
||||
"path": "contracts/payment/PaymentSplitter.sol",
|
||||
"label": "_shares",
|
||||
"astId": 8424,
|
||||
"type": "t_mapping<t_uint256>",
|
||||
"src": "1247:43:110"
|
||||
},
|
||||
{
|
||||
"contract": "PaymentSplitter",
|
||||
"path": "contracts/payment/PaymentSplitter.sol",
|
||||
"label": "_released",
|
||||
"astId": 8428,
|
||||
"type": "t_mapping<t_uint256>",
|
||||
"src": "1296:45:110"
|
||||
},
|
||||
{
|
||||
"contract": "PaymentSplitter",
|
||||
"path": "contracts/payment/PaymentSplitter.sol",
|
||||
"label": "_payees",
|
||||
"astId": 8431,
|
||||
"type": "t_array:dyn<t_address>",
|
||||
"src": "1347:25:110"
|
||||
},
|
||||
{
|
||||
"contract": "PaymentSplitter",
|
||||
"path": "contracts/payment/PaymentSplitter.sol",
|
||||
"label": "______gap",
|
||||
"astId": 8684,
|
||||
"type": "t_array:50<t_uint256>",
|
||||
"src": "5158:29:110"
|
||||
}
|
||||
],
|
||||
"warnings": {
|
||||
"hasConstructor": false,
|
||||
"hasSelfDestruct": false,
|
||||
"hasDelegateCall": false,
|
||||
"hasInitialValuesInDeclarations": false,
|
||||
"uninitializedBaseContracts": []
|
||||
}
|
||||
},
|
||||
"StandaloneERC20": {
|
||||
"address": "0x2ed7f08736297d10dfa04a9b272dffc03615644f",
|
||||
"constructorCode": "608060405234801561001057600080fd5b50613153806100206000396000f3fe",
|
||||
"bodyBytecodeHash": "ad8d45945d6a4f088a61fd605c38cdf2f40171624bca2a7c3b2d4e95b068eb3d",
|
||||
"localBytecodeHash": "bca15bc1a7aa87c603c9b185aab38e0d72b8adc6347426bb66954cef39e88a74",
|
||||
"deployedBytecodeHash": "bca15bc1a7aa87c603c9b185aab38e0d72b8adc6347426bb66954cef39e88a74",
|
||||
"types": {
|
||||
"t_bool": {
|
||||
"id": "t_bool",
|
||||
"kind": "elementary",
|
||||
"label": "bool"
|
||||
},
|
||||
"t_uint256": {
|
||||
"id": "t_uint256",
|
||||
"kind": "elementary",
|
||||
"label": "uint256"
|
||||
},
|
||||
"t_array:50<t_uint256>": {
|
||||
"id": "t_array:50<t_uint256>",
|
||||
"valueType": "t_uint256",
|
||||
"length": "50",
|
||||
"kind": "array",
|
||||
"label": "uint256[50]"
|
||||
},
|
||||
"t_string": {
|
||||
"id": "t_string",
|
||||
"kind": "elementary",
|
||||
"label": "string"
|
||||
},
|
||||
"t_uint8": {
|
||||
"id": "t_uint8",
|
||||
"kind": "elementary",
|
||||
"label": "uint8"
|
||||
},
|
||||
"t_mapping<t_uint256>": {
|
||||
"id": "t_mapping<t_uint256>",
|
||||
"valueType": "t_uint256",
|
||||
"label": "mapping(key => uint256)",
|
||||
"kind": "mapping"
|
||||
},
|
||||
"t_struct<Roles.Role>": {
|
||||
"id": "t_struct<Roles.Role>",
|
||||
"kind": "struct",
|
||||
"label": "Roles.Role",
|
||||
"members": [
|
||||
{
|
||||
"label": "bearer",
|
||||
"astId": 5,
|
||||
"type": "t_mapping<t_bool>",
|
||||
"src": "150:32:0"
|
||||
}
|
||||
]
|
||||
},
|
||||
"t_mapping<t_bool>": {
|
||||
"id": "t_mapping<t_bool>",
|
||||
"valueType": "t_bool",
|
||||
"label": "mapping(key => bool)",
|
||||
"kind": "mapping"
|
||||
}
|
||||
},
|
||||
"storage": [
|
||||
{
|
||||
"contract": "Initializable",
|
||||
"path": "@openzeppelin/upgrades/contracts/Initializable.sol",
|
||||
"label": "initialized",
|
||||
"astId": 13503,
|
||||
"type": "t_bool",
|
||||
"src": "757:24:147"
|
||||
},
|
||||
{
|
||||
"contract": "Initializable",
|
||||
"path": "@openzeppelin/upgrades/contracts/Initializable.sol",
|
||||
"label": "initializing",
|
||||
"astId": 13505,
|
||||
"type": "t_bool",
|
||||
"src": "876:25:147"
|
||||
},
|
||||
{
|
||||
"contract": "Initializable",
|
||||
"path": "@openzeppelin/upgrades/contracts/Initializable.sol",
|
||||
"label": "______gap",
|
||||
"astId": 13554,
|
||||
"type": "t_array:50<t_uint256>",
|
||||
"src": "1891:29:147"
|
||||
},
|
||||
{
|
||||
"contract": "ERC20Detailed",
|
||||
"path": "contracts/token/ERC20/ERC20Detailed.sol",
|
||||
"label": "_name",
|
||||
"astId": 9641,
|
||||
"type": "t_string",
|
||||
"src": "209:20:118"
|
||||
},
|
||||
{
|
||||
"contract": "ERC20Detailed",
|
||||
"path": "contracts/token/ERC20/ERC20Detailed.sol",
|
||||
"label": "_symbol",
|
||||
"astId": 9643,
|
||||
"type": "t_string",
|
||||
"src": "235:22:118"
|
||||
},
|
||||
{
|
||||
"contract": "ERC20Detailed",
|
||||
"path": "contracts/token/ERC20/ERC20Detailed.sol",
|
||||
"label": "_decimals",
|
||||
"astId": 9645,
|
||||
"type": "t_uint8",
|
||||
"src": "263:23:118"
|
||||
},
|
||||
{
|
||||
"contract": "ERC20Detailed",
|
||||
"path": "contracts/token/ERC20/ERC20Detailed.sol",
|
||||
"label": "______gap",
|
||||
"astId": 9697,
|
||||
"type": "t_array:50<t_uint256>",
|
||||
"src": "1645:29:118"
|
||||
},
|
||||
{
|
||||
"contract": "ERC20",
|
||||
"path": "contracts/token/ERC20/ERC20.sol",
|
||||
"label": "_balances",
|
||||
"astId": 9129,
|
||||
"type": "t_mapping<t_uint256>",
|
||||
"src": "1357:46:115"
|
||||
},
|
||||
{
|
||||
"contract": "ERC20",
|
||||
"path": "contracts/token/ERC20/ERC20.sol",
|
||||
"label": "_allowances",
|
||||
"astId": 9135,
|
||||
"type": "t_mapping<t_uint256>",
|
||||
"src": "1410:69:115"
|
||||
},
|
||||
{
|
||||
"contract": "ERC20",
|
||||
"path": "contracts/token/ERC20/ERC20.sol",
|
||||
"label": "_totalSupply",
|
||||
"astId": 9137,
|
||||
"type": "t_uint256",
|
||||
"src": "1486:28:115"
|
||||
},
|
||||
{
|
||||
"contract": "ERC20",
|
||||
"path": "contracts/token/ERC20/ERC20.sol",
|
||||
"label": "______gap",
|
||||
"astId": 9516,
|
||||
"type": "t_array:50<t_uint256>",
|
||||
"src": "7875:29:115"
|
||||
},
|
||||
{
|
||||
"contract": "MinterRole",
|
||||
"path": "contracts/access/roles/MinterRole.sol",
|
||||
"label": "_minters",
|
||||
"astId": 219,
|
||||
"type": "t_struct<Roles.Role>",
|
||||
"src": "271:27:2"
|
||||
},
|
||||
{
|
||||
"contract": "MinterRole",
|
||||
"path": "contracts/access/roles/MinterRole.sol",
|
||||
"label": "______gap",
|
||||
"astId": 319,
|
||||
"type": "t_array:50<t_uint256>",
|
||||
"src": "1133:29:2"
|
||||
},
|
||||
{
|
||||
"contract": "ERC20Mintable",
|
||||
"path": "contracts/token/ERC20/ERC20Mintable.sol",
|
||||
"label": "______gap",
|
||||
"astId": 9746,
|
||||
"type": "t_array:50<t_uint256>",
|
||||
"src": "816:29:119"
|
||||
},
|
||||
{
|
||||
"contract": "PauserRole",
|
||||
"path": "contracts/access/roles/PauserRole.sol",
|
||||
"label": "_pausers",
|
||||
"astId": 339,
|
||||
"type": "t_struct<Roles.Role>",
|
||||
"src": "271:27:3"
|
||||
},
|
||||
{
|
||||
"contract": "PauserRole",
|
||||
"path": "contracts/access/roles/PauserRole.sol",
|
||||
"label": "______gap",
|
||||
"astId": 439,
|
||||
"type": "t_array:50<t_uint256>",
|
||||
"src": "1133:29:3"
|
||||
},
|
||||
{
|
||||
"contract": "Pausable",
|
||||
"path": "contracts/lifecycle/Pausable.sol",
|
||||
"label": "_paused",
|
||||
"astId": 4481,
|
||||
"type": "t_bool",
|
||||
"src": "855:20:37"
|
||||
},
|
||||
{
|
||||
"contract": "Pausable",
|
||||
"path": "contracts/lifecycle/Pausable.sol",
|
||||
"label": "______gap",
|
||||
"astId": 4564,
|
||||
"type": "t_array:50<t_uint256>",
|
||||
"src": "2105:29:37"
|
||||
},
|
||||
{
|
||||
"contract": "ERC20Pausable",
|
||||
"path": "contracts/token/ERC20/ERC20Pausable.sol",
|
||||
"label": "______gap",
|
||||
"astId": 9869,
|
||||
"type": "t_array:50<t_uint256>",
|
||||
"src": "1178:29:120"
|
||||
}
|
||||
],
|
||||
"warnings": {
|
||||
"hasConstructor": false,
|
||||
"hasSelfDestruct": false,
|
||||
"hasDelegateCall": false,
|
||||
"hasInitialValuesInDeclarations": false,
|
||||
"uninitializedBaseContracts": []
|
||||
}
|
||||
},
|
||||
"StandaloneERC721": {
|
||||
"address": "0xf43fe8b882b9821b3d648fb9f4d99d2fd736368c",
|
||||
"constructorCode": "608060405234801561001057600080fd5b50614299806100206000396000f3fe",
|
||||
"bodyBytecodeHash": "9113153cb4b2b62f720cb12960ba3b4a7b9a5f3329e34a4a3ece0212d130ae53",
|
||||
"localBytecodeHash": "5dca693db1fee9a4ce973e49d6665a8770b823c36ba2c7e64f37d81046672074",
|
||||
"deployedBytecodeHash": "5dca693db1fee9a4ce973e49d6665a8770b823c36ba2c7e64f37d81046672074",
|
||||
"types": {
|
||||
"t_bool": {
|
||||
"id": "t_bool",
|
||||
"kind": "elementary",
|
||||
"label": "bool"
|
||||
},
|
||||
"t_uint256": {
|
||||
"id": "t_uint256",
|
||||
"kind": "elementary",
|
||||
"label": "uint256"
|
||||
},
|
||||
"t_array:50<t_uint256>": {
|
||||
"id": "t_array:50<t_uint256>",
|
||||
"valueType": "t_uint256",
|
||||
"length": "50",
|
||||
"kind": "array",
|
||||
"label": "uint256[50]"
|
||||
},
|
||||
"t_mapping<t_bool>": {
|
||||
"id": "t_mapping<t_bool>",
|
||||
"valueType": "t_bool",
|
||||
"label": "mapping(key => bool)",
|
||||
"kind": "mapping"
|
||||
},
|
||||
"t_address": {
|
||||
"id": "t_address",
|
||||
"kind": "elementary",
|
||||
"label": "address"
|
||||
},
|
||||
"t_mapping<t_address>": {
|
||||
"id": "t_mapping<t_address>",
|
||||
"valueType": "t_address",
|
||||
"label": "mapping(key => address)",
|
||||
"kind": "mapping"
|
||||
},
|
||||
"t_struct<Counters.Counter>": {
|
||||
"id": "t_struct<Counters.Counter>",
|
||||
"kind": "struct",
|
||||
"label": "Counters.Counter",
|
||||
"members": [
|
||||
{
|
||||
"label": "_value",
|
||||
"astId": 2533,
|
||||
"type": "t_uint256",
|
||||
"src": "1022:14:22"
|
||||
}
|
||||
]
|
||||
},
|
||||
"t_mapping<t_struct<Counters.Counter>>": {
|
||||
"id": "t_mapping<t_struct<Counters.Counter>>",
|
||||
"valueType": "t_struct<Counters.Counter>",
|
||||
"label": "mapping(key => Counters.Counter)",
|
||||
"kind": "mapping"
|
||||
},
|
||||
"t_array:dyn<t_uint256>": {
|
||||
"id": "t_array:dyn<t_uint256>",
|
||||
"valueType": "t_uint256",
|
||||
"length": "dyn",
|
||||
"kind": "array",
|
||||
"label": "uint256[]"
|
||||
},
|
||||
"t_mapping<t_array:dyn<t_uint256>>": {
|
||||
"id": "t_mapping<t_array:dyn<t_uint256>>",
|
||||
"valueType": "t_array:dyn<t_uint256>",
|
||||
"label": "mapping(key => uint256[])",
|
||||
"kind": "mapping"
|
||||
},
|
||||
"t_mapping<t_uint256>": {
|
||||
"id": "t_mapping<t_uint256>",
|
||||
"valueType": "t_uint256",
|
||||
"label": "mapping(key => uint256)",
|
||||
"kind": "mapping"
|
||||
},
|
||||
"t_string": {
|
||||
"id": "t_string",
|
||||
"kind": "elementary",
|
||||
"label": "string"
|
||||
},
|
||||
"t_mapping<t_string>": {
|
||||
"id": "t_mapping<t_string>",
|
||||
"valueType": "t_string",
|
||||
"label": "mapping(key => string)",
|
||||
"kind": "mapping"
|
||||
},
|
||||
"t_struct<Roles.Role>": {
|
||||
"id": "t_struct<Roles.Role>",
|
||||
"kind": "struct",
|
||||
"label": "Roles.Role",
|
||||
"members": [
|
||||
{
|
||||
"label": "bearer",
|
||||
"astId": 5,
|
||||
"type": "t_mapping<t_bool>",
|
||||
"src": "150:32:0"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"storage": [
|
||||
{
|
||||
"contract": "Initializable",
|
||||
"path": "@openzeppelin/upgrades/contracts/Initializable.sol",
|
||||
"label": "initialized",
|
||||
"astId": 13503,
|
||||
"type": "t_bool",
|
||||
"src": "757:24:147"
|
||||
},
|
||||
{
|
||||
"contract": "Initializable",
|
||||
"path": "@openzeppelin/upgrades/contracts/Initializable.sol",
|
||||
"label": "initializing",
|
||||
"astId": 13505,
|
||||
"type": "t_bool",
|
||||
"src": "876:25:147"
|
||||
},
|
||||
{
|
||||
"contract": "Initializable",
|
||||
"path": "@openzeppelin/upgrades/contracts/Initializable.sol",
|
||||
"label": "______gap",
|
||||
"astId": 13554,
|
||||
"type": "t_array:50<t_uint256>",
|
||||
"src": "1891:29:147"
|
||||
},
|
||||
{
|
||||
"contract": "ERC165",
|
||||
"path": "contracts/introspection/ERC165.sol",
|
||||
"label": "_supportedInterfaces",
|
||||
"astId": 4117,
|
||||
"type": "t_mapping<t_bool>",
|
||||
"src": "550:52:31"
|
||||
},
|
||||
{
|
||||
"contract": "ERC165",
|
||||
"path": "contracts/introspection/ERC165.sol",
|
||||
"label": "______gap",
|
||||
"astId": 4162,
|
||||
"type": "t_array:50<t_uint256>",
|
||||
"src": "1714:29:31"
|
||||
},
|
||||
{
|
||||
"contract": "ERC721",
|
||||
"path": "contracts/token/ERC721/ERC721.sol",
|
||||
"label": "_tokenOwner",
|
||||
"astId": 10508,
|
||||
"type": "t_mapping<t_address>",
|
||||
"src": "829:48:125"
|
||||
},
|
||||
{
|
||||
"contract": "ERC721",
|
||||
"path": "contracts/token/ERC721/ERC721.sol",
|
||||
"label": "_tokenApprovals",
|
||||
"astId": 10512,
|
||||
"type": "t_mapping<t_address>",
|
||||
"src": "933:52:125"
|
||||
},
|
||||
{
|
||||
"contract": "ERC721",
|
||||
"path": "contracts/token/ERC721/ERC721.sol",
|
||||
"label": "_ownedTokensCount",
|
||||
"astId": 10516,
|
||||
"type": "t_mapping<t_struct<Counters.Counter>>",
|
||||
"src": "1043:63:125"
|
||||
},
|
||||
{
|
||||
"contract": "ERC721",
|
||||
"path": "contracts/token/ERC721/ERC721.sol",
|
||||
"label": "_operatorApprovals",
|
||||
"astId": 10522,
|
||||
"type": "t_mapping<t_bool>",
|
||||
"src": "1161:73:125"
|
||||
},
|
||||
{
|
||||
"contract": "ERC721",
|
||||
"path": "contracts/token/ERC721/ERC721.sol",
|
||||
"label": "______gap",
|
||||
"astId": 11065,
|
||||
"type": "t_array:50<t_uint256>",
|
||||
"src": "12696:29:125"
|
||||
},
|
||||
{
|
||||
"contract": "ERC721Enumerable",
|
||||
"path": "contracts/token/ERC721/ERC721Enumerable.sol",
|
||||
"label": "_ownedTokens",
|
||||
"astId": 11117,
|
||||
"type": "t_mapping<t_array:dyn<t_uint256>>",
|
||||
"src": "445:50:127"
|
||||
},
|
||||
{
|
||||
"contract": "ERC721Enumerable",
|
||||
"path": "contracts/token/ERC721/ERC721Enumerable.sol",
|
||||
"label": "_ownedTokensIndex",
|
||||
"astId": 11121,
|
||||
"type": "t_mapping<t_uint256>",
|
||||
"src": "565:53:127"
|
||||
},
|
||||
{
|
||||
"contract": "ERC721Enumerable",
|
||||
"path": "contracts/token/ERC721/ERC721Enumerable.sol",
|
||||
"label": "_allTokens",
|
||||
"astId": 11124,
|
||||
"type": "t_array:dyn<t_uint256>",
|
||||
"src": "679:28:127"
|
||||
},
|
||||
{
|
||||
"contract": "ERC721Enumerable",
|
||||
"path": "contracts/token/ERC721/ERC721Enumerable.sol",
|
||||
"label": "_allTokensIndex",
|
||||
"astId": 11128,
|
||||
"type": "t_mapping<t_uint256>",
|
||||
"src": "778:51:127"
|
||||
},
|
||||
{
|
||||
"contract": "ERC721Enumerable",
|
||||
"path": "contracts/token/ERC721/ERC721Enumerable.sol",
|
||||
"label": "______gap",
|
||||
"astId": 11459,
|
||||
"type": "t_array:50<t_uint256>",
|
||||
"src": "8994:29:127"
|
||||
},
|
||||
{
|
||||
"contract": "ERC721Metadata",
|
||||
"path": "contracts/token/ERC721/ERC721Metadata.sol",
|
||||
"label": "_name",
|
||||
"astId": 11526,
|
||||
"type": "t_string",
|
||||
"src": "266:20:130"
|
||||
},
|
||||
{
|
||||
"contract": "ERC721Metadata",
|
||||
"path": "contracts/token/ERC721/ERC721Metadata.sol",
|
||||
"label": "_symbol",
|
||||
"astId": 11528,
|
||||
"type": "t_string",
|
||||
"src": "313:22:130"
|
||||
},
|
||||
{
|
||||
"contract": "ERC721Metadata",
|
||||
"path": "contracts/token/ERC721/ERC721Metadata.sol",
|
||||
"label": "_tokenURIs",
|
||||
"astId": 11532,
|
||||
"type": "t_mapping<t_string>",
|
||||
"src": "381:45:130"
|
||||
},
|
||||
{
|
||||
"contract": "ERC721Metadata",
|
||||
"path": "contracts/token/ERC721/ERC721Metadata.sol",
|
||||
"label": "______gap",
|
||||
"astId": 11663,
|
||||
"type": "t_array:50<t_uint256>",
|
||||
"src": "3029:29:130"
|
||||
},
|
||||
{
|
||||
"contract": "MinterRole",
|
||||
"path": "contracts/access/roles/MinterRole.sol",
|
||||
"label": "_minters",
|
||||
"astId": 219,
|
||||
"type": "t_struct<Roles.Role>",
|
||||
"src": "271:27:2"
|
||||
},
|
||||
{
|
||||
"contract": "MinterRole",
|
||||
"path": "contracts/access/roles/MinterRole.sol",
|
||||
"label": "______gap",
|
||||
"astId": 319,
|
||||
"type": "t_array:50<t_uint256>",
|
||||
"src": "1133:29:2"
|
||||
},
|
||||
{
|
||||
"contract": "ERC721MetadataMintable",
|
||||
"path": "contracts/token/ERC721/ERC721MetadataMintable.sol",
|
||||
"label": "______gap",
|
||||
"astId": 11733,
|
||||
"type": "t_array:50<t_uint256>",
|
||||
"src": "1042:29:131"
|
||||
},
|
||||
{
|
||||
"contract": "PauserRole",
|
||||
"path": "contracts/access/roles/PauserRole.sol",
|
||||
"label": "_pausers",
|
||||
"astId": 339,
|
||||
"type": "t_struct<Roles.Role>",
|
||||
"src": "271:27:3"
|
||||
},
|
||||
{
|
||||
"contract": "PauserRole",
|
||||
"path": "contracts/access/roles/PauserRole.sol",
|
||||
"label": "______gap",
|
||||
"astId": 439,
|
||||
"type": "t_array:50<t_uint256>",
|
||||
"src": "1133:29:3"
|
||||
},
|
||||
{
|
||||
"contract": "Pausable",
|
||||
"path": "contracts/lifecycle/Pausable.sol",
|
||||
"label": "_paused",
|
||||
"astId": 4481,
|
||||
"type": "t_bool",
|
||||
"src": "855:20:37"
|
||||
},
|
||||
{
|
||||
"contract": "Pausable",
|
||||
"path": "contracts/lifecycle/Pausable.sol",
|
||||
"label": "______gap",
|
||||
"astId": 4564,
|
||||
"type": "t_array:50<t_uint256>",
|
||||
"src": "2105:29:37"
|
||||
},
|
||||
{
|
||||
"contract": "ERC721Pausable",
|
||||
"path": "contracts/token/ERC721/ERC721Pausable.sol",
|
||||
"label": "______gap",
|
||||
"astId": 11878,
|
||||
"type": "t_array:50<t_uint256>",
|
||||
"src": "850:29:133"
|
||||
}
|
||||
],
|
||||
"warnings": {
|
||||
"hasConstructor": false,
|
||||
"hasSelfDestruct": false,
|
||||
"hasDelegateCall": false,
|
||||
"hasInitialValuesInDeclarations": false,
|
||||
"uninitializedBaseContracts": []
|
||||
}
|
||||
}
|
||||
},
|
||||
"solidityLibs": {},
|
||||
"proxies": {},
|
||||
"manifestVersion": "2.2",
|
||||
"frozen": true,
|
||||
"app": {
|
||||
"address": "0x27a09abca2c4d9f914dbc7bea164b0e6b74ce7a9"
|
||||
},
|
||||
"package": {
|
||||
"address": "0x2a9e7b63514438906a83a1e320dbbd814d417002"
|
||||
},
|
||||
"provider": {
|
||||
"address": "0xb818f726ea886a73dc4105252f0e7c10b6309cae"
|
||||
},
|
||||
"version": "2.2.0"
|
||||
}
|
||||
11
.solhint.json
Normal file
11
.solhint.json
Normal file
@ -0,0 +1,11 @@
|
||||
{
|
||||
"extends": "default",
|
||||
"rules": {
|
||||
"indent": ["error", 4],
|
||||
|
||||
"bracket-align": false,
|
||||
"compiler-fixed": false,
|
||||
"no-simple-event-func-name": false,
|
||||
"two-lines-top-level-separator": false
|
||||
}
|
||||
}
|
||||
@ -1 +0,0 @@
|
||||
node_modules
|
||||
@ -1,21 +0,0 @@
|
||||
{
|
||||
"extends": "solium:all",
|
||||
"plugins": ["security"],
|
||||
"rules": {
|
||||
"blank-lines": "off",
|
||||
"error-reason": "off",
|
||||
"indentation": ["error", 2],
|
||||
"lbrace": "off",
|
||||
"linebreak-style": ["error", "unix"],
|
||||
"max-len": ["error", 79],
|
||||
"no-constant": ["error"],
|
||||
"no-empty-blocks": "off",
|
||||
"quotes": ["error", "double"],
|
||||
"uppercase": "off",
|
||||
"visibility-first": "error",
|
||||
|
||||
"security/enforce-explicit-visibility": ["error"],
|
||||
"security/no-block-members": ["warning"],
|
||||
"security/no-inline-assembly": ["warning"]
|
||||
}
|
||||
}
|
||||
23
.travis.yml
23
.travis.yml
@ -15,29 +15,26 @@ jobs:
|
||||
# --elopio - 20180531
|
||||
fast_finish: true
|
||||
allow_failures:
|
||||
- env: SOLIDITY_COVERAGE=true
|
||||
- env: SOLC_NIGHTLY=true
|
||||
include:
|
||||
# Run the unit test suite three times in parallel.
|
||||
# The first one gets results faster and is the only one required to pass.
|
||||
# The second one generates the coverage report.
|
||||
# The third one is to keep us informed about possible issues with the
|
||||
# upcoming solidity release.
|
||||
- stage: tests
|
||||
name: "unit tests"
|
||||
name: "Linter"
|
||||
script: npm run lint
|
||||
|
||||
- stage: tests
|
||||
name: "Unit tests"
|
||||
script: npm run test
|
||||
|
||||
- stage: tests
|
||||
name: "unit tests with coverage"
|
||||
name: "Unit tests with coverage report"
|
||||
script: npm run test
|
||||
env: SOLIDITY_COVERAGE=true
|
||||
|
||||
- stage: tests
|
||||
name: "unit tests with solc nightly"
|
||||
name: "Unit tests using solc nightly"
|
||||
script: npm run test
|
||||
env: SOLC_NIGHTLY=true
|
||||
# solidity and javascript style tests.
|
||||
- stage: tests
|
||||
name: "static tests"
|
||||
script: npm run lint
|
||||
|
||||
- stage: update docs
|
||||
if: tag =~ ^v[0-9]+\.[0-9]+\.[0-9]+$
|
||||
addons:
|
||||
|
||||
65
CHANGELOG.md
Normal file
65
CHANGELOG.md
Normal file
@ -0,0 +1,65 @@
|
||||
# Changelog
|
||||
|
||||
## 2.2.1 (2019-07-22)
|
||||
|
||||
### Changes:
|
||||
* Renamed package to `@openzeppelin/contracts-ethereum-package`. ([#54](https://github.com/OpenZeppelin/openzeppelin-contracts-ethereum-package/pull/54))
|
||||
|
||||
## 2.2.0 (2019-03-14)
|
||||
|
||||
### New features:
|
||||
* `ERC20Snapshot`: create snapshots on demand of the token balances and total supply, to later retrieve and e.g. calculate dividends at a past time. ([#1617](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1617))
|
||||
* `SafeERC20`: `ERC20` contracts with no return value (i.e. that revert on failure) are now supported. ([#1655](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/))
|
||||
* `ERC20`: added internal `_approve(address owner, address spender, uint256 value)`, allowing derived contracts to set the allowance of arbitrary accounts. ([#1609](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1609))
|
||||
* `ERC20Metadata`: added internal `_setTokenURI(string memory tokenURI)`. ([#1618](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1618))
|
||||
* `TimedCrowdsale`: added internal `_extendTime(uint256 newClosingTime)` as well as `TimedCrowdsaleExtended(uint256 prevClosingTime, uint256 newClosingTime)` event allowing to extend the crowdsale, as long as it hasn't already closed.
|
||||
|
||||
### Improvements:
|
||||
* Upgraded the minimum compiler version to v0.5.2: this removes many Solidity warnings that were false positives. ([#1606](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1606))
|
||||
* `ECDSA`: `recover` no longer accepts malleable signatures (those using upper-range values for `s`, or 0/1 for `v`). ([#1622](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1622))
|
||||
* `ERC721`'s transfers are now more gas efficient due to removal of unnecessary `SafeMath` calls. ([#1610](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1610))
|
||||
* `Counter`'s API has been improved, and is now used by `ERC721` (though it is still in `drafts`). ([#1610](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1610))
|
||||
* Fixed variable shadowing issues. ([#1606](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1606))
|
||||
|
||||
### Bugfixes:
|
||||
* (minor) `SafeERC20`: `safeApprove` wasn't properly checking for a zero allowance when attempting to set a non-zero allowance. ([#1647](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1647))
|
||||
|
||||
### Breaking changes:
|
||||
* `TokenMetadata` (in drafts) has been renamed to `ERC20Metadata`. ([#1618](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1618))
|
||||
|
||||
## 2.1.3 (2019-02-26)
|
||||
* Backported `SafeERC20.safeApprove` bugfix. ([#1647](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1647))
|
||||
|
||||
## 2.1.2 (2019-01-17)
|
||||
* Removed most of the test suite from the npm package, except `PublicRole.behavior.js`, which may be useful to users testing their own `Roles`.
|
||||
|
||||
## 2.1.1 (2019-01-04)
|
||||
* Version bump to avoid conflict in the npm registry.
|
||||
|
||||
## 2.1.0 (2019-01-04)
|
||||
|
||||
### New features:
|
||||
* Now targeting the 0.5.x line of Solidity compilers. For 0.4.24 support, use version 2.0 of OpenZeppelin.
|
||||
* `WhitelistCrowdsale`: a crowdsale where only whitelisted accounts (`WhitelistedRole`) can purchase tokens. Adding or removing accounts from the whitelist is done by whitelist admins (`WhitelistAdminRole`). Similar to the pre-2.0 `WhitelistedCrowdsale`. ([#1525](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1525), [#1589](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1589))
|
||||
* `RefundablePostDeliveryCrowdsale`: replacement for `RefundableCrowdsale` (deprecated, see below) where tokens are only granted once the crowdsale ends (if it meets its goal). ([#1543](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1543))
|
||||
* `PausableCrowdsale`: allows for pausers (`PauserRole`) to pause token purchases. Other crowdsale operations (e.g. withdrawals and refunds, if applicable) are not affected. ([#832](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/832))
|
||||
* `ERC20`: `transferFrom` and `_burnFrom ` now emit `Approval` events, to represent the token's state comprehensively through events. ([#1524](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1524))
|
||||
* `ERC721`: added `_burn(uint256 tokenId)`, replacing the similar deprecated function (see below). ([#1550](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1550))
|
||||
* `ERC721`: added `_tokensOfOwner(address owner)`, allowing to internally retrieve the array of an account's owned tokens. ([#1522](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1522))
|
||||
* Crowdsales: all constructors are now `public`, meaning it is not necessary to extend these contracts in order to deploy them. The exception is `FinalizableCrowdsale`, since it is meaningless unless extended. ([#1564](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1564))
|
||||
* `SignedSafeMath`: added overflow-safe operations for signed integers (`int256`). ([#1559](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1559), [#1588](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1588))
|
||||
|
||||
### Improvements:
|
||||
* The compiler version required by `Array` was behind the rest of the libray so it was updated to `v0.4.24`. ([#1553](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1553))
|
||||
* Now conforming to a 4-space indentation code style. ([1508](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1508))
|
||||
* `ERC20`: more gas efficient due to removed redundant `require`s. ([#1409](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1409))
|
||||
* `ERC721`: fixed a bug that prevented internal data structures from being properly cleaned, missing potential gas refunds. ([#1539](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1539) and [#1549](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1549))
|
||||
* `ERC721`: general gas savings on `transferFrom`, `_mint` and `_burn`, due to redudant `require`s and `SSTORE`s. ([#1549](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1549))
|
||||
|
||||
### Bugfixes:
|
||||
|
||||
### Breaking changes:
|
||||
|
||||
### Deprecations:
|
||||
* `ERC721._burn(address owner, uint256 tokenId)`: due to the `owner` parameter being unnecessary. ([#1550](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1550))
|
||||
* `RefundableCrowdsale`: due to trading abuse potential on crowdsales that miss their goal. ([#1543](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1543))
|
||||
102
README.md
102
README.md
@ -1,42 +1,100 @@
|
||||
# <img src="logo.png" alt="OpenZeppelin" width="400px">
|
||||
|
||||
[](https://www.npmjs.org/package/openzeppelin-solidity)
|
||||
[](https://travis-ci.org/OpenZeppelin/openzeppelin-solidity)
|
||||
[](https://coveralls.io/github/OpenZeppelin/openzeppelin-solidity?branch=master)
|
||||
# OpenZeppelin Contracts Ethereum Package
|
||||
|
||||
**OpenZeppelin is a library for secure smart contract development.** It provides implementations of standards like ERC20 and ERC721 which you can deploy as-is or extend to suit your needs, as well as Solidity components to build custom contracts and more complex decentralized systems.
|
||||
[](https://www.npmjs.org/package/@openzeppelin/contracts-ethereum-package)
|
||||
[](https://travis-ci.org/OpenZeppelin/openzeppelin-contracts-ethereum-package)
|
||||
|
||||
**OpenZeppelin Contracts is a library for secure smart contract development.** It provides implementations of standards like ERC20 and ERC721 which you can deploy as-is or extend to suit your needs, as well as Solidity components to build custom contracts and more complex decentralized systems.
|
||||
|
||||
This fork of OpenZeppelin is set up as a **reusable Ethereum Package**. It is deployed to the kovan, rinkeby, and ropsten test networks, as well as to the main Ethereum network. You can reuse any of the pre-deployed on-chain contracts by simply linking to them using the [OpenZeppelin SDK](https://github.com/openzeppelin/openzeppelin-sdk), or reuse their Solidity source code as with the [vanilla version of OpenZeppelin Contracts](https://github.com/OpenZeppelin/openzeppelin-contracts).
|
||||
|
||||
## Differences with openzeppelin-contracts
|
||||
|
||||
This package contains the same contracts as the vanilla [openzeppelin-contracts](https://github.com/openZeppelin/openzeppelin-contracts). The main difference is that _all contracts in this package are potentially upgradeable_: you will notice that no contracts have constructors defined, but use [initializer functions](https://docs.zeppelinos.org/docs/writing_contracts.html#initializers) instead. Also, this package is set up as an Ethereum package, and provides a small set of pre-deployed logic contracts that can be used directly via the OpenZeppelin SDK, without needing to deploy them again.
|
||||
|
||||
All in all, **you should use this package instead of openzeppelin-solidity if you are managing your project via the OpenZeppelin CLI**.
|
||||
|
||||
## Install
|
||||
|
||||
```
|
||||
npm install openzeppelin-solidity
|
||||
npm install @openzeppelin/contracts-ethereum-package
|
||||
```
|
||||
|
||||
## Usage
|
||||
## Deployed logic contracts
|
||||
|
||||
To write your custom contracts, import ours and extend them through inheritance.
|
||||
- [StandaloneERC20](contracts/token/ERC20/StandaloneERC20.sol): ERC20 token implementation, optionally mintable and pausable.
|
||||
- [StandaloneERC721](contracts/token/ERC721/StandaloneERC721.sol): ERC721 non-fungible token implementation with metadata and enumerable extensions, optionally mintable and pausable.
|
||||
- [TokenVesting](contracts/drafts/TokenVesting.sol): tToken holder contract that can release its token balance gradually like a typical vesting scheme, with a cliff and vesting period, optionally revocable.
|
||||
- [PaymentSplitter](contracts/payment/PaymentSplitter.sol): Splits payments among a group of addresses proportionately to some number of shares they own.
|
||||
|
||||
## Using via the OpenZeppelin CLI
|
||||
|
||||
You can easily create upgradeable instances of any of the logic contracts listed above using the OpenZeppelin CLI. This will rely on the pre-deployed instances in mainnet, kovan, ropsten, or rinkeby, greatly reducing your gas deployment costs. To do this, just [create a new OpenZeppelin SDK project](https://docs.zeppelinos.org/docs/deploying.html) and [link to this package](https://docs.zeppelinos.org/docs/linking.html).
|
||||
|
||||
```bash
|
||||
$ npm install -g @openzeppelin/cli
|
||||
$ openzeppelin init
|
||||
$ openzeppelin link @openzeppelin/contracts-ethereum-package
|
||||
> Installing...
|
||||
$ openzeppelin create @openzeppelin/contracts-ethereum-package/StandaloneERC20
|
||||
> Creating...
|
||||
```
|
||||
|
||||
To create an instance of a contract, use the `openzeppelin create` command. As an example, you can run the following to create an upgradeable ERC20 named MyToken, with symbol TKN and 8 decimals, and an initial supply of 100 tokens assigned to the address HOLDER, with a MINTER and a PAUSER. Remember to replace $HOLDER, $MINTER, and $PAUSER with actual addresses when you run this command; you can specify more than one (or none at all) minters and pausers.
|
||||
|
||||
```
|
||||
$ openzeppelin create
|
||||
? Pick a contract to instantiate: @openzeppelin/contracts-ethereum-package/StandaloneERC20
|
||||
? Pick a network: development
|
||||
✓ Deploying @openzeppelin/contracts-ethereum-package dependency to network
|
||||
? Do you want to call a function on the instance after creating it?: Yes
|
||||
? Select which function: * initialize(name: string, symbol: string, decimals: uint8, initialSupply: uint256, initialHolder: address, minters: address[], pausers: address[])
|
||||
? name (string): MyToken
|
||||
? symbol (string): MYT
|
||||
? decimals (uint8): 18
|
||||
? initialSupply (uint256): 100e18
|
||||
? initialHolder (address): 0x90f8bf6a479f320ead074411a4b0e7944ea8c9c1
|
||||
? minters (address[]):
|
||||
? pausers (address[]):
|
||||
✓ Setting everything up to create contract instances
|
||||
✓ Instance created at 0x2612Af3A521c2df9EAF28422Ca335b04AdF3ac66
|
||||
```
|
||||
|
||||
OpenZeppelin will create an upgradeable ERC20 instance and keep track of its address in the `.openzeppelin/rinkeby.json` file. Should you update your version of the openzeppelin contracts ethereum package later down the road, you can simply run `openzeppelin update` to upgrade all your ERC20 instances to the latest version.
|
||||
|
||||
You can also deploy a ERC721 token by choosing the `StandaloneERC721` contract when running `openzeppelin create`. Refer to the `initialize` function of each of the predeployed logic contracts to see which parameters are required for initialization.
|
||||
|
||||
## Extending contracts
|
||||
|
||||
If you prefer to write your custom contracts, import the ones from this package and extend them through inheritance. Note that **you must use this package and not `@openzeppelin/contracts` if you are [writing upgradeable contracts](https://docs.zeppelinos.org/docs/writing_contracts.html)**.
|
||||
|
||||
```solidity
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
import 'openzeppelin-solidity/contracts/token/ERC721/ERC721Full.sol';
|
||||
import 'openzeppelin-solidity/contracts/token/ERC721/ERC721Mintable.sol';
|
||||
import '@openzeppelin/upgrades/contracts/Initializable.sol';
|
||||
import '@openzeppelin/contracts-ethereum-package/contracts/token/ERC721/ERC721Full.sol';
|
||||
import '@openzeppelin/contracts-ethereum-package/contracts/token/ERC721/ERC721Mintable.sol';
|
||||
|
||||
contract MyNFT is ERC721Full, ERC721Mintable {
|
||||
constructor() ERC721Full("MyNFT", "MNFT") public {
|
||||
contract MyNFT is Initializable, ERC721Full, ERC721Mintable {
|
||||
function initialize() public initializer {
|
||||
ERC721.initialize();
|
||||
ERC721Enumerable.initialize();
|
||||
ERC721Metadata.initialize("MyNFT", "MNFT");
|
||||
ERC721Mintable.initialize(msg.sender);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
> You need an ethereum development framework for the above import statements to work! Check out these guides for [Truffle] or [Embark].
|
||||
|
||||
On our site you will find a few [guides] to learn about the diferent parts of OpenZeppelin, as well as [documentation for the API][API docs]. Keep in mind that the API docs are work in progress, and don’t hesitate to ask questions in [our Slack][Slack].
|
||||
On our site you will find a few [guides] to learn about the different parts of OpenZeppelin, as well as [documentation for the API][API docs]. Keep in mind that the API docs are work in progress, and don’t hesitate to ask questions in [our forum][forum].
|
||||
|
||||
## Security
|
||||
|
||||
OpenZeppelin the project is maintained by [Zeppelin] the company, and developed following our high standards for code quality and security. OpenZeppelin is meant to provide tested and community-audited code, but please use common sense when doing anything that deals with real money! We take no responsibility for your implementation decisions and any security problems you might experience.
|
||||
OpenZeppelin Contracts is maintained by [OpenZeppelin](https://openzeppelin.com) the company, and developed following our high standards for code quality and security. OpenZeppelin Contracts is meant to provide tested and community-audited code, but please use common sense when doing anything that deals with real money! We take no responsibility for your implementation decisions and any security problems you might experience.
|
||||
|
||||
The core development principles and strategies that OpenZeppelin is based on include: security in depth, simple and modular code, clarity-driven naming conventions, comprehensive unit testing, pre-and-post-condition sanity checks, code consistency, and regular audits.
|
||||
The core development principles and strategies that OpenZeppelin Contracts is based on include: security in depth, simple and modular code, clarity-driven naming conventions, comprehensive unit testing, pre-and-post-condition sanity checks, code consistency, and regular audits.
|
||||
|
||||
The latest audit was done on October 2018 on version 2.0.0.
|
||||
|
||||
Please report any security issues you find to security@openzeppelin.org.
|
||||
|
||||
@ -48,11 +106,7 @@ OpenZeppelin exists thanks to its contributors. There are many ways you can part
|
||||
|
||||
OpenZeppelin is released under the [MIT License](LICENSE).
|
||||
|
||||
|
||||
[API docs]: https://openzeppelin.org/api/docs/token_ERC721_ERC721BasicToken.html
|
||||
[guides]: https://openzeppelin.org/api/docs/get-started.html
|
||||
[Slack]: https://slack.openzeppelin.org
|
||||
[Zeppelin]: https://zeppelin.solutions
|
||||
[API docs]: https://docs.openzeppelin.org/v2.3.0/api/token/erc20
|
||||
[guides]: https://docs.openzeppelin.org/v2.3.0/get-started
|
||||
[forum]: https://forum.zeppelin.solutions
|
||||
[contribution guide]: CONTRIBUTING.md
|
||||
[Truffle]: https://truffleframework.com/docs/truffle/quickstart
|
||||
[Embark]: https://embark.status.im/docs/quick_start.html
|
||||
|
||||
@ -34,7 +34,7 @@ git push upstream vX.Y.Z-rc.R
|
||||
|
||||
Draft the release notes in our [GitHub releases](https://github.com/OpenZeppelin/openzeppelin-solidity/releases). Make sure to mark it as a pre-release! Try to be consistent with our previous release notes in the title and format of the text. Release candidates don't need a detailed changelog, but make sure to include a link to GitHub's compare page.
|
||||
|
||||
Once the CI run for the new tag is green, publish on npm under the `next` tag.
|
||||
Once the CI run for the new tag is green, publish on npm under the `next` tag. You should see the contracts compile automatically.
|
||||
|
||||
```
|
||||
npm publish --tag next
|
||||
@ -51,18 +51,21 @@ git checkout release-vX.Y.Z
|
||||
git pull upstream
|
||||
```
|
||||
|
||||
Before starting the release process, make one final commit to CHANGELOG.md, including the date of the release.
|
||||
|
||||
Change the version string in `package.json`, `package-lock.json` and `ethpm.json` removing the "-rc.R" suffix. Commit these changes and tag the commit as `vX.Y.Z`.
|
||||
|
||||
```
|
||||
git add package.json package-lock.json ethpm.json
|
||||
git commit -m "Release vX.Y.Z"
|
||||
git tag -a vX.Y.Z
|
||||
git push upstream release-vX.Y.Z
|
||||
git push upstream vX.Y.Z
|
||||
```
|
||||
|
||||
Draft the release notes in GitHub releases. Try to be consistent with our previous release notes in the title and format of the text. Make sure to include a detailed changelog.
|
||||
|
||||
Once the CI run for the new tag is green, publish on npm.
|
||||
Once the CI run for the new tag is green, publish on npm. You should see the contracts compile automatically.
|
||||
|
||||
```
|
||||
npm publish
|
||||
|
||||
BIN
audit/2018-10.pdf
Normal file
BIN
audit/2018-10.pdf
Normal file
Binary file not shown.
@ -1,44 +1,40 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.2;
|
||||
|
||||
/**
|
||||
* @title Roles
|
||||
* @dev Library for managing addresses assigned to a Role.
|
||||
*/
|
||||
library Roles {
|
||||
struct Role {
|
||||
mapping (address => bool) bearer;
|
||||
}
|
||||
struct Role {
|
||||
mapping (address => bool) bearer;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev give an account access to this role
|
||||
*/
|
||||
function add(Role storage role, address account) internal {
|
||||
require(account != address(0));
|
||||
require(!has(role, account));
|
||||
/**
|
||||
* @dev give an account access to this role
|
||||
*/
|
||||
function add(Role storage role, address account) internal {
|
||||
require(account != address(0));
|
||||
require(!has(role, account));
|
||||
|
||||
role.bearer[account] = true;
|
||||
}
|
||||
role.bearer[account] = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev remove an account's access to this role
|
||||
*/
|
||||
function remove(Role storage role, address account) internal {
|
||||
require(account != address(0));
|
||||
require(has(role, account));
|
||||
/**
|
||||
* @dev remove an account's access to this role
|
||||
*/
|
||||
function remove(Role storage role, address account) internal {
|
||||
require(account != address(0));
|
||||
require(has(role, account));
|
||||
|
||||
role.bearer[account] = false;
|
||||
}
|
||||
role.bearer[account] = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev check if an account has this role
|
||||
* @return bool
|
||||
*/
|
||||
function has(Role storage role, address account)
|
||||
internal
|
||||
view
|
||||
returns (bool)
|
||||
{
|
||||
require(account != address(0));
|
||||
return role.bearer[account];
|
||||
}
|
||||
/**
|
||||
* @dev check if an account has this role
|
||||
* @return bool
|
||||
*/
|
||||
function has(Role storage role, address account) internal view returns (bool) {
|
||||
require(account != address(0));
|
||||
return role.bearer[account];
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,43 +1,49 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.2;
|
||||
|
||||
import "@openzeppelin/upgrades/contracts/Initializable.sol";
|
||||
import "../Roles.sol";
|
||||
|
||||
contract CapperRole {
|
||||
using Roles for Roles.Role;
|
||||
|
||||
event CapperAdded(address indexed account);
|
||||
event CapperRemoved(address indexed account);
|
||||
contract CapperRole is Initializable {
|
||||
using Roles for Roles.Role;
|
||||
|
||||
Roles.Role private cappers;
|
||||
event CapperAdded(address indexed account);
|
||||
event CapperRemoved(address indexed account);
|
||||
|
||||
constructor() internal {
|
||||
_addCapper(msg.sender);
|
||||
}
|
||||
Roles.Role private _cappers;
|
||||
|
||||
modifier onlyCapper() {
|
||||
require(isCapper(msg.sender));
|
||||
_;
|
||||
}
|
||||
function initialize(address sender) public initializer {
|
||||
if (!isCapper(sender)) {
|
||||
_addCapper(sender);
|
||||
}
|
||||
}
|
||||
|
||||
function isCapper(address account) public view returns (bool) {
|
||||
return cappers.has(account);
|
||||
}
|
||||
modifier onlyCapper() {
|
||||
require(isCapper(msg.sender));
|
||||
_;
|
||||
}
|
||||
|
||||
function addCapper(address account) public onlyCapper {
|
||||
_addCapper(account);
|
||||
}
|
||||
function isCapper(address account) public view returns (bool) {
|
||||
return _cappers.has(account);
|
||||
}
|
||||
|
||||
function renounceCapper() public {
|
||||
_removeCapper(msg.sender);
|
||||
}
|
||||
function addCapper(address account) public onlyCapper {
|
||||
_addCapper(account);
|
||||
}
|
||||
|
||||
function _addCapper(address account) internal {
|
||||
cappers.add(account);
|
||||
emit CapperAdded(account);
|
||||
}
|
||||
function renounceCapper() public {
|
||||
_removeCapper(msg.sender);
|
||||
}
|
||||
|
||||
function _removeCapper(address account) internal {
|
||||
cappers.remove(account);
|
||||
emit CapperRemoved(account);
|
||||
}
|
||||
function _addCapper(address account) internal {
|
||||
_cappers.add(account);
|
||||
emit CapperAdded(account);
|
||||
}
|
||||
|
||||
function _removeCapper(address account) internal {
|
||||
_cappers.remove(account);
|
||||
emit CapperRemoved(account);
|
||||
}
|
||||
|
||||
uint256[50] private ______gap;
|
||||
}
|
||||
|
||||
@ -1,43 +1,49 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.2;
|
||||
|
||||
import "@openzeppelin/upgrades/contracts/Initializable.sol";
|
||||
import "../Roles.sol";
|
||||
|
||||
contract MinterRole {
|
||||
using Roles for Roles.Role;
|
||||
|
||||
event MinterAdded(address indexed account);
|
||||
event MinterRemoved(address indexed account);
|
||||
contract MinterRole is Initializable {
|
||||
using Roles for Roles.Role;
|
||||
|
||||
Roles.Role private minters;
|
||||
event MinterAdded(address indexed account);
|
||||
event MinterRemoved(address indexed account);
|
||||
|
||||
constructor() internal {
|
||||
_addMinter(msg.sender);
|
||||
}
|
||||
Roles.Role private _minters;
|
||||
|
||||
modifier onlyMinter() {
|
||||
require(isMinter(msg.sender));
|
||||
_;
|
||||
}
|
||||
function initialize(address sender) public initializer {
|
||||
if (!isMinter(sender)) {
|
||||
_addMinter(sender);
|
||||
}
|
||||
}
|
||||
|
||||
function isMinter(address account) public view returns (bool) {
|
||||
return minters.has(account);
|
||||
}
|
||||
modifier onlyMinter() {
|
||||
require(isMinter(msg.sender));
|
||||
_;
|
||||
}
|
||||
|
||||
function addMinter(address account) public onlyMinter {
|
||||
_addMinter(account);
|
||||
}
|
||||
function isMinter(address account) public view returns (bool) {
|
||||
return _minters.has(account);
|
||||
}
|
||||
|
||||
function renounceMinter() public {
|
||||
_removeMinter(msg.sender);
|
||||
}
|
||||
function addMinter(address account) public onlyMinter {
|
||||
_addMinter(account);
|
||||
}
|
||||
|
||||
function _addMinter(address account) internal {
|
||||
minters.add(account);
|
||||
emit MinterAdded(account);
|
||||
}
|
||||
function renounceMinter() public {
|
||||
_removeMinter(msg.sender);
|
||||
}
|
||||
|
||||
function _removeMinter(address account) internal {
|
||||
minters.remove(account);
|
||||
emit MinterRemoved(account);
|
||||
}
|
||||
function _addMinter(address account) internal {
|
||||
_minters.add(account);
|
||||
emit MinterAdded(account);
|
||||
}
|
||||
|
||||
function _removeMinter(address account) internal {
|
||||
_minters.remove(account);
|
||||
emit MinterRemoved(account);
|
||||
}
|
||||
|
||||
uint256[50] private ______gap;
|
||||
}
|
||||
|
||||
@ -1,43 +1,49 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.2;
|
||||
|
||||
import "@openzeppelin/upgrades/contracts/Initializable.sol";
|
||||
import "../Roles.sol";
|
||||
|
||||
contract PauserRole {
|
||||
using Roles for Roles.Role;
|
||||
|
||||
event PauserAdded(address indexed account);
|
||||
event PauserRemoved(address indexed account);
|
||||
contract PauserRole is Initializable {
|
||||
using Roles for Roles.Role;
|
||||
|
||||
Roles.Role private pausers;
|
||||
event PauserAdded(address indexed account);
|
||||
event PauserRemoved(address indexed account);
|
||||
|
||||
constructor() internal {
|
||||
_addPauser(msg.sender);
|
||||
}
|
||||
Roles.Role private _pausers;
|
||||
|
||||
modifier onlyPauser() {
|
||||
require(isPauser(msg.sender));
|
||||
_;
|
||||
}
|
||||
function initialize(address sender) public initializer {
|
||||
if (!isPauser(sender)) {
|
||||
_addPauser(sender);
|
||||
}
|
||||
}
|
||||
|
||||
function isPauser(address account) public view returns (bool) {
|
||||
return pausers.has(account);
|
||||
}
|
||||
modifier onlyPauser() {
|
||||
require(isPauser(msg.sender));
|
||||
_;
|
||||
}
|
||||
|
||||
function addPauser(address account) public onlyPauser {
|
||||
_addPauser(account);
|
||||
}
|
||||
function isPauser(address account) public view returns (bool) {
|
||||
return _pausers.has(account);
|
||||
}
|
||||
|
||||
function renouncePauser() public {
|
||||
_removePauser(msg.sender);
|
||||
}
|
||||
function addPauser(address account) public onlyPauser {
|
||||
_addPauser(account);
|
||||
}
|
||||
|
||||
function _addPauser(address account) internal {
|
||||
pausers.add(account);
|
||||
emit PauserAdded(account);
|
||||
}
|
||||
function renouncePauser() public {
|
||||
_removePauser(msg.sender);
|
||||
}
|
||||
|
||||
function _removePauser(address account) internal {
|
||||
pausers.remove(account);
|
||||
emit PauserRemoved(account);
|
||||
}
|
||||
function _addPauser(address account) internal {
|
||||
_pausers.add(account);
|
||||
emit PauserAdded(account);
|
||||
}
|
||||
|
||||
function _removePauser(address account) internal {
|
||||
_pausers.remove(account);
|
||||
emit PauserRemoved(account);
|
||||
}
|
||||
|
||||
uint256[50] private ______gap;
|
||||
}
|
||||
|
||||
@ -1,43 +1,49 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.2;
|
||||
|
||||
import "@openzeppelin/upgrades/contracts/Initializable.sol";
|
||||
import "../Roles.sol";
|
||||
|
||||
contract SignerRole {
|
||||
using Roles for Roles.Role;
|
||||
|
||||
event SignerAdded(address indexed account);
|
||||
event SignerRemoved(address indexed account);
|
||||
contract SignerRole is Initializable {
|
||||
using Roles for Roles.Role;
|
||||
|
||||
Roles.Role private signers;
|
||||
event SignerAdded(address indexed account);
|
||||
event SignerRemoved(address indexed account);
|
||||
|
||||
constructor() internal {
|
||||
_addSigner(msg.sender);
|
||||
}
|
||||
Roles.Role private _signers;
|
||||
|
||||
modifier onlySigner() {
|
||||
require(isSigner(msg.sender));
|
||||
_;
|
||||
}
|
||||
function initialize(address sender) public initializer {
|
||||
if (!isSigner(sender)) {
|
||||
_addSigner(sender);
|
||||
}
|
||||
}
|
||||
|
||||
function isSigner(address account) public view returns (bool) {
|
||||
return signers.has(account);
|
||||
}
|
||||
modifier onlySigner() {
|
||||
require(isSigner(msg.sender));
|
||||
_;
|
||||
}
|
||||
|
||||
function addSigner(address account) public onlySigner {
|
||||
_addSigner(account);
|
||||
}
|
||||
function isSigner(address account) public view returns (bool) {
|
||||
return _signers.has(account);
|
||||
}
|
||||
|
||||
function renounceSigner() public {
|
||||
_removeSigner(msg.sender);
|
||||
}
|
||||
function addSigner(address account) public onlySigner {
|
||||
_addSigner(account);
|
||||
}
|
||||
|
||||
function _addSigner(address account) internal {
|
||||
signers.add(account);
|
||||
emit SignerAdded(account);
|
||||
}
|
||||
function renounceSigner() public {
|
||||
_removeSigner(msg.sender);
|
||||
}
|
||||
|
||||
function _removeSigner(address account) internal {
|
||||
signers.remove(account);
|
||||
emit SignerRemoved(account);
|
||||
}
|
||||
function _addSigner(address account) internal {
|
||||
_signers.add(account);
|
||||
emit SignerAdded(account);
|
||||
}
|
||||
|
||||
function _removeSigner(address account) internal {
|
||||
_signers.remove(account);
|
||||
emit SignerRemoved(account);
|
||||
}
|
||||
|
||||
uint256[50] private ______gap;
|
||||
}
|
||||
|
||||
53
contracts/access/roles/WhitelistAdminRole.sol
Normal file
53
contracts/access/roles/WhitelistAdminRole.sol
Normal file
@ -0,0 +1,53 @@
|
||||
pragma solidity ^0.5.2;
|
||||
|
||||
import "@openzeppelin/upgrades/contracts/Initializable.sol";
|
||||
|
||||
import "../Roles.sol";
|
||||
|
||||
/**
|
||||
* @title WhitelistAdminRole
|
||||
* @dev WhitelistAdmins are responsible for assigning and removing Whitelisted accounts.
|
||||
*/
|
||||
contract WhitelistAdminRole is Initializable {
|
||||
using Roles for Roles.Role;
|
||||
|
||||
event WhitelistAdminAdded(address indexed account);
|
||||
event WhitelistAdminRemoved(address indexed account);
|
||||
|
||||
Roles.Role private _whitelistAdmins;
|
||||
|
||||
function initialize(address sender) public initializer {
|
||||
if (!isWhitelistAdmin(sender)) {
|
||||
_addWhitelistAdmin(sender);
|
||||
}
|
||||
}
|
||||
|
||||
modifier onlyWhitelistAdmin() {
|
||||
require(isWhitelistAdmin(msg.sender));
|
||||
_;
|
||||
}
|
||||
|
||||
function isWhitelistAdmin(address account) public view returns (bool) {
|
||||
return _whitelistAdmins.has(account);
|
||||
}
|
||||
|
||||
function addWhitelistAdmin(address account) public onlyWhitelistAdmin {
|
||||
_addWhitelistAdmin(account);
|
||||
}
|
||||
|
||||
function renounceWhitelistAdmin() public {
|
||||
_removeWhitelistAdmin(msg.sender);
|
||||
}
|
||||
|
||||
function _addWhitelistAdmin(address account) internal {
|
||||
_whitelistAdmins.add(account);
|
||||
emit WhitelistAdminAdded(account);
|
||||
}
|
||||
|
||||
function _removeWhitelistAdmin(address account) internal {
|
||||
_whitelistAdmins.remove(account);
|
||||
emit WhitelistAdminRemoved(account);
|
||||
}
|
||||
|
||||
uint256[50] private ______gap;
|
||||
}
|
||||
58
contracts/access/roles/WhitelistedRole.sol
Normal file
58
contracts/access/roles/WhitelistedRole.sol
Normal file
@ -0,0 +1,58 @@
|
||||
pragma solidity ^0.5.2;
|
||||
|
||||
import "@openzeppelin/upgrades/contracts/Initializable.sol";
|
||||
|
||||
import "../Roles.sol";
|
||||
import "./WhitelistAdminRole.sol";
|
||||
|
||||
/**
|
||||
* @title WhitelistedRole
|
||||
* @dev Whitelisted accounts have been approved by a WhitelistAdmin to perform certain actions (e.g. participate in a
|
||||
* crowdsale). This role is special in that the only accounts that can add it are WhitelistAdmins (who can also remove
|
||||
* it), and not Whitelisteds themselves.
|
||||
*/
|
||||
contract WhitelistedRole is Initializable, WhitelistAdminRole {
|
||||
using Roles for Roles.Role;
|
||||
|
||||
event WhitelistedAdded(address indexed account);
|
||||
event WhitelistedRemoved(address indexed account);
|
||||
|
||||
Roles.Role private _whitelisteds;
|
||||
|
||||
modifier onlyWhitelisted() {
|
||||
require(isWhitelisted(msg.sender));
|
||||
_;
|
||||
}
|
||||
|
||||
function initialize(address sender) public initializer {
|
||||
WhitelistAdminRole.initialize(sender);
|
||||
}
|
||||
|
||||
function isWhitelisted(address account) public view returns (bool) {
|
||||
return _whitelisteds.has(account);
|
||||
}
|
||||
|
||||
function addWhitelisted(address account) public onlyWhitelistAdmin {
|
||||
_addWhitelisted(account);
|
||||
}
|
||||
|
||||
function removeWhitelisted(address account) public onlyWhitelistAdmin {
|
||||
_removeWhitelisted(account);
|
||||
}
|
||||
|
||||
function renounceWhitelisted() public {
|
||||
_removeWhitelisted(msg.sender);
|
||||
}
|
||||
|
||||
function _addWhitelisted(address account) internal {
|
||||
_whitelisteds.add(account);
|
||||
emit WhitelistedAdded(account);
|
||||
}
|
||||
|
||||
function _removeWhitelisted(address account) internal {
|
||||
_whitelisteds.remove(account);
|
||||
emit WhitelistedRemoved(account);
|
||||
}
|
||||
|
||||
uint256[50] private ______gap;
|
||||
}
|
||||
@ -1,5 +1,6 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.2;
|
||||
|
||||
import "@openzeppelin/upgrades/contracts/Initializable.sol";
|
||||
import "../token/ERC20/IERC20.sol";
|
||||
import "../math/SafeMath.sol";
|
||||
import "../token/ERC20/SafeERC20.sol";
|
||||
@ -11,231 +12,194 @@ import "../utils/ReentrancyGuard.sol";
|
||||
* allowing investors to purchase tokens with ether. This contract implements
|
||||
* such functionality in its most fundamental form and can be extended to provide additional
|
||||
* functionality and/or custom behavior.
|
||||
* The external interface represents the basic interface for purchasing tokens, and conform
|
||||
* the base architecture for crowdsales. They are *not* intended to be modified / overridden.
|
||||
* The external interface represents the basic interface for purchasing tokens, and conforms
|
||||
* the base architecture for crowdsales. It is *not* intended to be modified / overridden.
|
||||
* The internal interface conforms the extensible and modifiable surface of crowdsales. Override
|
||||
* the methods to add functionality. Consider using 'super' where appropriate to concatenate
|
||||
* behavior.
|
||||
*/
|
||||
contract Crowdsale is ReentrancyGuard {
|
||||
using SafeMath for uint256;
|
||||
using SafeERC20 for IERC20;
|
||||
contract Crowdsale is Initializable, ReentrancyGuard {
|
||||
using SafeMath for uint256;
|
||||
using SafeERC20 for IERC20;
|
||||
|
||||
// The token being sold
|
||||
IERC20 private _token;
|
||||
// The token being sold
|
||||
IERC20 private _token;
|
||||
|
||||
// Address where funds are collected
|
||||
address private _wallet;
|
||||
// Address where funds are collected
|
||||
address payable private _wallet;
|
||||
|
||||
// How many token units a buyer gets per wei.
|
||||
// The rate is the conversion between wei and the smallest and indivisible token unit.
|
||||
// So, if you are using a rate of 1 with a ERC20Detailed token with 3 decimals called TOK
|
||||
// 1 wei will give you 1 unit, or 0.001 TOK.
|
||||
uint256 private _rate;
|
||||
// How many token units a buyer gets per wei.
|
||||
// The rate is the conversion between wei and the smallest and indivisible token unit.
|
||||
// So, if you are using a rate of 1 with a ERC20Detailed token with 3 decimals called TOK
|
||||
// 1 wei will give you 1 unit, or 0.001 TOK.
|
||||
uint256 private _rate;
|
||||
|
||||
// Amount of wei raised
|
||||
uint256 private _weiRaised;
|
||||
// Amount of wei raised
|
||||
uint256 private _weiRaised;
|
||||
|
||||
/**
|
||||
* Event for token purchase logging
|
||||
* @param purchaser who paid for the tokens
|
||||
* @param beneficiary who got the tokens
|
||||
* @param value weis paid for purchase
|
||||
* @param amount amount of tokens purchased
|
||||
*/
|
||||
event TokensPurchased(
|
||||
address indexed purchaser,
|
||||
address indexed beneficiary,
|
||||
uint256 value,
|
||||
uint256 amount
|
||||
);
|
||||
/**
|
||||
* Event for token purchase logging
|
||||
* @param purchaser who paid for the tokens
|
||||
* @param beneficiary who got the tokens
|
||||
* @param value weis paid for purchase
|
||||
* @param amount amount of tokens purchased
|
||||
*/
|
||||
event TokensPurchased(address indexed purchaser, address indexed beneficiary, uint256 value, uint256 amount);
|
||||
|
||||
/**
|
||||
* @param rate Number of token units a buyer gets per wei
|
||||
* @dev The rate is the conversion between wei and the smallest and indivisible
|
||||
* token unit. So, if you are using a rate of 1 with a ERC20Detailed token
|
||||
* with 3 decimals called TOK, 1 wei will give you 1 unit, or 0.001 TOK.
|
||||
* @param wallet Address where collected funds will be forwarded to
|
||||
* @param token Address of the token being sold
|
||||
*/
|
||||
constructor(uint256 rate, address wallet, IERC20 token) internal {
|
||||
require(rate > 0);
|
||||
require(wallet != address(0));
|
||||
require(token != address(0));
|
||||
/**
|
||||
* @param rate Number of token units a buyer gets per wei
|
||||
* @dev The rate is the conversion between wei and the smallest and indivisible
|
||||
* token unit. So, if you are using a rate of 1 with a ERC20Detailed token
|
||||
* with 3 decimals called TOK, 1 wei will give you 1 unit, or 0.001 TOK.
|
||||
* @param wallet Address where collected funds will be forwarded to
|
||||
* @param token Address of the token being sold
|
||||
*/
|
||||
function initialize(uint256 rate, address payable wallet, IERC20 token) public initializer {
|
||||
require(rate > 0);
|
||||
require(wallet != address(0));
|
||||
require(address(token) != address(0));
|
||||
|
||||
_rate = rate;
|
||||
_wallet = wallet;
|
||||
_token = token;
|
||||
}
|
||||
_rate = rate;
|
||||
_wallet = wallet;
|
||||
_token = token;
|
||||
}
|
||||
|
||||
// -----------------------------------------
|
||||
// Crowdsale external interface
|
||||
// -----------------------------------------
|
||||
/**
|
||||
* @dev fallback function ***DO NOT OVERRIDE***
|
||||
* Note that other contracts will transfer funds with a base gas stipend
|
||||
* of 2300, which is not enough to call buyTokens. Consider calling
|
||||
* buyTokens directly when purchasing tokens from a contract.
|
||||
*/
|
||||
function () external payable {
|
||||
buyTokens(msg.sender);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev fallback function ***DO NOT OVERRIDE***
|
||||
* Note that other contracts will transfer fund with a base gas stipend
|
||||
* of 2300, which is not enough to call buyTokens. Consider calling
|
||||
* buyTokens directly when purchasing tokens from a contract.
|
||||
*/
|
||||
function () external payable {
|
||||
buyTokens(msg.sender);
|
||||
}
|
||||
/**
|
||||
* @return the token being sold.
|
||||
*/
|
||||
function token() public view returns (IERC20) {
|
||||
return _token;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the token being sold.
|
||||
*/
|
||||
function token() public view returns(IERC20) {
|
||||
return _token;
|
||||
}
|
||||
/**
|
||||
* @return the address where funds are collected.
|
||||
*/
|
||||
function wallet() public view returns (address payable) {
|
||||
return _wallet;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the address where funds are collected.
|
||||
*/
|
||||
function wallet() public view returns(address) {
|
||||
return _wallet;
|
||||
}
|
||||
/**
|
||||
* @return the number of token units a buyer gets per wei.
|
||||
*/
|
||||
function rate() public view returns (uint256) {
|
||||
return _rate;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the number of token units a buyer gets per wei.
|
||||
*/
|
||||
function rate() public view returns(uint256) {
|
||||
return _rate;
|
||||
}
|
||||
/**
|
||||
* @return the amount of wei raised.
|
||||
*/
|
||||
function weiRaised() public view returns (uint256) {
|
||||
return _weiRaised;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the amount of wei raised.
|
||||
*/
|
||||
function weiRaised() public view returns (uint256) {
|
||||
return _weiRaised;
|
||||
}
|
||||
/**
|
||||
* @dev low level token purchase ***DO NOT OVERRIDE***
|
||||
* This function has a non-reentrancy guard, so it shouldn't be called by
|
||||
* another `nonReentrant` function.
|
||||
* @param beneficiary Recipient of the token purchase
|
||||
*/
|
||||
function buyTokens(address beneficiary) public nonReentrant payable {
|
||||
uint256 weiAmount = msg.value;
|
||||
_preValidatePurchase(beneficiary, weiAmount);
|
||||
|
||||
/**
|
||||
* @dev low level token purchase ***DO NOT OVERRIDE***
|
||||
* This function has a non-reentrancy guard, so it shouldn't be called by
|
||||
* another `nonReentrant` function.
|
||||
* @param beneficiary Recipient of the token purchase
|
||||
*/
|
||||
function buyTokens(address beneficiary) public nonReentrant payable {
|
||||
// calculate token amount to be created
|
||||
uint256 tokens = _getTokenAmount(weiAmount);
|
||||
|
||||
uint256 weiAmount = msg.value;
|
||||
_preValidatePurchase(beneficiary, weiAmount);
|
||||
// update state
|
||||
_weiRaised = _weiRaised.add(weiAmount);
|
||||
|
||||
// calculate token amount to be created
|
||||
uint256 tokens = _getTokenAmount(weiAmount);
|
||||
_processPurchase(beneficiary, tokens);
|
||||
emit TokensPurchased(msg.sender, beneficiary, weiAmount, tokens);
|
||||
|
||||
// update state
|
||||
_weiRaised = _weiRaised.add(weiAmount);
|
||||
_updatePurchasingState(beneficiary, weiAmount);
|
||||
|
||||
_processPurchase(beneficiary, tokens);
|
||||
emit TokensPurchased(
|
||||
msg.sender,
|
||||
beneficiary,
|
||||
weiAmount,
|
||||
tokens
|
||||
);
|
||||
_forwardFunds();
|
||||
_postValidatePurchase(beneficiary, weiAmount);
|
||||
}
|
||||
|
||||
_updatePurchasingState(beneficiary, weiAmount);
|
||||
function _hasBeenInitialized() internal view returns (bool) {
|
||||
return ((_rate > 0) && (_wallet != address(0)) && (address(_token) != address(0)));
|
||||
}
|
||||
|
||||
_forwardFunds();
|
||||
_postValidatePurchase(beneficiary, weiAmount);
|
||||
}
|
||||
/**
|
||||
* @dev Validation of an incoming purchase. Use require statements to revert state when conditions are not met.
|
||||
* Use `super` in contracts that inherit from Crowdsale to extend their validations.
|
||||
* Example from CappedCrowdsale.sol's _preValidatePurchase method:
|
||||
* super._preValidatePurchase(beneficiary, weiAmount);
|
||||
* require(weiRaised().add(weiAmount) <= cap);
|
||||
* @param beneficiary Address performing the token purchase
|
||||
* @param weiAmount Value in wei involved in the purchase
|
||||
*/
|
||||
function _preValidatePurchase(address beneficiary, uint256 weiAmount) internal view {
|
||||
require(beneficiary != address(0));
|
||||
require(weiAmount != 0);
|
||||
}
|
||||
|
||||
// -----------------------------------------
|
||||
// Internal interface (extensible)
|
||||
// -----------------------------------------
|
||||
/**
|
||||
* @dev Validation of an executed purchase. Observe state and use revert statements to undo rollback when valid
|
||||
* conditions are not met.
|
||||
* @param beneficiary Address performing the token purchase
|
||||
* @param weiAmount Value in wei involved in the purchase
|
||||
*/
|
||||
function _postValidatePurchase(address beneficiary, uint256 weiAmount) internal view {
|
||||
// solhint-disable-previous-line no-empty-blocks
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Validation of an incoming purchase. Use require statements to revert state when conditions are not met. Use `super` in contracts that inherit from Crowdsale to extend their validations.
|
||||
* Example from CappedCrowdsale.sol's _preValidatePurchase method:
|
||||
* super._preValidatePurchase(beneficiary, weiAmount);
|
||||
* require(weiRaised().add(weiAmount) <= cap);
|
||||
* @param beneficiary Address performing the token purchase
|
||||
* @param weiAmount Value in wei involved in the purchase
|
||||
*/
|
||||
function _preValidatePurchase(
|
||||
address beneficiary,
|
||||
uint256 weiAmount
|
||||
)
|
||||
internal
|
||||
view
|
||||
{
|
||||
require(beneficiary != address(0));
|
||||
require(weiAmount != 0);
|
||||
}
|
||||
/**
|
||||
* @dev Source of tokens. Override this method to modify the way in which the crowdsale ultimately gets and sends
|
||||
* its tokens.
|
||||
* @param beneficiary Address performing the token purchase
|
||||
* @param tokenAmount Number of tokens to be emitted
|
||||
*/
|
||||
function _deliverTokens(address beneficiary, uint256 tokenAmount) internal {
|
||||
_token.safeTransfer(beneficiary, tokenAmount);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Validation of an executed purchase. Observe state and use revert statements to undo rollback when valid conditions are not met.
|
||||
* @param beneficiary Address performing the token purchase
|
||||
* @param weiAmount Value in wei involved in the purchase
|
||||
*/
|
||||
function _postValidatePurchase(
|
||||
address beneficiary,
|
||||
uint256 weiAmount
|
||||
)
|
||||
internal
|
||||
view
|
||||
{
|
||||
// optional override
|
||||
}
|
||||
/**
|
||||
* @dev Executed when a purchase has been validated and is ready to be executed. Doesn't necessarily emit/send
|
||||
* tokens.
|
||||
* @param beneficiary Address receiving the tokens
|
||||
* @param tokenAmount Number of tokens to be purchased
|
||||
*/
|
||||
function _processPurchase(address beneficiary, uint256 tokenAmount) internal {
|
||||
_deliverTokens(beneficiary, tokenAmount);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Source of tokens. Override this method to modify the way in which the crowdsale ultimately gets and sends its tokens.
|
||||
* @param beneficiary Address performing the token purchase
|
||||
* @param tokenAmount Number of tokens to be emitted
|
||||
*/
|
||||
function _deliverTokens(
|
||||
address beneficiary,
|
||||
uint256 tokenAmount
|
||||
)
|
||||
internal
|
||||
{
|
||||
_token.safeTransfer(beneficiary, tokenAmount);
|
||||
}
|
||||
/**
|
||||
* @dev Override for extensions that require an internal state to check for validity (current user contributions,
|
||||
* etc.)
|
||||
* @param beneficiary Address receiving the tokens
|
||||
* @param weiAmount Value in wei involved in the purchase
|
||||
*/
|
||||
function _updatePurchasingState(address beneficiary, uint256 weiAmount) internal {
|
||||
// solhint-disable-previous-line no-empty-blocks
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Executed when a purchase has been validated and is ready to be executed. Doesn't necessarily emit/send tokens.
|
||||
* @param beneficiary Address receiving the tokens
|
||||
* @param tokenAmount Number of tokens to be purchased
|
||||
*/
|
||||
function _processPurchase(
|
||||
address beneficiary,
|
||||
uint256 tokenAmount
|
||||
)
|
||||
internal
|
||||
{
|
||||
_deliverTokens(beneficiary, tokenAmount);
|
||||
}
|
||||
/**
|
||||
* @dev Override to extend the way in which ether is converted to tokens.
|
||||
* @param weiAmount Value in wei to be converted into tokens
|
||||
* @return Number of tokens that can be purchased with the specified _weiAmount
|
||||
*/
|
||||
function _getTokenAmount(uint256 weiAmount) internal view returns (uint256) {
|
||||
return weiAmount.mul(_rate);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Override for extensions that require an internal state to check for validity (current user contributions, etc.)
|
||||
* @param beneficiary Address receiving the tokens
|
||||
* @param weiAmount Value in wei involved in the purchase
|
||||
*/
|
||||
function _updatePurchasingState(
|
||||
address beneficiary,
|
||||
uint256 weiAmount
|
||||
)
|
||||
internal
|
||||
{
|
||||
// optional override
|
||||
}
|
||||
/**
|
||||
* @dev Determines how ETH is stored/forwarded on purchases.
|
||||
*/
|
||||
function _forwardFunds() internal {
|
||||
_wallet.transfer(msg.value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Override to extend the way in which ether is converted to tokens.
|
||||
* @param weiAmount Value in wei to be converted into tokens
|
||||
* @return Number of tokens that can be purchased with the specified _weiAmount
|
||||
*/
|
||||
function _getTokenAmount(uint256 weiAmount)
|
||||
internal view returns (uint256)
|
||||
{
|
||||
return weiAmount.mul(_rate);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Determines how ETH is stored/forwarded on purchases.
|
||||
*/
|
||||
function _forwardFunds() internal {
|
||||
_wallet.transfer(msg.value);
|
||||
}
|
||||
uint256[50] private ______gap;
|
||||
}
|
||||
|
||||
@ -1,50 +1,50 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.2;
|
||||
|
||||
import "@openzeppelin/upgrades/contracts/Initializable.sol";
|
||||
import "../../math/SafeMath.sol";
|
||||
import "../validation/TimedCrowdsale.sol";
|
||||
|
||||
/**
|
||||
* @title FinalizableCrowdsale
|
||||
* @dev Extension of Crowdsale with a one-off finalization action, where one
|
||||
* @dev Extension of TimedCrowdsale with a one-off finalization action, where one
|
||||
* can do extra work after finishing.
|
||||
*/
|
||||
contract FinalizableCrowdsale is TimedCrowdsale {
|
||||
using SafeMath for uint256;
|
||||
contract FinalizableCrowdsale is Initializable, TimedCrowdsale {
|
||||
using SafeMath for uint256;
|
||||
|
||||
bool private _finalized;
|
||||
bool private _finalized;
|
||||
|
||||
event CrowdsaleFinalized();
|
||||
event CrowdsaleFinalized();
|
||||
|
||||
constructor() internal {
|
||||
_finalized = false;
|
||||
}
|
||||
/**
|
||||
* @return true if the crowdsale is finalized, false otherwise.
|
||||
*/
|
||||
function finalized() public view returns (bool) {
|
||||
return _finalized;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if the crowdsale is finalized, false otherwise.
|
||||
*/
|
||||
function finalized() public view returns (bool) {
|
||||
return _finalized;
|
||||
}
|
||||
/**
|
||||
* @dev Must be called after crowdsale ends, to do some extra finalization
|
||||
* work. Calls the contract's finalization function.
|
||||
*/
|
||||
function finalize() public {
|
||||
require(!_finalized);
|
||||
require(hasClosed());
|
||||
|
||||
/**
|
||||
* @dev Must be called after crowdsale ends, to do some extra finalization
|
||||
* work. Calls the contract's finalization function.
|
||||
*/
|
||||
function finalize() public {
|
||||
require(!_finalized);
|
||||
require(hasClosed());
|
||||
_finalized = true;
|
||||
|
||||
_finalized = true;
|
||||
_finalization();
|
||||
emit CrowdsaleFinalized();
|
||||
}
|
||||
|
||||
_finalization();
|
||||
emit CrowdsaleFinalized();
|
||||
}
|
||||
/**
|
||||
* @dev Can be overridden to add finalization logic. The overriding function
|
||||
* should call super._finalization() to ensure the chain of finalization is
|
||||
* executed entirely.
|
||||
*/
|
||||
function _finalization() internal {
|
||||
// solhint-disable-previous-line no-empty-blocks
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Can be overridden to add finalization logic. The overriding function
|
||||
* should call super._finalization() to ensure the chain of finalization is
|
||||
* executed entirely.
|
||||
*/
|
||||
function _finalization() internal {
|
||||
}
|
||||
uint256[50] private ______gap;
|
||||
}
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.2;
|
||||
|
||||
import "@openzeppelin/upgrades/contracts/Initializable.sol";
|
||||
import "../validation/TimedCrowdsale.sol";
|
||||
import "../../math/SafeMath.sol";
|
||||
|
||||
@ -7,44 +8,38 @@ import "../../math/SafeMath.sol";
|
||||
* @title PostDeliveryCrowdsale
|
||||
* @dev Crowdsale that locks tokens from withdrawal until it ends.
|
||||
*/
|
||||
contract PostDeliveryCrowdsale is TimedCrowdsale {
|
||||
using SafeMath for uint256;
|
||||
contract PostDeliveryCrowdsale is Initializable, TimedCrowdsale {
|
||||
using SafeMath for uint256;
|
||||
|
||||
mapping(address => uint256) private _balances;
|
||||
mapping(address => uint256) private _balances;
|
||||
|
||||
constructor() internal {}
|
||||
/**
|
||||
* @dev Withdraw tokens only after crowdsale ends.
|
||||
* @param beneficiary Whose tokens will be withdrawn.
|
||||
*/
|
||||
function withdrawTokens(address beneficiary) public {
|
||||
require(hasClosed());
|
||||
uint256 amount = _balances[beneficiary];
|
||||
require(amount > 0);
|
||||
_balances[beneficiary] = 0;
|
||||
_deliverTokens(beneficiary, amount);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Withdraw tokens only after crowdsale ends.
|
||||
* @param beneficiary Whose tokens will be withdrawn.
|
||||
*/
|
||||
function withdrawTokens(address beneficiary) public {
|
||||
require(hasClosed());
|
||||
uint256 amount = _balances[beneficiary];
|
||||
require(amount > 0);
|
||||
_balances[beneficiary] = 0;
|
||||
_deliverTokens(beneficiary, amount);
|
||||
}
|
||||
/**
|
||||
* @return the balance of an account.
|
||||
*/
|
||||
function balanceOf(address account) public view returns (uint256) {
|
||||
return _balances[account];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the balance of an account.
|
||||
*/
|
||||
function balanceOf(address account) public view returns(uint256) {
|
||||
return _balances[account];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Overrides parent by storing balances instead of issuing tokens right away.
|
||||
* @param beneficiary Token purchaser
|
||||
* @param tokenAmount Amount of tokens purchased
|
||||
*/
|
||||
function _processPurchase(
|
||||
address beneficiary,
|
||||
uint256 tokenAmount
|
||||
)
|
||||
internal
|
||||
{
|
||||
_balances[beneficiary] = _balances[beneficiary].add(tokenAmount);
|
||||
}
|
||||
/**
|
||||
* @dev Overrides parent by storing balances instead of issuing tokens right away.
|
||||
* @param beneficiary Token purchaser
|
||||
* @param tokenAmount Amount of tokens purchased
|
||||
*/
|
||||
function _processPurchase(address beneficiary, uint256 tokenAmount) internal {
|
||||
_balances[beneficiary] = _balances[beneficiary].add(tokenAmount);
|
||||
}
|
||||
|
||||
uint256[50] private ______gap;
|
||||
}
|
||||
|
||||
@ -1,91 +1,92 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.2;
|
||||
|
||||
import "@openzeppelin/upgrades/contracts/Initializable.sol";
|
||||
import "../../math/SafeMath.sol";
|
||||
import "./FinalizableCrowdsale.sol";
|
||||
import "../../payment/escrow/RefundEscrow.sol";
|
||||
|
||||
/**
|
||||
* @title RefundableCrowdsale
|
||||
* @dev Extension of Crowdsale contract that adds a funding goal, and
|
||||
* the possibility of users getting a refund if goal is not met.
|
||||
* WARNING: note that if you allow tokens to be traded before the goal
|
||||
* is met, then an attack is possible in which the attacker purchases
|
||||
* tokens from the crowdsale and when they sees that the goal is
|
||||
* unlikely to be met, they sell their tokens (possibly at a discount).
|
||||
* The attacker will be refunded when the crowdsale is finalized, and
|
||||
* the users that purchased from them will be left with worthless
|
||||
* tokens. There are many possible ways to avoid this, like making the
|
||||
* the crowdsale inherit from PostDeliveryCrowdsale, or imposing
|
||||
* restrictions on token trading until the crowdsale is finalized.
|
||||
* This is being discussed in
|
||||
* https://github.com/OpenZeppelin/openzeppelin-solidity/issues/877
|
||||
* This contract will be updated when we agree on a general solution
|
||||
* for this problem.
|
||||
* @dev Extension of FinalizableCrowdsale contract that adds a funding goal, and the possibility of users
|
||||
* getting a refund if goal is not met.
|
||||
*
|
||||
* Deprecated, use RefundablePostDeliveryCrowdsale instead. Note that if you allow tokens to be traded before the goal
|
||||
* is met, then an attack is possible in which the attacker purchases tokens from the crowdsale and when they sees that
|
||||
* the goal is unlikely to be met, they sell their tokens (possibly at a discount). The attacker will be refunded when
|
||||
* the crowdsale is finalized, and the users that purchased from them will be left with worthless tokens.
|
||||
*/
|
||||
contract RefundableCrowdsale is FinalizableCrowdsale {
|
||||
using SafeMath for uint256;
|
||||
contract RefundableCrowdsale is Initializable, FinalizableCrowdsale {
|
||||
using SafeMath for uint256;
|
||||
|
||||
// minimum amount of funds to be raised in weis
|
||||
uint256 private _goal;
|
||||
// minimum amount of funds to be raised in weis
|
||||
uint256 private _goal;
|
||||
|
||||
// refund escrow used to hold funds while crowdsale is running
|
||||
RefundEscrow private _escrow;
|
||||
// refund escrow used to hold funds while crowdsale is running
|
||||
RefundEscrow private _escrow;
|
||||
|
||||
/**
|
||||
* @dev Constructor, creates RefundEscrow.
|
||||
* @param goal Funding goal
|
||||
*/
|
||||
constructor(uint256 goal) internal {
|
||||
require(goal > 0);
|
||||
_escrow = new RefundEscrow(wallet());
|
||||
_goal = goal;
|
||||
}
|
||||
/**
|
||||
* @dev Constructor, creates RefundEscrow.
|
||||
* @param goal Funding goal
|
||||
*/
|
||||
function initialize(uint256 goal) public initializer {
|
||||
// FinalizableCrowdsale depends on TimedCrowdsale
|
||||
assert(TimedCrowdsale._hasBeenInitialized());
|
||||
|
||||
/**
|
||||
* @return minimum amount of funds to be raised in wei.
|
||||
*/
|
||||
function goal() public view returns(uint256) {
|
||||
return _goal;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Investors can claim refunds here if crowdsale is unsuccessful
|
||||
* @param beneficiary Whose refund will be claimed.
|
||||
*/
|
||||
function claimRefund(address beneficiary) public {
|
||||
require(finalized());
|
||||
require(!goalReached());
|
||||
|
||||
_escrow.withdraw(beneficiary);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Checks whether funding goal was reached.
|
||||
* @return Whether funding goal was reached
|
||||
*/
|
||||
function goalReached() public view returns (bool) {
|
||||
return weiRaised() >= _goal;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev escrow finalization task, called when finalize() is called
|
||||
*/
|
||||
function _finalization() internal {
|
||||
if (goalReached()) {
|
||||
_escrow.close();
|
||||
_escrow.beneficiaryWithdraw();
|
||||
} else {
|
||||
_escrow.enableRefunds();
|
||||
require(goal > 0);
|
||||
// conditional added to make initializer idempotent in case of diamond inheritance
|
||||
if (address(_escrow) == address(0)) {
|
||||
_escrow = new RefundEscrow();
|
||||
_escrow.initialize(wallet(), address(this));
|
||||
}
|
||||
_goal = goal;
|
||||
}
|
||||
|
||||
super._finalization();
|
||||
}
|
||||
/**
|
||||
* @return minimum amount of funds to be raised in wei.
|
||||
*/
|
||||
function goal() public view returns (uint256) {
|
||||
return _goal;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Overrides Crowdsale fund forwarding, sending funds to escrow.
|
||||
*/
|
||||
function _forwardFunds() internal {
|
||||
_escrow.deposit.value(msg.value)(msg.sender);
|
||||
}
|
||||
/**
|
||||
* @dev Investors can claim refunds here if crowdsale is unsuccessful
|
||||
* @param refundee Whose refund will be claimed.
|
||||
*/
|
||||
function claimRefund(address payable refundee) public {
|
||||
require(finalized());
|
||||
require(!goalReached());
|
||||
|
||||
_escrow.withdraw(refundee);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Checks whether funding goal was reached.
|
||||
* @return Whether funding goal was reached
|
||||
*/
|
||||
function goalReached() public view returns (bool) {
|
||||
return weiRaised() >= _goal;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev escrow finalization task, called when finalize() is called
|
||||
*/
|
||||
function _finalization() internal {
|
||||
if (goalReached()) {
|
||||
_escrow.close();
|
||||
_escrow.beneficiaryWithdraw();
|
||||
} else {
|
||||
_escrow.enableRefunds();
|
||||
}
|
||||
|
||||
super._finalization();
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Overrides Crowdsale fund forwarding, sending funds to escrow.
|
||||
*/
|
||||
function _forwardFunds() internal {
|
||||
_escrow.deposit.value(msg.value)(msg.sender);
|
||||
}
|
||||
|
||||
uint256[50] private ______gap;
|
||||
}
|
||||
|
||||
@ -0,0 +1,23 @@
|
||||
pragma solidity ^0.5.2;
|
||||
|
||||
import "@openzeppelin/upgrades/contracts/Initializable.sol";
|
||||
|
||||
import "./RefundableCrowdsale.sol";
|
||||
import "./PostDeliveryCrowdsale.sol";
|
||||
|
||||
/**
|
||||
* @title RefundablePostDeliveryCrowdsale
|
||||
* @dev Extension of RefundableCrowdsale contract that only delivers the tokens
|
||||
* once the crowdsale has closed and the goal met, preventing refunds to be issued
|
||||
* to token holders.
|
||||
*/
|
||||
contract RefundablePostDeliveryCrowdsale is Initializable, RefundableCrowdsale, PostDeliveryCrowdsale {
|
||||
function withdrawTokens(address beneficiary) public {
|
||||
require(finalized());
|
||||
require(goalReached());
|
||||
|
||||
super.withdrawTokens(beneficiary);
|
||||
}
|
||||
|
||||
uint256[50] private ______gap;
|
||||
}
|
||||
@ -1,5 +1,6 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.2;
|
||||
|
||||
import "@openzeppelin/upgrades/contracts/Initializable.sol";
|
||||
import "../Crowdsale.sol";
|
||||
import "../../token/ERC20/IERC20.sol";
|
||||
import "../../token/ERC20/SafeERC20.sol";
|
||||
@ -10,50 +11,46 @@ import "../../math/Math.sol";
|
||||
* @title AllowanceCrowdsale
|
||||
* @dev Extension of Crowdsale where tokens are held by a wallet, which approves an allowance to the crowdsale.
|
||||
*/
|
||||
contract AllowanceCrowdsale is Crowdsale {
|
||||
using SafeMath for uint256;
|
||||
using SafeERC20 for IERC20;
|
||||
contract AllowanceCrowdsale is Initializable, Crowdsale {
|
||||
using SafeMath for uint256;
|
||||
using SafeERC20 for IERC20;
|
||||
|
||||
address private _tokenWallet;
|
||||
address private _tokenWallet;
|
||||
|
||||
/**
|
||||
* @dev Constructor, takes token wallet address.
|
||||
* @param tokenWallet Address holding the tokens, which has approved allowance to the crowdsale
|
||||
*/
|
||||
constructor(address tokenWallet) internal {
|
||||
require(tokenWallet != address(0));
|
||||
_tokenWallet = tokenWallet;
|
||||
}
|
||||
/**
|
||||
* @dev Constructor, takes token wallet address.
|
||||
* @param tokenWallet Address holding the tokens, which has approved allowance to the crowdsale
|
||||
*/
|
||||
function initialize(address tokenWallet) public initializer {
|
||||
assert(Crowdsale._hasBeenInitialized());
|
||||
|
||||
/**
|
||||
* @return the address of the wallet that will hold the tokens.
|
||||
*/
|
||||
function tokenWallet() public view returns(address) {
|
||||
return _tokenWallet;
|
||||
}
|
||||
require(tokenWallet != address(0));
|
||||
_tokenWallet = tokenWallet;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Checks the amount of tokens left in the allowance.
|
||||
* @return Amount of tokens left in the allowance
|
||||
*/
|
||||
function remainingTokens() public view returns (uint256) {
|
||||
return Math.min(
|
||||
token().balanceOf(_tokenWallet),
|
||||
token().allowance(_tokenWallet, this)
|
||||
);
|
||||
}
|
||||
/**
|
||||
* @return the address of the wallet that will hold the tokens.
|
||||
*/
|
||||
function tokenWallet() public view returns (address) {
|
||||
return _tokenWallet;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Overrides parent behavior by transferring tokens from wallet.
|
||||
* @param beneficiary Token purchaser
|
||||
* @param tokenAmount Amount of tokens purchased
|
||||
*/
|
||||
function _deliverTokens(
|
||||
address beneficiary,
|
||||
uint256 tokenAmount
|
||||
)
|
||||
internal
|
||||
{
|
||||
token().safeTransferFrom(_tokenWallet, beneficiary, tokenAmount);
|
||||
}
|
||||
/**
|
||||
* @dev Checks the amount of tokens left in the allowance.
|
||||
* @return Amount of tokens left in the allowance
|
||||
*/
|
||||
function remainingTokens() public view returns (uint256) {
|
||||
return Math.min(token().balanceOf(_tokenWallet), token().allowance(_tokenWallet, address(this)));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Overrides parent behavior by transferring tokens from wallet.
|
||||
* @param beneficiary Token purchaser
|
||||
* @param tokenAmount Amount of tokens purchased
|
||||
*/
|
||||
function _deliverTokens(address beneficiary, uint256 tokenAmount) internal {
|
||||
token().safeTransferFrom(_tokenWallet, beneficiary, tokenAmount);
|
||||
}
|
||||
|
||||
uint256[50] private ______gap;
|
||||
}
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.2;
|
||||
|
||||
import "@openzeppelin/upgrades/contracts/Initializable.sol";
|
||||
import "../Crowdsale.sol";
|
||||
import "../../token/ERC20/ERC20Mintable.sol";
|
||||
|
||||
@ -8,22 +9,16 @@ import "../../token/ERC20/ERC20Mintable.sol";
|
||||
* @dev Extension of Crowdsale contract whose tokens are minted in each purchase.
|
||||
* Token ownership should be transferred to MintedCrowdsale for minting.
|
||||
*/
|
||||
contract MintedCrowdsale is Crowdsale {
|
||||
constructor() internal {}
|
||||
contract MintedCrowdsale is Initializable, Crowdsale {
|
||||
/**
|
||||
* @dev Overrides delivery by minting tokens upon purchase.
|
||||
* @param beneficiary Token purchaser
|
||||
* @param tokenAmount Number of tokens to be minted
|
||||
*/
|
||||
function _deliverTokens(address beneficiary, uint256 tokenAmount) internal {
|
||||
// Potentially dangerous assumption about the type of the token.
|
||||
require(ERC20Mintable(address(token())).mint(beneficiary, tokenAmount));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Overrides delivery by minting tokens upon purchase.
|
||||
* @param beneficiary Token purchaser
|
||||
* @param tokenAmount Number of tokens to be minted
|
||||
*/
|
||||
function _deliverTokens(
|
||||
address beneficiary,
|
||||
uint256 tokenAmount
|
||||
)
|
||||
internal
|
||||
{
|
||||
// Potentially dangerous assumption about the type of the token.
|
||||
require(
|
||||
ERC20Mintable(address(token())).mint(beneficiary, tokenAmount));
|
||||
}
|
||||
uint256[50] private ______gap;
|
||||
}
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.2;
|
||||
|
||||
import "@openzeppelin/upgrades/contracts/Initializable.sol";
|
||||
import "../validation/TimedCrowdsale.sol";
|
||||
import "../../math/SafeMath.sol";
|
||||
|
||||
@ -9,73 +10,74 @@ import "../../math/SafeMath.sol";
|
||||
* Note that what should be provided to the constructor is the initial and final _rates_, that is,
|
||||
* the amount of tokens per wei contributed. Thus, the initial rate must be greater than the final rate.
|
||||
*/
|
||||
contract IncreasingPriceCrowdsale is TimedCrowdsale {
|
||||
using SafeMath for uint256;
|
||||
contract IncreasingPriceCrowdsale is Initializable, TimedCrowdsale {
|
||||
using SafeMath for uint256;
|
||||
|
||||
uint256 private _initialRate;
|
||||
uint256 private _finalRate;
|
||||
uint256 private _initialRate;
|
||||
uint256 private _finalRate;
|
||||
|
||||
/**
|
||||
* @dev Constructor, takes initial and final rates of tokens received per wei contributed.
|
||||
* @param initialRate Number of tokens a buyer gets per wei at the start of the crowdsale
|
||||
* @param finalRate Number of tokens a buyer gets per wei at the end of the crowdsale
|
||||
*/
|
||||
constructor(uint256 initialRate, uint256 finalRate) internal {
|
||||
require(finalRate > 0);
|
||||
require(initialRate > finalRate);
|
||||
_initialRate = initialRate;
|
||||
_finalRate = finalRate;
|
||||
}
|
||||
/**
|
||||
* @dev Constructor, takes initial and final rates of tokens received per wei contributed.
|
||||
* @param initialRate Number of tokens a buyer gets per wei at the start of the crowdsale
|
||||
* @param finalRate Number of tokens a buyer gets per wei at the end of the crowdsale
|
||||
*/
|
||||
function initialize(uint256 initialRate, uint256 finalRate) public initializer {
|
||||
assert(TimedCrowdsale._hasBeenInitialized());
|
||||
|
||||
/**
|
||||
* The base rate function is overridden to revert, since this crowdsale doens't use it, and
|
||||
* all calls to it are a mistake.
|
||||
*/
|
||||
function rate() public view returns(uint256) {
|
||||
revert();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the initial rate of the crowdsale.
|
||||
*/
|
||||
function initialRate() public view returns(uint256) {
|
||||
return _initialRate;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the final rate of the crowdsale.
|
||||
*/
|
||||
function finalRate() public view returns (uint256) {
|
||||
return _finalRate;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Returns the rate of tokens per wei at the present time.
|
||||
* Note that, as price _increases_ with time, the rate _decreases_.
|
||||
* @return The number of tokens a buyer gets per wei at a given time
|
||||
*/
|
||||
function getCurrentRate() public view returns (uint256) {
|
||||
if (!isOpen()) {
|
||||
return 0;
|
||||
require(finalRate > 0);
|
||||
require(initialRate > finalRate);
|
||||
_initialRate = initialRate;
|
||||
_finalRate = finalRate;
|
||||
}
|
||||
|
||||
// solium-disable-next-line security/no-block-members
|
||||
uint256 elapsedTime = block.timestamp.sub(openingTime());
|
||||
uint256 timeRange = closingTime().sub(openingTime());
|
||||
uint256 rateRange = _initialRate.sub(_finalRate);
|
||||
return _initialRate.sub(elapsedTime.mul(rateRange).div(timeRange));
|
||||
}
|
||||
/**
|
||||
* The base rate function is overridden to revert, since this crowdsale doesn't use it, and
|
||||
* all calls to it are a mistake.
|
||||
*/
|
||||
function rate() public view returns (uint256) {
|
||||
revert();
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Overrides parent method taking into account variable rate.
|
||||
* @param weiAmount The value in wei to be converted into tokens
|
||||
* @return The number of tokens _weiAmount wei will buy at present time
|
||||
*/
|
||||
function _getTokenAmount(uint256 weiAmount)
|
||||
internal view returns (uint256)
|
||||
{
|
||||
uint256 currentRate = getCurrentRate();
|
||||
return currentRate.mul(weiAmount);
|
||||
}
|
||||
/**
|
||||
* @return the initial rate of the crowdsale.
|
||||
*/
|
||||
function initialRate() public view returns (uint256) {
|
||||
return _initialRate;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the final rate of the crowdsale.
|
||||
*/
|
||||
function finalRate() public view returns (uint256) {
|
||||
return _finalRate;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Returns the rate of tokens per wei at the present time.
|
||||
* Note that, as price _increases_ with time, the rate _decreases_.
|
||||
* @return The number of tokens a buyer gets per wei at a given time
|
||||
*/
|
||||
function getCurrentRate() public view returns (uint256) {
|
||||
if (!isOpen()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// solhint-disable-next-line not-rely-on-time
|
||||
uint256 elapsedTime = block.timestamp.sub(openingTime());
|
||||
uint256 timeRange = closingTime().sub(openingTime());
|
||||
uint256 rateRange = _initialRate.sub(_finalRate);
|
||||
return _initialRate.sub(elapsedTime.mul(rateRange).div(timeRange));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Overrides parent method taking into account variable rate.
|
||||
* @param weiAmount The value in wei to be converted into tokens
|
||||
* @return The number of tokens _weiAmount wei will buy at present time
|
||||
*/
|
||||
function _getTokenAmount(uint256 weiAmount) internal view returns (uint256) {
|
||||
uint256 currentRate = getCurrentRate();
|
||||
return currentRate.mul(weiAmount);
|
||||
}
|
||||
|
||||
uint256[50] private ______gap;
|
||||
}
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.2;
|
||||
|
||||
import "@openzeppelin/upgrades/contracts/Initializable.sol";
|
||||
import "../../math/SafeMath.sol";
|
||||
import "../Crowdsale.sol";
|
||||
|
||||
@ -7,49 +8,46 @@ import "../Crowdsale.sol";
|
||||
* @title CappedCrowdsale
|
||||
* @dev Crowdsale with a limit for total contributions.
|
||||
*/
|
||||
contract CappedCrowdsale is Crowdsale {
|
||||
using SafeMath for uint256;
|
||||
contract CappedCrowdsale is Initializable, Crowdsale {
|
||||
using SafeMath for uint256;
|
||||
|
||||
uint256 private _cap;
|
||||
uint256 private _cap;
|
||||
|
||||
/**
|
||||
* @dev Constructor, takes maximum amount of wei accepted in the crowdsale.
|
||||
* @param cap Max amount of wei to be contributed
|
||||
*/
|
||||
constructor(uint256 cap) internal {
|
||||
require(cap > 0);
|
||||
_cap = cap;
|
||||
}
|
||||
/**
|
||||
* @dev Constructor, takes maximum amount of wei accepted in the crowdsale.
|
||||
* @param cap Max amount of wei to be contributed
|
||||
*/
|
||||
function initialize(uint256 cap) public initializer {
|
||||
assert(Crowdsale._hasBeenInitialized());
|
||||
|
||||
/**
|
||||
* @return the cap of the crowdsale.
|
||||
*/
|
||||
function cap() public view returns(uint256) {
|
||||
return _cap;
|
||||
}
|
||||
require(cap > 0);
|
||||
_cap = cap;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Checks whether the cap has been reached.
|
||||
* @return Whether the cap was reached
|
||||
*/
|
||||
function capReached() public view returns (bool) {
|
||||
return weiRaised() >= _cap;
|
||||
}
|
||||
/**
|
||||
* @return the cap of the crowdsale.
|
||||
*/
|
||||
function cap() public view returns (uint256) {
|
||||
return _cap;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Extend parent behavior requiring purchase to respect the funding cap.
|
||||
* @param beneficiary Token purchaser
|
||||
* @param weiAmount Amount of wei contributed
|
||||
*/
|
||||
function _preValidatePurchase(
|
||||
address beneficiary,
|
||||
uint256 weiAmount
|
||||
)
|
||||
internal
|
||||
view
|
||||
{
|
||||
super._preValidatePurchase(beneficiary, weiAmount);
|
||||
require(weiRaised().add(weiAmount) <= _cap);
|
||||
}
|
||||
/**
|
||||
* @dev Checks whether the cap has been reached.
|
||||
* @return Whether the cap was reached
|
||||
*/
|
||||
function capReached() public view returns (bool) {
|
||||
return weiRaised() >= _cap;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Extend parent behavior requiring purchase to respect the funding cap.
|
||||
* @param beneficiary Token purchaser
|
||||
* @param weiAmount Amount of wei contributed
|
||||
*/
|
||||
function _preValidatePurchase(address beneficiary, uint256 weiAmount) internal view {
|
||||
super._preValidatePurchase(beneficiary, weiAmount);
|
||||
require(weiRaised().add(weiAmount) <= _cap);
|
||||
}
|
||||
|
||||
uint256[50] private ______gap;
|
||||
}
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.2;
|
||||
|
||||
import "@openzeppelin/upgrades/contracts/Initializable.sol";
|
||||
import "../../math/SafeMath.sol";
|
||||
import "../Crowdsale.sol";
|
||||
import "../../access/roles/CapperRole.sol";
|
||||
@ -8,74 +9,64 @@ import "../../access/roles/CapperRole.sol";
|
||||
* @title IndividuallyCappedCrowdsale
|
||||
* @dev Crowdsale with per-beneficiary caps.
|
||||
*/
|
||||
contract IndividuallyCappedCrowdsale is Crowdsale, CapperRole {
|
||||
using SafeMath for uint256;
|
||||
contract IndividuallyCappedCrowdsale is Initializable, Crowdsale, CapperRole {
|
||||
using SafeMath for uint256;
|
||||
|
||||
mapping(address => uint256) private _contributions;
|
||||
mapping(address => uint256) private _caps;
|
||||
mapping(address => uint256) private _contributions;
|
||||
mapping(address => uint256) private _caps;
|
||||
|
||||
constructor() internal {}
|
||||
function initialize(address sender) public initializer {
|
||||
assert(Crowdsale._hasBeenInitialized());
|
||||
|
||||
/**
|
||||
* @dev Sets a specific beneficiary's maximum contribution.
|
||||
* @param beneficiary Address to be capped
|
||||
* @param cap Wei limit for individual contribution
|
||||
*/
|
||||
function setCap(address beneficiary, uint256 cap) external onlyCapper {
|
||||
_caps[beneficiary] = cap;
|
||||
}
|
||||
CapperRole.initialize(sender);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Returns the cap of a specific beneficiary.
|
||||
* @param beneficiary Address whose cap is to be checked
|
||||
* @return Current cap for individual beneficiary
|
||||
*/
|
||||
function getCap(address beneficiary) public view returns (uint256) {
|
||||
return _caps[beneficiary];
|
||||
}
|
||||
/**
|
||||
* @dev Sets a specific beneficiary's maximum contribution.
|
||||
* @param beneficiary Address to be capped
|
||||
* @param cap Wei limit for individual contribution
|
||||
*/
|
||||
function setCap(address beneficiary, uint256 cap) external onlyCapper {
|
||||
_caps[beneficiary] = cap;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Returns the amount contributed so far by a specific beneficiary.
|
||||
* @param beneficiary Address of contributor
|
||||
* @return Beneficiary contribution so far
|
||||
*/
|
||||
function getContribution(address beneficiary)
|
||||
public view returns (uint256)
|
||||
{
|
||||
return _contributions[beneficiary];
|
||||
}
|
||||
/**
|
||||
* @dev Returns the cap of a specific beneficiary.
|
||||
* @param beneficiary Address whose cap is to be checked
|
||||
* @return Current cap for individual beneficiary
|
||||
*/
|
||||
function getCap(address beneficiary) public view returns (uint256) {
|
||||
return _caps[beneficiary];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Extend parent behavior requiring purchase to respect the beneficiary's funding cap.
|
||||
* @param beneficiary Token purchaser
|
||||
* @param weiAmount Amount of wei contributed
|
||||
*/
|
||||
function _preValidatePurchase(
|
||||
address beneficiary,
|
||||
uint256 weiAmount
|
||||
)
|
||||
internal
|
||||
view
|
||||
{
|
||||
super._preValidatePurchase(beneficiary, weiAmount);
|
||||
require(
|
||||
_contributions[beneficiary].add(weiAmount) <= _caps[beneficiary]);
|
||||
}
|
||||
/**
|
||||
* @dev Returns the amount contributed so far by a specific beneficiary.
|
||||
* @param beneficiary Address of contributor
|
||||
* @return Beneficiary contribution so far
|
||||
*/
|
||||
function getContribution(address beneficiary) public view returns (uint256) {
|
||||
return _contributions[beneficiary];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Extend parent behavior to update beneficiary contributions
|
||||
* @param beneficiary Token purchaser
|
||||
* @param weiAmount Amount of wei contributed
|
||||
*/
|
||||
function _updatePurchasingState(
|
||||
address beneficiary,
|
||||
uint256 weiAmount
|
||||
)
|
||||
internal
|
||||
{
|
||||
super._updatePurchasingState(beneficiary, weiAmount);
|
||||
_contributions[beneficiary] = _contributions[beneficiary].add(
|
||||
weiAmount);
|
||||
}
|
||||
/**
|
||||
* @dev Extend parent behavior requiring purchase to respect the beneficiary's funding cap.
|
||||
* @param beneficiary Token purchaser
|
||||
* @param weiAmount Amount of wei contributed
|
||||
*/
|
||||
function _preValidatePurchase(address beneficiary, uint256 weiAmount) internal view {
|
||||
super._preValidatePurchase(beneficiary, weiAmount);
|
||||
require(_contributions[beneficiary].add(weiAmount) <= _caps[beneficiary]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Extend parent behavior to update beneficiary contributions
|
||||
* @param beneficiary Token purchaser
|
||||
* @param weiAmount Amount of wei contributed
|
||||
*/
|
||||
function _updatePurchasingState(address beneficiary, uint256 weiAmount) internal {
|
||||
super._updatePurchasingState(beneficiary, weiAmount);
|
||||
_contributions[beneficiary] = _contributions[beneficiary].add(weiAmount);
|
||||
}
|
||||
|
||||
uint256[50] private ______gap;
|
||||
}
|
||||
|
||||
31
contracts/crowdsale/validation/PausableCrowdsale.sol
Normal file
31
contracts/crowdsale/validation/PausableCrowdsale.sol
Normal file
@ -0,0 +1,31 @@
|
||||
pragma solidity ^0.5.2;
|
||||
|
||||
import "@openzeppelin/upgrades/contracts/Initializable.sol";
|
||||
|
||||
import "../Crowdsale.sol";
|
||||
import "../../lifecycle/Pausable.sol";
|
||||
|
||||
/**
|
||||
* @title PausableCrowdsale
|
||||
* @dev Extension of Crowdsale contract where purchases can be paused and unpaused by the pauser role.
|
||||
*/
|
||||
contract PausableCrowdsale is Initializable, Crowdsale, Pausable {
|
||||
function initialize(address sender) public initializer {
|
||||
assert(Crowdsale._hasBeenInitialized());
|
||||
|
||||
Pausable.initialize(sender);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Validation of an incoming purchase. Use require statements to revert state when conditions are not met.
|
||||
* Use super to concatenate validations.
|
||||
* Adds the validation that the crowdsale must not be paused.
|
||||
* @param _beneficiary Address performing the token purchase
|
||||
* @param _weiAmount Value in wei involved in the purchase
|
||||
*/
|
||||
function _preValidatePurchase(address _beneficiary, uint256 _weiAmount) internal view whenNotPaused {
|
||||
return super._preValidatePurchase(_beneficiary, _weiAmount);
|
||||
}
|
||||
|
||||
uint256[50] private ______gap;
|
||||
}
|
||||
@ -1,5 +1,6 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.2;
|
||||
|
||||
import "@openzeppelin/upgrades/contracts/Initializable.sol";
|
||||
import "../../math/SafeMath.sol";
|
||||
import "../Crowdsale.sol";
|
||||
|
||||
@ -7,79 +8,98 @@ import "../Crowdsale.sol";
|
||||
* @title TimedCrowdsale
|
||||
* @dev Crowdsale accepting contributions only within a time frame.
|
||||
*/
|
||||
contract TimedCrowdsale is Crowdsale {
|
||||
using SafeMath for uint256;
|
||||
contract TimedCrowdsale is Initializable, Crowdsale {
|
||||
using SafeMath for uint256;
|
||||
|
||||
uint256 private _openingTime;
|
||||
uint256 private _closingTime;
|
||||
uint256 private _openingTime;
|
||||
uint256 private _closingTime;
|
||||
|
||||
/**
|
||||
* @dev Reverts if not in crowdsale time range.
|
||||
*/
|
||||
modifier onlyWhileOpen {
|
||||
require(isOpen());
|
||||
_;
|
||||
}
|
||||
/**
|
||||
* Event for crowdsale extending
|
||||
* @param newClosingTime new closing time
|
||||
* @param prevClosingTime old closing time
|
||||
*/
|
||||
event TimedCrowdsaleExtended(uint256 prevClosingTime, uint256 newClosingTime);
|
||||
|
||||
/**
|
||||
* @dev Constructor, takes crowdsale opening and closing times.
|
||||
* @param openingTime Crowdsale opening time
|
||||
* @param closingTime Crowdsale closing time
|
||||
*/
|
||||
constructor(uint256 openingTime, uint256 closingTime) internal {
|
||||
// solium-disable-next-line security/no-block-members
|
||||
require(openingTime >= block.timestamp);
|
||||
require(closingTime > openingTime);
|
||||
/**
|
||||
* @dev Reverts if not in crowdsale time range.
|
||||
*/
|
||||
modifier onlyWhileOpen {
|
||||
require(isOpen());
|
||||
_;
|
||||
}
|
||||
|
||||
_openingTime = openingTime;
|
||||
_closingTime = closingTime;
|
||||
}
|
||||
/**
|
||||
* @dev Constructor, takes crowdsale opening and closing times.
|
||||
* @param openingTime Crowdsale opening time
|
||||
* @param closingTime Crowdsale closing time
|
||||
*/
|
||||
function initialize(uint256 openingTime, uint256 closingTime) public initializer {
|
||||
assert(Crowdsale._hasBeenInitialized());
|
||||
|
||||
/**
|
||||
* @return the crowdsale opening time.
|
||||
*/
|
||||
function openingTime() public view returns(uint256) {
|
||||
return _openingTime;
|
||||
}
|
||||
// solhint-disable-next-line not-rely-on-time
|
||||
require(openingTime >= block.timestamp);
|
||||
require(closingTime > openingTime);
|
||||
|
||||
/**
|
||||
* @return the crowdsale closing time.
|
||||
*/
|
||||
function closingTime() public view returns(uint256) {
|
||||
return _closingTime;
|
||||
}
|
||||
_openingTime = openingTime;
|
||||
_closingTime = closingTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if the crowdsale is open, false otherwise.
|
||||
*/
|
||||
function isOpen() public view returns (bool) {
|
||||
// solium-disable-next-line security/no-block-members
|
||||
return block.timestamp >= _openingTime && block.timestamp <= _closingTime;
|
||||
}
|
||||
/**
|
||||
* @return the crowdsale opening time.
|
||||
*/
|
||||
function openingTime() public view returns (uint256) {
|
||||
return _openingTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Checks whether the period in which the crowdsale is open has already elapsed.
|
||||
* @return Whether crowdsale period has elapsed
|
||||
*/
|
||||
function hasClosed() public view returns (bool) {
|
||||
// solium-disable-next-line security/no-block-members
|
||||
return block.timestamp > _closingTime;
|
||||
}
|
||||
/**
|
||||
* @return the crowdsale closing time.
|
||||
*/
|
||||
function closingTime() public view returns (uint256) {
|
||||
return _closingTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Extend parent behavior requiring to be within contributing period
|
||||
* @param beneficiary Token purchaser
|
||||
* @param weiAmount Amount of wei contributed
|
||||
*/
|
||||
function _preValidatePurchase(
|
||||
address beneficiary,
|
||||
uint256 weiAmount
|
||||
)
|
||||
internal
|
||||
onlyWhileOpen
|
||||
view
|
||||
{
|
||||
super._preValidatePurchase(beneficiary, weiAmount);
|
||||
}
|
||||
/**
|
||||
* @return true if the crowdsale is open, false otherwise.
|
||||
*/
|
||||
function isOpen() public view returns (bool) {
|
||||
// solhint-disable-next-line not-rely-on-time
|
||||
return block.timestamp >= _openingTime && block.timestamp <= _closingTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Checks whether the period in which the crowdsale is open has already elapsed.
|
||||
* @return Whether crowdsale period has elapsed
|
||||
*/
|
||||
function hasClosed() public view returns (bool) {
|
||||
// solhint-disable-next-line not-rely-on-time
|
||||
return block.timestamp > _closingTime;
|
||||
}
|
||||
|
||||
function _hasBeenInitialized() internal view returns (bool) {
|
||||
return ((_openingTime > 0) && (_closingTime > 0));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Extend parent behavior requiring to be within contributing period
|
||||
* @param beneficiary Token purchaser
|
||||
* @param weiAmount Amount of wei contributed
|
||||
*/
|
||||
function _preValidatePurchase(address beneficiary, uint256 weiAmount) internal onlyWhileOpen view {
|
||||
super._preValidatePurchase(beneficiary, weiAmount);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Extend crowdsale
|
||||
* @param newClosingTime Crowdsale closing time
|
||||
*/
|
||||
function _extendTime(uint256 newClosingTime) internal {
|
||||
require(!hasClosed());
|
||||
require(newClosingTime > _closingTime);
|
||||
|
||||
emit TimedCrowdsaleExtended(_closingTime, newClosingTime);
|
||||
_closingTime = newClosingTime;
|
||||
}
|
||||
|
||||
uint256[50] private ______gap;
|
||||
}
|
||||
|
||||
29
contracts/crowdsale/validation/WhitelistCrowdsale.sol
Normal file
29
contracts/crowdsale/validation/WhitelistCrowdsale.sol
Normal file
@ -0,0 +1,29 @@
|
||||
pragma solidity ^0.5.2;
|
||||
import "../Crowdsale.sol";
|
||||
import "../../access/roles/WhitelistedRole.sol";
|
||||
|
||||
|
||||
/**
|
||||
* @title WhitelistCrowdsale
|
||||
* @dev Crowdsale in which only whitelisted users can contribute.
|
||||
*/
|
||||
contract WhitelistCrowdsale is Initializable, WhitelistedRole, Crowdsale {
|
||||
function initialize(address sender) public initializer {
|
||||
WhitelistedRole.initialize(sender);
|
||||
|
||||
assert(Crowdsale._hasBeenInitialized());
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Extend parent behavior requiring beneficiary to be whitelisted. Note that no
|
||||
* restriction is imposed on the account sending the transaction.
|
||||
* @param _beneficiary Token beneficiary
|
||||
* @param _weiAmount Amount of wei contributed
|
||||
*/
|
||||
function _preValidatePurchase(address _beneficiary, uint256 _weiAmount) internal view {
|
||||
require(isWhitelisted(_beneficiary));
|
||||
super._preValidatePurchase(_beneficiary, _weiAmount);
|
||||
}
|
||||
|
||||
uint256[50] private ______gap;
|
||||
}
|
||||
@ -1,4 +1,4 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.2;
|
||||
|
||||
/**
|
||||
* @title Elliptic curve signature operations
|
||||
@ -8,64 +8,60 @@ pragma solidity ^0.4.24;
|
||||
*/
|
||||
|
||||
library ECDSA {
|
||||
/**
|
||||
* @dev Recover signer address from a message by using their signature
|
||||
* @param hash bytes32 message, the hash is the signed message. What is recovered is the signer address.
|
||||
* @param signature bytes signature, the signature is generated using web3.eth.sign()
|
||||
*/
|
||||
function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {
|
||||
// Check the signature length
|
||||
if (signature.length != 65) {
|
||||
return (address(0));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Recover signer address from a message by using their signature
|
||||
* @param hash bytes32 message, the hash is the signed message. What is recovered is the signer address.
|
||||
* @param signature bytes signature, the signature is generated using web3.eth.sign()
|
||||
*/
|
||||
function recover(bytes32 hash, bytes signature)
|
||||
internal
|
||||
pure
|
||||
returns (address)
|
||||
{
|
||||
bytes32 r;
|
||||
bytes32 s;
|
||||
uint8 v;
|
||||
// Divide the signature in r, s and v variables
|
||||
bytes32 r;
|
||||
bytes32 s;
|
||||
uint8 v;
|
||||
|
||||
// Check the signature length
|
||||
if (signature.length != 65) {
|
||||
return (address(0));
|
||||
// ecrecover takes the signature parameters, and the only way to get them
|
||||
// currently is to use assembly.
|
||||
// solhint-disable-next-line no-inline-assembly
|
||||
assembly {
|
||||
r := mload(add(signature, 0x20))
|
||||
s := mload(add(signature, 0x40))
|
||||
v := byte(0, mload(add(signature, 0x60)))
|
||||
}
|
||||
|
||||
// EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature
|
||||
// unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines
|
||||
// the valid range for s in (281): 0 < s < secp256k1n ÷ 2 + 1, and for v in (282): v ∈ {27, 28}. Most
|
||||
// signatures from current libraries generate a unique signature with an s-value in the lower half order.
|
||||
//
|
||||
// If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value
|
||||
// with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or
|
||||
// vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept
|
||||
// these malleable signatures as well.
|
||||
if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {
|
||||
return address(0);
|
||||
}
|
||||
|
||||
if (v != 27 && v != 28) {
|
||||
return address(0);
|
||||
}
|
||||
|
||||
// If the signature is valid (and not malleable), return the signer address
|
||||
return ecrecover(hash, v, r, s);
|
||||
}
|
||||
|
||||
// Divide the signature in r, s and v variables
|
||||
// ecrecover takes the signature parameters, and the only way to get them
|
||||
// currently is to use assembly.
|
||||
// solium-disable-next-line security/no-inline-assembly
|
||||
assembly {
|
||||
r := mload(add(signature, 0x20))
|
||||
s := mload(add(signature, 0x40))
|
||||
v := byte(0, mload(add(signature, 0x60)))
|
||||
/**
|
||||
* toEthSignedMessageHash
|
||||
* @dev prefix a bytes32 value with "\x19Ethereum Signed Message:"
|
||||
* and hash the result
|
||||
*/
|
||||
function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {
|
||||
// 32 is the length in bytes of hash,
|
||||
// enforced by the type signature above
|
||||
return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash));
|
||||
}
|
||||
|
||||
// Version of signature should be 27 or 28, but 0 and 1 are also possible versions
|
||||
if (v < 27) {
|
||||
v += 27;
|
||||
}
|
||||
|
||||
// If the version is correct return the signer address
|
||||
if (v != 27 && v != 28) {
|
||||
return (address(0));
|
||||
} else {
|
||||
// solium-disable-next-line arg-overflow
|
||||
return ecrecover(hash, v, r, s);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* toEthSignedMessageHash
|
||||
* @dev prefix a bytes32 value with "\x19Ethereum Signed Message:"
|
||||
* and hash the result
|
||||
*/
|
||||
function toEthSignedMessageHash(bytes32 hash)
|
||||
internal
|
||||
pure
|
||||
returns (bytes32)
|
||||
{
|
||||
// 32 is the length in bytes of hash,
|
||||
// enforced by the type signature above
|
||||
return keccak256(
|
||||
abi.encodePacked("\x19Ethereum Signed Message:\n32", hash)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.2;
|
||||
|
||||
/**
|
||||
* @title MerkleProof
|
||||
@ -6,37 +6,29 @@ pragma solidity ^0.4.24;
|
||||
* https://github.com/ameensol/merkle-tree-solidity/blob/master/src/MerkleProof.sol
|
||||
*/
|
||||
library MerkleProof {
|
||||
/**
|
||||
* @dev Verifies a Merkle proof proving the existence of a leaf in a Merkle tree. Assumes that each pair of leaves
|
||||
* and each pair of pre-images are sorted.
|
||||
* @param proof Merkle proof containing sibling hashes on the branch from the leaf to the root of the Merkle tree
|
||||
* @param root Merkle root
|
||||
* @param leaf Leaf of Merkle tree
|
||||
*/
|
||||
function verify(
|
||||
bytes32[] proof,
|
||||
bytes32 root,
|
||||
bytes32 leaf
|
||||
)
|
||||
internal
|
||||
pure
|
||||
returns (bool)
|
||||
{
|
||||
bytes32 computedHash = leaf;
|
||||
/**
|
||||
* @dev Verifies a Merkle proof proving the existence of a leaf in a Merkle tree. Assumes that each pair of leaves
|
||||
* and each pair of pre-images are sorted.
|
||||
* @param proof Merkle proof containing sibling hashes on the branch from the leaf to the root of the Merkle tree
|
||||
* @param root Merkle root
|
||||
* @param leaf Leaf of Merkle tree
|
||||
*/
|
||||
function verify(bytes32[] memory proof, bytes32 root, bytes32 leaf) internal pure returns (bool) {
|
||||
bytes32 computedHash = leaf;
|
||||
|
||||
for (uint256 i = 0; i < proof.length; i++) {
|
||||
bytes32 proofElement = proof[i];
|
||||
for (uint256 i = 0; i < proof.length; i++) {
|
||||
bytes32 proofElement = proof[i];
|
||||
|
||||
if (computedHash < proofElement) {
|
||||
// Hash(current computed hash + current element of the proof)
|
||||
computedHash = keccak256(abi.encodePacked(computedHash, proofElement));
|
||||
} else {
|
||||
// Hash(current element of the proof + current computed hash)
|
||||
computedHash = keccak256(abi.encodePacked(proofElement, computedHash));
|
||||
}
|
||||
if (computedHash < proofElement) {
|
||||
// Hash(current computed hash + current element of the proof)
|
||||
computedHash = keccak256(abi.encodePacked(computedHash, proofElement));
|
||||
} else {
|
||||
// Hash(current element of the proof + current computed hash)
|
||||
computedHash = keccak256(abi.encodePacked(proofElement, computedHash));
|
||||
}
|
||||
}
|
||||
|
||||
// Check if the computed hash (root) is equal to the provided root
|
||||
return computedHash == root;
|
||||
}
|
||||
|
||||
// Check if the computed hash (root) is equal to the provided root
|
||||
return computedHash == root;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,28 +0,0 @@
|
||||
pragma solidity ^0.4.24;
|
||||
|
||||
/**
|
||||
* @title Counter
|
||||
* @author Matt Condon (@shrugs)
|
||||
* @dev Provides an incrementing uint256 id acquired by the `Counter#next` getter.
|
||||
* Use this for issuing ERC721 ids or keeping track of request ids, anything you want, really.
|
||||
*
|
||||
* Include with `using Counter for Counter.Counter;`
|
||||
* @notice Does not allow an Id of 0, which is popularly used to signify a null state in solidity.
|
||||
* Does not protect from overflows, but if you have 2^256 ids, you have other problems.
|
||||
* (But actually, it's generally impossible to increment a counter this many times, energy wise
|
||||
* so it's not something you have to worry about.)
|
||||
*/
|
||||
library Counter {
|
||||
|
||||
struct Counter {
|
||||
uint256 current; // default: 0
|
||||
}
|
||||
|
||||
function next(Counter storage index)
|
||||
internal
|
||||
returns (uint256)
|
||||
{
|
||||
index.current += 1;
|
||||
return index.current;
|
||||
}
|
||||
}
|
||||
37
contracts/drafts/Counters.sol
Normal file
37
contracts/drafts/Counters.sol
Normal file
@ -0,0 +1,37 @@
|
||||
pragma solidity ^0.5.2;
|
||||
|
||||
import "../math/SafeMath.sol";
|
||||
|
||||
/**
|
||||
* @title Counters
|
||||
* @author Matt Condon (@shrugs)
|
||||
* @dev Provides counters that can only be incremented or decremented by one. This can be used e.g. to track the number
|
||||
* of elements in a mapping, issuing ERC721 ids, or counting request ids
|
||||
*
|
||||
* Include with `using Counters for Counters.Counter;`
|
||||
* Since it is not possible to overflow a 256 bit integer with increments of one, `increment` can skip the SafeMath
|
||||
* overflow check, thereby saving gas. This does assume however correct usage, in that the underlying `_value` is never
|
||||
* directly accessed.
|
||||
*/
|
||||
library Counters {
|
||||
using SafeMath for uint256;
|
||||
|
||||
struct Counter {
|
||||
// This variable should never be directly accessed by users of the library: interactions must be restricted to
|
||||
// the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add
|
||||
// this feature: see https://github.com/ethereum/solidity/issues/4637
|
||||
uint256 _value; // default: 0
|
||||
}
|
||||
|
||||
function current(Counter storage counter) internal view returns (uint256) {
|
||||
return counter._value;
|
||||
}
|
||||
|
||||
function increment(Counter storage counter) internal {
|
||||
counter._value += 1;
|
||||
}
|
||||
|
||||
function decrement(Counter storage counter) internal {
|
||||
counter._value = counter._value.sub(1);
|
||||
}
|
||||
}
|
||||
27
contracts/drafts/ERC1046/ERC20Metadata.sol
Normal file
27
contracts/drafts/ERC1046/ERC20Metadata.sol
Normal file
@ -0,0 +1,27 @@
|
||||
pragma solidity ^0.5.2;
|
||||
|
||||
import "@openzeppelin/upgrades/contracts/Initializable.sol";
|
||||
import "../../token/ERC20/IERC20.sol";
|
||||
|
||||
/**
|
||||
* @title ERC-1047 Token Metadata
|
||||
* @dev See https://eips.ethereum.org/EIPS/eip-1046
|
||||
* @dev tokenURI must respond with a URI that implements https://eips.ethereum.org/EIPS/eip-1047
|
||||
*/
|
||||
contract ERC20Metadata is Initializable {
|
||||
string private _tokenURI;
|
||||
|
||||
function initialize(string memory tokenURI_) public {
|
||||
_setTokenURI(tokenURI_);
|
||||
}
|
||||
|
||||
function tokenURI() external view returns (string memory) {
|
||||
return _tokenURI;
|
||||
}
|
||||
|
||||
function _setTokenURI(string memory tokenURI_) internal {
|
||||
_tokenURI = tokenURI_;
|
||||
}
|
||||
|
||||
uint256[50] private ______gap;
|
||||
}
|
||||
@ -1,27 +0,0 @@
|
||||
pragma solidity ^0.4.24;
|
||||
|
||||
import "../../token/ERC20/IERC20.sol";
|
||||
|
||||
/**
|
||||
* @title ERC-1047 Token Metadata
|
||||
* @dev See https://eips.ethereum.org/EIPS/eip-1046
|
||||
* @dev tokenURI must respond with a URI that implements https://eips.ethereum.org/EIPS/eip-1047
|
||||
* @dev TODO - update https://github.com/OpenZeppelin/openzeppelin-solidity/blob/master/contracts/token/ERC721/IERC721.sol#L17 when 1046 is finalized
|
||||
*/
|
||||
contract ERC20TokenMetadata is IERC20 {
|
||||
function tokenURI() external view returns (string);
|
||||
}
|
||||
|
||||
contract ERC20WithMetadata is ERC20TokenMetadata {
|
||||
string private _tokenURI;
|
||||
|
||||
constructor(string tokenURI)
|
||||
public
|
||||
{
|
||||
_tokenURI = tokenURI;
|
||||
}
|
||||
|
||||
function tokenURI() external view returns (string) {
|
||||
return _tokenURI;
|
||||
}
|
||||
}
|
||||
@ -1,5 +1,6 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.2;
|
||||
|
||||
import "@openzeppelin/upgrades/contracts/Initializable.sol";
|
||||
import "../token/ERC20/IERC20.sol";
|
||||
import "../token/ERC20/ERC20Mintable.sol";
|
||||
import "../token/ERC20/SafeERC20.sol";
|
||||
@ -17,13 +18,13 @@ import "../math/Math.sol";
|
||||
* OpenZeppelin's ERC20Mintable, but the only functions that are needed are
|
||||
* `isMinter(address)` and `mint(address, amount)`. The migrator will check
|
||||
* that it is a minter for the token.
|
||||
* The balance from the legacy token will be transfered to the migrator, as it
|
||||
* The balance from the legacy token will be transferred to the migrator, as it
|
||||
* is migrated, and remain there forever.
|
||||
* Although this contract can be used in many different scenarios, the main
|
||||
* motivation was to provide a way to migrate ERC20 tokens into an upgradeable
|
||||
* version of it using ZeppelinOS. To read more about how this can be done
|
||||
* version of it using the OpenZeppelin SDK. To read more about how this can be done
|
||||
* using this implementation, please follow the official documentation site of
|
||||
* ZeppelinOS: https://docs.zeppelinos.org/docs/erc20_onboarding.html
|
||||
* the OpenZeppelinSDK: https://docs.zeppelinos.org/docs/erc20_onboarding.html
|
||||
* Example of usage:
|
||||
* ```
|
||||
* const migrator = await ERC20Migrator.new(legacyToken.address);
|
||||
@ -31,70 +32,73 @@ import "../math/Math.sol";
|
||||
* await migrator.beginMigration(newToken.address);
|
||||
* ```
|
||||
*/
|
||||
contract ERC20Migrator {
|
||||
using SafeERC20 for IERC20;
|
||||
contract ERC20Migrator is Initializable {
|
||||
using SafeERC20 for IERC20;
|
||||
|
||||
/// Address of the old token contract
|
||||
IERC20 private _legacyToken;
|
||||
/// Address of the old token contract
|
||||
IERC20 private _legacyToken;
|
||||
|
||||
/// Address of the new token contract
|
||||
ERC20Mintable private _newToken;
|
||||
/// Address of the new token contract
|
||||
ERC20Mintable private _newToken;
|
||||
|
||||
/**
|
||||
* @param legacyToken address of the old token contract
|
||||
*/
|
||||
constructor(IERC20 legacyToken) public {
|
||||
require(legacyToken != address(0));
|
||||
_legacyToken = legacyToken;
|
||||
}
|
||||
/**
|
||||
* @param legacyToken address of the old token contract
|
||||
*/
|
||||
function initialize(IERC20 legacyToken) public initializer {
|
||||
require(address(legacyToken) != address(0));
|
||||
_legacyToken = legacyToken;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Returns the legacy token that is being migrated.
|
||||
*/
|
||||
function legacyToken() public view returns (IERC20) {
|
||||
return _legacyToken;
|
||||
}
|
||||
/**
|
||||
* @dev Returns the legacy token that is being migrated.
|
||||
*/
|
||||
function legacyToken() public view returns (IERC20) {
|
||||
return _legacyToken;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Returns the new token to which we are migrating.
|
||||
*/
|
||||
function newToken() public view returns (IERC20) {
|
||||
return _newToken;
|
||||
}
|
||||
/**
|
||||
* @dev Returns the new token to which we are migrating.
|
||||
*/
|
||||
function newToken() public view returns (IERC20) {
|
||||
return _newToken;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Begins the migration by setting which is the new token that will be
|
||||
* minted. This contract must be a minter for the new token.
|
||||
* @param newToken the token that will be minted
|
||||
*/
|
||||
function beginMigration(ERC20Mintable newToken) public {
|
||||
require(_newToken == address(0));
|
||||
require(newToken != address(0));
|
||||
require(newToken.isMinter(this));
|
||||
/**
|
||||
* @dev Begins the migration by setting which is the new token that will be
|
||||
* minted. This contract must be a minter for the new token.
|
||||
* @param newToken_ the token that will be minted
|
||||
*/
|
||||
function beginMigration(ERC20Mintable newToken_) public {
|
||||
require(address(_newToken) == address(0));
|
||||
require(address(newToken_) != address(0));
|
||||
require(newToken_.isMinter(address(this)));
|
||||
|
||||
_newToken = newToken;
|
||||
}
|
||||
_newToken = newToken_;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Transfers part of an account's balance in the old token to this
|
||||
* contract, and mints the same amount of new tokens for that account.
|
||||
* @param account whose tokens will be migrated
|
||||
* @param amount amount of tokens to be migrated
|
||||
*/
|
||||
function migrate(address account, uint256 amount) public {
|
||||
_legacyToken.safeTransferFrom(account, this, amount);
|
||||
_newToken.mint(account, amount);
|
||||
}
|
||||
/**
|
||||
* @dev Transfers part of an account's balance in the old token to this
|
||||
* contract, and mints the same amount of new tokens for that account.
|
||||
* @param account whose tokens will be migrated
|
||||
* @param amount amount of tokens to be migrated
|
||||
*/
|
||||
function migrate(address account, uint256 amount) public {
|
||||
require(address(_newToken) != address(0));
|
||||
_legacyToken.safeTransferFrom(account, address(this), amount);
|
||||
_newToken.mint(account, amount);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Transfers all of an account's allowed balance in the old token to
|
||||
* this contract, and mints the same amount of new tokens for that account.
|
||||
* @param account whose tokens will be migrated
|
||||
*/
|
||||
function migrateAll(address account) public {
|
||||
uint256 balance = _legacyToken.balanceOf(account);
|
||||
uint256 allowance = _legacyToken.allowance(account, this);
|
||||
uint256 amount = Math.min(balance, allowance);
|
||||
migrate(account, amount);
|
||||
}
|
||||
/**
|
||||
* @dev Transfers all of an account's allowed balance in the old token to
|
||||
* this contract, and mints the same amount of new tokens for that account.
|
||||
* @param account whose tokens will be migrated
|
||||
*/
|
||||
function migrateAll(address account) public {
|
||||
uint256 balance = _legacyToken.balanceOf(account);
|
||||
uint256 allowance = _legacyToken.allowance(account, address(this));
|
||||
uint256 amount = Math.min(balance, allowance);
|
||||
migrate(account, amount);
|
||||
}
|
||||
|
||||
uint256[50] private ______gap;
|
||||
}
|
||||
|
||||
142
contracts/drafts/ERC20Snapshot.sol
Normal file
142
contracts/drafts/ERC20Snapshot.sol
Normal file
@ -0,0 +1,142 @@
|
||||
pragma solidity ^0.5.2;
|
||||
|
||||
import "@openzeppelin/upgrades/contracts/Initializable.sol";
|
||||
import "../math/SafeMath.sol";
|
||||
import "../utils/Arrays.sol";
|
||||
import "../drafts/Counters.sol";
|
||||
import "../token/ERC20/ERC20.sol";
|
||||
|
||||
/**
|
||||
* @title ERC20 token with snapshots.
|
||||
* @dev Inspired by Jordi Baylina's MiniMeToken to record historical balances:
|
||||
* https://github.com/Giveth/minime/blob/ea04d950eea153a04c51fa510b068b9dded390cb/contracts/MiniMeToken.sol
|
||||
* When a snapshot is made, the balances and totalSupply at the time of the snapshot are recorded for later
|
||||
* access.
|
||||
*
|
||||
* To make a snapshot, call the `snapshot` function, which will emit the `Snapshot` event and return a snapshot id.
|
||||
* To get the total supply from a snapshot, call the function `totalSupplyAt` with the snapshot id.
|
||||
* To get the balance of an account from a snapshot, call the `balanceOfAt` function with the snapshot id and the
|
||||
* account address.
|
||||
* @author Validity Labs AG <info@validitylabs.org>
|
||||
*/
|
||||
contract ERC20Snapshot is Initializable, ERC20 {
|
||||
using SafeMath for uint256;
|
||||
using Arrays for uint256[];
|
||||
using Counters for Counters.Counter;
|
||||
|
||||
// Snapshotted values have arrays of ids and the value corresponding to that id. These could be an array of a
|
||||
// Snapshot struct, but that would impede usage of functions that work on an array.
|
||||
struct Snapshots {
|
||||
uint256[] ids;
|
||||
uint256[] values;
|
||||
}
|
||||
|
||||
mapping (address => Snapshots) private _accountBalanceSnapshots;
|
||||
Snapshots private _totalSupplySnaphots;
|
||||
|
||||
// Snapshot ids increase monotonically, with the first value being 1. An id of 0 is invalid.
|
||||
Counters.Counter private _currentSnapshotId;
|
||||
|
||||
event Snapshot(uint256 id);
|
||||
|
||||
// Creates a new snapshot id. Balances are only stored in snapshots on demand: unless a snapshot was taken, a
|
||||
// balance change will not be recorded. This means the extra added cost of storing snapshotted balances is only paid
|
||||
// when required, but is also flexible enough that it allows for e.g. daily snapshots.
|
||||
function snapshot() public returns (uint256) {
|
||||
_currentSnapshotId.increment();
|
||||
|
||||
uint256 currentId = _currentSnapshotId.current();
|
||||
emit Snapshot(currentId);
|
||||
return currentId;
|
||||
}
|
||||
|
||||
function balanceOfAt(address account, uint256 snapshotId) public view returns (uint256) {
|
||||
(bool snapshotted, uint256 value) = _valueAt(snapshotId, _accountBalanceSnapshots[account]);
|
||||
|
||||
return snapshotted ? value : balanceOf(account);
|
||||
}
|
||||
|
||||
function totalSupplyAt(uint256 snapshotId) public view returns(uint256) {
|
||||
(bool snapshotted, uint256 value) = _valueAt(snapshotId, _totalSupplySnaphots);
|
||||
|
||||
return snapshotted ? value : totalSupply();
|
||||
}
|
||||
|
||||
// _transfer, _mint and _burn are the only functions where the balances are modified, so it is there that the
|
||||
// snapshots are updated. Note that the update happens _before_ the balance change, with the pre-modified value.
|
||||
// The same is true for the total supply and _mint and _burn.
|
||||
function _transfer(address from, address to, uint256 value) internal {
|
||||
_updateAccountSnapshot(from);
|
||||
_updateAccountSnapshot(to);
|
||||
|
||||
super._transfer(from, to, value);
|
||||
}
|
||||
|
||||
function _mint(address account, uint256 value) internal {
|
||||
_updateAccountSnapshot(account);
|
||||
_updateTotalSupplySnapshot();
|
||||
|
||||
super._mint(account, value);
|
||||
}
|
||||
|
||||
function _burn(address account, uint256 value) internal {
|
||||
_updateAccountSnapshot(account);
|
||||
_updateTotalSupplySnapshot();
|
||||
|
||||
super._burn(account, value);
|
||||
}
|
||||
|
||||
// When a valid snapshot is queried, there are three possibilities:
|
||||
// a) The queried value was not modified after the snapshot was taken. Therefore, a snapshot entry was never
|
||||
// created for this id, and all stored snapshot ids are smaller than the requested one. The value that corresponds
|
||||
// to this id is the current one.
|
||||
// b) The queried value was modified after the snapshot was taken. Therefore, there will be an entry with the
|
||||
// requested id, and its value is the one to return.
|
||||
// c) More snapshots were created after the requested one, and the queried value was later modified. There will be
|
||||
// no entry for the requested id: the value that corresponds to it is that of the smallest snapshot id that is
|
||||
// larger than the requested one.
|
||||
//
|
||||
// In summary, we need to find an element in an array, returning the index of the smallest value that is larger if
|
||||
// it is not found, unless said value doesn't exist (e.g. when all values are smaller). Arrays.findUpperBound does
|
||||
// exactly this.
|
||||
function _valueAt(uint256 snapshotId, Snapshots storage snapshots)
|
||||
private view returns (bool, uint256)
|
||||
{
|
||||
require(snapshotId > 0);
|
||||
require(snapshotId <= _currentSnapshotId.current());
|
||||
|
||||
uint256 index = snapshots.ids.findUpperBound(snapshotId);
|
||||
|
||||
if (index == snapshots.ids.length) {
|
||||
return (false, 0);
|
||||
} else {
|
||||
return (true, snapshots.values[index]);
|
||||
}
|
||||
}
|
||||
|
||||
function _updateAccountSnapshot(address account) private {
|
||||
_updateSnapshot(_accountBalanceSnapshots[account], balanceOf(account));
|
||||
}
|
||||
|
||||
function _updateTotalSupplySnapshot() private {
|
||||
_updateSnapshot(_totalSupplySnaphots, totalSupply());
|
||||
}
|
||||
|
||||
function _updateSnapshot(Snapshots storage snapshots, uint256 currentValue) private {
|
||||
uint256 currentId = _currentSnapshotId.current();
|
||||
if (_lastSnapshotId(snapshots.ids) < currentId) {
|
||||
snapshots.ids.push(currentId);
|
||||
snapshots.values.push(currentValue);
|
||||
}
|
||||
}
|
||||
|
||||
function _lastSnapshotId(uint256[] storage ids) private view returns (uint256) {
|
||||
if (ids.length == 0) {
|
||||
return 0;
|
||||
} else {
|
||||
return ids[ids.length - 1];
|
||||
}
|
||||
}
|
||||
|
||||
uint256[50] private ______gap;
|
||||
}
|
||||
@ -1,5 +1,6 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.2;
|
||||
|
||||
import "@openzeppelin/upgrades/contracts/Initializable.sol";
|
||||
import "../access/roles/SignerRole.sol";
|
||||
import "../cryptography/ECDSA.sol";
|
||||
|
||||
@ -29,118 +30,94 @@ import "../cryptography/ECDSA.sol";
|
||||
* @notice A method that uses the `onlyValidSignatureAndData` modifier must make
|
||||
* the _signature parameter the "last" parameter. You cannot sign a message that
|
||||
* has its own signature in it so the last 128 bytes of msg.data (which
|
||||
* represents the length of the _signature data and the _signaature data itself)
|
||||
* represents the length of the _signature data and the _signature data itself)
|
||||
* is ignored when validating. Also non fixed sized parameters make constructing
|
||||
* the data in the signature much more complex.
|
||||
* See https://ethereum.stackexchange.com/a/50616 for more details.
|
||||
*/
|
||||
contract SignatureBouncer is SignerRole {
|
||||
using ECDSA for bytes32;
|
||||
contract SignatureBouncer is Initializable, SignerRole {
|
||||
using ECDSA for bytes32;
|
||||
|
||||
// Function selectors are 4 bytes long, as documented in
|
||||
// https://solidity.readthedocs.io/en/v0.4.24/abi-spec.html#function-selector
|
||||
uint256 private constant _METHOD_ID_SIZE = 4;
|
||||
// Signature size is 65 bytes (tightly packed v + r + s), but gets padded to 96 bytes
|
||||
uint256 private constant _SIGNATURE_SIZE = 96;
|
||||
// Function selectors are 4 bytes long, as documented in
|
||||
// https://solidity.readthedocs.io/en/v0.4.24/abi-spec.html#function-selector
|
||||
uint256 private constant _METHOD_ID_SIZE = 4;
|
||||
// Signature size is 65 bytes (tightly packed v + r + s), but gets padded to 96 bytes
|
||||
uint256 private constant _SIGNATURE_SIZE = 96;
|
||||
|
||||
constructor() internal {}
|
||||
|
||||
/**
|
||||
* @dev requires that a valid signature of a signer was provided
|
||||
*/
|
||||
modifier onlyValidSignature(bytes signature)
|
||||
{
|
||||
require(_isValidSignature(msg.sender, signature));
|
||||
_;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev requires that a valid signature with a specifed method of a signer was provided
|
||||
*/
|
||||
modifier onlyValidSignatureAndMethod(bytes signature)
|
||||
{
|
||||
require(_isValidSignatureAndMethod(msg.sender, signature));
|
||||
_;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev requires that a valid signature with a specifed method and params of a signer was provided
|
||||
*/
|
||||
modifier onlyValidSignatureAndData(bytes signature)
|
||||
{
|
||||
require(_isValidSignatureAndData(msg.sender, signature));
|
||||
_;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev is the signature of `this + sender` from a signer?
|
||||
* @return bool
|
||||
*/
|
||||
function _isValidSignature(address account, bytes signature)
|
||||
internal
|
||||
view
|
||||
returns (bool)
|
||||
{
|
||||
return _isValidDataHash(
|
||||
keccak256(abi.encodePacked(address(this), account)),
|
||||
signature
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev is the signature of `this + sender + methodId` from a signer?
|
||||
* @return bool
|
||||
*/
|
||||
function _isValidSignatureAndMethod(address account, bytes signature)
|
||||
internal
|
||||
view
|
||||
returns (bool)
|
||||
{
|
||||
bytes memory data = new bytes(_METHOD_ID_SIZE);
|
||||
for (uint i = 0; i < data.length; i++) {
|
||||
data[i] = msg.data[i];
|
||||
function initialize(address sender) public initializer {
|
||||
SignerRole.initialize(sender);
|
||||
}
|
||||
return _isValidDataHash(
|
||||
keccak256(abi.encodePacked(address(this), account, data)),
|
||||
signature
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev is the signature of `this + sender + methodId + params(s)` from a signer?
|
||||
* @notice the signature parameter of the method being validated must be the "last" parameter
|
||||
* @return bool
|
||||
*/
|
||||
function _isValidSignatureAndData(address account, bytes signature)
|
||||
internal
|
||||
view
|
||||
returns (bool)
|
||||
{
|
||||
require(msg.data.length > _SIGNATURE_SIZE);
|
||||
bytes memory data = new bytes(msg.data.length - _SIGNATURE_SIZE);
|
||||
for (uint i = 0; i < data.length; i++) {
|
||||
data[i] = msg.data[i];
|
||||
/**
|
||||
* @dev requires that a valid signature of a signer was provided
|
||||
*/
|
||||
modifier onlyValidSignature(bytes memory signature) {
|
||||
require(_isValidSignature(msg.sender, signature));
|
||||
_;
|
||||
}
|
||||
return _isValidDataHash(
|
||||
keccak256(abi.encodePacked(address(this), account, data)),
|
||||
signature
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev internal function to convert a hash to an eth signed message
|
||||
* and then recover the signature and check it against the signer role
|
||||
* @return bool
|
||||
*/
|
||||
function _isValidDataHash(bytes32 hash, bytes signature)
|
||||
internal
|
||||
view
|
||||
returns (bool)
|
||||
{
|
||||
address signer = hash
|
||||
.toEthSignedMessageHash()
|
||||
.recover(signature);
|
||||
/**
|
||||
* @dev requires that a valid signature with a specified method of a signer was provided
|
||||
*/
|
||||
modifier onlyValidSignatureAndMethod(bytes memory signature) {
|
||||
require(_isValidSignatureAndMethod(msg.sender, signature));
|
||||
_;
|
||||
}
|
||||
|
||||
return signer != address(0) && isSigner(signer);
|
||||
}
|
||||
/**
|
||||
* @dev requires that a valid signature with a specified method and params of a signer was provided
|
||||
*/
|
||||
modifier onlyValidSignatureAndData(bytes memory signature) {
|
||||
require(_isValidSignatureAndData(msg.sender, signature));
|
||||
_;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev is the signature of `this + account` from a signer?
|
||||
* @return bool
|
||||
*/
|
||||
function _isValidSignature(address account, bytes memory signature) internal view returns (bool) {
|
||||
return _isValidDataHash(keccak256(abi.encodePacked(address(this), account)), signature);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev is the signature of `this + account + methodId` from a signer?
|
||||
* @return bool
|
||||
*/
|
||||
function _isValidSignatureAndMethod(address account, bytes memory signature) internal view returns (bool) {
|
||||
bytes memory data = new bytes(_METHOD_ID_SIZE);
|
||||
for (uint i = 0; i < data.length; i++) {
|
||||
data[i] = msg.data[i];
|
||||
}
|
||||
return _isValidDataHash(keccak256(abi.encodePacked(address(this), account, data)), signature);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev is the signature of `this + account + methodId + params(s)` from a signer?
|
||||
* @notice the signature parameter of the method being validated must be the "last" parameter
|
||||
* @return bool
|
||||
*/
|
||||
function _isValidSignatureAndData(address account, bytes memory signature) internal view returns (bool) {
|
||||
require(msg.data.length > _SIGNATURE_SIZE);
|
||||
|
||||
bytes memory data = new bytes(msg.data.length - _SIGNATURE_SIZE);
|
||||
for (uint i = 0; i < data.length; i++) {
|
||||
data[i] = msg.data[i];
|
||||
}
|
||||
|
||||
return _isValidDataHash(keccak256(abi.encodePacked(address(this), account, data)), signature);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev internal function to convert a hash to an eth signed message
|
||||
* and then recover the signature and check it against the signer role
|
||||
* @return bool
|
||||
*/
|
||||
function _isValidDataHash(bytes32 hash, bytes memory signature) internal view returns (bool) {
|
||||
address signer = hash.toEthSignedMessageHash().recover(signature);
|
||||
|
||||
return signer != address(0) && isSigner(signer);
|
||||
}
|
||||
|
||||
uint256[50] private ______gap;
|
||||
}
|
||||
|
||||
60
contracts/drafts/SignedSafeMath.sol
Normal file
60
contracts/drafts/SignedSafeMath.sol
Normal file
@ -0,0 +1,60 @@
|
||||
pragma solidity ^0.5.2;
|
||||
|
||||
/**
|
||||
* @title SignedSafeMath
|
||||
* @dev Signed math operations with safety checks that revert on error
|
||||
*/
|
||||
library SignedSafeMath {
|
||||
int256 constant private INT256_MIN = -2**255;
|
||||
|
||||
/**
|
||||
* @dev Multiplies two signed integers, reverts on overflow.
|
||||
*/
|
||||
function mul(int256 a, int256 b) internal pure returns (int256) {
|
||||
// Gas optimization: this is cheaper than requiring 'a' not being zero, but the
|
||||
// benefit is lost if 'b' is also tested.
|
||||
// See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522
|
||||
if (a == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
require(!(a == -1 && b == INT256_MIN)); // This is the only case of overflow not detected by the check below
|
||||
|
||||
int256 c = a * b;
|
||||
require(c / a == b);
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Integer division of two signed integers truncating the quotient, reverts on division by zero.
|
||||
*/
|
||||
function div(int256 a, int256 b) internal pure returns (int256) {
|
||||
require(b != 0); // Solidity only automatically asserts when dividing by 0
|
||||
require(!(b == -1 && a == INT256_MIN)); // This is the only case of overflow
|
||||
|
||||
int256 c = a / b;
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Subtracts two signed integers, reverts on overflow.
|
||||
*/
|
||||
function sub(int256 a, int256 b) internal pure returns (int256) {
|
||||
int256 c = a - b;
|
||||
require((b >= 0 && c <= a) || (b < 0 && c > a));
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Adds two signed integers, reverts on overflow.
|
||||
*/
|
||||
function add(int256 a, int256 b) internal pure returns (int256) {
|
||||
int256 c = a + b;
|
||||
require((b >= 0 && c >= a) || (b < 0 && c < a));
|
||||
|
||||
return c;
|
||||
}
|
||||
}
|
||||
@ -1,7 +1,6 @@
|
||||
/* solium-disable security/no-block-members */
|
||||
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.2;
|
||||
|
||||
import "@openzeppelin/upgrades/contracts/Initializable.sol";
|
||||
import "../token/ERC20/SafeERC20.sol";
|
||||
import "../ownership/Ownable.sol";
|
||||
import "../math/SafeMath.sol";
|
||||
@ -12,164 +11,167 @@ import "../math/SafeMath.sol";
|
||||
* typical vesting scheme, with a cliff and vesting period. Optionally revocable by the
|
||||
* owner.
|
||||
*/
|
||||
contract TokenVesting is Ownable {
|
||||
using SafeMath for uint256;
|
||||
using SafeERC20 for IERC20;
|
||||
contract TokenVesting is Initializable, Ownable {
|
||||
// The vesting schedule is time-based (i.e. using block timestamps as opposed to e.g. block numbers), and is
|
||||
// therefore sensitive to timestamp manipulation (which is something miners can do, to a certain degree). Therefore,
|
||||
// it is recommended to avoid using short time durations (less than a minute). Typical vesting schemes, with a
|
||||
// cliff period of a year and a duration of four years, are safe to use.
|
||||
// solhint-disable not-rely-on-time
|
||||
|
||||
event TokensReleased(address token, uint256 amount);
|
||||
event TokenVestingRevoked(address token);
|
||||
using SafeMath for uint256;
|
||||
using SafeERC20 for IERC20;
|
||||
|
||||
// beneficiary of tokens after they are released
|
||||
address private _beneficiary;
|
||||
event TokensReleased(address token, uint256 amount);
|
||||
event TokenVestingRevoked(address token);
|
||||
|
||||
uint256 private _cliff;
|
||||
uint256 private _start;
|
||||
uint256 private _duration;
|
||||
// beneficiary of tokens after they are released
|
||||
address private _beneficiary;
|
||||
|
||||
bool private _revocable;
|
||||
// Durations and timestamps are expressed in UNIX time, the same units as block.timestamp.
|
||||
uint256 private _cliff;
|
||||
uint256 private _start;
|
||||
uint256 private _duration;
|
||||
|
||||
mapping (address => uint256) private _released;
|
||||
mapping (address => bool) private _revoked;
|
||||
bool private _revocable;
|
||||
|
||||
/**
|
||||
* @dev Creates a vesting contract that vests its balance of any ERC20 token to the
|
||||
* beneficiary, gradually in a linear fashion until start + duration. By then all
|
||||
* of the balance will have vested.
|
||||
* @param beneficiary address of the beneficiary to whom vested tokens are transferred
|
||||
* @param cliffDuration duration in seconds of the cliff in which tokens will begin to vest
|
||||
* @param start the time (as Unix time) at which point vesting starts
|
||||
* @param duration duration in seconds of the period in which the tokens will vest
|
||||
* @param revocable whether the vesting is revocable or not
|
||||
*/
|
||||
constructor(
|
||||
address beneficiary,
|
||||
uint256 start,
|
||||
uint256 cliffDuration,
|
||||
uint256 duration,
|
||||
bool revocable
|
||||
)
|
||||
public
|
||||
{
|
||||
require(beneficiary != address(0));
|
||||
require(cliffDuration <= duration);
|
||||
require(duration > 0);
|
||||
require(start.add(duration) > block.timestamp);
|
||||
mapping (address => uint256) private _released;
|
||||
mapping (address => bool) private _revoked;
|
||||
|
||||
_beneficiary = beneficiary;
|
||||
_revocable = revocable;
|
||||
_duration = duration;
|
||||
_cliff = start.add(cliffDuration);
|
||||
_start = start;
|
||||
}
|
||||
/**
|
||||
* @dev Creates a vesting contract that vests its balance of any ERC20 token to the
|
||||
* beneficiary, gradually in a linear fashion until start + duration. By then all
|
||||
* of the balance will have vested.
|
||||
* @param beneficiary address of the beneficiary to whom vested tokens are transferred
|
||||
* @param cliffDuration duration in seconds of the cliff in which tokens will begin to vest
|
||||
* @param start the time (as Unix time) at which point vesting starts
|
||||
* @param duration duration in seconds of the period in which the tokens will vest
|
||||
* @param revocable whether the vesting is revocable or not
|
||||
*/
|
||||
function initialize(address beneficiary, uint256 start, uint256 cliffDuration, uint256 duration, bool revocable, address sender) public initializer {
|
||||
Ownable.initialize(sender);
|
||||
|
||||
/**
|
||||
* @return the beneficiary of the tokens.
|
||||
*/
|
||||
function beneficiary() public view returns(address) {
|
||||
return _beneficiary;
|
||||
}
|
||||
require(beneficiary != address(0));
|
||||
require(cliffDuration <= duration);
|
||||
require(duration > 0);
|
||||
require(start.add(duration) > block.timestamp);
|
||||
|
||||
/**
|
||||
* @return the cliff time of the token vesting.
|
||||
*/
|
||||
function cliff() public view returns(uint256) {
|
||||
return _cliff;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the start time of the token vesting.
|
||||
*/
|
||||
function start() public view returns(uint256) {
|
||||
return _start;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the duration of the token vesting.
|
||||
*/
|
||||
function duration() public view returns(uint256) {
|
||||
return _duration;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if the vesting is revocable.
|
||||
*/
|
||||
function revocable() public view returns(bool) {
|
||||
return _revocable;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the amount of the token released.
|
||||
*/
|
||||
function released(address token) public view returns(uint256) {
|
||||
return _released[token];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if the token is revoked.
|
||||
*/
|
||||
function revoked(address token) public view returns(bool) {
|
||||
return _revoked[token];
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Transfers vested tokens to beneficiary.
|
||||
* @param token ERC20 token which is being vested
|
||||
*/
|
||||
function release(IERC20 token) public {
|
||||
uint256 unreleased = _releasableAmount(token);
|
||||
|
||||
require(unreleased > 0);
|
||||
|
||||
_released[token] = _released[token].add(unreleased);
|
||||
|
||||
token.safeTransfer(_beneficiary, unreleased);
|
||||
|
||||
emit TokensReleased(token, unreleased);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Allows the owner to revoke the vesting. Tokens already vested
|
||||
* remain in the contract, the rest are returned to the owner.
|
||||
* @param token ERC20 token which is being vested
|
||||
*/
|
||||
function revoke(IERC20 token) public onlyOwner {
|
||||
require(_revocable);
|
||||
require(!_revoked[token]);
|
||||
|
||||
uint256 balance = token.balanceOf(address(this));
|
||||
|
||||
uint256 unreleased = _releasableAmount(token);
|
||||
uint256 refund = balance.sub(unreleased);
|
||||
|
||||
_revoked[token] = true;
|
||||
|
||||
token.safeTransfer(owner(), refund);
|
||||
|
||||
emit TokenVestingRevoked(token);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Calculates the amount that has already vested but hasn't been released yet.
|
||||
* @param token ERC20 token which is being vested
|
||||
*/
|
||||
function _releasableAmount(IERC20 token) private view returns (uint256) {
|
||||
return _vestedAmount(token).sub(_released[token]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Calculates the amount that has already vested.
|
||||
* @param token ERC20 token which is being vested
|
||||
*/
|
||||
function _vestedAmount(IERC20 token) private view returns (uint256) {
|
||||
uint256 currentBalance = token.balanceOf(this);
|
||||
uint256 totalBalance = currentBalance.add(_released[token]);
|
||||
|
||||
if (block.timestamp < _cliff) {
|
||||
return 0;
|
||||
} else if (block.timestamp >= _start.add(_duration) || _revoked[token]) {
|
||||
return totalBalance;
|
||||
} else {
|
||||
return totalBalance.mul(block.timestamp.sub(_start)).div(_duration);
|
||||
_beneficiary = beneficiary;
|
||||
_revocable = revocable;
|
||||
_duration = duration;
|
||||
_cliff = start.add(cliffDuration);
|
||||
_start = start;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the beneficiary of the tokens.
|
||||
*/
|
||||
function beneficiary() public view returns (address) {
|
||||
return _beneficiary;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the cliff time of the token vesting.
|
||||
*/
|
||||
function cliff() public view returns (uint256) {
|
||||
return _cliff;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the start time of the token vesting.
|
||||
*/
|
||||
function start() public view returns (uint256) {
|
||||
return _start;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the duration of the token vesting.
|
||||
*/
|
||||
function duration() public view returns (uint256) {
|
||||
return _duration;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if the vesting is revocable.
|
||||
*/
|
||||
function revocable() public view returns (bool) {
|
||||
return _revocable;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the amount of the token released.
|
||||
*/
|
||||
function released(address token) public view returns (uint256) {
|
||||
return _released[token];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if the token is revoked.
|
||||
*/
|
||||
function revoked(address token) public view returns (bool) {
|
||||
return _revoked[token];
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Transfers vested tokens to beneficiary.
|
||||
* @param token ERC20 token which is being vested
|
||||
*/
|
||||
function release(IERC20 token) public {
|
||||
uint256 unreleased = _releasableAmount(token);
|
||||
|
||||
require(unreleased > 0);
|
||||
|
||||
_released[address(token)] = _released[address(token)].add(unreleased);
|
||||
|
||||
token.safeTransfer(_beneficiary, unreleased);
|
||||
|
||||
emit TokensReleased(address(token), unreleased);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Allows the owner to revoke the vesting. Tokens already vested
|
||||
* remain in the contract, the rest are returned to the owner.
|
||||
* @param token ERC20 token which is being vested
|
||||
*/
|
||||
function revoke(IERC20 token) public onlyOwner {
|
||||
require(_revocable);
|
||||
require(!_revoked[address(token)]);
|
||||
|
||||
uint256 balance = token.balanceOf(address(this));
|
||||
|
||||
uint256 unreleased = _releasableAmount(token);
|
||||
uint256 refund = balance.sub(unreleased);
|
||||
|
||||
_revoked[address(token)] = true;
|
||||
|
||||
token.safeTransfer(owner(), refund);
|
||||
|
||||
emit TokenVestingRevoked(address(token));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Calculates the amount that has already vested but hasn't been released yet.
|
||||
* @param token ERC20 token which is being vested
|
||||
*/
|
||||
function _releasableAmount(IERC20 token) private view returns (uint256) {
|
||||
return _vestedAmount(token).sub(_released[address(token)]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Calculates the amount that has already vested.
|
||||
* @param token ERC20 token which is being vested
|
||||
*/
|
||||
function _vestedAmount(IERC20 token) private view returns (uint256) {
|
||||
uint256 currentBalance = token.balanceOf(address(this));
|
||||
uint256 totalBalance = currentBalance.add(_released[address(token)]);
|
||||
|
||||
if (block.timestamp < _cliff) {
|
||||
return 0;
|
||||
} else if (block.timestamp >= _start.add(_duration) || _revoked[address(token)]) {
|
||||
return totalBalance;
|
||||
} else {
|
||||
return totalBalance.mul(block.timestamp.sub(_start)).div(_duration);
|
||||
}
|
||||
}
|
||||
|
||||
uint256[50] private ______gap;
|
||||
}
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.2;
|
||||
|
||||
import "@openzeppelin/upgrades/contracts/Initializable.sol";
|
||||
import "../crowdsale/validation/CappedCrowdsale.sol";
|
||||
import "../crowdsale/distribution/RefundableCrowdsale.sol";
|
||||
import "../crowdsale/emission/MintedCrowdsale.sol";
|
||||
@ -11,8 +12,13 @@ import "../token/ERC20/ERC20Detailed.sol";
|
||||
* @dev Very simple ERC20 Token that can be minted.
|
||||
* It is meant to be used in a crowdsale contract.
|
||||
*/
|
||||
contract SampleCrowdsaleToken is ERC20Mintable, ERC20Detailed {
|
||||
constructor() public ERC20Detailed("Sample Crowdsale Token", "SCT", 18) {}
|
||||
contract SampleCrowdsaleToken is Initializable, ERC20Mintable, ERC20Detailed {
|
||||
function initialize(address sender) public initializer {
|
||||
ERC20Mintable.initialize(sender);
|
||||
ERC20Detailed.initialize("Sample Crowdsale Token", "SCT", 18);
|
||||
}
|
||||
|
||||
uint256[50] private ______gap;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -28,30 +34,29 @@ contract SampleCrowdsaleToken is ERC20Mintable, ERC20Detailed {
|
||||
* After adding multiple features it's good practice to run integration tests
|
||||
* to ensure that subcontracts works together as intended.
|
||||
*/
|
||||
// XXX There doesn't seem to be a way to split this line that keeps solium
|
||||
// happy. See:
|
||||
// https://github.com/duaraghav8/Solium/issues/205
|
||||
// --elopio - 2018-05-10
|
||||
// solium-disable-next-line max-len
|
||||
contract SampleCrowdsale is CappedCrowdsale, RefundableCrowdsale, MintedCrowdsale {
|
||||
contract SampleCrowdsale is Initializable, Crowdsale, CappedCrowdsale, RefundableCrowdsale, MintedCrowdsale {
|
||||
|
||||
constructor(
|
||||
uint256 openingTime,
|
||||
uint256 closingTime,
|
||||
uint256 rate,
|
||||
address wallet,
|
||||
uint256 cap,
|
||||
ERC20Mintable token,
|
||||
uint256 goal
|
||||
)
|
||||
public
|
||||
Crowdsale(rate, wallet, token)
|
||||
CappedCrowdsale(cap)
|
||||
TimedCrowdsale(openingTime, closingTime)
|
||||
RefundableCrowdsale(goal)
|
||||
{
|
||||
//As goal needs to be met for a successful crowdsale
|
||||
//the value needs to less or equal than a cap which is limit for accepted funds
|
||||
require(goal <= cap);
|
||||
}
|
||||
function initialize(
|
||||
uint256 openingTime,
|
||||
uint256 closingTime,
|
||||
uint256 rate,
|
||||
address payable wallet,
|
||||
uint256 cap,
|
||||
ERC20Mintable token,
|
||||
uint256 goal
|
||||
)
|
||||
public
|
||||
initializer
|
||||
{
|
||||
Crowdsale.initialize(rate, wallet, token);
|
||||
CappedCrowdsale.initialize(cap);
|
||||
TimedCrowdsale.initialize(openingTime, closingTime);
|
||||
RefundableCrowdsale.initialize(goal);
|
||||
|
||||
//As goal needs to be met for a successful crowdsale
|
||||
//the value needs to less or equal than a cap which is limit for accepted funds
|
||||
require(goal <= cap);
|
||||
}
|
||||
|
||||
uint256[50] private ______gap;
|
||||
}
|
||||
|
||||
@ -1,6 +1,8 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.2;
|
||||
|
||||
import "@openzeppelin/upgrades/contracts/Initializable.sol";
|
||||
import "../token/ERC20/ERC20.sol";
|
||||
import "../token/ERC20/ERC20Detailed.sol";
|
||||
|
||||
/**
|
||||
* @title SimpleToken
|
||||
@ -8,19 +10,17 @@ import "../token/ERC20/ERC20.sol";
|
||||
* Note they can later distribute these tokens as they wish using `transfer` and other
|
||||
* `ERC20` functions.
|
||||
*/
|
||||
contract SimpleToken is ERC20 {
|
||||
contract SimpleToken is Initializable, ERC20, ERC20Detailed {
|
||||
uint8 public constant DECIMALS = 18;
|
||||
uint256 public constant INITIAL_SUPPLY = 10000 * (10 ** uint256(DECIMALS));
|
||||
|
||||
string public constant name = "SimpleToken";
|
||||
string public constant symbol = "SIM";
|
||||
uint8 public constant decimals = 18;
|
||||
|
||||
uint256 public constant INITIAL_SUPPLY = 10000 * (10 ** uint256(decimals));
|
||||
|
||||
/**
|
||||
* @dev Constructor that gives msg.sender all of existing tokens.
|
||||
*/
|
||||
constructor() public {
|
||||
_mint(msg.sender, INITIAL_SUPPLY);
|
||||
}
|
||||
/**
|
||||
* @dev Constructor that gives msg.sender all of existing tokens.
|
||||
*/
|
||||
function initialize(address sender) public initializer {
|
||||
ERC20Detailed.initialize("SimpleToken", "SIM", DECIMALS);
|
||||
_mint(sender, INITIAL_SUPPLY);
|
||||
}
|
||||
|
||||
uint256[50] private ______gap;
|
||||
}
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.2;
|
||||
|
||||
import "@openzeppelin/upgrades/contracts/Initializable.sol";
|
||||
import "./IERC165.sol";
|
||||
|
||||
/**
|
||||
@ -7,47 +8,40 @@ import "./IERC165.sol";
|
||||
* @author Matt Condon (@shrugs)
|
||||
* @dev Implements ERC165 using a lookup table.
|
||||
*/
|
||||
contract ERC165 is IERC165 {
|
||||
contract ERC165 is Initializable, IERC165 {
|
||||
bytes4 private constant _INTERFACE_ID_ERC165 = 0x01ffc9a7;
|
||||
/*
|
||||
* 0x01ffc9a7 ===
|
||||
* bytes4(keccak256('supportsInterface(bytes4)'))
|
||||
*/
|
||||
|
||||
bytes4 private constant _InterfaceId_ERC165 = 0x01ffc9a7;
|
||||
/**
|
||||
* 0x01ffc9a7 ===
|
||||
* bytes4(keccak256('supportsInterface(bytes4)'))
|
||||
*/
|
||||
/**
|
||||
* @dev a mapping of interface id to whether or not it's supported
|
||||
*/
|
||||
mapping(bytes4 => bool) private _supportedInterfaces;
|
||||
|
||||
/**
|
||||
* @dev a mapping of interface id to whether or not it's supported
|
||||
*/
|
||||
mapping(bytes4 => bool) private _supportedInterfaces;
|
||||
/**
|
||||
* @dev A contract implementing SupportsInterfaceWithLookup
|
||||
* implement ERC165 itself
|
||||
*/
|
||||
function initialize() public initializer {
|
||||
_registerInterface(_INTERFACE_ID_ERC165);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev A contract implementing SupportsInterfaceWithLookup
|
||||
* implement ERC165 itself
|
||||
*/
|
||||
constructor()
|
||||
internal
|
||||
{
|
||||
_registerInterface(_InterfaceId_ERC165);
|
||||
}
|
||||
/**
|
||||
* @dev implement supportsInterface(bytes4) using a lookup table
|
||||
*/
|
||||
function supportsInterface(bytes4 interfaceId) public view returns (bool) {
|
||||
return _supportedInterfaces[interfaceId];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev implement supportsInterface(bytes4) using a lookup table
|
||||
*/
|
||||
function supportsInterface(bytes4 interfaceId)
|
||||
external
|
||||
view
|
||||
returns (bool)
|
||||
{
|
||||
return _supportedInterfaces[interfaceId];
|
||||
}
|
||||
/**
|
||||
* @dev internal method for registering an interface
|
||||
*/
|
||||
function _registerInterface(bytes4 interfaceId) internal {
|
||||
require(interfaceId != 0xffffffff);
|
||||
_supportedInterfaces[interfaceId] = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev internal method for registering an interface
|
||||
*/
|
||||
function _registerInterface(bytes4 interfaceId)
|
||||
internal
|
||||
{
|
||||
require(interfaceId != 0xffffffff);
|
||||
_supportedInterfaces[interfaceId] = true;
|
||||
}
|
||||
uint256[50] private ______gap;
|
||||
}
|
||||
|
||||
@ -1,146 +1,123 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.2;
|
||||
|
||||
/**
|
||||
* @title ERC165Checker
|
||||
* @dev Use `using ERC165Checker for address`; to include this library
|
||||
* https://github.com/ethereum/EIPs/blob/master/EIPS/eip-165.md
|
||||
* https://eips.ethereum.org/EIPS/eip-165
|
||||
*/
|
||||
library ERC165Checker {
|
||||
// As per the EIP-165 spec, no interface should ever match 0xffffffff
|
||||
bytes4 private constant _InterfaceId_Invalid = 0xffffffff;
|
||||
// As per the EIP-165 spec, no interface should ever match 0xffffffff
|
||||
bytes4 private constant _INTERFACE_ID_INVALID = 0xffffffff;
|
||||
|
||||
bytes4 private constant _InterfaceId_ERC165 = 0x01ffc9a7;
|
||||
/**
|
||||
* 0x01ffc9a7 ===
|
||||
* bytes4(keccak256('supportsInterface(bytes4)'))
|
||||
*/
|
||||
bytes4 private constant _INTERFACE_ID_ERC165 = 0x01ffc9a7;
|
||||
/*
|
||||
* 0x01ffc9a7 ===
|
||||
* bytes4(keccak256('supportsInterface(bytes4)'))
|
||||
*/
|
||||
|
||||
/**
|
||||
* @notice Query if a contract supports ERC165
|
||||
* @param account The address of the contract to query for support of ERC165
|
||||
* @return true if the contract at account implements ERC165
|
||||
*/
|
||||
function _supportsERC165(address account)
|
||||
internal
|
||||
view
|
||||
returns (bool)
|
||||
{
|
||||
// Any contract that implements ERC165 must explicitly indicate support of
|
||||
// InterfaceId_ERC165 and explicitly indicate non-support of InterfaceId_Invalid
|
||||
return _supportsERC165Interface(account, _InterfaceId_ERC165) &&
|
||||
!_supportsERC165Interface(account, _InterfaceId_Invalid);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Query if a contract implements an interface, also checks support of ERC165
|
||||
* @param account The address of the contract to query for support of an interface
|
||||
* @param interfaceId The interface identifier, as specified in ERC-165
|
||||
* @return true if the contract at account indicates support of the interface with
|
||||
* identifier interfaceId, false otherwise
|
||||
* @dev Interface identification is specified in ERC-165.
|
||||
*/
|
||||
function _supportsInterface(address account, bytes4 interfaceId)
|
||||
internal
|
||||
view
|
||||
returns (bool)
|
||||
{
|
||||
// query support of both ERC165 as per the spec and support of _interfaceId
|
||||
return _supportsERC165(account) &&
|
||||
_supportsERC165Interface(account, interfaceId);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Query if a contract implements interfaces, also checks support of ERC165
|
||||
* @param account The address of the contract to query for support of an interface
|
||||
* @param interfaceIds A list of interface identifiers, as specified in ERC-165
|
||||
* @return true if the contract at account indicates support all interfaces in the
|
||||
* interfaceIds list, false otherwise
|
||||
* @dev Interface identification is specified in ERC-165.
|
||||
*/
|
||||
function _supportsAllInterfaces(address account, bytes4[] interfaceIds)
|
||||
internal
|
||||
view
|
||||
returns (bool)
|
||||
{
|
||||
// query support of ERC165 itself
|
||||
if (!_supportsERC165(account)) {
|
||||
return false;
|
||||
/**
|
||||
* @notice Query if a contract supports ERC165
|
||||
* @param account The address of the contract to query for support of ERC165
|
||||
* @return true if the contract at account implements ERC165
|
||||
*/
|
||||
function _supportsERC165(address account) internal view returns (bool) {
|
||||
// Any contract that implements ERC165 must explicitly indicate support of
|
||||
// InterfaceId_ERC165 and explicitly indicate non-support of InterfaceId_Invalid
|
||||
return _supportsERC165Interface(account, _INTERFACE_ID_ERC165) &&
|
||||
!_supportsERC165Interface(account, _INTERFACE_ID_INVALID);
|
||||
}
|
||||
|
||||
// query support of each interface in _interfaceIds
|
||||
for (uint256 i = 0; i < interfaceIds.length; i++) {
|
||||
if (!_supportsERC165Interface(account, interfaceIds[i])) {
|
||||
return false;
|
||||
}
|
||||
/**
|
||||
* @notice Query if a contract implements an interface, also checks support of ERC165
|
||||
* @param account The address of the contract to query for support of an interface
|
||||
* @param interfaceId The interface identifier, as specified in ERC-165
|
||||
* @return true if the contract at account indicates support of the interface with
|
||||
* identifier interfaceId, false otherwise
|
||||
* @dev Interface identification is specified in ERC-165.
|
||||
*/
|
||||
function _supportsInterface(address account, bytes4 interfaceId) internal view returns (bool) {
|
||||
// query support of both ERC165 as per the spec and support of _interfaceId
|
||||
return _supportsERC165(account) &&
|
||||
_supportsERC165Interface(account, interfaceId);
|
||||
}
|
||||
|
||||
// all interfaces supported
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
* @notice Query if a contract implements interfaces, also checks support of ERC165
|
||||
* @param account The address of the contract to query for support of an interface
|
||||
* @param interfaceIds A list of interface identifiers, as specified in ERC-165
|
||||
* @return true if the contract at account indicates support all interfaces in the
|
||||
* interfaceIds list, false otherwise
|
||||
* @dev Interface identification is specified in ERC-165.
|
||||
*/
|
||||
function _supportsAllInterfaces(address account, bytes4[] memory interfaceIds) internal view returns (bool) {
|
||||
// query support of ERC165 itself
|
||||
if (!_supportsERC165(account)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Query if a contract implements an interface, does not check ERC165 support
|
||||
* @param account The address of the contract to query for support of an interface
|
||||
* @param interfaceId The interface identifier, as specified in ERC-165
|
||||
* @return true if the contract at account indicates support of the interface with
|
||||
* identifier interfaceId, false otherwise
|
||||
* @dev Assumes that account contains a contract that supports ERC165, otherwise
|
||||
* the behavior of this method is undefined. This precondition can be checked
|
||||
* with the `supportsERC165` method in this library.
|
||||
* Interface identification is specified in ERC-165.
|
||||
*/
|
||||
function _supportsERC165Interface(address account, bytes4 interfaceId)
|
||||
private
|
||||
view
|
||||
returns (bool)
|
||||
{
|
||||
// success determines whether the staticcall succeeded and result determines
|
||||
// whether the contract at account indicates support of _interfaceId
|
||||
(bool success, bool result) = _callERC165SupportsInterface(
|
||||
account, interfaceId);
|
||||
// query support of each interface in _interfaceIds
|
||||
for (uint256 i = 0; i < interfaceIds.length; i++) {
|
||||
if (!_supportsERC165Interface(account, interfaceIds[i])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return (success && result);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Calls the function with selector 0x01ffc9a7 (ERC165) and suppresses throw
|
||||
* @param account The address of the contract to query for support of an interface
|
||||
* @param interfaceId The interface identifier, as specified in ERC-165
|
||||
* @return success true if the STATICCALL succeeded, false otherwise
|
||||
* @return result true if the STATICCALL succeeded and the contract at account
|
||||
* indicates support of the interface with identifier interfaceId, false otherwise
|
||||
*/
|
||||
function _callERC165SupportsInterface(
|
||||
address account,
|
||||
bytes4 interfaceId
|
||||
)
|
||||
private
|
||||
view
|
||||
returns (bool success, bool result)
|
||||
{
|
||||
bytes memory encodedParams = abi.encodeWithSelector(
|
||||
_InterfaceId_ERC165,
|
||||
interfaceId
|
||||
);
|
||||
|
||||
// solium-disable-next-line security/no-inline-assembly
|
||||
assembly {
|
||||
let encodedParams_data := add(0x20, encodedParams)
|
||||
let encodedParams_size := mload(encodedParams)
|
||||
|
||||
let output := mload(0x40) // Find empty storage location using "free memory pointer"
|
||||
mstore(output, 0x0)
|
||||
|
||||
success := staticcall(
|
||||
30000, // 30k gas
|
||||
account, // To addr
|
||||
encodedParams_data,
|
||||
encodedParams_size,
|
||||
output,
|
||||
0x20 // Outputs are 32 bytes long
|
||||
)
|
||||
|
||||
result := mload(output) // Load the result
|
||||
// all interfaces supported
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Query if a contract implements an interface, does not check ERC165 support
|
||||
* @param account The address of the contract to query for support of an interface
|
||||
* @param interfaceId The interface identifier, as specified in ERC-165
|
||||
* @return true if the contract at account indicates support of the interface with
|
||||
* identifier interfaceId, false otherwise
|
||||
* @dev Assumes that account contains a contract that supports ERC165, otherwise
|
||||
* the behavior of this method is undefined. This precondition can be checked
|
||||
* with the `supportsERC165` method in this library.
|
||||
* Interface identification is specified in ERC-165.
|
||||
*/
|
||||
function _supportsERC165Interface(address account, bytes4 interfaceId) private view returns (bool) {
|
||||
// success determines whether the staticcall succeeded and result determines
|
||||
// whether the contract at account indicates support of _interfaceId
|
||||
(bool success, bool result) = _callERC165SupportsInterface(account, interfaceId);
|
||||
|
||||
return (success && result);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Calls the function with selector 0x01ffc9a7 (ERC165) and suppresses throw
|
||||
* @param account The address of the contract to query for support of an interface
|
||||
* @param interfaceId The interface identifier, as specified in ERC-165
|
||||
* @return success true if the STATICCALL succeeded, false otherwise
|
||||
* @return result true if the STATICCALL succeeded and the contract at account
|
||||
* indicates support of the interface with identifier interfaceId, false otherwise
|
||||
*/
|
||||
function _callERC165SupportsInterface(address account, bytes4 interfaceId)
|
||||
private
|
||||
view
|
||||
returns (bool success, bool result)
|
||||
{
|
||||
bytes memory encodedParams = abi.encodeWithSelector(_INTERFACE_ID_ERC165, interfaceId);
|
||||
|
||||
// solhint-disable-next-line no-inline-assembly
|
||||
assembly {
|
||||
let encodedParams_data := add(0x20, encodedParams)
|
||||
let encodedParams_size := mload(encodedParams)
|
||||
|
||||
let output := mload(0x40) // Find empty storage location using "free memory pointer"
|
||||
mstore(output, 0x0)
|
||||
|
||||
success := staticcall(
|
||||
30000, // 30k gas
|
||||
account, // To addr
|
||||
encodedParams_data,
|
||||
encodedParams_size,
|
||||
output,
|
||||
0x20 // Outputs are 32 bytes long
|
||||
)
|
||||
|
||||
result := mload(output) // Load the result
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,19 +1,15 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.2;
|
||||
|
||||
/**
|
||||
* @title IERC165
|
||||
* @dev https://github.com/ethereum/EIPs/blob/master/EIPS/eip-165.md
|
||||
* @dev https://eips.ethereum.org/EIPS/eip-165
|
||||
*/
|
||||
interface IERC165 {
|
||||
|
||||
/**
|
||||
* @notice Query if a contract implements an interface
|
||||
* @param interfaceId The interface identifier, as specified in ERC-165
|
||||
* @dev Interface identification is specified in ERC-165. This function
|
||||
* uses less than 30,000 gas.
|
||||
*/
|
||||
function supportsInterface(bytes4 interfaceId)
|
||||
external
|
||||
view
|
||||
returns (bool);
|
||||
/**
|
||||
* @notice Query if a contract implements an interface
|
||||
* @param interfaceId The interface identifier, as specified in ERC-165
|
||||
* @dev Interface identification is specified in ERC-165. This function
|
||||
* uses less than 30,000 gas.
|
||||
*/
|
||||
function supportsInterface(bytes4 interfaceId) external view returns (bool);
|
||||
}
|
||||
|
||||
@ -1,57 +1,62 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.2;
|
||||
|
||||
import "@openzeppelin/upgrades/contracts/Initializable.sol";
|
||||
import "../access/roles/PauserRole.sol";
|
||||
|
||||
/**
|
||||
* @title Pausable
|
||||
* @dev Base contract which allows children to implement an emergency stop mechanism.
|
||||
*/
|
||||
contract Pausable is PauserRole {
|
||||
event Paused(address account);
|
||||
event Unpaused(address account);
|
||||
contract Pausable is Initializable, PauserRole {
|
||||
event Paused(address account);
|
||||
event Unpaused(address account);
|
||||
|
||||
bool private _paused;
|
||||
bool private _paused;
|
||||
|
||||
constructor() internal {
|
||||
_paused = false;
|
||||
}
|
||||
function initialize(address sender) public initializer {
|
||||
PauserRole.initialize(sender);
|
||||
|
||||
/**
|
||||
* @return true if the contract is paused, false otherwise.
|
||||
*/
|
||||
function paused() public view returns(bool) {
|
||||
return _paused;
|
||||
}
|
||||
_paused = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Modifier to make a function callable only when the contract is not paused.
|
||||
*/
|
||||
modifier whenNotPaused() {
|
||||
require(!_paused);
|
||||
_;
|
||||
}
|
||||
/**
|
||||
* @return true if the contract is paused, false otherwise.
|
||||
*/
|
||||
function paused() public view returns (bool) {
|
||||
return _paused;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Modifier to make a function callable only when the contract is paused.
|
||||
*/
|
||||
modifier whenPaused() {
|
||||
require(_paused);
|
||||
_;
|
||||
}
|
||||
/**
|
||||
* @dev Modifier to make a function callable only when the contract is not paused.
|
||||
*/
|
||||
modifier whenNotPaused() {
|
||||
require(!_paused);
|
||||
_;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev called by the owner to pause, triggers stopped state
|
||||
*/
|
||||
function pause() public onlyPauser whenNotPaused {
|
||||
_paused = true;
|
||||
emit Paused(msg.sender);
|
||||
}
|
||||
/**
|
||||
* @dev Modifier to make a function callable only when the contract is paused.
|
||||
*/
|
||||
modifier whenPaused() {
|
||||
require(_paused);
|
||||
_;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev called by the owner to unpause, returns to normal state
|
||||
*/
|
||||
function unpause() public onlyPauser whenPaused {
|
||||
_paused = false;
|
||||
emit Unpaused(msg.sender);
|
||||
}
|
||||
/**
|
||||
* @dev called by the owner to pause, triggers stopped state
|
||||
*/
|
||||
function pause() public onlyPauser whenNotPaused {
|
||||
_paused = true;
|
||||
emit Paused(msg.sender);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev called by the owner to unpause, returns to normal state
|
||||
*/
|
||||
function unpause() public onlyPauser whenPaused {
|
||||
_paused = false;
|
||||
emit Unpaused(msg.sender);
|
||||
}
|
||||
|
||||
uint256[50] private ______gap;
|
||||
}
|
||||
|
||||
@ -1,31 +1,31 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.2;
|
||||
|
||||
/**
|
||||
* @title Math
|
||||
* @dev Assorted math operations
|
||||
*/
|
||||
library Math {
|
||||
/**
|
||||
* @dev Returns the largest of two numbers.
|
||||
*/
|
||||
function max(uint256 a, uint256 b) internal pure returns (uint256) {
|
||||
return a >= b ? a : b;
|
||||
}
|
||||
/**
|
||||
* @dev Returns the largest of two numbers.
|
||||
*/
|
||||
function max(uint256 a, uint256 b) internal pure returns (uint256) {
|
||||
return a >= b ? a : b;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Returns the smallest of two numbers.
|
||||
*/
|
||||
function min(uint256 a, uint256 b) internal pure returns (uint256) {
|
||||
return a < b ? a : b;
|
||||
}
|
||||
/**
|
||||
* @dev Returns the smallest of two numbers.
|
||||
*/
|
||||
function min(uint256 a, uint256 b) internal pure returns (uint256) {
|
||||
return a < b ? a : b;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Calculates the average of two numbers. Since these are integers,
|
||||
* averages of an even and odd number cannot be represented, and will be
|
||||
* rounded down.
|
||||
*/
|
||||
function average(uint256 a, uint256 b) internal pure returns (uint256) {
|
||||
// (a + b) / 2 can overflow, so we distribute
|
||||
return (a / 2) + (b / 2) + ((a % 2 + b % 2) / 2);
|
||||
}
|
||||
/**
|
||||
* @dev Calculates the average of two numbers. Since these are integers,
|
||||
* averages of an even and odd number cannot be represented, and will be
|
||||
* rounded down.
|
||||
*/
|
||||
function average(uint256 a, uint256 b) internal pure returns (uint256) {
|
||||
// (a + b) / 2 can overflow, so we distribute
|
||||
return (a / 2) + (b / 2) + ((a % 2 + b % 2) / 2);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,65 +1,65 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.2;
|
||||
|
||||
/**
|
||||
* @title SafeMath
|
||||
* @dev Math operations with safety checks that revert on error
|
||||
* @dev Unsigned math operations with safety checks that revert on error
|
||||
*/
|
||||
library SafeMath {
|
||||
/**
|
||||
* @dev Multiplies two unsigned integers, reverts on overflow.
|
||||
*/
|
||||
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
|
||||
// Gas optimization: this is cheaper than requiring 'a' not being zero, but the
|
||||
// benefit is lost if 'b' is also tested.
|
||||
// See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522
|
||||
if (a == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Multiplies two numbers, reverts on overflow.
|
||||
*/
|
||||
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
|
||||
// Gas optimization: this is cheaper than requiring 'a' not being zero, but the
|
||||
// benefit is lost if 'b' is also tested.
|
||||
// See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522
|
||||
if (a == 0) {
|
||||
return 0;
|
||||
uint256 c = a * b;
|
||||
require(c / a == b);
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
uint256 c = a * b;
|
||||
require(c / a == b);
|
||||
/**
|
||||
* @dev Integer division of two unsigned integers truncating the quotient, reverts on division by zero.
|
||||
*/
|
||||
function div(uint256 a, uint256 b) internal pure returns (uint256) {
|
||||
// Solidity only automatically asserts when dividing by 0
|
||||
require(b > 0);
|
||||
uint256 c = a / b;
|
||||
// assert(a == b * c + a % b); // There is no case in which this doesn't hold
|
||||
|
||||
return c;
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Integer division of two numbers truncating the quotient, reverts on division by zero.
|
||||
*/
|
||||
function div(uint256 a, uint256 b) internal pure returns (uint256) {
|
||||
require(b > 0); // Solidity only automatically asserts when dividing by 0
|
||||
uint256 c = a / b;
|
||||
// assert(a == b * c + a % b); // There is no case in which this doesn't hold
|
||||
/**
|
||||
* @dev Subtracts two unsigned integers, reverts on overflow (i.e. if subtrahend is greater than minuend).
|
||||
*/
|
||||
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
|
||||
require(b <= a);
|
||||
uint256 c = a - b;
|
||||
|
||||
return c;
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Subtracts two numbers, reverts on overflow (i.e. if subtrahend is greater than minuend).
|
||||
*/
|
||||
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
|
||||
require(b <= a);
|
||||
uint256 c = a - b;
|
||||
/**
|
||||
* @dev Adds two unsigned integers, reverts on overflow.
|
||||
*/
|
||||
function add(uint256 a, uint256 b) internal pure returns (uint256) {
|
||||
uint256 c = a + b;
|
||||
require(c >= a);
|
||||
|
||||
return c;
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Adds two numbers, reverts on overflow.
|
||||
*/
|
||||
function add(uint256 a, uint256 b) internal pure returns (uint256) {
|
||||
uint256 c = a + b;
|
||||
require(c >= a);
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Divides two numbers and returns the remainder (unsigned integer modulo),
|
||||
* reverts when dividing by zero.
|
||||
*/
|
||||
function mod(uint256 a, uint256 b) internal pure returns (uint256) {
|
||||
require(b != 0);
|
||||
return a % b;
|
||||
}
|
||||
/**
|
||||
* @dev Divides two unsigned integers and returns the remainder (unsigned integer modulo),
|
||||
* reverts when dividing by zero.
|
||||
*/
|
||||
function mod(uint256 a, uint256 b) internal pure returns (uint256) {
|
||||
require(b != 0);
|
||||
return a % b;
|
||||
}
|
||||
}
|
||||
|
||||
19
contracts/mocks/Acknowledger.sol
Normal file
19
contracts/mocks/Acknowledger.sol
Normal file
@ -0,0 +1,19 @@
|
||||
pragma solidity ^0.5.2;
|
||||
|
||||
contract Acknowledger {
|
||||
event AcknowledgeFoo(uint256 a);
|
||||
event AcknowledgeBarSingle(uint256 a);
|
||||
event AcknowledgeBarDouble(uint256 a, uint256 b);
|
||||
|
||||
function foo(uint256 a) public {
|
||||
emit AcknowledgeFoo(a);
|
||||
}
|
||||
|
||||
function bar(uint256 a) public {
|
||||
emit AcknowledgeBarSingle(a);
|
||||
}
|
||||
|
||||
function bar(uint256 a, uint256 b) public {
|
||||
emit AcknowledgeBarDouble(a, b);
|
||||
}
|
||||
}
|
||||
@ -1,14 +1,9 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.2;
|
||||
|
||||
import "../utils/Address.sol";
|
||||
|
||||
contract AddressImpl {
|
||||
function isContract(address account)
|
||||
external
|
||||
view
|
||||
returns (bool)
|
||||
{
|
||||
return Address.isContract(account);
|
||||
}
|
||||
|
||||
function isContract(address account) external view returns (bool) {
|
||||
return Address.isContract(account);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,20 +1,13 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.2;
|
||||
|
||||
import "../token/ERC20/IERC20.sol";
|
||||
import "../crowdsale/emission/AllowanceCrowdsale.sol";
|
||||
|
||||
contract AllowanceCrowdsaleImpl is AllowanceCrowdsale {
|
||||
|
||||
constructor (
|
||||
uint256 rate,
|
||||
address wallet,
|
||||
IERC20 token,
|
||||
address tokenWallet
|
||||
)
|
||||
public
|
||||
Crowdsale(rate, wallet, token)
|
||||
AllowanceCrowdsale(tokenWallet)
|
||||
{
|
||||
}
|
||||
|
||||
constructor (uint256 rate, address payable wallet, IERC20 token, address tokenWallet)
|
||||
public
|
||||
{
|
||||
Crowdsale.initialize(rate, wallet, token);
|
||||
AllowanceCrowdsale.initialize(tokenWallet);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,18 +1,17 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.2;
|
||||
|
||||
import "../utils/Arrays.sol";
|
||||
|
||||
contract ArraysImpl {
|
||||
using Arrays for uint256[];
|
||||
|
||||
using Arrays for uint256[];
|
||||
uint256[] private array;
|
||||
|
||||
uint256[] private array;
|
||||
constructor (uint256[] memory _array) public {
|
||||
array = _array;
|
||||
}
|
||||
|
||||
constructor(uint256[] _array) public {
|
||||
array = _array;
|
||||
}
|
||||
|
||||
function findUpperBound(uint256 _element) external view returns (uint256) {
|
||||
return array.findUpperBound(_element);
|
||||
}
|
||||
function findUpperBound(uint256 _element) external view returns (uint256) {
|
||||
return array.findUpperBound(_element);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,20 +1,13 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.2;
|
||||
|
||||
import "../token/ERC20/IERC20.sol";
|
||||
import "../crowdsale/validation/CappedCrowdsale.sol";
|
||||
|
||||
contract CappedCrowdsaleImpl is CappedCrowdsale {
|
||||
|
||||
constructor (
|
||||
uint256 rate,
|
||||
address wallet,
|
||||
IERC20 token,
|
||||
uint256 cap
|
||||
)
|
||||
public
|
||||
Crowdsale(rate, wallet, token)
|
||||
CappedCrowdsale(cap)
|
||||
{
|
||||
}
|
||||
|
||||
constructor (uint256 rate, address payable wallet, IERC20 token, uint256 cap)
|
||||
public
|
||||
{
|
||||
Crowdsale.initialize(rate, wallet, token);
|
||||
CappedCrowdsale.initialize(cap);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,17 +1,22 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.2;
|
||||
|
||||
import "../access/roles/CapperRole.sol";
|
||||
|
||||
contract CapperRoleMock is CapperRole {
|
||||
function removeCapper(address account) public {
|
||||
_removeCapper(account);
|
||||
}
|
||||
constructor() public {
|
||||
CapperRole.initialize(msg.sender);
|
||||
}
|
||||
|
||||
function onlyCapperMock() public view onlyCapper {
|
||||
}
|
||||
function removeCapper(address account) public {
|
||||
_removeCapper(account);
|
||||
}
|
||||
|
||||
// Causes a compilation error if super._removeCapper is not internal
|
||||
function _removeCapper(address account) internal {
|
||||
super._removeCapper(account);
|
||||
}
|
||||
function onlyCapperMock() public view onlyCapper {
|
||||
// solhint-disable-previous-line no-empty-blocks
|
||||
}
|
||||
|
||||
// Causes a compilation error if super._removeCapper is not internal
|
||||
function _removeCapper(address account) internal {
|
||||
super._removeCapper(account);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,16 +1,20 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.2;
|
||||
|
||||
import "../payment/escrow/ConditionalEscrow.sol";
|
||||
|
||||
// mock class using ConditionalEscrow
|
||||
contract ConditionalEscrowMock is ConditionalEscrow {
|
||||
mapping(address => bool) private _allowed;
|
||||
mapping(address => bool) private _allowed;
|
||||
|
||||
function setAllowed(address payee, bool allowed) public {
|
||||
_allowed[payee] = allowed;
|
||||
}
|
||||
constructor() public {
|
||||
ConditionalEscrow.initialize(msg.sender);
|
||||
}
|
||||
|
||||
function withdrawalAllowed(address payee) public view returns (bool) {
|
||||
return _allowed[payee];
|
||||
}
|
||||
function setAllowed(address payee, bool allowed) public {
|
||||
_allowed[payee] = allowed;
|
||||
}
|
||||
|
||||
function withdrawalAllowed(address payee) public view returns (bool) {
|
||||
return _allowed[payee];
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,20 +0,0 @@
|
||||
pragma solidity ^0.4.24;
|
||||
|
||||
import "../drafts/Counter.sol";
|
||||
|
||||
contract CounterImpl {
|
||||
using Counter for Counter.Counter;
|
||||
|
||||
uint256 public theId;
|
||||
|
||||
// use whatever key you want to track your counters
|
||||
mapping(string => Counter.Counter) private _counters;
|
||||
|
||||
function doThing(string key)
|
||||
public
|
||||
returns (uint256)
|
||||
{
|
||||
theId = _counters[key].next();
|
||||
return theId;
|
||||
}
|
||||
}
|
||||
21
contracts/mocks/CountersImpl.sol
Normal file
21
contracts/mocks/CountersImpl.sol
Normal file
@ -0,0 +1,21 @@
|
||||
pragma solidity ^0.5.2;
|
||||
|
||||
import "../drafts/Counters.sol";
|
||||
|
||||
contract CountersImpl {
|
||||
using Counters for Counters.Counter;
|
||||
|
||||
Counters.Counter private _counter;
|
||||
|
||||
function current() public view returns (uint256) {
|
||||
return _counter.current();
|
||||
}
|
||||
|
||||
function increment() public {
|
||||
_counter.increment();
|
||||
}
|
||||
|
||||
function decrement() public {
|
||||
_counter.decrement();
|
||||
}
|
||||
}
|
||||
@ -1,9 +1,9 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.2;
|
||||
|
||||
import "../crowdsale/Crowdsale.sol";
|
||||
|
||||
contract CrowdsaleMock is Crowdsale {
|
||||
constructor(uint256 rate, address wallet, IERC20 token) public
|
||||
Crowdsale(rate, wallet, token) {
|
||||
}
|
||||
constructor (uint256 rate, address payable wallet, IERC20 token) public {
|
||||
Crowdsale.initialize(rate, wallet, token);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,15 +0,0 @@
|
||||
pragma solidity ^0.4.24;
|
||||
|
||||
import "../token/ERC20/ERC20.sol";
|
||||
import "../token/ERC20/ERC20Detailed.sol";
|
||||
|
||||
contract ERC20DetailedMock is ERC20, ERC20Detailed {
|
||||
constructor(
|
||||
string name,
|
||||
string symbol,
|
||||
uint8 decimals
|
||||
)
|
||||
ERC20Detailed(name, symbol, decimals)
|
||||
public
|
||||
{}
|
||||
}
|
||||
@ -1,23 +1,15 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.2;
|
||||
|
||||
import "../cryptography/ECDSA.sol";
|
||||
|
||||
contract ECDSAMock {
|
||||
using ECDSA for bytes32;
|
||||
using ECDSA for bytes32;
|
||||
|
||||
function recover(bytes32 hash, bytes signature)
|
||||
public
|
||||
pure
|
||||
returns (address)
|
||||
{
|
||||
return hash.recover(signature);
|
||||
}
|
||||
function recover(bytes32 hash, bytes memory signature) public pure returns (address) {
|
||||
return hash.recover(signature);
|
||||
}
|
||||
|
||||
function toEthSignedMessageHash(bytes32 hash)
|
||||
public
|
||||
pure
|
||||
returns (bytes32)
|
||||
{
|
||||
return hash.toEthSignedMessageHash();
|
||||
}
|
||||
function toEthSignedMessageHash(bytes32 hash) public pure returns (bytes32) {
|
||||
return hash.toEthSignedMessageHash();
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,66 +1,57 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.2;
|
||||
|
||||
import "../../introspection/IERC165.sol";
|
||||
|
||||
/**
|
||||
* https://github.com/ethereum/EIPs/blob/master/EIPS/eip-214.md#specification
|
||||
* > Any attempts to make state-changing operations inside an execution instance with STATIC set to true will instead throw an exception.
|
||||
* https://eips.ethereum.org/EIPS/eip-214#specification
|
||||
* From the specification:
|
||||
* > Any attempts to make state-changing operations inside an execution instance with STATIC set to true will instead
|
||||
* throw an exception.
|
||||
* > These operations include [...], LOG0, LOG1, LOG2, [...]
|
||||
*
|
||||
* therefore, because this contract is staticcall'd we need to not emit events (which is how solidity-coverage works)
|
||||
* solidity-coverage ignores the /mocks folder, so we duplicate its implementation here to avoid instrumenting it
|
||||
*/
|
||||
contract SupportsInterfaceWithLookupMock is IERC165 {
|
||||
bytes4 public constant INTERFACE_ID_ERC165 = 0x01ffc9a7;
|
||||
/*
|
||||
* 0x01ffc9a7 ===
|
||||
* bytes4(keccak256('supportsInterface(bytes4)'))
|
||||
*/
|
||||
|
||||
bytes4 public constant InterfaceId_ERC165 = 0x01ffc9a7;
|
||||
/**
|
||||
* 0x01ffc9a7 ===
|
||||
* bytes4(keccak256('supportsInterface(bytes4)'))
|
||||
*/
|
||||
/**
|
||||
* @dev a mapping of interface id to whether or not it's supported
|
||||
*/
|
||||
mapping(bytes4 => bool) private _supportedInterfaces;
|
||||
|
||||
/**
|
||||
* @dev a mapping of interface id to whether or not it's supported
|
||||
*/
|
||||
mapping(bytes4 => bool) private _supportedInterfaces;
|
||||
/**
|
||||
* @dev A contract implementing SupportsInterfaceWithLookup
|
||||
* implement ERC165 itself
|
||||
*/
|
||||
constructor () public {
|
||||
_registerInterface(INTERFACE_ID_ERC165);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev A contract implementing SupportsInterfaceWithLookup
|
||||
* implement ERC165 itself
|
||||
*/
|
||||
constructor()
|
||||
public
|
||||
{
|
||||
_registerInterface(InterfaceId_ERC165);
|
||||
}
|
||||
/**
|
||||
* @dev implement supportsInterface(bytes4) using a lookup table
|
||||
*/
|
||||
function supportsInterface(bytes4 interfaceId) external view returns (bool) {
|
||||
return _supportedInterfaces[interfaceId];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev implement supportsInterface(bytes4) using a lookup table
|
||||
*/
|
||||
function supportsInterface(bytes4 interfaceId)
|
||||
external
|
||||
view
|
||||
returns (bool)
|
||||
{
|
||||
return _supportedInterfaces[interfaceId];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev private method for registering an interface
|
||||
*/
|
||||
function _registerInterface(bytes4 interfaceId)
|
||||
internal
|
||||
{
|
||||
require(interfaceId != 0xffffffff);
|
||||
_supportedInterfaces[interfaceId] = true;
|
||||
}
|
||||
/**
|
||||
* @dev private method for registering an interface
|
||||
*/
|
||||
function _registerInterface(bytes4 interfaceId) internal {
|
||||
require(interfaceId != 0xffffffff);
|
||||
_supportedInterfaces[interfaceId] = true;
|
||||
}
|
||||
}
|
||||
|
||||
contract ERC165InterfacesSupported is SupportsInterfaceWithLookupMock {
|
||||
constructor (bytes4[] interfaceIds)
|
||||
public
|
||||
{
|
||||
for (uint256 i = 0; i < interfaceIds.length; i++) {
|
||||
_registerInterface(interfaceIds[i]);
|
||||
constructor (bytes4[] memory interfaceIds) public {
|
||||
for (uint256 i = 0; i < interfaceIds.length; i++) {
|
||||
_registerInterface(interfaceIds[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.2;
|
||||
|
||||
contract ERC165NotSupported {
|
||||
|
||||
// solhint-disable-previous-line no-empty-blocks
|
||||
}
|
||||
|
||||
@ -1,31 +1,19 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.2;
|
||||
|
||||
import "../introspection/ERC165Checker.sol";
|
||||
|
||||
contract ERC165CheckerMock {
|
||||
using ERC165Checker for address;
|
||||
using ERC165Checker for address;
|
||||
|
||||
function supportsERC165(address account)
|
||||
public
|
||||
view
|
||||
returns (bool)
|
||||
{
|
||||
return account._supportsERC165();
|
||||
}
|
||||
function supportsERC165(address account) public view returns (bool) {
|
||||
return account._supportsERC165();
|
||||
}
|
||||
|
||||
function supportsInterface(address account, bytes4 interfaceId)
|
||||
public
|
||||
view
|
||||
returns (bool)
|
||||
{
|
||||
return account._supportsInterface(interfaceId);
|
||||
}
|
||||
function supportsInterface(address account, bytes4 interfaceId) public view returns (bool) {
|
||||
return account._supportsInterface(interfaceId);
|
||||
}
|
||||
|
||||
function supportsAllInterfaces(address account, bytes4[] interfaceIds)
|
||||
public
|
||||
view
|
||||
returns (bool)
|
||||
{
|
||||
return account._supportsAllInterfaces(interfaceIds);
|
||||
}
|
||||
function supportsAllInterfaces(address account, bytes4[] memory interfaceIds) public view returns (bool) {
|
||||
return account._supportsAllInterfaces(interfaceIds);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,11 +1,13 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.2;
|
||||
|
||||
import "../introspection/ERC165.sol";
|
||||
|
||||
contract ERC165Mock is ERC165 {
|
||||
function registerInterface(bytes4 interfaceId)
|
||||
public
|
||||
{
|
||||
_registerInterface(interfaceId);
|
||||
}
|
||||
constructor() public {
|
||||
ERC165.initialize();
|
||||
}
|
||||
|
||||
function registerInterface(bytes4 interfaceId) public {
|
||||
_registerInterface(interfaceId);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,11 +1,9 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.2;
|
||||
|
||||
import "../token/ERC20/ERC20Burnable.sol";
|
||||
|
||||
contract ERC20BurnableMock is ERC20Burnable {
|
||||
|
||||
constructor(address initialAccount, uint256 initialBalance) public {
|
||||
_mint(initialAccount, initialBalance);
|
||||
}
|
||||
|
||||
constructor(address initialAccount, uint256 initialBalance) public {
|
||||
_mint(initialAccount, initialBalance);
|
||||
}
|
||||
}
|
||||
|
||||
13
contracts/mocks/ERC20CappedMock.sol
Normal file
13
contracts/mocks/ERC20CappedMock.sol
Normal file
@ -0,0 +1,13 @@
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
import "../token/ERC20/ERC20Capped.sol";
|
||||
import "./MinterRoleMock.sol";
|
||||
|
||||
|
||||
contract ERC20CappedMock is ERC20Capped, MinterRoleMock {
|
||||
|
||||
constructor(uint256 cap) public {
|
||||
ERC20Capped.initialize(cap, msg.sender);
|
||||
}
|
||||
|
||||
}
|
||||
12
contracts/mocks/ERC20DetailedMock.sol
Normal file
12
contracts/mocks/ERC20DetailedMock.sol
Normal file
@ -0,0 +1,12 @@
|
||||
pragma solidity ^0.5.2;
|
||||
|
||||
import "../token/ERC20/ERC20.sol";
|
||||
import "../token/ERC20/ERC20Detailed.sol";
|
||||
|
||||
contract ERC20DetailedMock is ERC20, ERC20Detailed {
|
||||
constructor (string memory name, string memory symbol, uint8 decimals)
|
||||
public
|
||||
{
|
||||
ERC20Detailed.initialize(name, symbol, decimals);
|
||||
}
|
||||
}
|
||||
14
contracts/mocks/ERC20MetadataMock.sol
Normal file
14
contracts/mocks/ERC20MetadataMock.sol
Normal file
@ -0,0 +1,14 @@
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
import "../token/ERC20/ERC20.sol";
|
||||
import "../drafts/ERC1046/ERC20Metadata.sol";
|
||||
|
||||
contract ERC20MetadataMock is ERC20, ERC20Metadata {
|
||||
constructor (string memory tokenURI) public {
|
||||
ERC20Metadata.initialize(tokenURI);
|
||||
}
|
||||
|
||||
function setTokenURI(string memory tokenURI) public {
|
||||
_setTokenURI(tokenURI);
|
||||
}
|
||||
}
|
||||
12
contracts/mocks/ERC20MigratorMock.sol
Normal file
12
contracts/mocks/ERC20MigratorMock.sol
Normal file
@ -0,0 +1,12 @@
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
import "../drafts/ERC20Migrator.sol";
|
||||
|
||||
|
||||
contract ERC20MigratorMock is ERC20Migrator {
|
||||
|
||||
constructor(IERC20 legacyToken) public {
|
||||
ERC20Migrator.initialize(legacyToken);
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,7 +1,10 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.2;
|
||||
|
||||
import "../token/ERC20/ERC20Mintable.sol";
|
||||
import "./MinterRoleMock.sol";
|
||||
|
||||
contract ERC20MintableMock is ERC20Mintable, MinterRoleMock {
|
||||
constructor() public {
|
||||
ERC20Mintable.initialize(msg.sender);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,24 +1,26 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.2;
|
||||
|
||||
import "../token/ERC20/ERC20.sol";
|
||||
|
||||
// mock class using ERC20
|
||||
contract ERC20Mock is ERC20 {
|
||||
constructor (address initialAccount, uint256 initialBalance) public {
|
||||
_mint(initialAccount, initialBalance);
|
||||
}
|
||||
|
||||
constructor(address initialAccount, uint256 initialBalance) public {
|
||||
_mint(initialAccount, initialBalance);
|
||||
}
|
||||
function mint(address account, uint256 amount) public {
|
||||
_mint(account, amount);
|
||||
}
|
||||
|
||||
function mint(address account, uint256 amount) public {
|
||||
_mint(account, amount);
|
||||
}
|
||||
function burn(address account, uint256 amount) public {
|
||||
_burn(account, amount);
|
||||
}
|
||||
|
||||
function burn(address account, uint256 amount) public {
|
||||
_burn(account, amount);
|
||||
}
|
||||
|
||||
function burnFrom(address account, uint256 amount) public {
|
||||
_burnFrom(account, amount);
|
||||
}
|
||||
function burnFrom(address account, uint256 amount) public {
|
||||
_burnFrom(account, amount);
|
||||
}
|
||||
|
||||
function approveInternal(address owner, address spender, uint256 value) public {
|
||||
_approve(owner, spender, value);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,13 +1,12 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.2;
|
||||
|
||||
import "../token/ERC20/ERC20Pausable.sol";
|
||||
import "./PauserRoleMock.sol";
|
||||
|
||||
// mock class using ERC20Pausable
|
||||
contract ERC20PausableMock is ERC20Pausable, PauserRoleMock {
|
||||
|
||||
constructor(address initialAccount, uint initialBalance) public {
|
||||
_mint(initialAccount, initialBalance);
|
||||
}
|
||||
|
||||
constructor (address initialAccount, uint initialBalance) public {
|
||||
ERC20Pausable.initialize(msg.sender);
|
||||
_mint(initialAccount, initialBalance);
|
||||
}
|
||||
}
|
||||
|
||||
18
contracts/mocks/ERC20SnapshotMock.sol
Normal file
18
contracts/mocks/ERC20SnapshotMock.sol
Normal file
@ -0,0 +1,18 @@
|
||||
pragma solidity ^0.5.2;
|
||||
|
||||
import "../drafts/ERC20Snapshot.sol";
|
||||
|
||||
|
||||
contract ERC20SnapshotMock is ERC20Snapshot {
|
||||
constructor(address initialAccount, uint256 initialBalance) public {
|
||||
_mint(initialAccount, initialBalance);
|
||||
}
|
||||
|
||||
function mint(address account, uint256 amount) public {
|
||||
_mint(account, amount);
|
||||
}
|
||||
|
||||
function burn(address account, uint256 amount) public {
|
||||
_burn(account, amount);
|
||||
}
|
||||
}
|
||||
@ -1,11 +0,0 @@
|
||||
pragma solidity ^0.4.24;
|
||||
|
||||
import "../token/ERC20/ERC20.sol";
|
||||
import "../drafts/ERC1046/TokenMetadata.sol";
|
||||
|
||||
contract ERC20WithMetadataMock is ERC20, ERC20WithMetadata {
|
||||
constructor(string tokenURI) public
|
||||
ERC20WithMetadata(tokenURI)
|
||||
{
|
||||
}
|
||||
}
|
||||
@ -1,4 +1,4 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.2;
|
||||
|
||||
import "../token/ERC721/ERC721Full.sol";
|
||||
import "../token/ERC721/ERC721Mintable.sol";
|
||||
@ -7,26 +7,27 @@ import "../token/ERC721/ERC721Burnable.sol";
|
||||
|
||||
/**
|
||||
* @title ERC721FullMock
|
||||
* This mock just provides a public mint and burn functions for testing purposes,
|
||||
* and a public setter for metadata URI
|
||||
* This mock just provides public functions for setting metadata URI, getting all tokens of an owner,
|
||||
* checking token existence, removal of a token from an address
|
||||
*/
|
||||
contract ERC721FullMock
|
||||
is ERC721Full, ERC721Mintable, ERC721MetadataMintable, ERC721Burnable {
|
||||
contract ERC721FullMock is ERC721Full, ERC721Mintable, ERC721MetadataMintable, ERC721Burnable {
|
||||
constructor (string memory name, string memory symbol) public {
|
||||
ERC721.initialize();
|
||||
ERC721Metadata.initialize(name, symbol);
|
||||
ERC721Enumerable.initialize();
|
||||
ERC721Mintable.initialize(msg.sender);
|
||||
ERC721MetadataMintable.initialize(msg.sender);
|
||||
}
|
||||
|
||||
constructor(string name, string symbol) public
|
||||
ERC721Mintable()
|
||||
ERC721Full(name, symbol)
|
||||
{}
|
||||
function exists(uint256 tokenId) public view returns (bool) {
|
||||
return _exists(tokenId);
|
||||
}
|
||||
|
||||
function exists(uint256 tokenId) public view returns (bool) {
|
||||
return _exists(tokenId);
|
||||
}
|
||||
function tokensOfOwner(address owner) public view returns (uint256[] memory) {
|
||||
return _tokensOfOwner(owner);
|
||||
}
|
||||
|
||||
function setTokenURI(uint256 tokenId, string uri) public {
|
||||
_setTokenURI(tokenId, uri);
|
||||
}
|
||||
|
||||
function removeTokenFrom(address from, uint256 tokenId) public {
|
||||
_removeTokenFrom(from, tokenId);
|
||||
}
|
||||
function setTokenURI(uint256 tokenId, string memory uri) public {
|
||||
_setTokenURI(tokenId, uri);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.2;
|
||||
|
||||
import "../token/ERC721/ERC721Full.sol";
|
||||
import "../token/ERC721/ERC721Mintable.sol";
|
||||
@ -8,13 +8,12 @@ import "../token/ERC721/ERC721Burnable.sol";
|
||||
/**
|
||||
* @title ERC721MintableBurnableImpl
|
||||
*/
|
||||
contract ERC721MintableBurnableImpl
|
||||
is ERC721Full, ERC721Mintable, ERC721MetadataMintable, ERC721Burnable {
|
||||
|
||||
constructor()
|
||||
ERC721Mintable()
|
||||
ERC721Full("Test", "TEST")
|
||||
public
|
||||
{
|
||||
}
|
||||
contract ERC721MintableBurnableImpl is ERC721Full, ERC721Mintable, ERC721MetadataMintable, ERC721Burnable {
|
||||
constructor () public {
|
||||
ERC721.initialize();
|
||||
ERC721Metadata.initialize("Test", "TEST");
|
||||
ERC721Enumerable.initialize();
|
||||
ERC721Mintable.initialize(msg.sender);
|
||||
ERC721MetadataMintable.initialize(msg.sender);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.2;
|
||||
|
||||
import "../token/ERC721/ERC721.sol";
|
||||
|
||||
@ -7,11 +7,19 @@ import "../token/ERC721/ERC721.sol";
|
||||
* This mock just provides a public mint and burn functions for testing purposes
|
||||
*/
|
||||
contract ERC721Mock is ERC721 {
|
||||
function mint(address to, uint256 tokenId) public {
|
||||
_mint(to, tokenId);
|
||||
}
|
||||
constructor() public {
|
||||
ERC721.initialize();
|
||||
}
|
||||
|
||||
function burn(uint256 tokenId) public {
|
||||
_burn(ownerOf(tokenId), tokenId);
|
||||
}
|
||||
function mint(address to, uint256 tokenId) public {
|
||||
_mint(to, tokenId);
|
||||
}
|
||||
|
||||
function burn(address owner, uint256 tokenId) public {
|
||||
_burn(owner, tokenId);
|
||||
}
|
||||
|
||||
function burn(uint256 tokenId) public {
|
||||
_burn(tokenId);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.2;
|
||||
|
||||
import "../token/ERC721/ERC721Pausable.sol";
|
||||
import "./PauserRoleMock.sol";
|
||||
@ -8,15 +8,20 @@ import "./PauserRoleMock.sol";
|
||||
* This mock just provides a public mint, burn and exists functions for testing purposes
|
||||
*/
|
||||
contract ERC721PausableMock is ERC721Pausable, PauserRoleMock {
|
||||
function mint(address to, uint256 tokenId) public {
|
||||
super._mint(to, tokenId);
|
||||
}
|
||||
constructor() public {
|
||||
ERC721.initialize();
|
||||
ERC721Pausable.initialize(msg.sender);
|
||||
}
|
||||
|
||||
function burn(uint256 tokenId) public {
|
||||
super._burn(ownerOf(tokenId), tokenId);
|
||||
}
|
||||
function mint(address to, uint256 tokenId) public {
|
||||
super._mint(to, tokenId);
|
||||
}
|
||||
|
||||
function exists(uint256 tokenId) public view returns (bool) {
|
||||
return super._exists(tokenId);
|
||||
}
|
||||
function burn(uint256 tokenId) public {
|
||||
super._burn(tokenId);
|
||||
}
|
||||
|
||||
function exists(uint256 tokenId) public view returns (bool) {
|
||||
return super._exists(tokenId);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,41 +1,23 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.2;
|
||||
|
||||
import "../token/ERC721/IERC721Receiver.sol";
|
||||
|
||||
contract ERC721ReceiverMock is IERC721Receiver {
|
||||
bytes4 private _retval;
|
||||
bool private _reverts;
|
||||
bytes4 private _retval;
|
||||
bool private _reverts;
|
||||
|
||||
event Received(
|
||||
address operator,
|
||||
address from,
|
||||
uint256 tokenId,
|
||||
bytes data,
|
||||
uint256 gas
|
||||
);
|
||||
event Received(address operator, address from, uint256 tokenId, bytes data, uint256 gas);
|
||||
|
||||
constructor(bytes4 retval, bool reverts) public {
|
||||
_retval = retval;
|
||||
_reverts = reverts;
|
||||
}
|
||||
constructor (bytes4 retval, bool reverts) public {
|
||||
_retval = retval;
|
||||
_reverts = reverts;
|
||||
}
|
||||
|
||||
function onERC721Received(
|
||||
address operator,
|
||||
address from,
|
||||
uint256 tokenId,
|
||||
bytes data
|
||||
)
|
||||
public
|
||||
returns(bytes4)
|
||||
{
|
||||
require(!_reverts);
|
||||
emit Received(
|
||||
operator,
|
||||
from,
|
||||
tokenId,
|
||||
data,
|
||||
gasleft() // msg.gas was deprecated in solidityv0.4.21
|
||||
);
|
||||
return _retval;
|
||||
}
|
||||
function onERC721Received(address operator, address from, uint256 tokenId, bytes memory data)
|
||||
public returns (bytes4)
|
||||
{
|
||||
require(!_reverts);
|
||||
emit Received(operator, from, tokenId, data, gasleft());
|
||||
return _retval;
|
||||
}
|
||||
}
|
||||
|
||||
9
contracts/mocks/EscrowMock.sol
Normal file
9
contracts/mocks/EscrowMock.sol
Normal file
@ -0,0 +1,9 @@
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
import "../payment/escrow/Escrow.sol";
|
||||
|
||||
contract EscrowMock is Escrow {
|
||||
constructor() public {
|
||||
Escrow.initialize(msg.sender);
|
||||
}
|
||||
}
|
||||
@ -1,62 +1,73 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.2;
|
||||
|
||||
contract EventEmitter {
|
||||
event Argumentless();
|
||||
event ShortUint(uint8 value);
|
||||
event ShortInt(int8 value);
|
||||
event LongUint(uint256 value);
|
||||
event LongInt(int256 value);
|
||||
event Address(address value);
|
||||
event Boolean(bool value);
|
||||
event String(string value);
|
||||
event LongUintBooleanString(
|
||||
uint256 uintValue,
|
||||
bool booleanValue,
|
||||
string stringValue
|
||||
);
|
||||
event Argumentless();
|
||||
event ShortUint(uint8 value);
|
||||
event ShortInt(int8 value);
|
||||
event LongUint(uint256 value);
|
||||
event LongInt(int256 value);
|
||||
event Address(address value);
|
||||
event Boolean(bool value);
|
||||
event String(string value);
|
||||
event LongUintBooleanString(uint256 uintValue, bool booleanValue, string stringValue);
|
||||
|
||||
function emitArgumentless() public {
|
||||
emit Argumentless();
|
||||
}
|
||||
constructor (uint8 uintValue, bool booleanValue, string memory stringValue) public {
|
||||
emit ShortUint(uintValue);
|
||||
emit Boolean(booleanValue);
|
||||
emit String(stringValue);
|
||||
}
|
||||
|
||||
function emitShortUint(uint8 value) public {
|
||||
emit ShortUint(value);
|
||||
}
|
||||
function emitArgumentless() public {
|
||||
emit Argumentless();
|
||||
}
|
||||
|
||||
function emitShortInt(int8 value) public {
|
||||
emit ShortInt(value);
|
||||
}
|
||||
function emitShortUint(uint8 value) public {
|
||||
emit ShortUint(value);
|
||||
}
|
||||
|
||||
function emitLongUint(uint256 value) public {
|
||||
emit LongUint(value);
|
||||
}
|
||||
function emitShortInt(int8 value) public {
|
||||
emit ShortInt(value);
|
||||
}
|
||||
|
||||
function emitLongInt(int256 value) public {
|
||||
emit LongInt(value);
|
||||
}
|
||||
function emitLongUint(uint256 value) public {
|
||||
emit LongUint(value);
|
||||
}
|
||||
|
||||
function emitAddress(address value) public {
|
||||
emit Address(value);
|
||||
}
|
||||
function emitLongInt(int256 value) public {
|
||||
emit LongInt(value);
|
||||
}
|
||||
|
||||
function emitBoolean(bool value) public {
|
||||
emit Boolean(value);
|
||||
}
|
||||
function emitAddress(address value) public {
|
||||
emit Address(value);
|
||||
}
|
||||
|
||||
function emitString(string value) public {
|
||||
emit String(value);
|
||||
}
|
||||
function emitBoolean(bool value) public {
|
||||
emit Boolean(value);
|
||||
}
|
||||
|
||||
function emitLongUintBooleanString(
|
||||
uint256 uintValue,
|
||||
bool booleanValue,
|
||||
string stringValue)
|
||||
public {
|
||||
emit LongUintBooleanString(uintValue, booleanValue, stringValue);
|
||||
}
|
||||
function emitString(string memory value) public {
|
||||
emit String(value);
|
||||
}
|
||||
|
||||
function emitLongUintAndBoolean(uint256 uintValue, bool boolValue) public {
|
||||
emit LongUint(uintValue);
|
||||
emit Boolean(boolValue);
|
||||
}
|
||||
function emitLongUintBooleanString(uint256 uintValue, bool booleanValue, string memory stringValue) public {
|
||||
emit LongUintBooleanString(uintValue, booleanValue, stringValue);
|
||||
}
|
||||
|
||||
function emitLongUintAndBoolean(uint256 uintValue, bool boolValue) public {
|
||||
emit LongUint(uintValue);
|
||||
emit Boolean(boolValue);
|
||||
}
|
||||
|
||||
function emitStringAndEmitIndirectly(string memory value, IndirectEventEmitter emitter) public {
|
||||
emit String(value);
|
||||
emitter.emitStringIndirectly(value);
|
||||
}
|
||||
}
|
||||
|
||||
contract IndirectEventEmitter {
|
||||
event IndirectString(string value);
|
||||
|
||||
function emitStringIndirectly(string memory value) public {
|
||||
emit IndirectString(value);
|
||||
}
|
||||
}
|
||||
|
||||
23
contracts/mocks/Failer.sol
Normal file
23
contracts/mocks/Failer.sol
Normal file
@ -0,0 +1,23 @@
|
||||
pragma solidity ^0.5.2;
|
||||
|
||||
contract Failer {
|
||||
uint256[] private array;
|
||||
|
||||
function dontFail() public pure {
|
||||
// solhint-disable-previous-line no-empty-blocks
|
||||
}
|
||||
|
||||
function failWithRevert() public pure {
|
||||
revert();
|
||||
}
|
||||
|
||||
function failWithThrow() public pure {
|
||||
assert(false);
|
||||
}
|
||||
|
||||
function failWithOutOfGas() public {
|
||||
for (uint256 i = 0; i < 2**200; ++i) {
|
||||
array.push(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,21 +1,13 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.2;
|
||||
|
||||
import "../token/ERC20/IERC20.sol";
|
||||
import "../crowdsale/distribution/FinalizableCrowdsale.sol";
|
||||
|
||||
contract FinalizableCrowdsaleImpl is FinalizableCrowdsale {
|
||||
|
||||
constructor (
|
||||
uint256 openingTime,
|
||||
uint256 closingTime,
|
||||
uint256 rate,
|
||||
address wallet,
|
||||
IERC20 token
|
||||
)
|
||||
public
|
||||
Crowdsale(rate, wallet, token)
|
||||
TimedCrowdsale(openingTime, closingTime)
|
||||
{
|
||||
}
|
||||
|
||||
constructor (uint256 openingTime, uint256 closingTime, uint256 rate, address payable wallet, IERC20 token)
|
||||
public
|
||||
{
|
||||
Crowdsale.initialize(rate, wallet, token);
|
||||
TimedCrowdsale.initialize(openingTime, closingTime);
|
||||
}
|
||||
}
|
||||
|
||||
18
contracts/mocks/ForceEther.sol
Normal file
18
contracts/mocks/ForceEther.sol
Normal file
@ -0,0 +1,18 @@
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
|
||||
// @title Force Ether into a contract.
|
||||
// @notice even
|
||||
// if the contract is not payable.
|
||||
// @notice To use, construct the contract with the target as argument.
|
||||
// @author Remco Bloemen <remco@neufund.org>
|
||||
contract ForceEther {
|
||||
|
||||
constructor() public payable {
|
||||
// solhint-disable-previous-line no-empty-blocks
|
||||
}
|
||||
|
||||
function destroyAndSend(address payable recipient) public {
|
||||
selfdestruct(recipient);
|
||||
}
|
||||
}
|
||||
@ -1,23 +1,21 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.2;
|
||||
|
||||
import "../crowdsale/price/IncreasingPriceCrowdsale.sol";
|
||||
import "../math/SafeMath.sol";
|
||||
|
||||
contract IncreasingPriceCrowdsaleImpl is IncreasingPriceCrowdsale {
|
||||
|
||||
constructor (
|
||||
uint256 openingTime,
|
||||
uint256 closingTime,
|
||||
address wallet,
|
||||
IERC20 token,
|
||||
uint256 initialRate,
|
||||
uint256 finalRate
|
||||
)
|
||||
public
|
||||
Crowdsale(initialRate, wallet, token)
|
||||
TimedCrowdsale(openingTime, closingTime)
|
||||
IncreasingPriceCrowdsale(initialRate, finalRate)
|
||||
{
|
||||
}
|
||||
|
||||
constructor (
|
||||
uint256 openingTime,
|
||||
uint256 closingTime,
|
||||
address payable wallet,
|
||||
IERC20 token,
|
||||
uint256 initialRate,
|
||||
uint256 finalRate
|
||||
)
|
||||
public
|
||||
{
|
||||
Crowdsale.initialize(initialRate, wallet, token);
|
||||
TimedCrowdsale.initialize(openingTime, closingTime);
|
||||
IncreasingPriceCrowdsale.initialize(initialRate, finalRate);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,19 +1,12 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.2;
|
||||
|
||||
import "../token/ERC20/IERC20.sol";
|
||||
import "../crowdsale/validation/IndividuallyCappedCrowdsale.sol";
|
||||
import "./CapperRoleMock.sol";
|
||||
|
||||
contract IndividuallyCappedCrowdsaleImpl
|
||||
is IndividuallyCappedCrowdsale, CapperRoleMock {
|
||||
|
||||
constructor(
|
||||
uint256 rate,
|
||||
address wallet,
|
||||
IERC20 token
|
||||
)
|
||||
public
|
||||
Crowdsale(rate, wallet, token)
|
||||
{
|
||||
}
|
||||
contract IndividuallyCappedCrowdsaleImpl is IndividuallyCappedCrowdsale, CapperRoleMock {
|
||||
constructor (uint256 rate, address payable wallet, IERC20 token) public {
|
||||
Crowdsale.initialize(rate, wallet, token);
|
||||
IndividuallyCappedCrowdsale.initialize(msg.sender);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,17 +1,17 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.2;
|
||||
|
||||
import "../math/Math.sol";
|
||||
|
||||
contract MathMock {
|
||||
function max(uint256 a, uint256 b) public pure returns (uint256) {
|
||||
return Math.max(a, b);
|
||||
}
|
||||
function max(uint256 a, uint256 b) public pure returns (uint256) {
|
||||
return Math.max(a, b);
|
||||
}
|
||||
|
||||
function min(uint256 a, uint256 b) public pure returns (uint256) {
|
||||
return Math.min(a, b);
|
||||
}
|
||||
function min(uint256 a, uint256 b) public pure returns (uint256) {
|
||||
return Math.min(a, b);
|
||||
}
|
||||
|
||||
function average(uint256 a, uint256 b) public pure returns (uint256) {
|
||||
return Math.average(a, b);
|
||||
}
|
||||
function average(uint256 a, uint256 b) public pure returns (uint256) {
|
||||
return Math.average(a, b);
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user