Compare commits

...

78 Commits

Author SHA1 Message Date
63a3665a17 3.0.0-rc.1 2020-04-03 16:22:56 -03:00
92a60b2587 Merge branch 'master' into release-v3.0.0 2020-04-03 16:22:25 -03:00
a0f6bd3926 Add 'deploy-ready' token contracts (#2167)
* Add ERC20DeployReady

* Add ERC721DeployReady

* Improve docs

* Fix linter errors

* Rename DeployReady contracts to MinterPauser, add docs

* Fix deploy ready docs

* Minor doc adjustment
2020-04-03 16:21:58 -03:00
402c6ab4cc Update docs (#2168)
* Update docs for ERC20 and ERC721

* Add EnumerableMap to docs

* Update misc guides

* Apply suggestions from code review

Co-Authored-By: Francisco Giordano <frangio.1@gmail.com>

Co-authored-by: Francisco Giordano <frangio.1@gmail.com>
2020-04-03 13:17:24 -03:00
6668a4d05c Remove unused behavior 2020-04-02 19:14:33 -03:00
bd0778461d Add EnumerableMap, refactor ERC721 (#2160)
* Implement AddressSet in terms of a generic Set

* Add Uint256Set

* Add EnumerableMap

* Fix wording on EnumerableSet docs and tests

* Refactor ERC721 using EnumerableSet and EnumerableMap

* Fix tests

* Fix linter error

* Gas optimization for EnumerableMap

* Gas optimization for EnumerableSet

* Remove often not-taken if from Enumerable data structures

* Fix failing test

* Gas optimization for EnumerableMap

* Fix linter errors

* Add comment for clarification

* Improve test naming

* Rename EnumerableMap.add to set

* Add overload for EnumerableMap.get with custom error message

* Improve Enumerable docs

* Rename Uint256Set to UintSet

* Add changelog entry
2020-04-02 15:43:06 -03:00
0408e51ae6 Bundle ERC20Detailed (#2161)
* Merge ERC20Detailed into ERC20, make derived contracts abstract

* Fix Create2 tests

* Fix failing test

* Default decimals to 18

* Add tests for setupDecimals

* Add changelog entry

* Update CHANGELOG.md

* Update CHANGELOG.md

* Replace isConstructor for !isContract

* Update CHANGELOG.md

Co-Authored-By: Francisco Giordano <frangio.1@gmail.com>

Co-authored-by: Francisco Giordano <frangio.1@gmail.com>
2020-04-02 15:30:21 -03:00
5b5d91c9d4 Remove 'external' functions (#2162)
* Remove _grantRole and _revokeRole, replace with _setupRole

* Make all external AccessControl functions public

* Remove Ownable._transferOwnership

* Rename ERC721's _safeTransferFrom and _transferFrom to _safeTransfer and _transfer

* Make all ERC721 external functions public

* Make all miscelaneous external functions public instead

* Add changelog entry

* Move calldata arguments to memory

* Update contracts/access/AccessControl.sol

Co-Authored-By: Francisco Giordano <frangio.1@gmail.com>

* Restrict setupRole to the constructor

* Replace isConstructor for !isContract

Co-authored-by: Francisco Giordano <frangio.1@gmail.com>
2020-04-02 15:29:58 -03:00
1bc923b6a2 fix use of asciidoc quotes 2020-03-30 20:13:30 -03:00
d704b5257b Fix typo in changelog, replace burn(owner) with burn(tokenId) (#2159) 2020-03-30 13:34:36 -03:00
06ae096586 Bump @openzeppelin/cli from 2.7.2 to 2.8.0 (#2157)
Bumps [@openzeppelin/cli](https://github.com/OpenZeppelin/openzeppelin-sdk) from 2.7.2 to 2.8.0.
- [Release notes](https://github.com/OpenZeppelin/openzeppelin-sdk/releases)
- [Commits](https://github.com/OpenZeppelin/openzeppelin-sdk/compare/v2.7.2...v2.8.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-03-30 13:22:59 -03:00
0f9adc1749 Fix broken xrefs (#2153)
* fix mentions of drafts.adoc

* fix 721.adoc
2020-03-30 12:47:13 -03:00
feb7ead005 Add revert if the bytecode length is zero (#2117)
* Add revert if the bytecode length is not greater than zero

* Add value parameter to create2 deploy function

Add tests for contract balance revert and depositing funds

* Change parameter name to amount for clarity

* Fix test for value sending

* Fix linter error

* Change revert reason

* Improve Create2.deploy documentation

* Slight test improvement

* Add changelog entry

Co-authored-by: Nicolás Venturo <nicolas.venturo@gmail.com>
2020-03-28 12:55:13 -03:00
7415ebe8bc API improvements for EnumerableSet (#2151)
* Add revert reason to EnumerableSet.get.

* Rename EnumerableSet values to keys

* Rename get to at

* Add changelog entry

* Rename keys to values

* Add leading underscore to struct members
2020-03-27 18:39:18 -03:00
24c37c1f9e Bundle ERC721 extensions into base contract (#2149)
* Add IERC721Metadata implementation into ERC721

* Add IERC721Enumerable into ERC721

* Update ERC721Pausable and ERC721Burnable

* Delete ERC721Metadata, ERC721Enumerable and ERC721 (now ERC721)

* Update mocks

* Update tests

* Update contracts/token/ERC721/ERC721.sol

Co-Authored-By: Francisco Giordano <frangio.1@gmail.com>

* Make ERC721Pausable and ERC721Burnable abstract

Co-authored-by: Francisco Giordano <frangio.1@gmail.com>
2020-03-27 17:27:41 -03:00
c8bef057f8 [Security] Bump acorn from 6.4.0 to 6.4.1 (#2152)
Bumps [acorn](https://github.com/acornjs/acorn) from 6.4.0 to 6.4.1. **This update includes a security fix.**
- [Release notes](https://github.com/acornjs/acorn/releases)
- [Commits](https://github.com/acornjs/acorn/compare/6.4.0...6.4.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-03-27 17:19:00 -03:00
97894a140d Adhere to naming convention (#2150)
* Upgrade to latest solhint rc

* Add private-vars-leading-underscore linter rule

* Add leading underscore to GSNRecipient constants

* Remove leading underscore from ERC165Checker functions

* Add leading underscore to multiple private constants

* Fix linter errors in mocks

* Add leading underscore to ERC777's ERC1820 registry

* Add changelog entry
2020-03-27 13:49:08 -03:00
4476a2d531 Unsigned conversion #2111 (#2123)
* Add signed to unsigned conversion to SafeCast

* Update SafeCast exception message

* Add test for SafeCast int to uint conversion

- Update SafeCastMock
- Add tests for SafeCast int256 to uint256

* Update SafeCast int to uint definition

Apply suggestions from code review.

Co-Authored-By: Nicolás Venturo <nicolas.venturo@gmail.com>

* Update test for SafeCast int to uint conversion

* Update SafeCast test after code review

- Change "downcasts" to "casts"
- Move test closer to its function

* Fix error in SafeCast toUint256 description

* Fix breaking error in SafeCast

* Add uint256 to int256 conversion to SafeCast

- Add function
- Add mock
- Add test

* Update SafeCast unsigned to signed conversion

- Update error in conversion to be more clear
- Update constants in test to be powers of 2 instead of shifts

* Add changelog entry

* Update SafeCast tests

- Add minus in INT256_MIN for clarity

Co-Authored-By: Nicolás Venturo <nicolas.venturo@gmail.com>

Co-authored-by: Nicolás Venturo <nicolas.venturo@gmail.com>
2020-03-27 10:56:30 -03:00
7554ea84a3 Update support request (#2148) 2020-03-26 10:11:55 -03:00
3118bb33ac Add forum link in new issue page 2020-03-25 19:59:41 -03:00
7c3606a19b Bump solidity-docgen from 0.4.0-beta.1 to 0.4.1 (#2145)
Bumps solidity-docgen from 0.4.0-beta.1 to 0.4.1.

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-03-25 15:06:43 -03:00
d6616fdb0d Bump mocha from 7.1.0 to 7.1.1 (#2144)
Bumps [mocha](https://github.com/mochajs/mocha) from 7.1.0 to 7.1.1.
- [Release notes](https://github.com/mochajs/mocha/releases)
- [Changelog](https://github.com/mochajs/mocha/blob/master/CHANGELOG.md)
- [Commits](https://github.com/mochajs/mocha/compare/v7.1.0...v7.1.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-03-25 15:06:10 -03:00
c8aab57d8c Bump eslint-config-standard from 14.1.0 to 14.1.1 (#2143)
Bumps [eslint-config-standard](https://github.com/standard/eslint-config-standard) from 14.1.0 to 14.1.1.
- [Release notes](https://github.com/standard/eslint-config-standard/releases)
- [Changelog](https://github.com/standard/eslint-config-standard/blob/master/CHANGELOG.md)
- [Commits](https://github.com/standard/eslint-config-standard/compare/v14.1.0...v14.1.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-03-25 15:05:46 -03:00
3ae631c81d Fix display of array arguments in documentation (#2141)
* remove pass:normal from docs template

* add back pass:normal for auto links
2020-03-20 19:22:24 -03:00
0afba1fb9d [Security] Bump handlebars from 4.1.2 to 4.7.3 (#2138)
Bumps [handlebars](https://github.com/wycats/handlebars.js) from 4.1.2 to 4.7.3. **This update includes a security fix.**
- [Release notes](https://github.com/wycats/handlebars.js/releases)
- [Changelog](https://github.com/wycats/handlebars.js/blob/master/release-notes.md)
- [Commits](https://github.com/wycats/handlebars.js/compare/v4.1.2...v4.7.3)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
Co-authored-by: Nicolás Venturo <nicolas.venturo@gmail.com>
2020-03-18 00:07:59 -03:00
a65bcfdbe8 [Security] Bump acorn from 5.7.3 to 6.4.1 (#2137)
Bumps [acorn](https://github.com/acornjs/acorn) from 5.7.3 to 6.4.1. **This update includes a security fix.**
- [Release notes](https://github.com/acornjs/acorn/releases)
- [Commits](https://github.com/acornjs/acorn/compare/5.7.3...6.4.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-03-18 00:07:34 -03:00
60a73c6365 Merge branch 'master' into release-v3.0.0 2020-03-17 12:01:13 -03:00
5112b6b1b5 update solidity-docgen with support for solidity 0.6 (#2136) 2020-03-17 12:00:43 -03:00
865aae0106 Temporarily hide hooks page 2020-03-17 11:49:05 -03:00
5ccecab631 Add prerelease marker 2020-03-17 11:48:13 -03:00
a3c6e5f088 3.0.0-rc.0 2020-03-16 20:47:28 -03:00
a8d6f13c94 Remove all 'available since' notices 2020-03-16 20:44:56 -03:00
e7b22483af Make ERC777 operator the caller (#2134)
* Make the sender the operator

* Make hook methods private

* Add changelog entry
2020-03-16 19:49:17 -03:00
90058040f0 Make AccessControl GSN compatible (#2135) 2020-03-16 19:40:28 -03:00
63c89c772b [Security] Bump acorn from 6.4.0 to 6.4.1 (#2132)
Bumps [acorn](https://github.com/acornjs/acorn) from 6.4.0 to 6.4.1. **This update includes a security fix.**
- [Release notes](https://github.com/acornjs/acorn/releases)
- [Commits](https://github.com/acornjs/acorn/compare/6.4.0...6.4.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-03-16 19:37:48 -03:00
9975a1a0c2 Remove Address.toPayable (#2133)
* Remove Address.toPayable

* Add changelog entry
2020-03-16 18:22:02 -03:00
eb34ae67ff Make IERC721 contracts interfaces instead (#2113)
* Make IERC721 contracts interfaces instead

* Bump minimum compiler version for IERC721
2020-03-16 18:21:16 -03:00
f1db30955d Remove deprecated functions and contracts (#2125)
* Remove ERC721.burn(owner, tokenId)

* Remove ERC721._checkOnERC721Received from the contract's API

* Fix linter error

* Remove Escrow and PullPayment withdrawWithGas, replace for withdraw

* Add changelog entry

* Add reentrancy notice
2020-03-16 17:42:33 -03:00
c173392e15 Revamped Access Control (#2112)
* Remove Roles

* Add AccessControl and tests

* Removed IAccessControl

* Add RoleGranted and RoleRevoked events

* Make roles grantable and revokable regardless of their previous status

* Fix typo

* Add documentation

* Cleanup tests

* Add enumeration tests

* Add _setRoleAdmin tests

* Fix lint error

* Fix AccessControl link in docs

* WIP on access control guide

* Rename getRoleMembersCount

* Add tests for new role admin

* Make AccessControl GSN compatible

* Update access control guide

* Rename admin to adminRole

* Rename roleIds to roles

* Add 'operator' to RoleGranted and RoleRevoked events.

* Only emit events if the roles were not previously granted/revoked

* Uncomment expectEvent.not tests

* Rename operator to sender

* Add changelog entry
2020-03-16 17:41:24 -03:00
c9630526e2 Draft and lifecycles directories cleanup (#2122)
* Move Pausable into utils

* Move Strings into utils

* Move Counters into utils

* Move SignedSafeMath into math

* Remove ERC1046

* Make ERC20Snapshot.snapshot internal

* Move ERC20Snapshot into ERC20

* Add drafts deprecation notice

* Remove drafts directory

* Add changelog entry

* Apply suggestions from code review

Co-Authored-By: Francisco Giordano <frangio.1@gmail.com>

Co-authored-by: Francisco Giordano <frangio.1@gmail.com>
2020-03-16 16:27:15 -03:00
8176a901a9 Cleanup of Ownership directory (#2120)
* Remove Ownable.isOwner.

* Remove ownable behavior from tests

* Make Escrow use Ownable instead of Secondary

* Migrate GSNRecipientERC20Fee to Ownable

* Remove Secondary

* Move Ownable to access directory

* Remove mentions of Secondary

* Add changelog entry

* Move Ownable tests to access

* Remove unused mock
2020-03-16 15:12:29 -03:00
baaadde3c5 Remove ERC20._burnFrom (#2119)
* Remove ERC20._burnFrom

* Add changelog entry
2020-03-16 15:06:19 -03:00
68ad1ed18f Bump @openzeppelin/cli from 2.7.1 to 2.7.2 (#2129)
Bumps [@openzeppelin/cli](https://github.com/OpenZeppelin/openzeppelin-sdk) from 2.7.1 to 2.7.2.
- [Release notes](https://github.com/OpenZeppelin/openzeppelin-sdk/releases)
- [Commits](https://github.com/OpenZeppelin/openzeppelin-sdk/compare/v2.7.1...v2.7.2)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-03-16 13:28:42 -03:00
d14007d035 Bump @openzeppelin/test-helpers from 0.5.4 to 0.5.5 (#2127)
Bumps [@openzeppelin/test-helpers](https://github.com/OpenZeppelin/openzeppelin-test-helpers) from 0.5.4 to 0.5.5.
- [Release notes](https://github.com/OpenZeppelin/openzeppelin-test-helpers/releases)
- [Changelog](https://github.com/OpenZeppelin/openzeppelin-test-helpers/blob/master/CHANGELOG.md)
- [Commits](https://github.com/OpenZeppelin/openzeppelin-test-helpers/compare/v0.5.4...v0.5.5)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-03-16 13:28:18 -03:00
a949d4e2bf Bump @openzeppelin/gsn-provider from 0.1.9 to 0.1.10 (#2126)
Bumps [@openzeppelin/gsn-provider](https://github.com/OpenZeppelin/openzeppelin-gsn-provider) from 0.1.9 to 0.1.10.
- [Release notes](https://github.com/OpenZeppelin/openzeppelin-gsn-provider/releases)
- [Changelog](https://github.com/OpenZeppelin/openzeppelin-gsn-provider/blob/master/CHANGELOG.md)
- [Commits](https://github.com/OpenZeppelin/openzeppelin-gsn-provider/compare/v0.1.9...v0.1.10)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-03-16 13:28:05 -03:00
ed2c289c2c Bump acorn from 6.4.0 to 6.4.1 (#2124)
Bumps [acorn](https://github.com/acornjs/acorn) from 6.4.0 to 6.4.1.
- [Release notes](https://github.com/acornjs/acorn/releases)
- [Commits](https://github.com/acornjs/acorn/compare/6.4.0...6.4.1)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2020-03-13 17:54:03 -03:00
7acd60d152 Add notice about deprecated Crowdsales (#2116)
* Remove crowdsales from sidebar documentation, add links to old version

* Remove mentions of Crowdsales from the documentation
2020-03-11 15:26:21 -03:00
0449062126 Bump solhint from 3.0.0-rc.3 to 3.0.0-rc.5 (#2109)
Bumps [solhint](https://github.com/protofire/solhint) from 3.0.0-rc.3 to 3.0.0-rc.5.
- [Release notes](https://github.com/protofire/solhint/releases)
- [Changelog](https://github.com/protofire/solhint/blob/master/CHANGELOG.md)
- [Commits](https://github.com/protofire/solhint/commits)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-03-11 12:56:26 -03:00
65e4ffde58 Make ECDSA.recover revert on error. (#2114)
* Make ECDSA.recover revert on error

* Removed unused test

* Remove duplicate line

* Add tests for invalid signatures

* Fix linter errors

* Add changelog entry
2020-03-10 20:13:32 -03:00
e2813df879 Use bytes32 explicitly for Create2.computeAddress() (#2088)
* Use bytes32 explicitly for Create2.computeAddress(), to force users cache hash of the bytecode

* Remove only from test :)
2020-03-09 13:02:14 -03:00
ca19cea05e install @openzeppelin/docs-utils 2020-03-09 11:37:41 -03:00
3296ca7219 Rearrange erc721metadata layout to mimic eth-pkg (#2098)
In https://github.com/OpenZeppelin/openzeppelin-contracts-ethereum-package/pull/76, we are rearranging the erc721metadata contract storage layout, so the new variable is added at the end. This commit applies the same change to the vanilla contracts repository, so migration from 2.5 to 3.0 is easier for users using the transpiler.
2020-03-04 15:31:57 -03:00
cb458f3250 Bump mocha from 7.0.1 to 7.1.0 (#2104)
Bumps [mocha](https://github.com/mochajs/mocha) from 7.0.1 to 7.1.0.
- [Release notes](https://github.com/mochajs/mocha/releases)
- [Changelog](https://github.com/mochajs/mocha/blob/master/CHANGELOG.md)
- [Commits](https://github.com/mochajs/mocha/compare/v7.0.1...v7.1.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-03-02 13:05:48 -03:00
21d2b90d74 allow running specific test files on their own 2020-02-28 18:56:14 -03:00
ab19138f1f Bump @openzeppelin/test-environment from 0.1.2 to 0.1.3 (#2101)
Bumps [@openzeppelin/test-environment](https://github.com/OpenZeppelin/openzeppelin-test-environment) from 0.1.2 to 0.1.3.
- [Release notes](https://github.com/OpenZeppelin/openzeppelin-test-environment/releases)
- [Changelog](https://github.com/OpenZeppelin/openzeppelin-test-environment/blob/master/CHANGELOG.md)
- [Commits](https://github.com/OpenZeppelin/openzeppelin-test-environment/compare/v0.1.2...v0.1.3)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-02-26 15:17:07 -03:00
970122a9d5 Bump solhint from 3.0.0-rc.2 to 3.0.0-rc.3 (#2096)
Bumps [solhint](https://github.com/protofire/solhint) from 3.0.0-rc.2 to 3.0.0-rc.3.
- [Release notes](https://github.com/protofire/solhint/releases)
- [Changelog](https://github.com/protofire/solhint/blob/master/CHANGELOG.md)
- [Commits](https://github.com/protofire/solhint/commits)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-02-18 11:20:10 -03:00
62065cf043 add prepare-docs script to subpackage 2020-02-17 19:02:13 -03:00
03b61e074e Bump @openzeppelin/cli from 2.7.0-rc.2 to 2.7.1 (#2097)
Bumps [@openzeppelin/cli](https://github.com/OpenZeppelin/openzeppelin-sdk) from 2.7.0-rc.2 to 2.7.1.
- [Release notes](https://github.com/OpenZeppelin/openzeppelin-sdk/releases)
- [Commits](https://github.com/OpenZeppelin/openzeppelin-sdk/compare/v2.7.0-rc.2...v2.7.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-02-17 18:22:57 -03:00
1350f49939 Bump openzeppelin-docs-utils from af3466e to 459f171 (#2094)
Bumps [openzeppelin-docs-utils](https://github.com/OpenZeppelin/docs-utils) from `af3466e` to `459f171`.
- [Release notes](https://github.com/OpenZeppelin/docs-utils/releases)
- [Commits](af3466e234...459f1710a0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-02-17 17:00:43 -03:00
1c22c79a32 [Security] Bump eslint-utils from 1.4.0 to 1.4.3 (#2093)
Bumps [eslint-utils](https://github.com/mysticatea/eslint-utils) from 1.4.0 to 1.4.3. **This update includes security fixes.**
- [Release notes](https://github.com/mysticatea/eslint-utils/releases)
- [Commits](https://github.com/mysticatea/eslint-utils/compare/v1.4.0...v1.4.3)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-02-17 16:43:26 -03:00
08cea10aa7 Fix operatorBurn description typo. (#2091) 2020-02-17 16:31:26 -03:00
82147dc2ee [Security] Bump handlebars from 4.1.2 to 4.7.3 (#2095)
Bumps [handlebars](https://github.com/wycats/handlebars.js) from 4.1.2 to 4.7.3. **This update includes a security fix.**
- [Release notes](https://github.com/wycats/handlebars.js/releases)
- [Changelog](https://github.com/wycats/handlebars.js/blob/master/release-notes.md)
- [Commits](https://github.com/wycats/handlebars.js/compare/v4.1.2...v4.7.3)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-02-17 16:23:28 -03:00
e4d2830f1d Update release script for major releases 2020-02-14 13:37:28 -03:00
19417c7cd5 Rename CREATE2 argument from bytecodeHash to bytecode and add new method for precomputed bytecode hash (#2087)
* Rename CREATE2 argument from bytecodeHash to bytecode and add new method for precomputed bytecode hash

* Remove only from test

* Fix linter error
2020-02-14 11:29:38 -03:00
5dfe7215a9 Migrate Contracts to Solidity v0.6 (#2080)
* Initial migration to Solidity 0.6.x - v3.0 first steps (#2063)

* Initial migration, missing GSN, 721, 777 and Crowdsales.

* Add _beforeTokenOperation and _afterTokenOperation.

* Add documentation for hooks.

* Add hooks doc

* Add missing drafts

* Add back ERC721 with hooks

* Bring back ERC777

* Notes on hooks

* Bring back GSN

* Make functions virtual

* Make GSN overrides explicit

* Fix ERC20Pausable tests

* Remove virtual from some view functions

* Update linter

* Delete examples

* Remove unnecessary virtual

* Remove roles from Pausable

* Remove roles

* Remove users of roles

* Adapt ERC20 tests

* Fix ERC721 tests

* Add all ERC721 hooks

* Add ERC777 hooks

* Fix remaining tests

* Bump compiler version

* Move 721BurnableMock into mocks directory

* Remove _before hooks

* Fix tests

* Upgrade linter

* Put modifiers last

* Remove _beforeTokenApproval and _beforeOperatorApproval hooks
2020-02-14 11:12:32 -03:00
04a1b21874 update docs-utils to keep docs version in sync 2020-02-11 19:04:17 -03:00
f905a14f5f Fix docsite link 2020-02-06 18:07:03 -03:00
4a531fe588 Add note about gas costs (#2079)
* Add note about gas costs

* Update wording
2020-02-06 15:26:19 -03:00
25dec297bf Bump solidity-docgen (#2078) 2020-02-05 12:07:29 -03:00
8e58cda8c3 Revert "Fix ignoring mock artifacts on release"
This reverts commit e7bded655b.
2020-02-05 00:04:29 -03:00
e7bded655b Fix ignoring mock artifacts on release 2020-02-04 20:23:01 -03:00
5f357d85de Merge branch 'release-v2.5.0' 2020-02-04 20:22:32 -03:00
7988c044e0 EnumerableSet improvements (#2077)
* Remove newAddressSet

* Add count and get functions.

* Fix lint
2020-02-04 19:15:32 -03:00
8975289c6b Fix EnumerableSetMock for 2.5.rc1 (#2069)
* Drafted Enumerable.sol.

* Drafted test framework.

* Tweaked the tests to follow oz structure.

* Coded EnumerableSet.

* Moved EnumerableSet to `utils`.

* Fixed linting.

* Improved comments.

* Tweaked contract description.

* Renamed struct to AddressSet.

* Relaxed version pragma to 0.5.0

* Removed events.

* Revert on useless operations.

* Small comment.

* Created AddressSet factory method.

* Failed transactions return false.

* Transactions now return false on failure.

* Remove comments from mock

* Rename mock functions

* Adapt tests to code style, use test-helpers

* Fix bug in remove, improve tests.

* Add changelog entry

* Add entry on Utils doc

* Add optimization for removal of last slot

* Update docs

* Fix headings of utilities documentation

* Simplified mock.

* Fixed comment.

* Revert "Fixed comment."

This reverts commit 39627f9a6f.

* Revert "Simplified mock."

This reverts commit 67468e464b.

* Simplified mock.

Co-authored-by: Nicolás Venturo <nicolas.venturo@gmail.com>
2020-01-30 15:42:21 -03:00
6102ddf675 Update README link to learn guide (#2070)
Reported from Community Member via Intercom
2020-01-30 14:30:52 -03:00
5a67a69f80 [Security] Bump eslint-utils from 1.4.0 to 1.4.3 (#2064)
Bumps [eslint-utils](https://github.com/mysticatea/eslint-utils) from 1.4.0 to 1.4.3. **This update includes security fixes.**
- [Release notes](https://github.com/mysticatea/eslint-utils/releases)
- [Commits](https://github.com/mysticatea/eslint-utils/compare/v1.4.0...v1.4.3)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-01-27 12:42:40 -03:00
f2512a4f7b [Security] Bump handlebars from 4.1.2 to 4.7.2 (#2065)
Bumps [handlebars](https://github.com/wycats/handlebars.js) from 4.1.2 to 4.7.2. **This update includes a security fix.**
- [Release notes](https://github.com/wycats/handlebars.js/releases)
- [Changelog](https://github.com/wycats/handlebars.js/blob/master/release-notes.md)
- [Commits](https://github.com/wycats/handlebars.js/compare/v4.1.2...v4.7.2)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-01-27 12:31:09 -03:00
06be0ab39a Bump mocha from 7.0.0 to 7.0.1 (#2066)
Bumps [mocha](https://github.com/mochajs/mocha) from 7.0.0 to 7.0.1.
- [Release notes](https://github.com/mochajs/mocha/releases)
- [Changelog](https://github.com/mochajs/mocha/blob/master/CHANGELOG.md)
- [Commits](https://github.com/mochajs/mocha/compare/v7.0.0...v7.0.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-01-27 12:30:42 -03:00
270 changed files with 9148 additions and 11799 deletions

4
.github/ISSUE_TEMPLATE/config.yml vendored Normal file
View File

@ -0,0 +1,4 @@
contact_links:
- name: Support request
url: https://forum.openzeppelin.com/c/support/contracts/18
about: Ask the community in the Community Forum

View File

@ -1,14 +1,10 @@
{
"extends": "solhint:recommended",
"rules": {
"indent": ["error", 4],
"func-order": "off",
"bracket-align": "off",
"compiler-fixed": "off",
"no-simple-event-func-name": "off",
"separate-by-one-line-in-contract": "off",
"two-lines-top-level-separator": "off",
"mark-callable-contracts": "off",
"compiler-version": ["error", "^0.5.0"]
"no-empty-blocks": "off",
"compiler-version": ["error", "^0.6.0"],
"private-vars-leading-underscore": "error"
}
}

View File

@ -1,5 +1,41 @@
# Changelog
## 3.0.0 (unreleased)
### New features
* `AccessControl`: new contract for managing permissions in a system, replacement for `Ownable` and `Roles`. ([#2112](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2112))
* `SafeCast`: new functions to convert to and from signed and unsigned values: `toUint256` and `toInt256`. ([#2123](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2123))
* `EnumerableMap`: a new data structure for key-value pairs (like `mapping`) that can be iterated over. ([#2160](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2160))
### Breaking changes
* `ERC721`: `burn(owner, tokenId)` was removed, use `burn(tokenId)` instead. ([#2125](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2125))
* `ERC721`: `_checkOnERC721Received` was removed. ([#2125](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2125))
* `ERC721`: `_transferFrom` and `_safeTransferFrom` were renamed to `_transfer` and `_safeTransfer`. ([#2162](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2162))
* `Ownable`: removed `_transferOwnership`. ([#2162](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2162))
* `PullPayment`, `Escrow`: `withdrawWithGas` was removed. The old `withdraw` function now forwards all gas. ([#2125](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2125))
* `Roles` was removed, use `AccessControl` as a replacement. ([#2112](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2112))
* `ECDSA`: when receiving an invalid signature, `recover` now reverts instead of returning the zero address. ([#2114](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2114))
* `Create2`: added an `amount` argument to `deploy` for contracts with `payable` constructors. ([#2117](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2117))
* `Pausable`: moved to the `utils` directory. ([#2122](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2122))
* `Strings`: moved to the `utils` directory. ([#2122](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2122))
* `Counters`: moved to the `utils` directory. ([#2122](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2122))
* `SignedSafeMath`: moved to the `math` directory. ([#2122](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2122))
* `ERC20Snapshot`: moved to the `token/ERC20` directory. `snapshot` was changed into an `internal` function. ([#2122](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2122))
* `Ownable`: moved to the `access` directory. ([#2120](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2120))
* `Ownable`: removed `isOwner`. ([#2120](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2120))
* `Secondary`: removed from the library, use `Ownable` instead. ([#2120](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2120))
* `Escrow`, `ConditionalEscrow`, `RefundEscrow`: these now use `Ownable` instead of `Secondary`, their external API changed accordingly. ([#2120](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2120))
* `ERC20`: removed `_burnFrom`. ([#2119](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2119))
* `Address`: removed `toPayable`, use `payable(address)` instead. ([#2133](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2133))
* `ERC777`: `_send`, `_mint` and `_burn` now use the caller as the operator. ([#2134](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2134))
* `ERC777`: removed `_callsTokensToSend` and `_callTokensReceived`. ([#2134](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2134))
* `EnumerableSet`: renamed `get` to `at`. ([#2151](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2151))
* `ERC165Checker`: functions no longer have a leading underscore. ([#2150](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2150))
* `ERC721Metadata`, `ERC721Enumerable`: these contracts were removed, and their functionality merged into `ERC721`. ([#2160](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2160))
* `ERC721`: added a constructor for `name` and `symbol`. ([#2160](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2160))
* `ERC20Detailed`: this contract was removed and its functionality merged into `ERC20`. ([#2161](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2161))
* `ERC20`: added a constructor for `name` and `symbol`. `decimals` now defaults to 18. ([#2161](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2161))
## 2.5.0 (2020-02-04)
### New features

View File

@ -38,9 +38,9 @@ contract MyNFT is ERC721Full, ERC721Mintable {
}
```
_If you're new to smart contract development, head to [Developing Smart Contracts](https://docs.openzeppelin.com/contracts/learn::developing-smart-contracts) to learn about creating a new project and compiling your contracts._
_If you're new to smart contract development, head to [Developing Smart Contracts](https://docs.openzeppelin.com/learn/developing-smart-contracts) to learn about creating a new project and compiling your contracts._
To keep your system secure, you should **always** use the installed code as-is, and neither copy-paste it from online sources, nor modify it yourself.
To keep your system secure, you should **always** use the installed code as-is, and neither copy-paste it from online sources, nor modify it yourself. The library is designed so that only the contracts and functions you use are deployed, so you don't need to worry about it needlessly increasing gas costs.
## Learn More

View File

@ -1,4 +1,4 @@
pragma solidity ^0.5.0;
pragma solidity ^0.6.0;
/*
* @dev Provides information about the current execution context, including the
@ -14,13 +14,12 @@ contract Context {
// Empty internal constructor, to prevent people from mistakenly deploying
// an instance of this contract, which should be used via inheritance.
constructor () internal { }
// solhint-disable-previous-line no-empty-blocks
function _msgSender() internal view returns (address payable) {
function _msgSender() internal view virtual returns (address payable) {
return msg.sender;
}
function _msgData() internal view returns (bytes memory) {
function _msgData() internal view virtual returns (bytes memory) {
this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691
return msg.data;
}

View File

@ -1,4 +1,4 @@
pragma solidity ^0.5.0;
pragma solidity ^0.6.0;
import "./IRelayRecipient.sol";
import "./IRelayHub.sol";
@ -15,15 +15,15 @@ import "./Context.sol";
* information on how to use the pre-built {GSNRecipientSignature} and
* {GSNRecipientERC20Fee}, or how to write your own.
*/
contract GSNRecipient is IRelayRecipient, Context {
abstract contract GSNRecipient is IRelayRecipient, Context {
// Default RelayHub address, deployed on mainnet and all testnets at the same address
address private _relayHub = 0xD216153c06E857cD7f72665E0aF1d7D82172F494;
uint256 constant private RELAYED_CALL_ACCEPTED = 0;
uint256 constant private RELAYED_CALL_REJECTED = 11;
uint256 constant private _RELAYED_CALL_ACCEPTED = 0;
uint256 constant private _RELAYED_CALL_REJECTED = 11;
// How much gas is forwarded to postRelayedCall
uint256 constant internal POST_RELAYED_CALL_MAX_GAS = 100000;
uint256 constant internal _POST_RELAYED_CALL_MAX_GAS = 100000;
/**
* @dev Emitted when a contract changes its {IRelayHub} contract to a new one.
@ -33,7 +33,7 @@ contract GSNRecipient is IRelayRecipient, Context {
/**
* @dev Returns the address of the {IRelayHub} contract for this recipient.
*/
function getHubAddr() public view returns (address) {
function getHubAddr() public view override returns (address) {
return _relayHub;
}
@ -44,7 +44,7 @@ contract GSNRecipient is IRelayRecipient, Context {
* IMPORTANT: After upgrading, the {GSNRecipient} will no longer be able to receive relayed calls from the old
* {IRelayHub} instance. Additionally, all funds should be previously withdrawn via {_withdrawDeposits}.
*/
function _upgradeRelayHub(address newRelayHub) internal {
function _upgradeRelayHub(address newRelayHub) internal virtual {
address currentRelayHub = _relayHub;
require(newRelayHub != address(0), "GSNRecipient: new RelayHub is the zero address");
require(newRelayHub != currentRelayHub, "GSNRecipient: new RelayHub is the current one");
@ -70,7 +70,7 @@ contract GSNRecipient is IRelayRecipient, Context {
*
* Derived contracts should expose this in an external interface with proper access control.
*/
function _withdrawDeposits(uint256 amount, address payable payee) internal {
function _withdrawDeposits(uint256 amount, address payable payee) internal virtual {
IRelayHub(_relayHub).withdraw(amount, payee);
}
@ -85,7 +85,7 @@ contract GSNRecipient is IRelayRecipient, Context {
*
* IMPORTANT: Contracts derived from {GSNRecipient} should never use `msg.sender`, and use {_msgSender} instead.
*/
function _msgSender() internal view returns (address payable) {
function _msgSender() internal view virtual override returns (address payable) {
if (msg.sender != _relayHub) {
return msg.sender;
} else {
@ -99,7 +99,7 @@ contract GSNRecipient is IRelayRecipient, Context {
*
* IMPORTANT: Contracts derived from {GSNRecipient} should never use `msg.data`, and use {_msgData} instead.
*/
function _msgData() internal view returns (bytes memory) {
function _msgData() internal view virtual override returns (bytes memory) {
if (msg.sender != _relayHub) {
return msg.data;
} else {
@ -119,7 +119,7 @@ contract GSNRecipient is IRelayRecipient, Context {
*
* - the caller must be the `RelayHub` contract.
*/
function preRelayedCall(bytes calldata context) external returns (bytes32) {
function preRelayedCall(bytes memory context) public virtual override returns (bytes32) {
require(msg.sender == getHubAddr(), "GSNRecipient: caller is not RelayHub");
return _preRelayedCall(context);
}
@ -131,7 +131,7 @@ contract GSNRecipient is IRelayRecipient, Context {
* must implement this function with any relayed-call preprocessing they may wish to do.
*
*/
function _preRelayedCall(bytes memory context) internal returns (bytes32);
function _preRelayedCall(bytes memory context) internal virtual returns (bytes32);
/**
* @dev See `IRelayRecipient.postRelayedCall`.
@ -142,7 +142,7 @@ contract GSNRecipient is IRelayRecipient, Context {
*
* - the caller must be the `RelayHub` contract.
*/
function postRelayedCall(bytes calldata context, bool success, uint256 actualCharge, bytes32 preRetVal) external {
function postRelayedCall(bytes memory context, bool success, uint256 actualCharge, bytes32 preRetVal) public virtual override {
require(msg.sender == getHubAddr(), "GSNRecipient: caller is not RelayHub");
_postRelayedCall(context, success, actualCharge, preRetVal);
}
@ -154,7 +154,7 @@ contract GSNRecipient is IRelayRecipient, Context {
* must implement this function with any relayed-call postprocessing they may wish to do.
*
*/
function _postRelayedCall(bytes memory context, bool success, uint256 actualCharge, bytes32 preRetVal) internal;
function _postRelayedCall(bytes memory context, bool success, uint256 actualCharge, bytes32 preRetVal) internal virtual;
/**
* @dev Return this in acceptRelayedCall to proceed with the execution of a relayed call. Note that this contract
@ -170,14 +170,14 @@ contract GSNRecipient is IRelayRecipient, Context {
* This overload forwards `context` to _preRelayedCall and _postRelayedCall.
*/
function _approveRelayedCall(bytes memory context) internal pure returns (uint256, bytes memory) {
return (RELAYED_CALL_ACCEPTED, context);
return (_RELAYED_CALL_ACCEPTED, context);
}
/**
* @dev Return this in acceptRelayedCall to impede execution of a relayed call. No fees will be charged.
*/
function _rejectRelayedCall(uint256 errorCode) internal pure returns (uint256, bytes memory) {
return (RELAYED_CALL_REJECTED + errorCode, "");
return (_RELAYED_CALL_REJECTED + errorCode, "");
}
/*

View File

@ -1,11 +1,10 @@
pragma solidity ^0.5.0;
pragma solidity ^0.6.0;
import "./GSNRecipient.sol";
import "../math/SafeMath.sol";
import "../ownership/Secondary.sol";
import "../access/Ownable.sol";
import "../token/ERC20/SafeERC20.sol";
import "../token/ERC20/ERC20.sol";
import "../token/ERC20/ERC20Detailed.sol";
/**
* @dev A xref:ROOT:gsn-strategies.adoc#gsn-strategies[GSN strategy] that charges transaction fees in a special purpose ERC20
@ -17,20 +16,20 @@ import "../token/ERC20/ERC20Detailed.sol";
* internal {_mint} function.
*/
contract GSNRecipientERC20Fee is GSNRecipient {
using SafeERC20 for __unstable__ERC20PrimaryAdmin;
using SafeERC20 for __unstable__ERC20Owned;
using SafeMath for uint256;
enum GSNRecipientERC20FeeErrorCodes {
INSUFFICIENT_BALANCE
}
__unstable__ERC20PrimaryAdmin private _token;
__unstable__ERC20Owned private _token;
/**
* @dev The arguments to the constructor are the details that the gas payment token will have: `name` and `symbol`. `decimals` is hard-coded to 18.
*/
constructor(string memory name, string memory symbol) public {
_token = new __unstable__ERC20PrimaryAdmin(name, symbol, 18);
_token = new __unstable__ERC20Owned(name, symbol);
}
/**
@ -43,7 +42,7 @@ contract GSNRecipientERC20Fee is GSNRecipient {
/**
* @dev Internal function that mints the gas payment token. Derived contracts should expose this function in their public API, with proper access control mechanisms.
*/
function _mint(address account, uint256 amount) internal {
function _mint(address account, uint256 amount) internal virtual {
_token.mint(account, amount);
}
@ -53,16 +52,18 @@ contract GSNRecipientERC20Fee is GSNRecipient {
function acceptRelayedCall(
address,
address from,
bytes calldata,
bytes memory,
uint256 transactionFee,
uint256 gasPrice,
uint256,
uint256,
bytes calldata,
bytes memory,
uint256 maxPossibleCharge
)
external
public
view
virtual
override
returns (uint256, bytes memory)
{
if (_token.balanceOf(from) < maxPossibleCharge) {
@ -78,7 +79,7 @@ contract GSNRecipientERC20Fee is GSNRecipient {
* actual charge, necessary because we cannot predict how much gas the execution will actually need. The remainder
* is returned to the user in {_postRelayedCall}.
*/
function _preRelayedCall(bytes memory context) internal returns (bytes32) {
function _preRelayedCall(bytes memory context) internal virtual override returns (bytes32) {
(address from, uint256 maxPossibleCharge) = abi.decode(context, (address, uint256));
// The maximum token charge is pre-charged from the user
@ -88,14 +89,14 @@ contract GSNRecipientERC20Fee is GSNRecipient {
/**
* @dev Returns to the user the extra amount that was previously charged, once the actual execution cost is known.
*/
function _postRelayedCall(bytes memory context, bool, uint256 actualCharge, bytes32) internal {
function _postRelayedCall(bytes memory context, bool, uint256 actualCharge, bytes32) internal virtual override {
(address from, uint256 maxPossibleCharge, uint256 transactionFee, uint256 gasPrice) =
abi.decode(context, (address, uint256, uint256, uint256));
// actualCharge is an _estimated_ charge, which assumes postRelayedCall will use all available gas.
// This implementation's gas cost can be roughly estimated as 10k gas, for the two SSTORE operations in an
// ERC20 transfer.
uint256 overestimation = _computeCharge(POST_RELAYED_CALL_MAX_GAS.sub(10000), gasPrice, transactionFee);
uint256 overestimation = _computeCharge(_POST_RELAYED_CALL_MAX_GAS.sub(10000), gasPrice, transactionFee);
actualCharge = actualCharge.sub(overestimation);
// After the relayed call has been executed and the actual charge estimated, the excess pre-charge is returned
@ -104,44 +105,42 @@ contract GSNRecipientERC20Fee is GSNRecipient {
}
/**
* @title __unstable__ERC20PrimaryAdmin
* @title __unstable__ERC20Owned
* @dev An ERC20 token owned by another contract, which has minting permissions and can use transferFrom to receive
* anyone's tokens. This contract is an internal helper for GSNRecipientERC20Fee, and should not be used
* outside of this context.
*/
// solhint-disable-next-line contract-name-camelcase
contract __unstable__ERC20PrimaryAdmin is ERC20, ERC20Detailed, Secondary {
uint256 private constant UINT256_MAX = 2**256 - 1;
contract __unstable__ERC20Owned is ERC20, Ownable {
uint256 private constant _UINT256_MAX = 2**256 - 1;
constructor(string memory name, string memory symbol, uint8 decimals) public ERC20Detailed(name, symbol, decimals) {
// solhint-disable-previous-line no-empty-blocks
}
constructor(string memory name, string memory symbol) public ERC20(name, symbol) { }
// The primary account (GSNRecipientERC20Fee) can mint tokens
function mint(address account, uint256 amount) public onlyPrimary {
// The owner (GSNRecipientERC20Fee) can mint tokens
function mint(address account, uint256 amount) public onlyOwner {
_mint(account, amount);
}
// The primary account has 'infinite' allowance for all token holders
function allowance(address owner, address spender) public view returns (uint256) {
if (spender == primary()) {
return UINT256_MAX;
// The owner has 'infinite' allowance for all token holders
function allowance(address tokenOwner, address spender) public view override returns (uint256) {
if (spender == owner()) {
return _UINT256_MAX;
} else {
return super.allowance(owner, spender);
return super.allowance(tokenOwner, spender);
}
}
// Allowance for the primary account cannot be changed (it is always 'infinite')
function _approve(address owner, address spender, uint256 value) internal {
if (spender == primary()) {
// Allowance for the owner cannot be changed (it is always 'infinite')
function _approve(address tokenOwner, address spender, uint256 value) internal override {
if (spender == owner()) {
return;
} else {
super._approve(owner, spender, value);
super._approve(tokenOwner, spender, value);
}
}
function transferFrom(address sender, address recipient, uint256 amount) public returns (bool) {
if (recipient == primary()) {
function transferFrom(address sender, address recipient, uint256 amount) public override returns (bool) {
if (recipient == owner()) {
_transfer(sender, recipient, amount);
return true;
} else {

View File

@ -1,4 +1,4 @@
pragma solidity ^0.5.0;
pragma solidity ^0.6.0;
import "./GSNRecipient.sol";
import "../cryptography/ECDSA.sol";
@ -32,16 +32,18 @@ contract GSNRecipientSignature is GSNRecipient {
function acceptRelayedCall(
address relay,
address from,
bytes calldata encodedFunction,
bytes memory encodedFunction,
uint256 transactionFee,
uint256 gasPrice,
uint256 gasLimit,
uint256 nonce,
bytes calldata approvalData,
bytes memory approvalData,
uint256
)
external
public
view
virtual
override
returns (uint256, bytes memory)
{
bytes memory blob = abi.encodePacked(
@ -62,11 +64,7 @@ contract GSNRecipientSignature is GSNRecipient {
}
}
function _preRelayedCall(bytes memory) internal returns (bytes32) {
// solhint-disable-previous-line no-empty-blocks
}
function _preRelayedCall(bytes memory) internal virtual override returns (bytes32) { }
function _postRelayedCall(bytes memory, bool, uint256, bytes32) internal {
// solhint-disable-previous-line no-empty-blocks
}
function _postRelayedCall(bytes memory, bool, uint256, bytes32) internal virtual override { }
}

View File

@ -1,4 +1,4 @@
pragma solidity ^0.5.0;
pragma solidity ^0.6.0;
/**
* @dev Interface for `RelayHub`, the core contract of the GSN. Users should not need to interact with this contract
@ -207,7 +207,7 @@ interface IRelayHub {
event CanRelayFailed(address indexed relay, address indexed from, address indexed to, bytes4 selector, uint256 reason);
/**
* @dev Emitted when a transaction is relayed.
* @dev Emitted when a transaction is relayed.
* Useful when monitoring a relay's operation and relayed calls to a contract
*
* Note that the actual encoded function might be reverted: this is indicated in the `status` parameter.
@ -236,7 +236,7 @@ interface IRelayHub {
*/
function maxPossibleCharge(uint256 relayedCallStipend, uint256 gasPrice, uint256 transactionFee) external view returns (uint256);
// Relay penalization.
// Relay penalization.
// Any account can penalize relays, removing them from the system immediately, and rewarding the
// reporter with half of the relay's stake. The other half is burned so that, even if the relay penalizes itself, it
// still loses half of its stake.

View File

@ -1,4 +1,4 @@
pragma solidity ^0.5.0;
pragma solidity ^0.6.0;
/**
* @dev Base interface for a contract that will be called via the GSN from {IRelayHub}.

View File

@ -0,0 +1,194 @@
pragma solidity ^0.6.0;
import "../utils/EnumerableSet.sol";
import "../utils/Address.sol";
import "../GSN/Context.sol";
/**
* @dev Contract module that allows children to implement role-based access
* control mechanisms.
*
* Roles are referred to by their `bytes32` identifier. These should be exposed
* in the external API and be unique. The best way to achieve this is by
* using `public constant` hash digests:
*
* ```
* bytes32 public constant MY_ROLE = keccak256("MY_ROLE");
* ```
*
* Roles can be used to represent a set of permissions. To restrict access to a
* function call, use {hasRole}:
*
* ```
* function foo() public {
* require(hasRole(MY_ROLE, _msgSender()));
* ...
* }
* ```
*
* Roles can be granted and revoked dynamically via the {grantRole} and
* {revokeRole} functions. Each role has an associated admin role, and only
* accounts that have a role's admin role can call {grantRole} and {revokeRoke}.
*
* By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means
* that only accounts with this role will be able to grant or revoke other
* roles. More complex role relationships can be created by using
* {_setRoleAdmin}.
*/
abstract contract AccessControl is Context {
using EnumerableSet for EnumerableSet.AddressSet;
using Address for address;
struct RoleData {
EnumerableSet.AddressSet members;
bytes32 adminRole;
}
mapping (bytes32 => RoleData) private _roles;
bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;
/**
* @dev Emitted when `account` is granted `role`.
*
* `sender` is the account that originated the contract call, an admin role
* bearer except when using {_setupRole}.
*/
event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);
/**
* @dev Emitted when `account` is revoked `role`.
*
* `sender` is the account that originated the contract call:
* - if using `revokeRole`, it is the admin role bearer
* - if using `renounceRole`, it is the role bearer (i.e. `account`)
*/
event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);
/**
* @dev Returns `true` if `account` has been granted `role`.
*/
function hasRole(bytes32 role, address account) public view returns (bool) {
return _roles[role].members.contains(account);
}
/**
* @dev Returns the number of accounts that have `role`. Can be used
* together with {getRoleMember} to enumerate all bearers of a role.
*/
function getRoleMemberCount(bytes32 role) public view returns (uint256) {
return _roles[role].members.length();
}
/**
* @dev Returns one of the accounts that have `role`. `index` must be a
* value between 0 and {getRoleMemberCount}, non-inclusive.
*
* Role bearers are not sorted in any particular way, and their ordering may
* change at any point.
*
* WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure
* you perform all queries on the same block. See the following
* https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]
* for more information.
*/
function getRoleMember(bytes32 role, uint256 index) public view returns (address) {
return _roles[role].members.at(index);
}
/**
* @dev Returns the admin role that controls `role`. See {grantRole} and
* {revokeRole}.
*
* To change a role's admin, use {_setRoleAdmin}.
*/
function getRoleAdmin(bytes32 role) public view returns (bytes32) {
return _roles[role].adminRole;
}
/**
* @dev Grants `role` to `account`.
*
* If `account` had not been already granted `role`, emits a {RoleGranted}
* event.
*
* Requirements:
*
* - the caller must have `role`'s admin role.
*/
function grantRole(bytes32 role, address account) public virtual {
require(hasRole(_roles[role].adminRole, _msgSender()), "AccessControl: sender must be an admin to grant");
_grantRole(role, account);
}
/**
* @dev Revokes `role` from `account`.
*
* If `account` had been granted `role`, emits a {RoleRevoked} event.
*
* Requirements:
*
* - the caller must have `role`'s admin role.
*/
function revokeRole(bytes32 role, address account) public virtual {
require(hasRole(_roles[role].adminRole, _msgSender()), "AccessControl: sender must be an admin to revoke");
_revokeRole(role, account);
}
/**
* @dev Revokes `role` from the calling account.
*
* Roles are often managed via {grantRole} and {revokeRole}: this function's
* purpose is to provide a mechanism for accounts to lose their privileges
* if they are compromised (such as when a trusted device is misplaced).
*
* If the calling account had been granted `role`, emits a {RoleRevoked}
* event.
*
* Requirements:
*
* - the caller must be `account`.
*/
function renounceRole(bytes32 role, address account) public virtual {
require(account == _msgSender(), "AccessControl: can only renounce roles for self");
_revokeRole(role, account);
}
/**
* @dev Grants `role` to `account`.
*
* If `account` had not been already granted `role`, emits a {RoleGranted}
* event. Note that unlike {grantRole}, this function doesn't perform any
* checks on the calling account.
*
* Requirements:
*
* - this function can only be called from a constructor.
*/
function _setupRole(bytes32 role, address account) internal virtual {
require(!address(this).isContract(), "AccessControl: roles cannot be setup after construction");
_grantRole(role, account);
}
/**
* @dev Sets `adminRole` as `role`'s admin role.
*/
function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {
_roles[role].adminRole = adminRole;
}
function _grantRole(bytes32 role, address account) private {
if (_roles[role].members.add(account)) {
emit RoleGranted(role, account, _msgSender());
}
}
function _revokeRole(bytes32 role, address account) private {
if (_roles[role].members.remove(account)) {
emit RoleRevoked(role, account, _msgSender());
}
}
}

View File

@ -1,4 +1,4 @@
pragma solidity ^0.5.0;
pragma solidity ^0.6.0;
import "../GSN/Context.sol";
/**
@ -6,6 +6,9 @@ import "../GSN/Context.sol";
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* By default, the owner account will be the one that deploys the contract. This
* can later be changed with {transferOwnership}.
*
* This module is used through inheritance. It will make available the modifier
* `onlyOwner`, which can be applied to your functions to restrict their use to
* the owner.
@ -35,17 +38,10 @@ contract Ownable is Context {
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
require(isOwner(), "Ownable: caller is not the owner");
require(_owner == _msgSender(), "Ownable: caller is not the owner");
_;
}
/**
* @dev Returns true if the caller is the current owner.
*/
function isOwner() public view returns (bool) {
return _msgSender() == _owner;
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions anymore. Can only be called by the current owner.
@ -53,7 +49,7 @@ contract Ownable is Context {
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby removing any functionality that is only available to the owner.
*/
function renounceOwnership() public onlyOwner {
function renounceOwnership() public virtual onlyOwner {
emit OwnershipTransferred(_owner, address(0));
_owner = address(0);
}
@ -62,14 +58,7 @@ contract Ownable is Context {
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) public onlyOwner {
_transferOwnership(newOwner);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
*/
function _transferOwnership(address newOwner) internal {
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
emit OwnershipTransferred(_owner, newOwner);
_owner = newOwner;

View File

@ -1,21 +1,9 @@
= Access
NOTE: This page is incomplete. We're working to improve it for the next release. Stay tuned!
Contract modules for authorization and access control mechanisms.
== Library
== Contracts
{{Roles}}
{{Ownable}}
== Roles
{{CapperRole}}
{{MinterRole}}
{{PauserRole}}
{{SignerRole}}
{{WhitelistAdminRole}}
{{WhitelistedRole}}
{{AccessControl}}

View File

@ -1,36 +0,0 @@
pragma solidity ^0.5.0;
/**
* @title Roles
* @dev Library for managing addresses assigned to a Role.
*/
library Roles {
struct Role {
mapping (address => bool) bearer;
}
/**
* @dev Give an account access to this role.
*/
function add(Role storage role, address account) internal {
require(!has(role, account), "Roles: account already has role");
role.bearer[account] = true;
}
/**
* @dev Remove an account's access to this role.
*/
function remove(Role storage role, address account) internal {
require(has(role, account), "Roles: account does not have role");
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), "Roles: account is the zero address");
return role.bearer[account];
}
}

View File

@ -1,44 +0,0 @@
pragma solidity ^0.5.0;
import "../../GSN/Context.sol";
import "../Roles.sol";
contract CapperRole is Context {
using Roles for Roles.Role;
event CapperAdded(address indexed account);
event CapperRemoved(address indexed account);
Roles.Role private _cappers;
constructor () internal {
_addCapper(_msgSender());
}
modifier onlyCapper() {
require(isCapper(_msgSender()), "CapperRole: caller does not have the Capper role");
_;
}
function isCapper(address account) public view returns (bool) {
return _cappers.has(account);
}
function addCapper(address account) public onlyCapper {
_addCapper(account);
}
function renounceCapper() public {
_removeCapper(_msgSender());
}
function _addCapper(address account) internal {
_cappers.add(account);
emit CapperAdded(account);
}
function _removeCapper(address account) internal {
_cappers.remove(account);
emit CapperRemoved(account);
}
}

View File

@ -1,44 +0,0 @@
pragma solidity ^0.5.0;
import "../../GSN/Context.sol";
import "../Roles.sol";
contract MinterRole is Context {
using Roles for Roles.Role;
event MinterAdded(address indexed account);
event MinterRemoved(address indexed account);
Roles.Role private _minters;
constructor () internal {
_addMinter(_msgSender());
}
modifier onlyMinter() {
require(isMinter(_msgSender()), "MinterRole: caller does not have the Minter role");
_;
}
function isMinter(address account) public view returns (bool) {
return _minters.has(account);
}
function addMinter(address account) public onlyMinter {
_addMinter(account);
}
function renounceMinter() public {
_removeMinter(_msgSender());
}
function _addMinter(address account) internal {
_minters.add(account);
emit MinterAdded(account);
}
function _removeMinter(address account) internal {
_minters.remove(account);
emit MinterRemoved(account);
}
}

View File

@ -1,44 +0,0 @@
pragma solidity ^0.5.0;
import "../../GSN/Context.sol";
import "../Roles.sol";
contract PauserRole is Context {
using Roles for Roles.Role;
event PauserAdded(address indexed account);
event PauserRemoved(address indexed account);
Roles.Role private _pausers;
constructor () internal {
_addPauser(_msgSender());
}
modifier onlyPauser() {
require(isPauser(_msgSender()), "PauserRole: caller does not have the Pauser role");
_;
}
function isPauser(address account) public view returns (bool) {
return _pausers.has(account);
}
function addPauser(address account) public onlyPauser {
_addPauser(account);
}
function renouncePauser() public {
_removePauser(_msgSender());
}
function _addPauser(address account) internal {
_pausers.add(account);
emit PauserAdded(account);
}
function _removePauser(address account) internal {
_pausers.remove(account);
emit PauserRemoved(account);
}
}

View File

@ -1,44 +0,0 @@
pragma solidity ^0.5.0;
import "../../GSN/Context.sol";
import "../Roles.sol";
contract SignerRole is Context {
using Roles for Roles.Role;
event SignerAdded(address indexed account);
event SignerRemoved(address indexed account);
Roles.Role private _signers;
constructor () internal {
_addSigner(_msgSender());
}
modifier onlySigner() {
require(isSigner(_msgSender()), "SignerRole: caller does not have the Signer role");
_;
}
function isSigner(address account) public view returns (bool) {
return _signers.has(account);
}
function addSigner(address account) public onlySigner {
_addSigner(account);
}
function renounceSigner() public {
_removeSigner(_msgSender());
}
function _addSigner(address account) internal {
_signers.add(account);
emit SignerAdded(account);
}
function _removeSigner(address account) internal {
_signers.remove(account);
emit SignerRemoved(account);
}
}

View File

@ -1,48 +0,0 @@
pragma solidity ^0.5.0;
import "../../GSN/Context.sol";
import "../Roles.sol";
/**
* @title WhitelistAdminRole
* @dev WhitelistAdmins are responsible for assigning and removing Whitelisted accounts.
*/
contract WhitelistAdminRole is Context {
using Roles for Roles.Role;
event WhitelistAdminAdded(address indexed account);
event WhitelistAdminRemoved(address indexed account);
Roles.Role private _whitelistAdmins;
constructor () internal {
_addWhitelistAdmin(_msgSender());
}
modifier onlyWhitelistAdmin() {
require(isWhitelistAdmin(_msgSender()), "WhitelistAdminRole: caller does not have the WhitelistAdmin role");
_;
}
function isWhitelistAdmin(address account) public view returns (bool) {
return _whitelistAdmins.has(account);
}
function addWhitelistAdmin(address account) public onlyWhitelistAdmin {
_addWhitelistAdmin(account);
}
function renounceWhitelistAdmin() public {
_removeWhitelistAdmin(_msgSender());
}
function _addWhitelistAdmin(address account) internal {
_whitelistAdmins.add(account);
emit WhitelistAdminAdded(account);
}
function _removeWhitelistAdmin(address account) internal {
_whitelistAdmins.remove(account);
emit WhitelistAdminRemoved(account);
}
}

View File

@ -1,51 +0,0 @@
pragma solidity ^0.5.0;
import "../../GSN/Context.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 Context, WhitelistAdminRole {
using Roles for Roles.Role;
event WhitelistedAdded(address indexed account);
event WhitelistedRemoved(address indexed account);
Roles.Role private _whitelisteds;
modifier onlyWhitelisted() {
require(isWhitelisted(_msgSender()), "WhitelistedRole: caller does not have the Whitelisted role");
_;
}
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(_msgSender());
}
function _addWhitelisted(address account) internal {
_whitelisteds.add(account);
emit WhitelistedAdded(account);
}
function _removeWhitelisted(address account) internal {
_whitelisteds.remove(account);
emit WhitelistedRemoved(account);
}
}

View File

@ -1,200 +0,0 @@
pragma solidity ^0.5.0;
import "../GSN/Context.sol";
import "../token/ERC20/IERC20.sol";
import "../math/SafeMath.sol";
import "../token/ERC20/SafeERC20.sol";
import "../utils/ReentrancyGuard.sol";
/**
* @title Crowdsale
* @dev Crowdsale is a base contract for managing a token crowdsale,
* 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 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 Context, ReentrancyGuard {
using SafeMath for uint256;
using SafeERC20 for IERC20;
// The token being sold
IERC20 private _token;
// 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;
// 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);
/**
* @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 payable wallet, IERC20 token) public {
require(rate > 0, "Crowdsale: rate is 0");
require(wallet != address(0), "Crowdsale: wallet is the zero address");
require(address(token) != address(0), "Crowdsale: token is the zero address");
_rate = rate;
_wallet = wallet;
_token = token;
}
/**
* @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(_msgSender());
}
/**
* @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 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;
}
/**
* @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);
// calculate token amount to be created
uint256 tokens = _getTokenAmount(weiAmount);
// update state
_weiRaised = _weiRaised.add(weiAmount);
_processPurchase(beneficiary, tokens);
emit TokensPurchased(_msgSender(), beneficiary, weiAmount, tokens);
_updatePurchasingState(beneficiary, weiAmount);
_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), "Crowdsale: beneficiary is the zero address");
require(weiAmount != 0, "Crowdsale: weiAmount is 0");
this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691
}
/**
* @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 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 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 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 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);
}
}

View File

@ -1,35 +0,0 @@
= Crowdsales
NOTE: This page is incomplete. We're working to improve it for the next release. Stay tuned!
== Core
{{Crowdsale}}
== Emission
{{AllowanceCrowdsale}}
{{MintedCrowdsale}}
== Validation
{{CappedCrowdsale}}
{{IndividuallyCappedCrowdsale}}
{{PausableCrowdsale}}
{{TimedCrowdsale}}
{{WhitelistCrowdsale}}
== Distribution
{{FinalizableCrowdsale}}
{{PostDeliveryCrowdsale}}
{{RefundableCrowdsale}}
{{RefundablePostDeliveryCrowdsale}}

View File

@ -1,51 +0,0 @@
pragma solidity ^0.5.0;
import "../../math/SafeMath.sol";
import "../validation/TimedCrowdsale.sol";
/**
* @title FinalizableCrowdsale
* @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;
bool private _finalized;
event CrowdsaleFinalized();
constructor () internal {
_finalized = false;
}
/**
* @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, "FinalizableCrowdsale: already finalized");
require(hasClosed(), "FinalizableCrowdsale: not closed");
_finalized = true;
_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
}
}

View File

@ -1,65 +0,0 @@
pragma solidity ^0.5.0;
import "../validation/TimedCrowdsale.sol";
import "../../math/SafeMath.sol";
import "../../ownership/Secondary.sol";
import "../../token/ERC20/IERC20.sol";
/**
* @title PostDeliveryCrowdsale
* @dev Crowdsale that locks tokens from withdrawal until it ends.
*/
contract PostDeliveryCrowdsale is TimedCrowdsale {
using SafeMath for uint256;
mapping(address => uint256) private _balances;
__unstable__TokenVault private _vault;
constructor() public {
_vault = new __unstable__TokenVault();
}
/**
* @dev Withdraw tokens only after crowdsale ends.
* @param beneficiary Whose tokens will be withdrawn.
*/
function withdrawTokens(address beneficiary) public {
require(hasClosed(), "PostDeliveryCrowdsale: not closed");
uint256 amount = _balances[beneficiary];
require(amount > 0, "PostDeliveryCrowdsale: beneficiary is not due any tokens");
_balances[beneficiary] = 0;
_vault.transfer(token(), beneficiary, amount);
}
/**
* @return the balance of an account.
*/
function balanceOf(address account) public view returns (uint256) {
return _balances[account];
}
/**
* @dev Overrides parent by storing due balances, and delivering tokens to the vault instead of the end user. This
* ensures that the tokens will be available by the time they are withdrawn (which may not be the case if
* `_deliverTokens` was called later).
* @param beneficiary Token purchaser
* @param tokenAmount Amount of tokens purchased
*/
function _processPurchase(address beneficiary, uint256 tokenAmount) internal {
_balances[beneficiary] = _balances[beneficiary].add(tokenAmount);
_deliverTokens(address(_vault), tokenAmount);
}
}
/**
* @title __unstable__TokenVault
* @dev Similar to an Escrow for tokens, this contract allows its primary account to spend its tokens as it sees fit.
* This contract is an internal helper for PostDeliveryCrowdsale, and should not be used outside of this context.
*/
// solhint-disable-next-line contract-name-camelcase
contract __unstable__TokenVault is Secondary {
function transfer(IERC20 token, address to, uint256 amount) public onlyPrimary {
token.transfer(to, amount);
}
}

View File

@ -1,83 +0,0 @@
pragma solidity ^0.5.0;
import "../../GSN/Context.sol";
import "../../math/SafeMath.sol";
import "./FinalizableCrowdsale.sol";
import "../../payment/escrow/RefundEscrow.sol";
/**
* @title RefundableCrowdsale
* @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 Context, FinalizableCrowdsale {
using SafeMath for uint256;
// 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;
/**
* @dev Constructor, creates RefundEscrow.
* @param goal Funding goal
*/
constructor (uint256 goal) public {
require(goal > 0, "RefundableCrowdsale: goal is 0");
_escrow = new RefundEscrow(wallet());
_goal = goal;
}
/**
* @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 refundee Whose refund will be claimed.
*/
function claimRefund(address payable refundee) public {
require(finalized(), "RefundableCrowdsale: not finalized");
require(!goalReached(), "RefundableCrowdsale: goal reached");
_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)(_msgSender());
}
}

View File

@ -1,20 +0,0 @@
pragma solidity ^0.5.0;
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 RefundableCrowdsale, PostDeliveryCrowdsale {
function withdrawTokens(address beneficiary) public {
require(finalized(), "RefundablePostDeliveryCrowdsale: not finalized");
require(goalReached(), "RefundablePostDeliveryCrowdsale: goal not reached");
super.withdrawTokens(beneficiary);
}
}

View File

@ -1,51 +0,0 @@
pragma solidity ^0.5.0;
import "../Crowdsale.sol";
import "../../token/ERC20/IERC20.sol";
import "../../token/ERC20/SafeERC20.sol";
import "../../math/SafeMath.sol";
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;
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) public {
require(tokenWallet != address(0), "AllowanceCrowdsale: token wallet is the zero address");
_tokenWallet = tokenWallet;
}
/**
* @return the address of the wallet that will hold the tokens.
*/
function tokenWallet() public view returns (address) {
return _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, 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);
}
}

View File

@ -1,24 +0,0 @@
pragma solidity ^0.5.0;
import "../Crowdsale.sol";
import "../../token/ERC20/ERC20Mintable.sol";
/**
* @title MintedCrowdsale
* @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 {
/**
* @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),
"MintedCrowdsale: minting failed"
);
}
}

View File

@ -1,79 +0,0 @@
pragma solidity ^0.5.0;
import "../validation/TimedCrowdsale.sol";
import "../../math/SafeMath.sol";
/**
* @title IncreasingPriceCrowdsale
* @dev Extension of Crowdsale contract that increases the price of tokens linearly in time.
* 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;
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) public {
require(finalRate > 0, "IncreasingPriceCrowdsale: final rate is 0");
// solhint-disable-next-line max-line-length
require(initialRate > finalRate, "IncreasingPriceCrowdsale: initial rate is not greater than final rate");
_initialRate = initialRate;
_finalRate = finalRate;
}
/**
* 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("IncreasingPriceCrowdsale: rate() called");
}
/**
* @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);
}
}

View File

@ -1,48 +0,0 @@
pragma solidity ^0.5.0;
import "../../math/SafeMath.sol";
import "../Crowdsale.sol";
/**
* @title CappedCrowdsale
* @dev Crowdsale with a limit for total contributions.
*/
contract CappedCrowdsale is Crowdsale {
using SafeMath for uint256;
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) public {
require(cap > 0, "CappedCrowdsale: cap is 0");
_cap = cap;
}
/**
* @return the cap of the crowdsale.
*/
function cap() public view returns (uint256) {
return _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, "CappedCrowdsale: cap exceeded");
}
}

View File

@ -1,64 +0,0 @@
pragma solidity ^0.5.0;
import "../../math/SafeMath.sol";
import "../Crowdsale.sol";
import "../../access/roles/CapperRole.sol";
/**
* @title IndividuallyCappedCrowdsale
* @dev Crowdsale with per-beneficiary caps.
*/
contract IndividuallyCappedCrowdsale is Crowdsale, CapperRole {
using SafeMath for uint256;
mapping(address => uint256) private _contributions;
mapping(address => uint256) private _caps;
/**
* @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 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 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 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);
// solhint-disable-next-line max-line-length
require(_contributions[beneficiary].add(weiAmount) <= _caps[beneficiary], "IndividuallyCappedCrowdsale: beneficiary's cap exceeded");
}
/**
* @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);
}
}

View File

@ -1,21 +0,0 @@
pragma solidity ^0.5.0;
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 Crowdsale, Pausable {
/**
* @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);
}
}

View File

@ -1,98 +0,0 @@
pragma solidity ^0.5.0;
import "../../math/SafeMath.sol";
import "../Crowdsale.sol";
/**
* @title TimedCrowdsale
* @dev Crowdsale accepting contributions only within a time frame.
*/
contract TimedCrowdsale is Crowdsale {
using SafeMath for uint256;
uint256 private _openingTime;
uint256 private _closingTime;
/**
* Event for crowdsale extending
* @param newClosingTime new closing time
* @param prevClosingTime old closing time
*/
event TimedCrowdsaleExtended(uint256 prevClosingTime, uint256 newClosingTime);
/**
* @dev Reverts if not in crowdsale time range.
*/
modifier onlyWhileOpen {
require(isOpen(), "TimedCrowdsale: not open");
_;
}
/**
* @dev Constructor, takes crowdsale opening and closing times.
* @param openingTime Crowdsale opening time
* @param closingTime Crowdsale closing time
*/
constructor (uint256 openingTime, uint256 closingTime) public {
// solhint-disable-next-line not-rely-on-time
require(openingTime >= block.timestamp, "TimedCrowdsale: opening time is before current time");
// solhint-disable-next-line max-line-length
require(closingTime > openingTime, "TimedCrowdsale: opening time is not before closing time");
_openingTime = openingTime;
_closingTime = closingTime;
}
/**
* @return the crowdsale opening time.
*/
function openingTime() public view returns (uint256) {
return _openingTime;
}
/**
* @return the crowdsale closing time.
*/
function closingTime() public view returns (uint256) {
return _closingTime;
}
/**
* @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;
}
/**
* @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(), "TimedCrowdsale: already closed");
// solhint-disable-next-line max-line-length
require(newClosingTime > _closingTime, "TimedCrowdsale: new closing time is before current closing time");
emit TimedCrowdsaleExtended(_closingTime, newClosingTime);
_closingTime = newClosingTime;
}
}

View File

@ -1,21 +0,0 @@
pragma solidity ^0.5.0;
import "../Crowdsale.sol";
import "../../access/roles/WhitelistedRole.sol";
/**
* @title WhitelistCrowdsale
* @dev Crowdsale in which only whitelisted users can contribute.
*/
contract WhitelistCrowdsale is WhitelistedRole, Crowdsale {
/**
* @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), "WhitelistCrowdsale: beneficiary doesn't have the Whitelisted role");
super._preValidatePurchase(_beneficiary, _weiAmount);
}
}

View File

@ -1,4 +1,4 @@
pragma solidity ^0.5.0;
pragma solidity ^0.6.0;
/**
* @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.
@ -15,10 +15,6 @@ library ECDSA {
* this function rejects them by requiring the `s` value to be in the lower
* half order, and the `v` value to be either 27 or 28.
*
* NOTE: This call _does not revert_ if the signature is invalid, or
* if the signer is otherwise unable to be retrieved. In those scenarios,
* the zero address is returned.
*
* IMPORTANT: `hash` _must_ be the result of a hash operation for the
* verification to be secure: it is possible to craft signatures that
* recover to arbitrary addresses for non-hashed data. A safe way to ensure
@ -28,7 +24,7 @@ library ECDSA {
function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {
// Check the signature length
if (signature.length != 65) {
return (address(0));
revert("ECDSA: invalid signature length");
}
// Divide the signature in r, s and v variables
@ -55,15 +51,18 @@ library ECDSA {
// 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);
revert("ECDSA: invalid signature 's' value");
}
if (v != 27 && v != 28) {
return address(0);
revert("ECDSA: invalid signature 'v' value");
}
// If the signature is valid (and not malleable), return the signer address
return ecrecover(hash, v, r, s);
address signer = ecrecover(hash, v, r, s);
require(signer != address(0), "ECDSA: invalid signature");
return signer;
}
/**

View File

@ -1,4 +1,4 @@
pragma solidity ^0.5.0;
pragma solidity ^0.6.0;
/**
* @dev These functions deal with verification of Merkle trees (hash trees),

View File

@ -0,0 +1,85 @@
pragma solidity ^0.6.0;
import "../access/AccessControl.sol";
import "../GSN/Context.sol";
import "../token/ERC20/ERC20.sol";
import "../token/ERC20/ERC20Burnable.sol";
import "../token/ERC20/ERC20Pausable.sol";
/**
* @dev {ERC20} token, including:
*
* - ability for holders to burn (destroy) their tokens
* - a minter role that allows for token minting (creation)
* - a pauser role that allows to stop all token transfers
*
* This contract uses {AccessControl} to lock permissioned functions using the
* different roles - head to its documentation for details.
*
* The account that deploys the contract will be granted the minter role, the
* pauser role, and the default admin role, meaning it will be able to grant
* both the minter and pauser roles.
*/
contract ERC20MinterPauser is Context, AccessControl, ERC20Burnable, ERC20Pausable {
bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");
bytes32 public constant PAUSER_ROLE = keccak256("PAUSER_ROLE");
/**
* @dev Grants `DEFAULT_ADMIN_ROLE`, `MINTER_ROLE` and `PAUSER_ROLE` to the
* account that deploys the contract.
*
* See {ERC20-constructor}.
*/
constructor(string memory name, string memory symbol) public ERC20(name, symbol) {
_setupRole(DEFAULT_ADMIN_ROLE, _msgSender());
_setupRole(MINTER_ROLE, _msgSender());
_setupRole(PAUSER_ROLE, _msgSender());
}
/**
* @dev Creates `amount` new tokens for `to`.
*
* See {ERC20-_mint}.
*
* Requirements:
*
* - the caller must have the `MINTER_ROLE`.
*/
function mint(address to, uint256 amount) public {
require(hasRole(MINTER_ROLE, _msgSender()), "ERC20MinterPauser: must have minter role to mint");
_mint(to, amount);
}
/**
* @dev Pauses all token transfers.
*
* See {ERC20Pausable} and {Pausable-_pause}.
*
* Requirements:
*
* - the caller must have the `PAUSER_ROLE`.
*/
function pause() public {
require(hasRole(PAUSER_ROLE, _msgSender()), "ERC20MinterPauser: must have pauser role to pause");
_pause();
}
/**
* @dev Unpauses all token transfers.
*
* See {ERC20Pausable} and {Pausable-_unpause}.
*
* Requirements:
*
* - the caller must have the `PAUSER_ROLE`.
*/
function unpause() public {
require(hasRole(PAUSER_ROLE, _msgSender()), "ERC20MinterPauser: must have pauser role to unpause");
_unpause();
}
function _beforeTokenTransfer(address from, address to, uint256 amount) internal override(ERC20, ERC20Pausable) {
super._beforeTokenTransfer(from, to, amount);
}
}

View File

@ -0,0 +1,85 @@
pragma solidity ^0.6.0;
import "../access/AccessControl.sol";
import "../GSN/Context.sol";
import "../token/ERC721/ERC721.sol";
import "../token/ERC721/ERC721Burnable.sol";
import "../token/ERC721/ERC721Pausable.sol";
/**
* @dev {ERC721} token, including:
*
* - ability for holders to burn (destroy) their tokens
* - a minter role that allows for token minting (creation)
* - a pauser role that allows to stop all token transfers
*
* This contract uses {AccessControl} to lock permissioned functions using the
* different roles - head to its documentation for details.
*
* The account that deploys the contract will be granted the minter role, the
* pauser role, and the default admin role, meaning it will be able to grant
* both the minter and pauser roles.
*/
contract ERC721MinterPauser is Context, AccessControl, ERC721Burnable, ERC721Pausable {
bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");
bytes32 public constant PAUSER_ROLE = keccak256("PAUSER_ROLE");
/**
* @dev Grants `DEFAULT_ADMIN_ROLE`, `MINTER_ROLE` and `PAUSER_ROLE` to the
* account that deploys the contract.
*
* See {ERC721-constructor}.
*/
constructor(string memory name, string memory symbol) public ERC721(name, symbol) {
_setupRole(DEFAULT_ADMIN_ROLE, _msgSender());
_setupRole(MINTER_ROLE, _msgSender());
_setupRole(PAUSER_ROLE, _msgSender());
}
/**
* @dev Creates the `tokenId` tokens for `to`.
*
* See {ERC721-_mint}.
*
* Requirements:
*
* - the caller must have the `MINTER_ROLE`.
*/
function mint(address to, uint256 tokenId) public {
require(hasRole(MINTER_ROLE, _msgSender()), "ERC721MinterPauser: must have minter role to mint");
_mint(to, tokenId);
}
/**
* @dev Pauses all token transfers.
*
* See {ERC721Pausable} and {Pausable-_pause}.
*
* Requirements:
*
* - the caller must have the `PAUSER_ROLE`.
*/
function pause() public {
require(hasRole(PAUSER_ROLE, _msgSender()), "ERC721MinterPauser: must have pauser role to pause");
_pause();
}
/**
* @dev Unpauses all token transfers.
*
* See {ERC20Pausable} and {Pausable-_unpause}.
*
* Requirements:
*
* - the caller must have the `PAUSER_ROLE`.
*/
function unpause() public {
require(hasRole(PAUSER_ROLE, _msgSender()), "ERC721MinterPauser: must have pauser role to unpause");
_unpause();
}
function _beforeTokenTransfer(address from, address to, uint256 tokenId) internal override(ERC721, ERC721Pausable) {
super._beforeTokenTransfer(from, to, tokenId);
}
}

View File

@ -0,0 +1,13 @@
= Deploy Ready
These contracts integrate different Ethereum standards (ERCs) with custom extensions and modules, showcasing common configurations that are ready to deploy **without having to write any Solidity code**.
They can be used as-is for quick prototyping and testing, but are **also suitable for production environments**.
TIP: Intermediate and advanced users can use these as starting points when writing their own contracts, extending them with custom functionality as they see fit.
== Tokens
{{ERC20MinterPauser}}
{{ERC721MinterPauser}}

View File

@ -1,24 +0,0 @@
pragma solidity ^0.5.0;
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 {
string private _tokenURI;
constructor (string memory tokenURI_) public {
_setTokenURI(tokenURI_);
}
function tokenURI() external view returns (string memory) {
return _tokenURI;
}
function _setTokenURI(string memory tokenURI_) internal {
_tokenURI = tokenURI_;
}
}

View File

@ -1,103 +0,0 @@
pragma solidity ^0.5.0;
import "../token/ERC20/IERC20.sol";
import "../token/ERC20/ERC20Mintable.sol";
import "../token/ERC20/SafeERC20.sol";
import "../math/Math.sol";
/**
* @title ERC20Migrator
* @dev This contract can be used to migrate an ERC20 token from one
* contract to another, where each token holder has to opt-in to the migration.
* To opt-in, users must approve for this contract the number of tokens they
* want to migrate. Once the allowance is set up, anyone can trigger the
* migration to the new token contract. In this way, token holders "turn in"
* their old balance and will be minted an equal amount in the new token.
* The new token contract must be mintable. For the precise interface refer to
* OpenZeppelin's {ERC20Mintable}, but the only functions that are needed are
* {MinterRole-isMinter} and {ERC20Mintable-mint}. The migrator will check
* that it is a minter for the token.
* 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
* using this implementation, please follow the official documentation site of
* ZeppelinOS: https://docs.zeppelinos.org/docs/erc20_onboarding.html
*
* Example of usage:
* ```
* const migrator = await ERC20Migrator.new(legacyToken.address);
* await newToken.addMinter(migrator.address);
* await migrator.beginMigration(newToken.address);
* ```
*/
contract ERC20Migrator {
using SafeERC20 for IERC20;
/// Address of the old token contract
IERC20 private _legacyToken;
/// Address of the new token contract
ERC20Mintable private _newToken;
/**
* @param legacyToken address of the old token contract
*/
constructor (IERC20 legacyToken) public {
require(address(legacyToken) != address(0), "ERC20Migrator: legacy token is the zero address");
_legacyToken = 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 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), "ERC20Migrator: migration already started");
require(address(newToken_) != address(0), "ERC20Migrator: new token is the zero address");
//solhint-disable-next-line max-line-length
require(newToken_.isMinter(address(this)), "ERC20Migrator: not a minter for new token");
_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 {
require(address(_newToken) != address(0), "ERC20Migrator: migration not started");
_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, address(this));
uint256 amount = Math.min(balance, allowance);
migrate(account, amount);
}
}

View File

@ -1,23 +0,0 @@
= Drafts
Contracts in this category should be considered unstable. They are as thoroughly reviewed as everything else in OpenZeppelin Contracts, but we have doubts about their API so we don't commit to backwards compatibility. This means these contracts can receive breaking changes in a minor version, so you should pay special attention to the changelog when upgrading. For anything that is outside of this category you can read more about xref:ROOT:api-stability.adoc[API Stability].
NOTE: This page is incomplete. We're working to improve it for the next release. Stay tuned!
== ERC 20
{{ERC20Migrator}}
{{ERC20Snapshot}}
{{TokenVesting}}
== Miscellaneous
{{Counters}}
{{SignedSafeMath}}
== ERC 1046
{{ERC1046}}

View File

@ -1,7 +1,7 @@
pragma solidity ^0.5.0;
pragma solidity ^0.6.0;
import "../token/ERC20/SafeERC20.sol";
import "../ownership/Ownable.sol";
import "../access/Ownable.sol";
import "../math/SafeMath.sol";
/**

View File

@ -1,53 +0,0 @@
pragma solidity ^0.5.0;
import "../crowdsale/validation/CappedCrowdsale.sol";
import "../crowdsale/distribution/RefundableCrowdsale.sol";
import "../crowdsale/emission/MintedCrowdsale.sol";
import "../token/ERC20/ERC20Mintable.sol";
import "../token/ERC20/ERC20Detailed.sol";
/**
* @title SampleCrowdsaleToken
* @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) {
// solhint-disable-previous-line no-empty-blocks
}
}
/**
* @title SampleCrowdsale
* @dev This is an example of a fully fledged crowdsale.
* The way to add new features to a base crowdsale is by multiple inheritance.
* In this example we are providing following extensions:
* CappedCrowdsale - sets a max boundary for raised funds
* RefundableCrowdsale - set a min goal to be reached and returns funds if it's not met
* MintedCrowdsale - assumes the token can be minted by the crowdsale, which does so
* when receiving purchases.
*
* After adding multiple features it's good practice to run integration tests
* to ensure that subcontracts works together as intended.
*/
contract SampleCrowdsale is CappedCrowdsale, RefundableCrowdsale, MintedCrowdsale {
constructor (
uint256 openingTime,
uint256 closingTime,
uint256 rate,
address payable 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, "SampleCrowdSale: goal is greater than cap");
}
}

View File

@ -1,21 +0,0 @@
pragma solidity ^0.5.0;
import "../GSN/Context.sol";
import "../token/ERC20/ERC20.sol";
import "../token/ERC20/ERC20Detailed.sol";
/**
* @title SimpleToken
* @dev Very simple ERC20 Token example, where all tokens are pre-assigned to the creator.
* Note they can later distribute these tokens as they wish using `transfer` and other
* `ERC20` functions.
*/
contract SimpleToken is Context, ERC20, ERC20Detailed {
/**
* @dev Constructor that gives _msgSender() all of existing tokens.
*/
constructor () public ERC20Detailed("SimpleToken", "SIM", 18) {
_mint(_msgSender(), 10000 * (10 ** uint256(decimals())));
}
}

View File

@ -1,4 +1,4 @@
pragma solidity ^0.5.0;
pragma solidity ^0.6.0;
import "./IERC165.sol";
@ -30,7 +30,7 @@ contract ERC165 is IERC165 {
*
* Time complexity O(1), guaranteed to always use less than 30 000 gas.
*/
function supportsInterface(bytes4 interfaceId) external view returns (bool) {
function supportsInterface(bytes4 interfaceId) public view override returns (bool) {
return _supportedInterfaces[interfaceId];
}
@ -45,7 +45,7 @@ contract ERC165 is IERC165 {
*
* - `interfaceId` cannot be the ERC165 invalid interface (`0xffffffff`).
*/
function _registerInterface(bytes4 interfaceId) internal {
function _registerInterface(bytes4 interfaceId) internal virtual {
require(interfaceId != 0xffffffff, "ERC165: invalid interface id");
_supportedInterfaces[interfaceId] = true;
}

View File

@ -1,4 +1,4 @@
pragma solidity ^0.5.10;
pragma solidity ^0.6.0;
/**
* @dev Library used to query support of an interface declared via {IERC165}.
@ -19,7 +19,7 @@ library ERC165Checker {
/**
* @dev Returns true if `account` supports the {IERC165} interface,
*/
function _supportsERC165(address account) internal view returns (bool) {
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) &&
@ -32,9 +32,9 @@ library ERC165Checker {
*
* See {IERC165-supportsInterface}.
*/
function _supportsInterface(address account, bytes4 interfaceId) internal view returns (bool) {
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) &&
return supportsERC165(account) &&
_supportsERC165Interface(account, interfaceId);
}
@ -47,9 +47,9 @@ library ERC165Checker {
*
* See {IERC165-supportsInterface}.
*/
function _supportsAllInterfaces(address account, bytes4[] memory interfaceIds) internal view returns (bool) {
function supportsAllInterfaces(address account, bytes4[] memory interfaceIds) internal view returns (bool) {
// query support of ERC165 itself
if (!_supportsERC165(account)) {
if (!supportsERC165(account)) {
return false;
}
@ -72,7 +72,7 @@ library ERC165Checker {
* 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.
* with {supportsERC165}.
* Interface identification is specified in ERC-165.
*/
function _supportsERC165Interface(address account, bytes4 interfaceId) private view returns (bool) {

View File

@ -1,4 +1,4 @@
pragma solidity ^0.5.0;
pragma solidity ^0.6.0;
import "./IERC1820Implementer.sol";
@ -11,15 +11,15 @@ import "./IERC1820Implementer.sol";
* registration to be complete.
*/
contract ERC1820Implementer is IERC1820Implementer {
bytes32 constant private ERC1820_ACCEPT_MAGIC = keccak256(abi.encodePacked("ERC1820_ACCEPT_MAGIC"));
bytes32 constant private _ERC1820_ACCEPT_MAGIC = keccak256(abi.encodePacked("ERC1820_ACCEPT_MAGIC"));
mapping(bytes32 => mapping(address => bool)) private _supportedInterfaces;
/**
* See {IERC1820Implementer-canImplementInterfaceForAddress}.
*/
function canImplementInterfaceForAddress(bytes32 interfaceHash, address account) external view returns (bytes32) {
return _supportedInterfaces[interfaceHash][account] ? ERC1820_ACCEPT_MAGIC : bytes32(0x00);
function canImplementInterfaceForAddress(bytes32 interfaceHash, address account) public view override returns (bytes32) {
return _supportedInterfaces[interfaceHash][account] ? _ERC1820_ACCEPT_MAGIC : bytes32(0x00);
}
/**
@ -29,7 +29,7 @@ contract ERC1820Implementer is IERC1820Implementer {
* See {IERC1820Registry-setInterfaceImplementer} and
* {IERC1820Registry-interfaceHash}.
*/
function _registerInterfaceForAddress(bytes32 interfaceHash, address account) internal {
function _registerInterfaceForAddress(bytes32 interfaceHash, address account) internal virtual {
_supportedInterfaces[interfaceHash][account] = true;
}
}

View File

@ -1,4 +1,4 @@
pragma solidity ^0.5.0;
pragma solidity ^0.6.0;
/**
* @dev Interface of the ERC165 standard, as defined in the

View File

@ -1,4 +1,4 @@
pragma solidity ^0.5.0;
pragma solidity ^0.6.0;
/**
* @dev Interface for an ERC1820 implementer, as defined in the

View File

@ -1,4 +1,4 @@
pragma solidity ^0.5.0;
pragma solidity ^0.6.0;
/**
* @dev Interface of the global ERC1820 Registry, as defined in the

View File

@ -1,6 +1,6 @@
= Introspection
This set of interfaces and contracts deal with [type introspection](https://en.wikipedia.org/wiki/Type_introspection) of contracts, that is, examining which functions can be called on them. This is usually referred to as a contract's _interface_.
This set of interfaces and contracts deal with https://en.wikipedia.org/wiki/Type_introspection[type introspection] of contracts, that is, examining which functions can be called on them. This is usually referred to as a contract's _interface_.
Ethereum contracts have no native concept of an interface, so applications must usually simply trust they are not making an incorrect call. For trusted setups this is a non-issue, but often unknown and untrusted third-party addresses need to be interacted with. There may even not be any direct calls to them! (e.g. `ERC20` tokens may be sent to a contract that lacks a way to transfer them out of it, locking them forever). In these cases, a contract _declaring_ its interface can be very helpful in preventing errors.

View File

@ -1,5 +0,0 @@
= Lifecycle
== Pausable
{{Pausable}}

View File

@ -1,4 +1,4 @@
pragma solidity ^0.5.0;
pragma solidity ^0.6.0;
/**
* @dev Standard math utilities missing in the Solidity language.

View File

@ -6,4 +6,6 @@ These are math-related utilities.
{{SafeMath}}
{{SignedSafeMath}}
{{Math}}

View File

@ -1,4 +1,4 @@
pragma solidity ^0.5.0;
pragma solidity ^0.6.0;
/**
* @dev Wrappers over Solidity's arithmetic operations with added overflow
@ -51,8 +51,6 @@ library SafeMath {
*
* Requirements:
* - Subtraction cannot overflow.
*
* _Available since v2.4.0._
*/
function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b <= a, errorMessage);
@ -109,8 +107,6 @@ library SafeMath {
*
* Requirements:
* - The divisor cannot be zero.
*
* _Available since v2.4.0._
*/
function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
// Solidity only automatically asserts when dividing by 0
@ -146,8 +142,6 @@ library SafeMath {
*
* Requirements:
* - The divisor cannot be zero.
*
* _Available since v2.4.0._
*/
function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b != 0, errorMessage);

View File

@ -1,11 +1,11 @@
pragma solidity ^0.5.0;
pragma solidity ^0.6.0;
/**
* @title SignedSafeMath
* @dev Signed math operations with safety checks that revert on error.
*/
library SignedSafeMath {
int256 constant private INT256_MIN = -2**255;
int256 constant private _INT256_MIN = -2**255;
/**
* @dev Multiplies two signed integers, reverts on overflow.
@ -18,7 +18,7 @@ library SignedSafeMath {
return 0;
}
require(!(a == -1 && b == INT256_MIN), "SignedSafeMath: multiplication overflow");
require(!(a == -1 && b == _INT256_MIN), "SignedSafeMath: multiplication overflow");
int256 c = a * b;
require(c / a == b, "SignedSafeMath: multiplication overflow");
@ -31,7 +31,7 @@ library SignedSafeMath {
*/
function div(int256 a, int256 b) internal pure returns (int256) {
require(b != 0, "SignedSafeMath: division by zero");
require(!(b == -1 && a == INT256_MIN), "SignedSafeMath: division overflow");
require(!(b == -1 && a == _INT256_MIN), "SignedSafeMath: division overflow");
int256 c = a / b;

View File

@ -0,0 +1,17 @@
pragma solidity ^0.6.0;
import "../access/AccessControl.sol";
contract AccessControlMock is AccessControl {
constructor() public {
_setupRole(DEFAULT_ADMIN_ROLE, _msgSender());
}
function setRoleAdmin(bytes32 roleId, bytes32 adminRoleId) public {
_setRoleAdmin(roleId, adminRoleId);
}
function setupRole(bytes32 roleId, address account) public {
_setupRole(roleId, account);
}
}

View File

@ -1,4 +1,4 @@
pragma solidity ^0.5.0;
pragma solidity ^0.6.0;
import "../utils/Address.sol";
@ -7,13 +7,10 @@ contract AddressImpl {
return Address.isContract(account);
}
function toPayable(address account) external pure returns (address payable) {
return Address.toPayable(account);
}
function sendValue(address payable receiver, uint256 amount) external {
Address.sendValue(receiver, amount);
}
function () external payable { } // sendValue's tests require the contract to hold Ether
// sendValue's tests require the contract to hold Ether
receive () external payable { }
}

View File

@ -1,14 +0,0 @@
pragma solidity ^0.5.0;
import "../token/ERC20/IERC20.sol";
import "../crowdsale/emission/AllowanceCrowdsale.sol";
contract AllowanceCrowdsaleImpl is AllowanceCrowdsale {
constructor (uint256 rate, address payable wallet, IERC20 token, address tokenWallet)
public
Crowdsale(rate, wallet, token)
AllowanceCrowdsale(tokenWallet)
{
// solhint-disable-previous-line no-empty-blocks
}
}

View File

@ -1,17 +1,17 @@
pragma solidity ^0.5.0;
pragma solidity ^0.6.0;
import "../utils/Arrays.sol";
contract ArraysImpl {
using Arrays for uint256[];
uint256[] private array;
uint256[] private _array;
constructor (uint256[] memory _array) public {
array = _array;
constructor (uint256[] memory 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);
}
}

View File

@ -1,14 +0,0 @@
pragma solidity ^0.5.0;
import "../token/ERC20/IERC20.sol";
import "../crowdsale/validation/CappedCrowdsale.sol";
contract CappedCrowdsaleImpl is CappedCrowdsale {
constructor (uint256 rate, address payable wallet, IERC20 token, uint256 cap)
public
Crowdsale(rate, wallet, token)
CappedCrowdsale(cap)
{
// solhint-disable-previous-line no-empty-blocks
}
}

View File

@ -1,18 +0,0 @@
pragma solidity ^0.5.0;
import "../access/roles/CapperRole.sol";
contract CapperRoleMock is CapperRole {
function removeCapper(address account) public {
_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);
}
}

View File

@ -1,4 +1,4 @@
pragma solidity ^0.5.0;
pragma solidity ^0.6.0;
import "../payment/escrow/ConditionalEscrow.sol";
@ -10,7 +10,7 @@ contract ConditionalEscrowMock is ConditionalEscrow {
_allowed[payee] = allowed;
}
function withdrawalAllowed(address payee) public view returns (bool) {
function withdrawalAllowed(address payee) public view override returns (bool) {
return _allowed[payee];
}
}

View File

@ -1,4 +1,4 @@
pragma solidity ^0.5.0;
pragma solidity ^0.6.0;
import "../GSN/Context.sol";

View File

@ -1,6 +1,6 @@
pragma solidity ^0.5.0;
pragma solidity ^0.6.0;
import "../drafts/Counters.sol";
import "../utils/Counters.sol";
contract CountersImpl {
using Counters for Counters.Counter;

View File

@ -1,23 +1,25 @@
pragma solidity ^0.5.0;
pragma solidity ^0.6.0;
import "../utils/Create2.sol";
import "../token/ERC20/ERC20.sol";
import "../introspection/ERC1820Implementer.sol";
contract Create2Impl {
function deploy(bytes32 salt, bytes memory code) public {
Create2.deploy(salt, code);
function deploy(uint256 value, bytes32 salt, bytes memory code) public {
Create2.deploy(value, salt, code);
}
function deployERC20(bytes32 salt) public {
function deployERC1820Implementer(uint256 value, bytes32 salt) public {
// solhint-disable-next-line indent
Create2.deploy(salt, type(ERC20).creationCode);
Create2.deploy(value, salt, type(ERC1820Implementer).creationCode);
}
function computeAddress(bytes32 salt, bytes memory code) public view returns (address) {
return Create2.computeAddress(salt, code);
function computeAddress(bytes32 salt, bytes32 codeHash) public view returns (address) {
return Create2.computeAddress(salt, codeHash);
}
function computeAddress(bytes32 salt, bytes memory code, address deployer) public pure returns (address) {
return Create2.computeAddress(salt, code, deployer);
function computeAddressWithDeployer(bytes32 salt, bytes32 codeHash, address deployer) public pure returns (address) {
return Create2.computeAddress(salt, codeHash, deployer);
}
receive() payable external {}
}

View File

@ -1,9 +0,0 @@
pragma solidity ^0.5.0;
import "../crowdsale/Crowdsale.sol";
contract CrowdsaleMock is Crowdsale {
constructor (uint256 rate, address payable wallet, IERC20 token) public Crowdsale(rate, wallet, token) {
// solhint-disable-previous-line no-empty-blocks
}
}

View File

@ -1,4 +1,4 @@
pragma solidity ^0.5.0;
pragma solidity ^0.6.0;
import "../cryptography/ECDSA.sol";

View File

@ -1,4 +1,4 @@
pragma solidity ^0.5.0;
pragma solidity ^0.6.0;
import "../../introspection/IERC165.sol";
@ -34,7 +34,7 @@ contract SupportsInterfaceWithLookupMock is IERC165 {
/**
* @dev Implement supportsInterface(bytes4) using a lookup table.
*/
function supportsInterface(bytes4 interfaceId) external view returns (bool) {
function supportsInterface(bytes4 interfaceId) public view override returns (bool) {
return _supportedInterfaces[interfaceId];
}

View File

@ -1,5 +1,3 @@
pragma solidity ^0.5.0;
pragma solidity ^0.6.0;
contract ERC165NotSupported {
// solhint-disable-previous-line no-empty-blocks
}
contract ERC165NotSupported { }

View File

@ -1,4 +1,4 @@
pragma solidity ^0.5.0;
pragma solidity ^0.6.0;
import "../introspection/ERC165Checker.sol";
@ -6,14 +6,14 @@ contract ERC165CheckerMock {
using ERC165Checker for address;
function supportsERC165(address account) public view returns (bool) {
return account._supportsERC165();
return account.supportsERC165();
}
function supportsInterface(address account, bytes4 interfaceId) public view returns (bool) {
return account._supportsInterface(interfaceId);
return account.supportsInterface(interfaceId);
}
function supportsAllInterfaces(address account, bytes4[] memory interfaceIds) public view returns (bool) {
return account._supportsAllInterfaces(interfaceIds);
return account.supportsAllInterfaces(interfaceIds);
}
}

View File

@ -1,4 +1,4 @@
pragma solidity ^0.5.0;
pragma solidity ^0.6.0;
import "../introspection/ERC165.sol";

View File

@ -1,4 +1,4 @@
pragma solidity ^0.5.0;
pragma solidity ^0.6.0;
import "../introspection/ERC1820Implementer.sol";

View File

@ -1,9 +1,14 @@
pragma solidity ^0.5.0;
pragma solidity ^0.6.0;
import "../token/ERC20/ERC20Burnable.sol";
contract ERC20BurnableMock is ERC20Burnable {
constructor (address initialAccount, uint256 initialBalance) public {
constructor (
string memory name,
string memory symbol,
address initialAccount,
uint256 initialBalance
) public ERC20(name, symbol) {
_mint(initialAccount, initialBalance);
}
}

View File

@ -0,0 +1,13 @@
pragma solidity ^0.6.0;
import "../token/ERC20/ERC20Capped.sol";
contract ERC20CappedMock is ERC20Capped {
constructor (string memory name, string memory symbol, uint256 cap)
public ERC20(name, symbol) ERC20Capped(cap)
{ }
function mint(address to, uint256 tokenId) public {
_mint(to, tokenId);
}
}

View File

@ -0,0 +1,13 @@
pragma solidity ^0.6.0;
import "../token/ERC20/ERC20.sol";
contract ERC20DecimalsMock is ERC20 {
constructor (string memory name, string memory symbol, uint8 decimals) public ERC20(name, symbol) {
_setupDecimals(decimals);
}
function setupDecimals(uint8 decimals) public {
_setupDecimals(decimals);
}
}

View File

@ -1,13 +0,0 @@
pragma solidity ^0.5.0;
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(name, symbol, decimals)
{
// solhint-disable-previous-line no-empty-blocks
}
}

View File

@ -1,14 +0,0 @@
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(tokenURI) {
// solhint-disable-previous-line no-empty-blocks
}
function setTokenURI(string memory tokenURI) public {
_setTokenURI(tokenURI);
}
}

View File

@ -1,8 +0,0 @@
pragma solidity ^0.5.0;
import "../token/ERC20/ERC20Mintable.sol";
import "./MinterRoleMock.sol";
contract ERC20MintableMock is ERC20Mintable, MinterRoleMock {
// solhint-disable-previous-line no-empty-blocks
}

View File

@ -1,10 +1,15 @@
pragma solidity ^0.5.0;
pragma solidity ^0.6.0;
import "../token/ERC20/ERC20.sol";
// mock class using ERC20
contract ERC20Mock is ERC20 {
constructor (address initialAccount, uint256 initialBalance) public {
constructor (
string memory name,
string memory symbol,
address initialAccount,
uint256 initialBalance
) public payable ERC20(name, symbol) {
_mint(initialAccount, initialBalance);
}
@ -16,10 +21,6 @@ contract ERC20Mock is ERC20 {
_burn(account, amount);
}
function burnFrom(address account, uint256 amount) public {
_burnFrom(account, amount);
}
function transferInternal(address from, address to, uint256 value) public {
_transfer(from, to, value);
}

View File

@ -1,11 +1,23 @@
pragma solidity ^0.5.0;
pragma solidity ^0.6.0;
import "../token/ERC20/ERC20Pausable.sol";
import "./PauserRoleMock.sol";
// mock class using ERC20Pausable
contract ERC20PausableMock is ERC20Pausable, PauserRoleMock {
constructor (address initialAccount, uint256 initialBalance) public {
contract ERC20PausableMock is ERC20Pausable {
constructor (
string memory name,
string memory symbol,
address initialAccount,
uint256 initialBalance
) public ERC20(name, symbol) {
_mint(initialAccount, initialBalance);
}
function pause() external {
_pause();
}
function unpause() external {
_unpause();
}
}

View File

@ -1,13 +1,22 @@
pragma solidity ^0.5.0;
pragma solidity ^0.6.0;
import "../drafts/ERC20Snapshot.sol";
import "../token/ERC20/ERC20Snapshot.sol";
contract ERC20SnapshotMock is ERC20Snapshot {
constructor(address initialAccount, uint256 initialBalance) public {
constructor(
string memory name,
string memory symbol,
address initialAccount,
uint256 initialBalance
) public ERC20(name, symbol) {
_mint(initialAccount, initialBalance);
}
function snapshot() public {
_snapshot();
}
function mint(address account, uint256 amount) public {
_mint(account, amount);
}

View File

@ -0,0 +1,11 @@
pragma solidity ^0.6.0;
import "../token/ERC721/ERC721Burnable.sol";
contract ERC721BurnableMock is ERC721Burnable {
constructor(string memory name, string memory symbol) public ERC721(name, symbol) { }
function mint(address to, uint256 tokenId) public {
_mint(to, tokenId);
}
}

View File

@ -1,33 +0,0 @@
pragma solidity ^0.5.0;
import "../token/ERC721/ERC721Full.sol";
import "../token/ERC721/ERC721Mintable.sol";
import "../token/ERC721/ERC721MetadataMintable.sol";
import "../token/ERC721/ERC721Burnable.sol";
/**
* @title ERC721FullMock
* 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 {
constructor (string memory name, string memory symbol) public ERC721Mintable() ERC721Full(name, symbol) {
// solhint-disable-previous-line no-empty-blocks
}
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 memory uri) public {
_setTokenURI(tokenId, uri);
}
function setBaseURI(string memory baseURI) public {
_setBaseURI(baseURI);
}
}

View File

@ -1,4 +1,4 @@
pragma solidity ^0.5.0;
pragma solidity ^0.6.0;
import "../token/ERC721/ERC721.sol";
import "../GSN/GSNRecipient.sol";
@ -9,10 +9,21 @@ import "../GSN/GSNRecipientSignature.sol";
* A simple ERC721 mock that has GSN support enabled
*/
contract ERC721GSNRecipientMock is ERC721, GSNRecipient, GSNRecipientSignature {
constructor(address trustedSigner) public GSNRecipientSignature(trustedSigner) { }
// solhint-disable-previous-line no-empty-blocks
constructor(string memory name, string memory symbol, address trustedSigner)
public
ERC721(name, symbol)
GSNRecipientSignature(trustedSigner)
{ }
function mint(uint256 tokenId) public {
_mint(_msgSender(), tokenId);
}
function _msgSender() internal view override(Context, GSNRecipient) returns (address payable) {
return GSNRecipient._msgSender();
}
function _msgData() internal view override(Context, GSNRecipient) returns (bytes memory) {
return GSNRecipient._msgData();
}
}

View File

@ -1,15 +0,0 @@
pragma solidity ^0.5.0;
import "../token/ERC721/ERC721Full.sol";
import "../token/ERC721/ERC721Mintable.sol";
import "../token/ERC721/ERC721MetadataMintable.sol";
import "../token/ERC721/ERC721Burnable.sol";
/**
* @title ERC721MintableBurnableImpl
*/
contract ERC721MintableBurnableImpl is ERC721Full, ERC721Mintable, ERC721MetadataMintable, ERC721Burnable {
constructor () public ERC721Mintable() ERC721Full("Test", "TEST") {
// solhint-disable-previous-line no-empty-blocks
}
}

View File

@ -1,4 +1,4 @@
pragma solidity ^0.5.0;
pragma solidity ^0.6.0;
import "../token/ERC721/ERC721.sol";
@ -7,6 +7,24 @@ import "../token/ERC721/ERC721.sol";
* This mock just provides a public safeMint, mint, and burn functions for testing purposes
*/
contract ERC721Mock is ERC721 {
constructor (string memory name, string memory symbol) public ERC721(name, symbol) { }
function exists(uint256 tokenId) public view returns (bool) {
return _exists(tokenId);
}
function setTokenURI(uint256 tokenId, string memory uri) public {
_setTokenURI(tokenId, uri);
}
function setBaseURI(string memory baseURI) public {
_setBaseURI(baseURI);
}
function mint(address to, uint256 tokenId) public {
_mint(to, tokenId);
}
function safeMint(address to, uint256 tokenId) public {
_safeMint(to, tokenId);
}
@ -15,14 +33,6 @@ contract ERC721Mock is ERC721 {
_safeMint(to, tokenId, _data);
}
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);
}

View File

@ -1,13 +1,14 @@
pragma solidity ^0.5.0;
pragma solidity ^0.6.0;
import "../token/ERC721/ERC721Pausable.sol";
import "./PauserRoleMock.sol";
/**
* @title ERC721PausableMock
* This mock just provides a public mint, burn and exists functions for testing purposes
*/
contract ERC721PausableMock is ERC721Pausable, PauserRoleMock {
contract ERC721PausableMock is ERC721Pausable {
constructor (string memory name, string memory symbol) public ERC721(name, symbol) { }
function mint(address to, uint256 tokenId) public {
super._mint(to, tokenId);
}
@ -19,4 +20,12 @@ contract ERC721PausableMock is ERC721Pausable, PauserRoleMock {
function exists(uint256 tokenId) public view returns (bool) {
return super._exists(tokenId);
}
function pause() external {
_pause();
}
function unpause() external {
_unpause();
}
}

View File

@ -1,4 +1,4 @@
pragma solidity ^0.5.0;
pragma solidity ^0.6.0;
import "../token/ERC721/IERC721Receiver.sol";
@ -14,7 +14,7 @@ contract ERC721ReceiverMock is IERC721Receiver {
}
function onERC721Received(address operator, address from, uint256 tokenId, bytes memory data)
public returns (bytes4)
public override returns (bytes4)
{
require(!_reverts, "ERC721ReceiverMock: reverting");
emit Received(operator, from, tokenId, data, gasleft());

View File

@ -1,4 +1,4 @@
pragma solidity ^0.5.0;
pragma solidity ^0.6.0;
import "../GSN/Context.sol";
import "../token/ERC777/ERC777.sol";
@ -11,16 +11,15 @@ contract ERC777Mock is Context, ERC777 {
string memory symbol,
address[] memory defaultOperators
) public ERC777(name, symbol, defaultOperators) {
_mint(_msgSender(), initialHolder, initialBalance, "", "");
_mint(initialHolder, initialBalance, "", "");
}
function mintInternal (
address operator,
address to,
uint256 amount,
bytes memory userData,
bytes memory operatorData
) public {
_mint(operator, to, amount, userData, operatorData);
_mint(to, amount, userData, operatorData);
}
}

View File

@ -1,4 +1,4 @@
pragma solidity ^0.5.0;
pragma solidity ^0.6.0;
import "../GSN/Context.sol";
import "../token/ERC777/IERC777.sol";
@ -37,8 +37,8 @@ contract ERC777SenderRecipientMock is Context, IERC777Sender, IERC777Recipient,
IERC1820Registry private _erc1820 = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);
bytes32 constant private TOKENS_SENDER_INTERFACE_HASH = keccak256("ERC777TokensSender");
bytes32 constant private TOKENS_RECIPIENT_INTERFACE_HASH = keccak256("ERC777TokensRecipient");
bytes32 constant private _TOKENS_SENDER_INTERFACE_HASH = keccak256("ERC777TokensSender");
bytes32 constant private _TOKENS_RECIPIENT_INTERFACE_HASH = keccak256("ERC777TokensRecipient");
function tokensToSend(
address operator,
@ -47,7 +47,7 @@ contract ERC777SenderRecipientMock is Context, IERC777Sender, IERC777Recipient,
uint256 amount,
bytes calldata userData,
bytes calldata operatorData
) external {
) external override {
if (_shouldRevertSend) {
revert();
}
@ -78,7 +78,7 @@ contract ERC777SenderRecipientMock is Context, IERC777Sender, IERC777Recipient,
uint256 amount,
bytes calldata userData,
bytes calldata operatorData
) external{
) external override {
if (_shouldRevertReceive) {
revert();
}
@ -103,7 +103,7 @@ contract ERC777SenderRecipientMock is Context, IERC777Sender, IERC777Recipient,
}
function senderFor(address account) public {
_registerInterfaceForAddress(TOKENS_SENDER_INTERFACE_HASH, account);
_registerInterfaceForAddress(_TOKENS_SENDER_INTERFACE_HASH, account);
address self = address(this);
if (account == self) {
@ -112,11 +112,11 @@ contract ERC777SenderRecipientMock is Context, IERC777Sender, IERC777Recipient,
}
function registerSender(address sender) public {
_erc1820.setInterfaceImplementer(address(this), TOKENS_SENDER_INTERFACE_HASH, sender);
_erc1820.setInterfaceImplementer(address(this), _TOKENS_SENDER_INTERFACE_HASH, sender);
}
function recipientFor(address account) public {
_registerInterfaceForAddress(TOKENS_RECIPIENT_INTERFACE_HASH, account);
_registerInterfaceForAddress(_TOKENS_RECIPIENT_INTERFACE_HASH, account);
address self = address(this);
if (account == self) {
@ -125,7 +125,7 @@ contract ERC777SenderRecipientMock is Context, IERC777Sender, IERC777Recipient,
}
function registerRecipient(address recipient) public {
_erc1820.setInterfaceImplementer(address(this), TOKENS_RECIPIENT_INTERFACE_HASH, recipient);
_erc1820.setInterfaceImplementer(address(this), _TOKENS_RECIPIENT_INTERFACE_HASH, recipient);
}
function setShouldRevertSend(bool shouldRevert) public {

View File

@ -0,0 +1,38 @@
pragma solidity ^0.6.0;
import "../utils/EnumerableMap.sol";
contract EnumerableMapMock {
using EnumerableMap for EnumerableMap.UintToAddressMap;
event OperationResult(bool result);
EnumerableMap.UintToAddressMap private _map;
function contains(uint256 key) public view returns (bool) {
return _map.contains(key);
}
function set(uint256 key, address value) public {
bool result = _map.set(key, value);
emit OperationResult(result);
}
function remove(uint256 key) public {
bool result = _map.remove(key);
emit OperationResult(result);
}
function length() public view returns (uint256) {
return _map.length();
}
function at(uint256 index) public view returns (uint256 key, address value) {
return _map.at(index);
}
function get(uint256 key) public view returns (address) {
return _map.get(key);
}
}

View File

@ -1,37 +1,33 @@
pragma solidity ^0.5.0;
pragma solidity ^0.6.0;
import "../utils/EnumerableSet.sol";
contract EnumerableSetMock{
contract EnumerableSetMock {
using EnumerableSet for EnumerableSet.AddressSet;
event TransactionResult(bool result);
event OperationResult(bool result);
EnumerableSet.AddressSet private set;
EnumerableSet.AddressSet private _set;
function contains(address value) public view returns (bool) {
return set.contains(value);
return _set.contains(value);
}
function add(address value) public {
bool result = set.add(value);
emit TransactionResult(result);
bool result = _set.add(value);
emit OperationResult(result);
}
function remove(address value) public {
bool result = set.remove(value);
emit TransactionResult(result);
}
function enumerate() public view returns (address[] memory) {
return set.enumerate();
bool result = _set.remove(value);
emit OperationResult(result);
}
function length() public view returns (uint256) {
return set.length();
return _set.length();
}
function get(uint256 index) public view returns (address) {
return set.get(index);
function at(uint256 index) public view returns (address) {
return _set.at(index);
}
}

View File

@ -1,4 +1,4 @@
pragma solidity ^0.5.0;
pragma solidity ^0.6.0;
contract EtherReceiverMock {
bool private _acceptEther;
@ -7,7 +7,7 @@ contract EtherReceiverMock {
_acceptEther = acceptEther;
}
function () external payable {
receive () external payable {
if (!_acceptEther) {
revert();
}

View File

@ -1,14 +0,0 @@
pragma solidity ^0.5.0;
import "../token/ERC20/IERC20.sol";
import "../crowdsale/distribution/FinalizableCrowdsale.sol";
contract FinalizableCrowdsaleImpl is FinalizableCrowdsale {
constructor (uint256 openingTime, uint256 closingTime, uint256 rate, address payable wallet, IERC20 token)
public
Crowdsale(rate, wallet, token)
TimedCrowdsale(openingTime, closingTime)
{
// solhint-disable-previous-line no-empty-blocks
}
}

View File

@ -1,12 +1,10 @@
pragma solidity ^0.5.0;
pragma solidity ^0.6.0;
import "../GSN/GSNRecipient.sol";
import "../GSN/GSNRecipientERC20Fee.sol";
contract GSNRecipientERC20FeeMock is GSNRecipient, GSNRecipientERC20Fee {
constructor(string memory name, string memory symbol) public GSNRecipientERC20Fee(name, symbol) {
// solhint-disable-previous-line no-empty-blocks
}
constructor(string memory name, string memory symbol) public GSNRecipientERC20Fee(name, symbol) { }
function mint(address account, uint256 amount) public {
_mint(account, amount);

View File

@ -1,4 +1,4 @@
pragma solidity ^0.5.0;
pragma solidity ^0.6.0;
import "./ContextMock.sol";
import "../GSN/GSNRecipient.sol";
@ -12,20 +12,25 @@ contract GSNRecipientMock is ContextMock, GSNRecipient {
function acceptRelayedCall(address, address, bytes calldata, uint256, uint256, uint256, uint256, bytes calldata, uint256)
external
view
override
returns (uint256, bytes memory)
{
return (0, "");
}
function _preRelayedCall(bytes memory) internal returns (bytes32) {
// solhint-disable-previous-line no-empty-blocks
}
function _preRelayedCall(bytes memory) internal override returns (bytes32) { }
function _postRelayedCall(bytes memory, bool, uint256, bytes32) internal {
// solhint-disable-previous-line no-empty-blocks
}
function _postRelayedCall(bytes memory, bool, uint256, bytes32) internal override { }
function upgradeRelayHub(address newRelayHub) public {
return _upgradeRelayHub(newRelayHub);
}
function _msgSender() internal override(Context, GSNRecipient) view virtual returns (address payable) {
return GSNRecipient._msgSender();
}
function _msgData() internal override(Context, GSNRecipient) view virtual returns (bytes memory) {
return GSNRecipient._msgData();
}
}

View File

@ -1,12 +1,10 @@
pragma solidity ^0.5.0;
pragma solidity ^0.6.0;
import "../GSN/GSNRecipient.sol";
import "../GSN/GSNRecipientSignature.sol";
contract GSNRecipientSignatureMock is GSNRecipient, GSNRecipientSignature {
constructor(address trustedSigner) public GSNRecipientSignature(trustedSigner) {
// solhint-disable-previous-line no-empty-blocks
}
constructor(address trustedSigner) public GSNRecipientSignature(trustedSigner) { }
event MockFunctionCalled();

View File

@ -1,22 +0,0 @@
pragma solidity ^0.5.0;
import "../crowdsale/price/IncreasingPriceCrowdsale.sol";
import "../math/SafeMath.sol";
contract IncreasingPriceCrowdsaleImpl is IncreasingPriceCrowdsale {
constructor (
uint256 openingTime,
uint256 closingTime,
address payable wallet,
IERC20 token,
uint256 initialRate,
uint256 finalRate
)
public
Crowdsale(initialRate, wallet, token)
TimedCrowdsale(openingTime, closingTime)
IncreasingPriceCrowdsale(initialRate, finalRate)
{
// solhint-disable-previous-line no-empty-blocks
}
}

Some files were not shown because too many files have changed in this diff Show More