Compare commits

...

41 Commits

Author SHA1 Message Date
a3af8266db 2.3.0-rc.0 2019-04-24 11:35:30 -03:00
9d868ee846 Add revert reasons changelog entry. 2019-04-24 11:32:30 -03:00
2f8e844514 Fix remaining revert reasons. 2019-04-24 11:25:09 -03:00
3682c6575c Added message string for require() (#1704)
* Error handling in ERC20 and ERC721

* Added message string for require.

* Fixed solhint errors.

* Updated PR as per issue #1709

* changes as per #1709 and openzeppelin forum.

* Changes in require statement

* Changes in require statement

* build pipeline fix

* Changes as per @nventuro's comment.

* Update revert reason strings.

* Fianal update of revert reason strings.

* WIP: Updating reason strings in test cases

* WIP: Added changes to ERC20 and ERC721

* Fixes linting errors in *.tes.js files

* Achieved 100% code coverage

* Updated the test cases with shouldFail.reverting.withMessage()

* Fix package-lock.

* address review comments

* fix linter issues

* fix remaining revert reasons
2019-04-24 11:17:08 -03:00
4a0a67b04c make some updates on the get started guide (#1725) 2019-04-23 20:20:01 -03:00
97a9ca5681 Add a vault to PostDeliveryCrowdsale. (#1721)
* Add a vault to PostDeliveryCrowdsale.

* Add changelog entry.

* Apply suggestions from code review

Co-Authored-By: nventuro <nicolas.venturo@gmail.com>

* Rename TokenVault.

* add solhint ignore directive
2019-04-23 19:06:09 -03:00
19c7414052 Bump minimum Solidity version to 0.5.7 (#1724)
* Bump Solidity version to 0.5.7

* Add changelog entry.
2019-04-23 16:18:08 -03:00
5e46cf6de4 Fix linter error. 2019-04-23 14:30:58 -03:00
ed5652b0aa New documentation setup (#1708)
* initial docsite setup

* switch from pushd to cd

* install and set up solidity-docgen

* use the docsite branch next for now

* make it clear that env var is a repository

* add a clarifying comment about a relative path

* change relative to absolute path in docsite script

* add docgen script

* add first few READMEs for contract documentation

* update solidity-docgen

* add docsite as dependency and adjust script

* update openzeppelin-docsite

* update solidity-docgen

* remove dummy text

* update docgen and docsite

* update openzeppelin-docsite

* add netlify.toml

* udpate tokens guide for 2.2

* add DOCUMENTATION.md

* Update docs/learn-about-utilities.md

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

* fix PaymentSplitter docs wording

* update solidity-docgen

* add missing ERC20 contracts

* update solidity-docgen

* trigger deploy with cleared cache

* update solidity-docgen

* update openzeppelin-docsite

* remove travis docs setup

* update openzeppelin-docsite

* switch to published solidity-docgen
2019-04-23 12:25:22 -03:00
412cdfd0be Release automation (#1720)
* Create autoamtic release script.

* Add changelog update date script.

* Improve release scripts.

* Apply suggestions from code review

Co-Authored-By: nventuro <nicolas.venturo@gmail.com>

* Apply suggestions from code review

Co-Authored-By: nventuro <nicolas.venturo@gmail.com>

* Remove moment dependency.
2019-04-22 17:31:32 -03:00
59f03f00c5 Fix stalebot exempt labels 2019-04-19 15:25:36 -03:00
ea59f86cdf Update stalebot wording and timing. (#1722) 2019-04-19 02:20:47 -03:00
0df0e1b250 Fixes/Improves constants inline documentation. (#1707)
* Fixes/Improves constants inline documentation.

* Fixed solhint error.

* Moved the comment before the variable
2019-04-17 16:38:33 -03:00
5a2b349992 Feature/erc777 #1159 (#1684)
* IERC777 from specs, constants returned, up to defaultOperators. (#1159)

* IERC777 oprarator approvals (#1159)

* ERC777 oprarator approvals fixes and tests

* IERC777 send and receive with ERC820 (#1159)

* ERC777 Add burn functions and fix send functions (#1159)

* ERC777 Make expectEvent compatible with web3.js 1.0 (#1159)

* ERC777 Add ERC820 deploy script (#1159)

* ERC777 Complete implementation of ERC777 (#1159)

This implementation conforms to the current EIP

* ERC777 Update ERC820 Registry contract to final version (#1159)

* ERC777 Move contracts to 'drafts' folder (#1159)

* ERC777: Update to ERC1820 registry and linter error fix (#1159)

* ERC777: implement recent changes of EIP777 (#1159)

* ERC777 Fix formatting (#1159)

* ERC777 Update to solc 0.5.2 (#1159)

* ERC777 Fix travis CI errors (#1159)

* ERC777 Fix linter errors again... (#1159)

* ERC777 Fix unit test (#1159)

* ERC777 Fix unit test again (#1159)

* Remove extra newlines.

* Rename ERC777Base to ERC777.

* Remove 'Token' from contract names.

* Replace ops for operators.

* Move operator check out of _send.

* Remove ERC777Burnable.

* Remove ERC1820Client, now using the interface directly.

* Minor internal refactors in contracts.

* Delete extra test helpers.

* Simplified tests.

* Add basic 777 tests.

* Add granularity send test.

* Add first operator send tests.

* Add burn tests.

* Refactor send and burn tests.

* Improve send burn refactor.

* Greatly improve test module.

* Burn instead of send removed tokens.

* Add operator tests.

* Improve send tests under changing operators.

* Refactor and merge send and burn tests.

* Add missing and not-implemented tests.

* Make _burn private.

* Fix typo.

* Greatly improve tokensToSend tests.

* Refactor hook tests.

* Fix hook tests.

* Update openzeppelin-test-helpers and ERC1820 address.

* Fix natspec indentation.

* Make interface functions external.

* Remove redundant private revoke and authorize functions.

* Improved readability of if statement.

* Remove unnecessary asserts.

* Add non-one granularity test.

* Fix hook call order in _mint.

* Fix _mint not reverting on failure to implement tokensReceived.

* Remove special case in operatorFn when from is 0.

* Refactor ERC777SenderMock.

* Add tokensReceived tests.

* switch to updated ganache-cli-coverage fork

* Fix linter errors.

* Add mint tests.

* Fix linter errors.

* Fix tests.

* Update test/drafts/ERC777/ERC777.test.js

Co-Authored-By: nventuro <nicolas.venturo@gmail.com>

* Add changelog entry.
2019-04-16 13:13:46 -03:00
963f1eb35b removed unnecessary require and renaming of null to zero (#1717)
* removed unnecessary require

* build pipeline fix

* kept as it is

* Added require
2019-04-15 16:03:44 -03:00
bbe0eefd9f removing unused variables (#1719)
* removing unused variables

* undeleting the _
2019-04-12 13:25:21 -03:00
19c705d928 Fix/rename anyone account #1357 (#1718)
* replacing all instances of from: anyone with from: other

* replacing all instances of from: anyone with from: other

* replacing all instances of from: anyone with from: other

* changing anyone to other

* changing anyone to other
2019-04-11 12:34:10 -03:00
d45f0c89db Update copyright notice 2019-04-10 19:23:54 -03:00
1ebeef7ffd Remove unnecessary SLOAD. (#1715) 2019-04-10 12:29:58 -03:00
b353f7e18c Add more extensive documentation to PaymentSplitter (#1713)
* Update PaymentSplitter.sol

* add back private function docs

* add non-zero address requirement

* add comprehensive contract-level docs

* use capital E for Ether
2019-04-09 19:47:20 -03:00
92e68e3aaa Revert "Add WIP bot."
This reverts commit 07fc8c731a.
2019-04-09 18:52:17 -03:00
07fc8c731a Add WIP bot. 2019-04-09 18:44:39 -03:00
81e36d2e74 Fix from account in remove public role behaviors (#1710) 2019-04-05 18:06:22 -03:00
35d8e860ad Remove unused files (#1698)
* Remove unused dependencies.

* Remove unused mock contracts.
2019-04-01 15:00:39 -03:00
8b44efd035 add note about Counters rename in changelog (#1703) 2019-04-01 13:24:50 -03:00
3cb4a00fce Added basic punctuation to @dev docs (#1697) (#1700)
* Added basic punctuation to @dev docs (#1697)

* add missing uppercase
2019-03-30 16:48:17 -03:00
c008f1f0c6 Exclude on-hold PRs and issues on stalebot. (#1696) 2019-03-26 16:21:13 -03:00
dc5ca8edc4 Edit Ethereum dev framework links in README. (#1695)
Added Buidler.
2019-03-25 16:22:48 -03:00
7ccd224567 Update SafeERC20.sol (#1693) 2019-03-25 14:27:26 -03:00
cf7375d6b8 Update openzeppelin-test-helpers dependency. 2019-03-19 17:54:02 -03:00
308a4c9907 Draft EIP 1820 (#1677)
* Add barebones EIP1820 support.

* Update openzeppelin-test-helpers dependency to have ERC1820 support.

* Add tests for ERC1820.

* Improve inline documentation.

* Add changelog entry.

* Update test-helpers, refactor tests to use new helpers.

* Rename ERC1820 to ERC1820Implementer.

* Improve implementer docstring.

* Remove _implementsInterfaceForAddress.

* update openzeppelin-test-helpers to 0.2.0

* Update contracts/drafts/ERC1820Implementer.sol

Co-Authored-By: nventuro <nicolas.venturo@gmail.com>

* Fix how solidity coverage is run to allow for free events.

* Fix coverage testing script.
2019-03-19 15:13:55 -03:00
269e096c5a Remove unused return variables. (#1686) 2019-03-19 11:51:46 -03:00
edfce5a3dd Add probot/stale to the repo. (#1681) 2019-03-17 22:38:36 -03:00
ab14debb08 Make waiting for ganache to launch more robust. (#1683) 2019-03-17 16:59:29 -03:00
40d2eb3007 Merge branch 'release-v2.2.0' 2019-03-14 18:46:11 -03:00
2a37b09cf6 Improve test script. (#1675) 2019-03-12 17:17:33 -03:00
29fa0a4ce5 Add API stability doc link. (#1672)
* Add API stability doc link.

* Update README.md

Co-Authored-By: nventuro <nicolas.venturo@gmail.com>
2019-03-12 13:31:22 -03:00
06f7266a6e Replace mentions of Slack for forum links. (#1671)
* Replace mentions of Slack for forum links.

* make forum lowercase
2019-03-12 13:15:46 -03:00
4c706480e5 Fix typo in ERC20Snapshot. (#1670) 2019-03-12 13:15:08 -03:00
4dd8575bb6 Improve erc165 testing #1203 (#1666)
* Rename variable from thing to contractUnderTest

* Compute function signatures in ERC165 interfaces

The ERC165 tests currently precompute some known interface ids.
This commit extracts the interfaces into a separate object and
precomputes the individual function signatures.

This will be useful to identify contracts that support an interface
but do not implement all of the corresponding functions.

* Add tests for ERC165 interface implementations

The ERC165 tests confirm that contracts claim to support
particular interfaces ( using the supportsInterface method )

This commit extends those tests to confirm that the corresponding
functions are included in the contract ABI.

It also rewords the existing test names in order to group the
implementation tests with the corresponding interface tests.

* Remove obsolete ERC721Exists interface constant
2019-03-07 19:41:22 -03:00
9c69df5962 Fix changelog entry. 2019-03-07 14:34:51 -03:00
220 changed files with 14402 additions and 1113 deletions

View File

@ -6,7 +6,7 @@ about: Report a bug in OpenZeppelin
<!-- Briefly describe the issue you're experiencing. Tell us what you were trying to do and what happened instead. -->
<!-- Remember, this is not a place to ask for help debugging code. For that, we welcome you in the OpenZeppelin Slack channel: https://slack.openzeppelin.org/. -->
<!-- Remember, this is not a place to ask for help debugging code. For that, we welcome you in the Zeppelin Forum: https://forum.zeppelin.solutions/. -->
**💻 Environment**

66
.github/stale.yml vendored Normal file
View File

@ -0,0 +1,66 @@
# Configuration for probot-stale - https://github.com/probot/stale
# Number of days of inactivity before an Issue or Pull Request becomes stale
daysUntilStale: 15
# Number of days of inactivity before an Issue or Pull Request with the stale label is closed.
# Set to false to disable. If disabled, issues still need to be closed manually, but will remain marked as stale.
daysUntilClose: 15
# Issues or Pull Requests with these labels will never be considered stale. Set to `[]` to disable
exemptLabels:
- on hold
# Set to true to ignore issues in a project (defaults to false)
exemptProjects: false
# Set to true to ignore issues in a milestone (defaults to false)
exemptMilestones: false
# Set to true to ignore issues with an assignee (defaults to false)
exemptAssignees: false
# Label to use when marking as stale
staleLabel: stale
# Comment to post when marking as stale. Set to `false` to disable
markComment: >
Hi all!
This Pull Request has not had any recent activity, is it still relevant? If so, what is blocking it?
Is there anything we can do to help move it forward?
Thanks!
# Comment to post when removing the stale label.
# unmarkComment: >
# Your comment here.
# Comment to post when closing a stale Issue or Pull Request.
closeComment: >
Hi folks!
This Pull Request is being closed as there was no response to the previous prompt.
However, please leave a comment whenever you're ready to resume, so it can be reopened.
Thanks again!
# Limit the number of actions per hour, from 1-30. Default is 30
limitPerRun: 30
# Limit to only `issues` or `pulls`
only: pulls
# Optionally, specify configuration settings that are specific to just 'issues' or 'pulls':
# pulls:
# daysUntilStale: 30
# markComment: >
# This pull request has been automatically marked as stale because it has not had
# recent activity. It will be closed if no further activity occurs. Thank you
# for your contributions.
# issues:
# exemptLabels:
# - confirmed

4
.gitignore vendored
View File

@ -40,3 +40,7 @@ build/
# IntelliJ IDE
.idea
# docsite artifacts
docsite-build
docs/api

View File

@ -35,15 +35,6 @@ jobs:
script: npm run test
env: SOLC_NIGHTLY=true
- stage: update docs
if: tag =~ ^v[0-9]+\.[0-9]+\.[0-9]+$
addons:
apt:
packages:
- curl
script:
- ./scripts/ci/trigger_docs_update "${TRAVIS_TAG}"
notifications:
slack:
rooms:

View File

@ -1,10 +1,23 @@
# Changelog
## 2.3.0 (unreleased)
### New features:
* `ERC1820`: added support for interacting with the [ERC1820](https://eips.ethereum.org/EIPS/eip-1820) registry contract (`IERC1820Registry`), as well as base contracts that can be registered as implementers there. ([#1677](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1677))
* `ERC777`: initial support for the [ERC777 token](https://eips.ethereum.org/EIPS/eip-777), which has multiple improvements over `ERC20` such as built-in burning, a more straightforward permission system, and optional sender and receiver hooks on transfer (mandatory for contracts!). ([#1684](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1684))
* All contracts now have revert reason strings, which give insight into error conditions, and help debug failing transactions. ([#1704](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1704))
### Improvements:
* Upgraded the minimum compiler version to v0.5.7: this prevents users from encountering compiler bugs that were fixed in this version. ([#1724](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1724))
### Bugfixes:
* `PostDeliveryCrowdsale`: some validations where skipped when paired with other crowdsale flavors, such as `AllowanceCrowdsale`, or `MintableCrowdsale` and `ERC20Capped`, which could cause buyers to not be able to claim their purchased tokens. ([#1721](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1721))
## 2.2.0 (2019-03-14)
### New features:
* `ERC20Snapshot`: create snapshots on demand of the token balances and total supply, to later retrieve and e.g. calculate dividends at a past time. ([#1617](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1617))
* `SafeERC20`: `ERC20` contracts with no return value (i.e. that revert on failure) are now supported. ([#1655](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/))
* `SafeERC20`: `ERC20` contracts with no return value (i.e. that revert on failure) are now supported. ([#1655](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1655))
* `ERC20`: added internal `_approve(address owner, address spender, uint256 value)`, allowing derived contracts to set the allowance of arbitrary accounts. ([#1609](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1609))
* `ERC20Metadata`: added internal `_setTokenURI(string memory tokenURI)`. ([#1618](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1618))
* `TimedCrowdsale`: added internal `_extendTime(uint256 newClosingTime)` as well as `TimedCrowdsaleExtended(uint256 prevClosingTime, uint256 newClosingTime)` event allowing to extend the crowdsale, as long as it hasn't already closed.
@ -13,14 +26,14 @@
* Upgraded the minimum compiler version to v0.5.2: this removes many Solidity warnings that were false positives. ([#1606](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1606))
* `ECDSA`: `recover` no longer accepts malleable signatures (those using upper-range values for `s`, or 0/1 for `v`). ([#1622](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1622))
* `ERC721`'s transfers are now more gas efficient due to removal of unnecessary `SafeMath` calls. ([#1610](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1610))
* `Counter`'s API has been improved, and is now used by `ERC721` (though it is still in `drafts`). ([#1610](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1610))
* Fixed variable shadowing issues. ([#1606](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1606))
### Bugfixes:
* (minor) `SafeERC20`: `safeApprove` wasn't properly checking for a zero allowance when attempting to set a non-zero allowance. ([#1647](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1647))
### Breaking changes:
* `TokenMetadata` (in drafts) has been renamed to `ERC20Metadata`. ([#1618](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1618))
### Breaking changes in drafts:
* `TokenMetadata` has been renamed to `ERC20Metadata`. ([#1618](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1618))
* The library `Counter` has been renamed to `Counters` and its API has been improved. See an example in `ERC721`, lines [17](https://github.com/OpenZeppelin/openzeppelin-solidity/blob/3cb4a00fce1da76196ac0ac3a0ae9702b99642b5/contracts/token/ERC721/ERC721.sol#L17) and [204](https://github.com/OpenZeppelin/openzeppelin-solidity/blob/3cb4a00fce1da76196ac0ac3a0ae9702b99642b5/contracts/token/ERC721/ERC721.sol#L204). ([#1610](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1610))
## 2.1.3 (2019-02-26)
* Backported `SafeERC20.safeApprove` bugfix. ([#1647](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1647))

19
DOCUMENTATION.md Normal file
View File

@ -0,0 +1,19 @@
We're building an improved documentation website. It's still in development and
contributions will be really appreciated.
All of the content for the site is in this repository. The guides are in the
[docs](/docs) directory, and the API Reference is extracted from comments in
the source code. If you want to help improve the content, this is the
repository you should be contributing to.
[`solidity-docgen`](https://github.com/OpenZeppelin/solidity-docgen/tree/next) is the
program that extracts the API Reference from source code.
The [`openzeppelin-docsite`](https://github.com/OpenZeppelin/openzeppelin-docsite/tree/next)
repository hosts the configuration for Docusaurus, the static site generator
that we use.
To run the docsite locally you should run `npm run docsite start` on this
repository. This will live reload as the guides are edited, but not with
changes to the source code comments, for that you need to restart the server.
This should be improved eventually (contributions welcome!).

View File

@ -1,6 +1,6 @@
The MIT License (MIT)
Copyright (c) 2016 Smart Contract Solutions, Inc.
Copyright (c) 2016-2019 zOS Global Limited
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the

View File

@ -12,6 +12,8 @@
npm install openzeppelin-solidity
```
OpenZeppelin features a stable API, which means your contracts won't break unexpectedly when upgrading to a newer minor version. You can read ṫhe details in our [API Stability](https://forum.zeppelin.solutions/t/api-stability/138) document.
## Usage
To write your custom contracts, import ours and extend them through inheritance.
@ -28,9 +30,9 @@ contract MyNFT is ERC721Full, ERC721Mintable {
}
```
> You need an ethereum development framework for the above import statements to work! Check out these guides for [Truffle] or [Embark].
> You need an ethereum development framework for the above import statements to work! Check out these guides for [Truffle], [Embark] or [Buidler].
On our site you will find a few [guides] to learn about the different parts of OpenZeppelin, as well as [documentation for the API][API docs]. Keep in mind that the API docs are work in progress, and dont hesitate to ask questions in [our Slack][Slack].
On our site you will find a few [guides] to learn about the different parts of OpenZeppelin, as well as [documentation for the API][API docs]. Keep in mind that the API docs are work in progress, and dont hesitate to ask questions in [our forum][forum].
## Security
@ -53,8 +55,9 @@ OpenZeppelin is released under the [MIT License](LICENSE).
[API docs]: https://openzeppelin.org/api/docs/token_ERC721_ERC721BasicToken.html
[guides]: https://openzeppelin.org/api/docs/get-started.html
[Slack]: https://slack.openzeppelin.org
[forum]: https://forum.zeppelin.solutions
[Zeppelin]: https://zeppelin.solutions
[contribution guide]: CONTRIBUTING.md
[Truffle]: https://truffleframework.com/docs/truffle/quickstart
[Embark]: https://embark.status.im/docs/quick_start.html
[Buidler]: https://buidler.dev/guides/#getting-started

View File

@ -40,7 +40,7 @@ Once the CI run for the new tag is green, publish on npm under the `next` tag. Y
npm publish --tag next
```
Publish the release notes on GitHub and ask our community manager to announce the release candidate on at least Slack and Twitter.
Publish the release notes on GitHub and the forum, and ask our community manager to announce the release candidate on at least Twitter.
## Creating the final release

View File

@ -0,0 +1,7 @@
---
sections:
- title: Library
contracts:
- Roles
- subdirectory: roles
---

View File

@ -1,4 +1,4 @@
pragma solidity ^0.5.2;
pragma solidity ^0.5.7;
/**
* @title Roles
@ -10,31 +10,27 @@ library Roles {
}
/**
* @dev give an account access to this role
* @dev Give an account access to this role.
*/
function add(Role storage role, address account) internal {
require(account != address(0));
require(!has(role, account));
require(!has(role, account), "Roles: account already has role");
role.bearer[account] = true;
}
/**
* @dev remove an account's access to this role
* @dev Remove an account's access to this role.
*/
function remove(Role storage role, address account) internal {
require(account != address(0));
require(has(role, account));
require(has(role, account), "Roles: account does not have role");
role.bearer[account] = false;
}
/**
* @dev check if an account has this role
* @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));
require(account != address(0), "Roles: account is the zero address");
return role.bearer[account];
}
}

View File

@ -1,4 +1,4 @@
pragma solidity ^0.5.2;
pragma solidity ^0.5.7;
import "../Roles.sol";
@ -15,7 +15,7 @@ contract CapperRole {
}
modifier onlyCapper() {
require(isCapper(msg.sender));
require(isCapper(msg.sender), "CapperRole: caller does not have the Capper role");
_;
}

View File

@ -1,4 +1,4 @@
pragma solidity ^0.5.2;
pragma solidity ^0.5.7;
import "../Roles.sol";
@ -15,7 +15,7 @@ contract MinterRole {
}
modifier onlyMinter() {
require(isMinter(msg.sender));
require(isMinter(msg.sender), "MinterRole: caller does not have the Minter role");
_;
}

View File

@ -1,4 +1,4 @@
pragma solidity ^0.5.2;
pragma solidity ^0.5.7;
import "../Roles.sol";
@ -15,7 +15,7 @@ contract PauserRole {
}
modifier onlyPauser() {
require(isPauser(msg.sender));
require(isPauser(msg.sender), "PauserRole: caller does not have the Pauser role");
_;
}

View File

@ -1,4 +1,4 @@
pragma solidity ^0.5.2;
pragma solidity ^0.5.7;
import "../Roles.sol";
@ -15,7 +15,7 @@ contract SignerRole {
}
modifier onlySigner() {
require(isSigner(msg.sender));
require(isSigner(msg.sender), "SignerRole: caller does not have the Signer role");
_;
}

View File

@ -1,4 +1,4 @@
pragma solidity ^0.5.2;
pragma solidity ^0.5.7;
import "../Roles.sol";
@ -19,7 +19,7 @@ contract WhitelistAdminRole {
}
modifier onlyWhitelistAdmin() {
require(isWhitelistAdmin(msg.sender));
require(isWhitelistAdmin(msg.sender), "WhitelistAdminRole: caller does not have the WhitelistAdmin role");
_;
}

View File

@ -1,4 +1,4 @@
pragma solidity ^0.5.2;
pragma solidity ^0.5.7;
import "../Roles.sol";
import "./WhitelistAdminRole.sol";
@ -18,7 +18,7 @@ contract WhitelistedRole is WhitelistAdminRole {
Roles.Role private _whitelisteds;
modifier onlyWhitelisted() {
require(isWhitelisted(msg.sender));
require(isWhitelisted(msg.sender), "WhitelistedRole: caller does not have the Whitelisted role");
_;
}

View File

@ -1,4 +1,4 @@
pragma solidity ^0.5.2;
pragma solidity ^0.5.7;
import "../token/ERC20/IERC20.sol";
import "../math/SafeMath.sol";
@ -54,9 +54,9 @@ contract Crowdsale is ReentrancyGuard {
* @param token Address of the token being sold
*/
constructor (uint256 rate, address payable wallet, IERC20 token) public {
require(rate > 0);
require(wallet != address(0));
require(address(token) != address(0));
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;
@ -136,8 +136,8 @@ contract Crowdsale is ReentrancyGuard {
* @param weiAmount Value in wei involved in the purchase
*/
function _preValidatePurchase(address beneficiary, uint256 weiAmount) internal view {
require(beneficiary != address(0));
require(weiAmount != 0);
require(beneficiary != address(0), "Crowdsale: beneficiary is the zero address");
require(weiAmount != 0, "Crowdsale: weiAmount is 0");
}
/**

View File

@ -0,0 +1,11 @@
---
title: Crowdsales
sections:
- title: Core
contracts:
- Crowdsale
- subdirectory: emission
- subdirectory: price
- subdirectory: validation
- subdirectory: distribution
---

View File

@ -1,4 +1,4 @@
pragma solidity ^0.5.2;
pragma solidity ^0.5.7;
import "../../math/SafeMath.sol";
import "../validation/TimedCrowdsale.sol";
@ -31,8 +31,8 @@ contract FinalizableCrowdsale is TimedCrowdsale {
* work. Calls the contract's finalization function.
*/
function finalize() public {
require(!_finalized);
require(hasClosed());
require(!_finalized, "FinalizableCrowdsale: already finalized");
require(hasClosed(), "FinalizableCrowdsale: not closed");
_finalized = true;

View File

@ -1,7 +1,9 @@
pragma solidity ^0.5.2;
pragma solidity ^0.5.7;
import "../validation/TimedCrowdsale.sol";
import "../../math/SafeMath.sol";
import "../../ownership/Secondary.sol";
import "../../token/ERC20/IERC20.sol";
/**
* @title PostDeliveryCrowdsale
@ -11,17 +13,23 @@ 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());
require(hasClosed(), "PostDeliveryCrowdsale: not closed");
uint256 amount = _balances[beneficiary];
require(amount > 0);
require(amount > 0, "PostDeliveryCrowdsale: beneficiary is not due any tokens");
_balances[beneficiary] = 0;
_deliverTokens(beneficiary, amount);
_vault.transfer(token(), beneficiary, amount);
}
/**
@ -32,12 +40,26 @@ contract PostDeliveryCrowdsale is TimedCrowdsale {
}
/**
* @dev Overrides parent by storing balances instead of issuing tokens right away.
* @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,4 +1,4 @@
pragma solidity ^0.5.2;
pragma solidity ^0.5.7;
import "../../math/SafeMath.sol";
import "./FinalizableCrowdsale.sol";
@ -28,7 +28,7 @@ contract RefundableCrowdsale is FinalizableCrowdsale {
* @param goal Funding goal
*/
constructor (uint256 goal) public {
require(goal > 0);
require(goal > 0, "RefundableCrowdsale: goal is 0");
_escrow = new RefundEscrow(wallet());
_goal = goal;
}
@ -41,12 +41,12 @@ contract RefundableCrowdsale is FinalizableCrowdsale {
}
/**
* @dev Investors can claim refunds here if crowdsale is unsuccessful
* @dev Investors can claim refunds here if crowdsale is unsuccessful.
* @param refundee Whose refund will be claimed.
*/
function claimRefund(address payable refundee) public {
require(finalized());
require(!goalReached());
require(finalized(), "RefundableCrowdsale: not finalized");
require(!goalReached(), "RefundableCrowdsale: goal reached");
_escrow.withdraw(refundee);
}
@ -60,7 +60,7 @@ contract RefundableCrowdsale is FinalizableCrowdsale {
}
/**
* @dev escrow finalization task, called when finalize() is called
* @dev Escrow finalization task, called when finalize() is called.
*/
function _finalization() internal {
if (goalReached()) {

View File

@ -1,4 +1,4 @@
pragma solidity ^0.5.2;
pragma solidity ^0.5.7;
import "./RefundableCrowdsale.sol";
import "./PostDeliveryCrowdsale.sol";
@ -12,8 +12,8 @@ import "./PostDeliveryCrowdsale.sol";
*/
contract RefundablePostDeliveryCrowdsale is RefundableCrowdsale, PostDeliveryCrowdsale {
function withdrawTokens(address beneficiary) public {
require(finalized());
require(goalReached());
require(finalized(), "RefundablePostDeliveryCrowdsale: not finalized");
require(goalReached(), "RefundablePostDeliveryCrowdsale: goal not reached");
super.withdrawTokens(beneficiary);
}

View File

@ -1,4 +1,4 @@
pragma solidity ^0.5.2;
pragma solidity ^0.5.7;
import "../Crowdsale.sol";
import "../../token/ERC20/IERC20.sol";
@ -18,10 +18,10 @@ contract AllowanceCrowdsale is Crowdsale {
/**
* @dev Constructor, takes token wallet address.
* @param tokenWallet Address holding the tokens, which has approved allowance to the crowdsale
* @param tokenWallet Address holding the tokens, which has approved allowance to the crowdsale.
*/
constructor (address tokenWallet) public {
require(tokenWallet != address(0));
require(tokenWallet != address(0), "AllowanceCrowdsale: token wallet is the zero address");
_tokenWallet = tokenWallet;
}

View File

@ -1,4 +1,4 @@
pragma solidity ^0.5.2;
pragma solidity ^0.5.7;
import "../Crowdsale.sol";
import "../../token/ERC20/ERC20Mintable.sol";
@ -16,6 +16,9 @@ contract MintedCrowdsale is Crowdsale {
*/
function _deliverTokens(address beneficiary, uint256 tokenAmount) internal {
// Potentially dangerous assumption about the type of the token.
require(ERC20Mintable(address(token())).mint(beneficiary, tokenAmount));
require(
ERC20Mintable(address(token())).mint(beneficiary, tokenAmount),
"MintedCrowdsale: minting failed"
);
}
}

View File

@ -1,4 +1,4 @@
pragma solidity ^0.5.2;
pragma solidity ^0.5.7;
import "../validation/TimedCrowdsale.sol";
import "../../math/SafeMath.sol";
@ -21,8 +21,9 @@ contract IncreasingPriceCrowdsale is TimedCrowdsale {
* @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);
require(initialRate > finalRate);
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;
}
@ -32,7 +33,7 @@ contract IncreasingPriceCrowdsale is TimedCrowdsale {
* all calls to it are a mistake.
*/
function rate() public view returns (uint256) {
revert();
revert("IncreasingPriceCrowdsale: rate() called");
}
/**

View File

@ -1,4 +1,4 @@
pragma solidity ^0.5.2;
pragma solidity ^0.5.7;
import "../../math/SafeMath.sol";
import "../Crowdsale.sol";
@ -17,7 +17,7 @@ contract CappedCrowdsale is Crowdsale {
* @param cap Max amount of wei to be contributed
*/
constructor (uint256 cap) public {
require(cap > 0);
require(cap > 0, "CappedCrowdsale: cap is 0");
_cap = cap;
}
@ -43,6 +43,6 @@ contract CappedCrowdsale is Crowdsale {
*/
function _preValidatePurchase(address beneficiary, uint256 weiAmount) internal view {
super._preValidatePurchase(beneficiary, weiAmount);
require(weiRaised().add(weiAmount) <= _cap);
require(weiRaised().add(weiAmount) <= _cap, "CappedCrowdsale: cap exceeded");
}
}

View File

@ -1,4 +1,4 @@
pragma solidity ^0.5.2;
pragma solidity ^0.5.7;
import "../../math/SafeMath.sol";
import "../Crowdsale.sol";
@ -48,11 +48,12 @@ contract IndividuallyCappedCrowdsale is Crowdsale, CapperRole {
*/
function _preValidatePurchase(address beneficiary, uint256 weiAmount) internal view {
super._preValidatePurchase(beneficiary, weiAmount);
require(_contributions[beneficiary].add(weiAmount) <= _caps[beneficiary]);
// 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
* @dev Extend parent behavior to update beneficiary contributions.
* @param beneficiary Token purchaser
* @param weiAmount Amount of wei contributed
*/

View File

@ -1,4 +1,4 @@
pragma solidity ^0.5.2;
pragma solidity ^0.5.7;
import "../Crowdsale.sol";
import "../../lifecycle/Pausable.sol";

View File

@ -1,4 +1,4 @@
pragma solidity ^0.5.2;
pragma solidity ^0.5.7;
import "../../math/SafeMath.sol";
import "../Crowdsale.sol";
@ -24,7 +24,7 @@ contract TimedCrowdsale is Crowdsale {
* @dev Reverts if not in crowdsale time range.
*/
modifier onlyWhileOpen {
require(isOpen());
require(isOpen(), "TimedCrowdsale: not open");
_;
}
@ -35,8 +35,9 @@ contract TimedCrowdsale is Crowdsale {
*/
constructor (uint256 openingTime, uint256 closingTime) public {
// solhint-disable-next-line not-rely-on-time
require(openingTime >= block.timestamp);
require(closingTime > openingTime);
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;
@ -74,7 +75,7 @@ contract TimedCrowdsale is Crowdsale {
}
/**
* @dev Extend parent behavior requiring to be within contributing period
* @dev Extend parent behavior requiring to be within contributing period.
* @param beneficiary Token purchaser
* @param weiAmount Amount of wei contributed
*/
@ -83,12 +84,13 @@ contract TimedCrowdsale is Crowdsale {
}
/**
* @dev Extend crowdsale
* @dev Extend crowdsale.
* @param newClosingTime Crowdsale closing time
*/
function _extendTime(uint256 newClosingTime) internal {
require(!hasClosed());
require(newClosingTime > _closingTime);
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,4 +1,4 @@
pragma solidity ^0.5.2;
pragma solidity ^0.5.7;
import "../Crowdsale.sol";
import "../../access/roles/WhitelistedRole.sol";
@ -15,7 +15,7 @@ contract WhitelistCrowdsale is WhitelistedRole, Crowdsale {
* @param _weiAmount Amount of wei contributed
*/
function _preValidatePurchase(address _beneficiary, uint256 _weiAmount) internal view {
require(isWhitelisted(_beneficiary));
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.2;
pragma solidity ^0.5.7;
/**
* @title Elliptic curve signature operations
@ -9,7 +9,7 @@ pragma solidity ^0.5.2;
library ECDSA {
/**
* @dev Recover signer address from a message by using their signature
* @dev Recover signer address from a message by using their signature.
* @param hash bytes32 message, the hash is the signed message. What is recovered is the signer address.
* @param signature bytes signature, the signature is generated using web3.eth.sign()
*/
@ -56,8 +56,8 @@ library ECDSA {
/**
* toEthSignedMessageHash
* @dev prefix a bytes32 value with "\x19Ethereum Signed Message:"
* and hash the result
* @dev Prefix a bytes32 value with "\x19Ethereum Signed Message:"
* and hash the result.
*/
function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {
// 32 is the length in bytes of hash,

View File

@ -1,4 +1,4 @@
pragma solidity ^0.5.2;
pragma solidity ^0.5.7;
/**
* @title MerkleProof

View File

@ -1,4 +1,4 @@
pragma solidity ^0.5.2;
pragma solidity ^0.5.7;
import "../math/SafeMath.sol";
@ -6,7 +6,7 @@ import "../math/SafeMath.sol";
* @title Counters
* @author Matt Condon (@shrugs)
* @dev Provides counters that can only be incremented or decremented by one. This can be used e.g. to track the number
* of elements in a mapping, issuing ERC721 ids, or counting request ids
* of elements in a mapping, issuing ERC721 ids, or counting request ids.
*
* Include with `using Counters for Counters.Counter;`
* Since it is not possible to overflow a 256 bit integer with increments of one, `increment` can skip the SafeMath

View File

@ -1,4 +1,4 @@
pragma solidity ^0.5.2;
pragma solidity ^0.5.7;
import "../../token/ERC20/IERC20.sol";

View File

@ -0,0 +1,24 @@
pragma solidity ^0.5.7;
import "./IERC1820Implementer.sol";
/**
* @dev ERC1820Implementer allows your contract to implement an interface for another account in the sense of ERC1820.
* That account or one of its ERC1820 managers can register the implementer in the ERC1820 registry, but the registry
* will first check with the implementer if it agrees to it, and only allow it if it does. Using the internal
* function _registerInterfaceForAddress provided by this contract, you are expressing this agreement,
* and you will be able to register the contract as an implementer in the registry for that account.
*/
contract ERC1820Implementer is IERC1820Implementer {
bytes32 constant private ERC1820_ACCEPT_MAGIC = keccak256(abi.encodePacked("ERC1820_ACCEPT_MAGIC"));
mapping(bytes32 => mapping(address => bool)) private _supportedInterfaces;
function canImplementInterfaceForAddress(bytes32 interfaceHash, address account) external view returns (bytes32) {
return _supportedInterfaces[interfaceHash][account] ? ERC1820_ACCEPT_MAGIC : bytes32(0x00);
}
function _registerInterfaceForAddress(bytes32 interfaceHash, address account) internal {
_supportedInterfaces[interfaceHash][account] = true;
}
}

View File

@ -1,4 +1,4 @@
pragma solidity ^0.5.2;
pragma solidity ^0.5.7;
import "../token/ERC20/IERC20.sol";
import "../token/ERC20/ERC20Mintable.sol";
@ -44,7 +44,7 @@ contract ERC20Migrator {
* @param legacyToken address of the old token contract
*/
constructor (IERC20 legacyToken) public {
require(address(legacyToken) != address(0));
require(address(legacyToken) != address(0), "ERC20Migrator: legacy token is the zero address");
_legacyToken = legacyToken;
}
@ -68,9 +68,10 @@ contract ERC20Migrator {
* @param newToken_ the token that will be minted
*/
function beginMigration(ERC20Mintable newToken_) public {
require(address(_newToken) == address(0));
require(address(newToken_) != address(0));
require(newToken_.isMinter(address(this)));
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_;
}
@ -82,7 +83,7 @@ contract ERC20Migrator {
* @param amount amount of tokens to be migrated
*/
function migrate(address account, uint256 amount) public {
require(address(_newToken) != address(0));
require(address(_newToken) != address(0), "ERC20Migrator: migration not started");
_legacyToken.safeTransferFrom(account, address(this), amount);
_newToken.mint(account, amount);
}

View File

@ -1,4 +1,4 @@
pragma solidity ^0.5.2;
pragma solidity ^0.5.7;
import "../math/SafeMath.sol";
import "../utils/Arrays.sol";
@ -31,7 +31,7 @@ contract ERC20Snapshot is ERC20 {
}
mapping (address => Snapshots) private _accountBalanceSnapshots;
Snapshots private _totalSupplySnaphots;
Snapshots private _totalSupplySnapshots;
// Snapshot ids increase monotonically, with the first value being 1. An id of 0 is invalid.
Counters.Counter private _currentSnapshotId;
@ -56,7 +56,7 @@ contract ERC20Snapshot is ERC20 {
}
function totalSupplyAt(uint256 snapshotId) public view returns(uint256) {
(bool snapshotted, uint256 value) = _valueAt(snapshotId, _totalSupplySnaphots);
(bool snapshotted, uint256 value) = _valueAt(snapshotId, _totalSupplySnapshots);
return snapshotted ? value : totalSupply();
}
@ -101,8 +101,9 @@ contract ERC20Snapshot is ERC20 {
function _valueAt(uint256 snapshotId, Snapshots storage snapshots)
private view returns (bool, uint256)
{
require(snapshotId > 0);
require(snapshotId <= _currentSnapshotId.current());
require(snapshotId > 0, "ERC20Snapshot: id is 0");
// solhint-disable-next-line max-line-length
require(snapshotId <= _currentSnapshotId.current(), "ERC20Snapshot: nonexistent id");
uint256 index = snapshots.ids.findUpperBound(snapshotId);
@ -118,7 +119,7 @@ contract ERC20Snapshot is ERC20 {
}
function _updateTotalSupplySnapshot() private {
_updateSnapshot(_totalSupplySnaphots, totalSupply());
_updateSnapshot(_totalSupplySnapshots, totalSupply());
}
function _updateSnapshot(Snapshots storage snapshots, uint256 currentValue) private {

View File

@ -0,0 +1,357 @@
pragma solidity ^0.5.7;
import "./IERC777.sol";
import "./IERC777Recipient.sol";
import "./IERC777Sender.sol";
import "../../math/SafeMath.sol";
import "../../utils/Address.sol";
import "../IERC1820Registry.sol";
/**
* @title ERC777 token implementation
* @author etsvigun <utgarda@gmail.com>, Bertrand Masius <github@catageeks.tk>
*/
contract ERC777 is IERC777 {
using SafeMath for uint256;
using Address for address;
IERC1820Registry private _erc1820 = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);
string private _name;
string private _symbol;
mapping(address => uint256) private _balances;
uint256 private _totalSupply;
uint256 private _granularity;
bytes32 constant private TOKENS_SENDER_INTERFACE_HASH = keccak256("ERC777TokensSender");
bytes32 constant private TOKENS_RECIPIENT_INTERFACE_HASH = keccak256("ERC777TokensRecipient");
// This isn't ever read from - it's only used to respond to the defaultOperators query.
address[] private _defaultOperatorsArray;
// Immutable, but accounts may revoke them (tracked in __revokedDefaultOperators).
mapping(address => bool) private _defaultOperators;
// For each account, a mapping of its operators and revoked default operators.
mapping(address => mapping(address => bool)) private _operators;
mapping(address => mapping(address => bool)) private _revokedDefaultOperators;
constructor(
string memory name,
string memory symbol,
uint256 granularity,
address[] memory defaultOperators
) public {
require(granularity > 0);
_name = name;
_symbol = symbol;
_granularity = granularity;
_defaultOperatorsArray = defaultOperators;
for (uint256 i = 0; i < _defaultOperatorsArray.length; i++) {
_defaultOperators[_defaultOperatorsArray[i]] = true;
}
// register interface
_erc1820.setInterfaceImplementer(address(this), keccak256("ERC777Token"), address(this));
}
/**
* @dev Send the amount of tokens from the address msg.sender to the address to
* @param to address recipient address
* @param amount uint256 amount of tokens to transfer
* @param data bytes information attached to the send, and intended for the recipient (to)
*/
function send(address to, uint256 amount, bytes calldata data) external {
_send(msg.sender, msg.sender, to, amount, data, "");
}
/**
* @dev Send the amount of tokens on behalf of the address from to the address to
* @param from address token holder address.
* @param to address recipient address
* @param amount uint256 amount of tokens to transfer
* @param data bytes information attached to the send, and intended for the recipient (to)
* @param operatorData bytes extra information provided by the operator (if any)
*/
function operatorSend(
address from,
address to,
uint256 amount,
bytes calldata data,
bytes calldata operatorData
)
external
{
require(isOperatorFor(msg.sender, from));
_send(msg.sender, from, to, amount, data, operatorData);
}
/**
* @dev Burn the amount of tokens from the address msg.sender
* @param amount uint256 amount of tokens to transfer
* @param data bytes extra information provided by the token holder
*/
function burn(uint256 amount, bytes calldata data) external {
_burn(msg.sender, msg.sender, amount, data, "");
}
/**
* @dev Burn the amount of tokens on behalf of the address from
* @param from address token holder address.
* @param amount uint256 amount of tokens to transfer
* @param data bytes extra information provided by the token holder
* @param operatorData bytes extra information provided by the operator (if any)
*/
function operatorBurn(address from, uint256 amount, bytes calldata data, bytes calldata operatorData) external {
require(isOperatorFor(msg.sender, from));
_burn(msg.sender, from, amount, data, operatorData);
}
/**
* @dev Authorize an operator for the sender
* @param operator address to be authorized as operator
*/
function authorizeOperator(address operator) external {
require(msg.sender != operator);
if (_defaultOperators[operator]) {
delete _revokedDefaultOperators[msg.sender][operator];
} else {
_operators[msg.sender][operator] = true;
}
emit AuthorizedOperator(operator, msg.sender);
}
/**
* @dev Revoke operator rights from one of the default operators
* @param operator address to revoke operator rights from
*/
function revokeOperator(address operator) external {
require(operator != msg.sender);
if (_defaultOperators[operator]) {
_revokedDefaultOperators[msg.sender][operator] = true;
} else {
delete _operators[msg.sender][operator];
}
emit RevokedOperator(operator, msg.sender);
}
/**
* @return the name of the token.
*/
function name() public view returns (string memory) {
return _name;
}
/**
* @return the symbol of the token.
*/
function symbol() public view returns (string memory) {
return _symbol;
}
/**
* @dev Total number of tokens in existence
*/
function totalSupply() public view returns (uint256) {
return _totalSupply;
}
/**
* @dev Gets the balance of the specified address.
* @param tokenHolder The address to query the balance of.
* @return uint256 representing the amount owned by the specified address.
*/
function balanceOf(address tokenHolder) public view returns (uint256) {
return _balances[tokenHolder];
}
/**
* @dev Gets the token's granularity,
* i.e. the smallest number of tokens (in the basic unit)
* which may be minted, sent or burned at any time
* @return uint256 granularity
*/
function granularity() public view returns (uint256) {
return _granularity;
}
/**
* @dev Get the list of default operators as defined by the token contract.
* @return address[] default operators
*/
function defaultOperators() public view returns (address[] memory) {
return _defaultOperatorsArray;
}
/**
* @dev Indicate whether an address
* is an operator of the tokenHolder address
* @param operator address which may be an operator of tokenHolder
* @param tokenHolder address of a token holder which may have the operator
* address as an operator.
*/
function isOperatorFor(
address operator,
address tokenHolder
) public view returns (bool) {
return operator == tokenHolder ||
(_defaultOperators[operator] && !_revokedDefaultOperators[tokenHolder][operator]) ||
_operators[tokenHolder][operator];
}
/**
* @dev Mint tokens. Does not check authorization of operator
* @dev the caller may ckeck that operator is authorized before calling
* @param operator address operator requesting the operation
* @param to address token recipient address
* @param amount uint256 amount of tokens to mint
* @param userData bytes extra information defined by the token recipient (if any)
* @param operatorData bytes extra information provided by the operator (if any)
*/
function _mint(
address operator,
address to,
uint256 amount,
bytes memory userData,
bytes memory operatorData
)
internal
{
require(to != address(0));
require((amount % _granularity) == 0);
// Update state variables
_totalSupply = _totalSupply.add(amount);
_balances[to] = _balances[to].add(amount);
_callTokensReceived(operator, address(0), to, amount, userData, operatorData);
emit Minted(operator, to, amount, userData, operatorData);
}
/**
* @dev Send tokens
* @param operator address operator requesting the transfer
* @param from address token holder address
* @param to address recipient address
* @param amount uint256 amount of tokens to transfer
* @param userData bytes extra information provided by the token holder (if any)
* @param operatorData bytes extra information provided by the operator (if any)
*/
function _send(
address operator,
address from,
address to,
uint256 amount,
bytes memory userData,
bytes memory operatorData
)
private
{
require(from != address(0));
require(to != address(0));
require((amount % _granularity) == 0);
_callTokensToSend(operator, from, to, amount, userData, operatorData);
// Update state variables
_balances[from] = _balances[from].sub(amount);
_balances[to] = _balances[to].add(amount);
_callTokensReceived(operator, from, to, amount, userData, operatorData);
emit Sent(operator, from, to, amount, userData, operatorData);
}
/**
* @dev Burn tokens
* @param operator address operator requesting the operation
* @param from address token holder address
* @param amount uint256 amount of tokens to burn
* @param data bytes extra information provided by the token holder
* @param operatorData bytes extra information provided by the operator (if any)
*/
function _burn(
address operator,
address from,
uint256 amount,
bytes memory data,
bytes memory operatorData
)
private
{
require(from != address(0));
require((amount % _granularity) == 0);
_callTokensToSend(operator, from, address(0), amount, data, operatorData);
// Update state variables
_totalSupply = _totalSupply.sub(amount);
_balances[from] = _balances[from].sub(amount);
emit Burned(operator, from, amount, data, operatorData);
}
/**
* @dev Call from.tokensToSend() if the interface is registered
* @param operator address operator requesting the transfer
* @param from address token holder address
* @param to address recipient address
* @param amount uint256 amount of tokens to transfer
* @param userData bytes extra information provided by the token holder (if any)
* @param operatorData bytes extra information provided by the operator (if any)
*/
function _callTokensToSend(
address operator,
address from,
address to,
uint256 amount,
bytes memory userData,
bytes memory operatorData
)
private
{
address implementer = _erc1820.getInterfaceImplementer(from, TOKENS_SENDER_INTERFACE_HASH);
if (implementer != address(0)) {
IERC777Sender(implementer).tokensToSend(operator, from, to, amount, userData, operatorData);
}
}
/**
* @dev Call to.tokensReceived() if the interface is registered. Reverts if the recipient is a contract but
* tokensReceived() was not registered for the recipient
* @param operator address operator requesting the transfer
* @param from address token holder address
* @param to address recipient address
* @param amount uint256 amount of tokens to transfer
* @param userData bytes extra information provided by the token holder (if any)
* @param operatorData bytes extra information provided by the operator (if any)
*/
function _callTokensReceived(
address operator,
address from,
address to,
uint256 amount,
bytes memory userData,
bytes memory operatorData
)
private
{
address implementer = _erc1820.getInterfaceImplementer(to, TOKENS_RECIPIENT_INTERFACE_HASH);
if (implementer != address(0)) {
IERC777Recipient(implementer).tokensReceived(operator, from, to, amount, userData, operatorData);
} else {
require(!to.isContract());
}
}
}

View File

@ -0,0 +1,61 @@
pragma solidity ^0.5.7;
/**
* @title ERC777 token interface
* @dev See https://eips.ethereum.org/EIPS/eip-777
*/
interface IERC777 {
function authorizeOperator(address operator) external;
function revokeOperator(address operator) external;
function send(address to, uint256 amount, bytes calldata data) external;
function operatorSend(
address from,
address to,
uint256 amount,
bytes calldata data,
bytes calldata operatorData
) external;
function burn(uint256 amount, bytes calldata data) external;
function operatorBurn(
address from,
uint256 amount,
bytes calldata data,
bytes calldata operatorData
) external;
function name() external view returns (string memory);
function symbol() external view returns (string memory);
function totalSupply() external view returns (uint256);
function balanceOf(address owner) external view returns (uint256);
function granularity() external view returns (uint256);
function defaultOperators() external view returns (address[] memory);
function isOperatorFor(address operator, address tokenHolder) external view returns (bool);
event Sent(
address indexed operator,
address indexed from,
address indexed to,
uint256 amount,
bytes data,
bytes operatorData
);
event Minted(address indexed operator, address indexed to, uint256 amount, bytes data, bytes operatorData);
event Burned(address indexed operator, address indexed from, uint256 amount, bytes data, bytes operatorData);
event AuthorizedOperator(address indexed operator, address indexed tokenHolder);
event RevokedOperator(address indexed operator, address indexed tokenHolder);
}

View File

@ -0,0 +1,16 @@
pragma solidity ^0.5.7;
/**
* @title ERC777 token recipient interface
* @dev See https://eips.ethereum.org/EIPS/eip-777
*/
interface IERC777Recipient {
function tokensReceived(
address operator,
address from,
address to,
uint amount,
bytes calldata userData,
bytes calldata operatorData
) external;
}

View File

@ -0,0 +1,16 @@
pragma solidity ^0.5.7;
/**
* @title ERC777 token sender interface
* @dev See https://eips.ethereum.org/EIPS/eip-777
*/
interface IERC777Sender {
function tokensToSend(
address operator,
address from,
address to,
uint amount,
bytes calldata userData,
bytes calldata operatorData
) external;
}

View File

@ -0,0 +1,17 @@
pragma solidity ^0.5.7;
/**
* @title IERC1820Implementer
* Interface for contracts that will be registered as implementers in the ERC1820 registry.
* @notice For more details, see https://eips.ethereum.org/EIPS/eip-1820
*/
interface IERC1820Implementer {
/**
* @notice Indicates whether the contract implements the interface `interfaceHash` for the address `account` or
* not.
* @param interfaceHash keccak256 hash of the name of the interface
* @param account Address for which the contract will implement the interface
* @return ERC1820_ACCEPT_MAGIC only if the contract implements `interfaceHash` for the address `account`.
*/
function canImplementInterfaceForAddress(bytes32 interfaceHash, address account) external view returns (bytes32);
}

View File

@ -0,0 +1,90 @@
pragma solidity ^0.5.7;
/**
* @title ERC1820 Pseudo-introspection Registry Contract
* @author Jordi Baylina and Jacques Dafflon
* @notice For more details, see https://eips.ethereum.org/EIPS/eip-1820
*/
interface IERC1820Registry {
/**
* @notice Sets the contract which implements a specific interface for an address.
* Only the manager defined for that address can set it.
* (Each address is the manager for itself until it sets a new manager.)
* @param account Address for which to set the interface.
* (If 'account' is the zero address then 'msg.sender' is assumed.)
* @param interfaceHash Keccak256 hash of the name of the interface as a string.
* E.g., 'web3.utils.keccak256("ERC777TokensRecipient")' for the 'ERC777TokensRecipient' interface.
* @param implementer Contract address implementing `interfaceHash` for `account.address()`.
*/
function setInterfaceImplementer(address account, bytes32 interfaceHash, address implementer) external;
/**
* @notice Sets `newManager.address()` as manager for `account.address()`.
* The new manager will be able to call 'setInterfaceImplementer' for `account.address()`.
* @param account Address for which to set the new manager.
* @param newManager Address of the new manager for `addr.address()`.
* (Pass '0x0' to reset the manager to `account.address()`.)
*/
function setManager(address account, address newManager) external;
/**
* @notice Updates the cache with whether the contract implements an ERC165 interface or not.
* @param account Address of the contract for which to update the cache.
* @param interfaceId ERC165 interface for which to update the cache.
*/
function updateERC165Cache(address account, bytes4 interfaceId) external;
/**
* @notice Get the manager of an address.
* @param account Address for which to return the manager.
* @return Address of the manager for a given address.
*/
function getManager(address account) external view returns (address);
/**
* @notice Query if an address implements an interface and through which contract.
* @param account Address being queried for the implementer of an interface.
* (If 'account' is the zero address then 'msg.sender' is assumed.)
* @param interfaceHash Keccak256 hash of the name of the interface as a string.
* E.g., 'web3.utils.keccak256("ERC777TokensRecipient")' for the 'ERC777TokensRecipient' interface.
* @return The address of the contract which implements the interface `interfaceHash` for `account.address()`
* or '0' if `account.address()` did not register an implementer for this interface.
*/
function getInterfaceImplementer(address account, bytes32 interfaceHash) external view returns (address);
/**
* @notice Checks whether a contract implements an ERC165 interface or not.
* If the result is not cached a direct lookup on the contract address is performed.
* If the result is not cached or the cached value is out-of-date, the cache MUST be updated manually by calling
* 'updateERC165Cache' with the contract address.
* @param account Address of the contract to check.
* @param interfaceId ERC165 interface to check.
* @return True if `account.address()` implements `interfaceId`, false otherwise.
*/
function implementsERC165Interface(address account, bytes4 interfaceId) external view returns (bool);
/**
* @notice Checks whether a contract implements an ERC165 interface or not without using nor updating the cache.
* @param account Address of the contract to check.
* @param interfaceId ERC165 interface to check.
* @return True if `account.address()` implements `interfaceId`, false otherwise.
*/
function implementsERC165InterfaceNoCache(address account, bytes4 interfaceId) external view returns (bool);
/**
* @notice Compute the keccak256 hash of an interface given its name.
* @param interfaceName Name of the interface.
* @return The keccak256 hash of an interface name.
*/
function interfaceHash(string calldata interfaceName) external pure returns (bytes32);
/**
* @notice Indicates a contract is the `implementer` of `interfaceHash` for `account`.
*/
event InterfaceImplementerSet(address indexed account, bytes32 indexed interfaceHash, address indexed implementer);
/**
* @notice Indicates `newManager` is the address of the new manager for `account`.
*/
event ManagerChanged(address indexed account, address indexed newManager);
}

View File

@ -1,4 +1,4 @@
pragma solidity ^0.5.2;
pragma solidity ^0.5.7;
import "../access/roles/SignerRole.sol";
import "../cryptography/ECDSA.sol";
@ -48,26 +48,28 @@ contract SignatureBouncer is SignerRole {
}
/**
* @dev requires that a valid signature of a signer was provided
* @dev Requires that a valid signature of a signer was provided.
*/
modifier onlyValidSignature(bytes memory signature) {
require(_isValidSignature(msg.sender, signature));
require(_isValidSignature(msg.sender, signature), "SignatureBouncer: invalid signature for caller");
_;
}
/**
* @dev requires that a valid signature with a specified method of a signer was provided
* @dev Requires that a valid signature with a specified method of a signer was provided.
*/
modifier onlyValidSignatureAndMethod(bytes memory signature) {
require(_isValidSignatureAndMethod(msg.sender, signature));
// solhint-disable-next-line max-line-length
require(_isValidSignatureAndMethod(msg.sender, signature), "SignatureBouncer: invalid signature for caller and method");
_;
}
/**
* @dev requires that a valid signature with a specified method and params of a signer was provided
* @dev Requires that a valid signature with a specified method and params of a signer was provided.
*/
modifier onlyValidSignatureAndData(bytes memory signature) {
require(_isValidSignatureAndData(msg.sender, signature));
// solhint-disable-next-line max-line-length
require(_isValidSignatureAndData(msg.sender, signature), "SignatureBouncer: invalid signature for caller and data");
_;
}
@ -97,7 +99,7 @@ contract SignatureBouncer is SignerRole {
* @return bool
*/
function _isValidSignatureAndData(address account, bytes memory signature) internal view returns (bool) {
require(msg.data.length > _SIGNATURE_SIZE);
require(msg.data.length > _SIGNATURE_SIZE, "SignatureBouncer: data is too short");
bytes memory data = new bytes(msg.data.length - _SIGNATURE_SIZE);
for (uint i = 0; i < data.length; i++) {
@ -108,8 +110,8 @@ contract SignatureBouncer is SignerRole {
}
/**
* @dev internal function to convert a hash to an eth signed message
* and then recover the signature and check it against the signer role
* @dev Internal function to convert a hash to an eth signed message
* and then recover the signature and check it against the signer role.
* @return bool
*/
function _isValidDataHash(bytes32 hash, bytes memory signature) internal view returns (bool) {

View File

@ -1,8 +1,8 @@
pragma solidity ^0.5.2;
pragma solidity ^0.5.7;
/**
* @title SignedSafeMath
* @dev Signed math operations with safety checks that revert on error
* @dev Signed math operations with safety checks that revert on error.
*/
library SignedSafeMath {
int256 constant private INT256_MIN = -2**255;
@ -18,10 +18,10 @@ library SignedSafeMath {
return 0;
}
require(!(a == -1 && b == INT256_MIN)); // This is the only case of overflow not detected by the check below
require(!(a == -1 && b == INT256_MIN), "SignedSafeMath: multiplication overflow");
int256 c = a * b;
require(c / a == b);
require(c / a == b, "SignedSafeMath: multiplication overflow");
return c;
}
@ -30,8 +30,8 @@ library SignedSafeMath {
* @dev Integer division of two signed integers truncating the quotient, reverts on division by zero.
*/
function div(int256 a, int256 b) internal pure returns (int256) {
require(b != 0); // Solidity only automatically asserts when dividing by 0
require(!(b == -1 && a == INT256_MIN)); // This is the only case of overflow
require(b != 0, "SignedSafeMath: division by zero");
require(!(b == -1 && a == INT256_MIN), "SignedSafeMath: division overflow");
int256 c = a / b;
@ -43,7 +43,7 @@ library SignedSafeMath {
*/
function sub(int256 a, int256 b) internal pure returns (int256) {
int256 c = a - b;
require((b >= 0 && c <= a) || (b < 0 && c > a));
require((b >= 0 && c <= a) || (b < 0 && c > a), "SignedSafeMath: subtraction overflow");
return c;
}
@ -53,7 +53,7 @@ library SignedSafeMath {
*/
function add(int256 a, int256 b) internal pure returns (int256) {
int256 c = a + b;
require((b >= 0 && c >= a) || (b < 0 && c < a));
require((b >= 0 && c >= a) || (b < 0 && c < a), "SignedSafeMath: addition overflow");
return c;
}

View File

@ -1,4 +1,4 @@
pragma solidity ^0.5.2;
pragma solidity ^0.5.7;
import "../token/ERC20/SafeERC20.sol";
import "../ownership/Ownable.sol";
@ -47,10 +47,12 @@ contract TokenVesting is Ownable {
* @param revocable whether the vesting is revocable or not
*/
constructor (address beneficiary, uint256 start, uint256 cliffDuration, uint256 duration, bool revocable) public {
require(beneficiary != address(0));
require(cliffDuration <= duration);
require(duration > 0);
require(start.add(duration) > block.timestamp);
require(beneficiary != address(0), "TokenVesting: beneficiary is the zero address");
// solhint-disable-next-line max-line-length
require(cliffDuration <= duration, "TokenVesting: cliff is longer than duration");
require(duration > 0, "TokenVesting: duration is 0");
// solhint-disable-next-line max-line-length
require(start.add(duration) > block.timestamp, "TokenVesting: final time is before current time");
_beneficiary = beneficiary;
_revocable = revocable;
@ -115,7 +117,7 @@ contract TokenVesting is Ownable {
function release(IERC20 token) public {
uint256 unreleased = _releasableAmount(token);
require(unreleased > 0);
require(unreleased > 0, "TokenVesting: no tokens are due");
_released[address(token)] = _released[address(token)].add(unreleased);
@ -130,8 +132,8 @@ contract TokenVesting is Ownable {
* @param token ERC20 token which is being vested
*/
function revoke(IERC20 token) public onlyOwner {
require(_revocable);
require(!_revoked[address(token)]);
require(_revocable, "TokenVesting: cannot revoke");
require(!_revoked[address(token)], "TokenVesting: token already revoked");
uint256 balance = token.balanceOf(address(this));

View File

@ -1,4 +1,4 @@
pragma solidity ^0.5.2;
pragma solidity ^0.5.7;
import "../crowdsale/validation/CappedCrowdsale.sol";
import "../crowdsale/distribution/RefundableCrowdsale.sol";
@ -48,6 +48,6 @@ contract SampleCrowdsale is CappedCrowdsale, RefundableCrowdsale, MintedCrowdsal
{
//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);
require(goal <= cap, "SampleCrowdSale: goal is greater than cap");
}
}

View File

@ -1,4 +1,4 @@
pragma solidity ^0.5.2;
pragma solidity ^0.5.7;
import "../token/ERC20/ERC20.sol";
import "../token/ERC20/ERC20Detailed.sol";

View File

@ -1,4 +1,4 @@
pragma solidity ^0.5.2;
pragma solidity ^0.5.7;
import "./IERC165.sol";
@ -8,37 +8,36 @@ import "./IERC165.sol";
* @dev Implements ERC165 using a lookup table.
*/
contract ERC165 is IERC165 {
bytes4 private constant _INTERFACE_ID_ERC165 = 0x01ffc9a7;
/*
* 0x01ffc9a7 ===
* bytes4(keccak256('supportsInterface(bytes4)'))
* bytes4(keccak256('supportsInterface(bytes4)')) == 0x01ffc9a7
*/
bytes4 private constant _INTERFACE_ID_ERC165 = 0x01ffc9a7;
/**
* @dev a mapping of interface id to whether or not it's supported
* @dev Mapping of interface ids to whether or not it's supported.
*/
mapping(bytes4 => bool) private _supportedInterfaces;
/**
* @dev A contract implementing SupportsInterfaceWithLookup
* implement ERC165 itself
* implements ERC165 itself.
*/
constructor () internal {
_registerInterface(_INTERFACE_ID_ERC165);
}
/**
* @dev implement supportsInterface(bytes4) using a lookup table
* @dev Implement supportsInterface(bytes4) using a lookup table.
*/
function supportsInterface(bytes4 interfaceId) external view returns (bool) {
return _supportedInterfaces[interfaceId];
}
/**
* @dev internal method for registering an interface
* @dev Internal method for registering an interface.
*/
function _registerInterface(bytes4 interfaceId) internal {
require(interfaceId != 0xffffffff);
require(interfaceId != 0xffffffff, "ERC165: invalid interface id");
_supportedInterfaces[interfaceId] = true;
}
}

View File

@ -1,4 +1,4 @@
pragma solidity ^0.5.2;
pragma solidity ^0.5.7;
/**
* @title ERC165Checker
@ -9,11 +9,10 @@ library ERC165Checker {
// As per the EIP-165 spec, no interface should ever match 0xffffffff
bytes4 private constant _INTERFACE_ID_INVALID = 0xffffffff;
bytes4 private constant _INTERFACE_ID_ERC165 = 0x01ffc9a7;
/*
* 0x01ffc9a7 ===
* bytes4(keccak256('supportsInterface(bytes4)'))
* bytes4(keccak256('supportsInterface(bytes4)')) == 0x01ffc9a7
*/
bytes4 private constant _INTERFACE_ID_ERC165 = 0x01ffc9a7;
/**
* @notice Query if a contract supports ERC165

View File

@ -1,4 +1,4 @@
pragma solidity ^0.5.2;
pragma solidity ^0.5.7;
/**
* @title IERC165

View File

@ -1,4 +1,4 @@
pragma solidity ^0.5.2;
pragma solidity ^0.5.7;
import "../access/roles/PauserRole.sol";
@ -17,7 +17,7 @@ contract Pausable is PauserRole {
}
/**
* @return true if the contract is paused, false otherwise.
* @return True if the contract is paused, false otherwise.
*/
function paused() public view returns (bool) {
return _paused;
@ -27,7 +27,7 @@ contract Pausable is PauserRole {
* @dev Modifier to make a function callable only when the contract is not paused.
*/
modifier whenNotPaused() {
require(!_paused);
require(!_paused, "Pausable: paused");
_;
}
@ -35,12 +35,12 @@ contract Pausable is PauserRole {
* @dev Modifier to make a function callable only when the contract is paused.
*/
modifier whenPaused() {
require(_paused);
require(_paused, "Pausable: not paused");
_;
}
/**
* @dev called by the owner to pause, triggers stopped state
* @dev Called by a pauser to pause, triggers stopped state.
*/
function pause() public onlyPauser whenNotPaused {
_paused = true;
@ -48,7 +48,7 @@ contract Pausable is PauserRole {
}
/**
* @dev called by the owner to unpause, returns to normal state
* @dev Called by a pauser to unpause, returns to normal state.
*/
function unpause() public onlyPauser whenPaused {
_paused = false;

View File

@ -1,8 +1,8 @@
pragma solidity ^0.5.2;
pragma solidity ^0.5.7;
/**
* @title Math
* @dev Assorted math operations
* @dev Assorted math operations.
*/
library Math {
/**

View File

@ -1,8 +1,8 @@
pragma solidity ^0.5.2;
pragma solidity ^0.5.7;
/**
* @title SafeMath
* @dev Unsigned math operations with safety checks that revert on error
* @dev Unsigned math operations with safety checks that revert on error.
*/
library SafeMath {
/**
@ -17,7 +17,7 @@ library SafeMath {
}
uint256 c = a * b;
require(c / a == b);
require(c / a == b, "SafeMath: multiplication overflow");
return c;
}
@ -27,7 +27,7 @@ library SafeMath {
*/
function div(uint256 a, uint256 b) internal pure returns (uint256) {
// Solidity only automatically asserts when dividing by 0
require(b > 0);
require(b > 0, "SafeMath: division by zero");
uint256 c = a / b;
// assert(a == b * c + a % b); // There is no case in which this doesn't hold
@ -38,7 +38,7 @@ library SafeMath {
* @dev Subtracts two unsigned integers, reverts on overflow (i.e. if subtrahend is greater than minuend).
*/
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
require(b <= a);
require(b <= a, "SafeMath: subtraction overflow");
uint256 c = a - b;
return c;
@ -49,7 +49,7 @@ library SafeMath {
*/
function add(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a + b;
require(c >= a);
require(c >= a, "SafeMath: addition overflow");
return c;
}
@ -59,7 +59,7 @@ library SafeMath {
* reverts when dividing by zero.
*/
function mod(uint256 a, uint256 b) internal pure returns (uint256) {
require(b != 0);
require(b != 0, "SafeMath: modulo by zero");
return a % b;
}
}

View File

@ -1,19 +0,0 @@
pragma solidity ^0.5.2;
contract Acknowledger {
event AcknowledgeFoo(uint256 a);
event AcknowledgeBarSingle(uint256 a);
event AcknowledgeBarDouble(uint256 a, uint256 b);
function foo(uint256 a) public {
emit AcknowledgeFoo(a);
}
function bar(uint256 a) public {
emit AcknowledgeBarSingle(a);
}
function bar(uint256 a, uint256 b) public {
emit AcknowledgeBarDouble(a, b);
}
}

View File

@ -1,4 +1,4 @@
pragma solidity ^0.5.2;
pragma solidity ^0.5.7;
import "../utils/Address.sol";

View File

@ -1,4 +1,4 @@
pragma solidity ^0.5.2;
pragma solidity ^0.5.7;
import "../token/ERC20/IERC20.sol";
import "../crowdsale/emission/AllowanceCrowdsale.sol";

View File

@ -1,4 +1,4 @@
pragma solidity ^0.5.2;
pragma solidity ^0.5.7;
import "../utils/Arrays.sol";

View File

@ -1,4 +1,4 @@
pragma solidity ^0.5.2;
pragma solidity ^0.5.7;
import "../token/ERC20/IERC20.sol";
import "../crowdsale/validation/CappedCrowdsale.sol";

View File

@ -1,4 +1,4 @@
pragma solidity ^0.5.2;
pragma solidity ^0.5.7;
import "../access/roles/CapperRole.sol";

View File

@ -1,4 +1,4 @@
pragma solidity ^0.5.2;
pragma solidity ^0.5.7;
import "../payment/escrow/ConditionalEscrow.sol";

View File

@ -1,4 +1,4 @@
pragma solidity ^0.5.2;
pragma solidity ^0.5.7;
import "../drafts/Counters.sol";

View File

@ -1,4 +1,4 @@
pragma solidity ^0.5.2;
pragma solidity ^0.5.7;
import "../crowdsale/Crowdsale.sol";

View File

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

View File

@ -1,4 +1,4 @@
pragma solidity ^0.5.2;
pragma solidity ^0.5.7;
import "../../introspection/IERC165.sol";
@ -13,37 +13,36 @@ import "../../introspection/IERC165.sol";
* solidity-coverage ignores the /mocks folder, so we duplicate its implementation here to avoid instrumenting it
*/
contract SupportsInterfaceWithLookupMock is IERC165 {
bytes4 public constant INTERFACE_ID_ERC165 = 0x01ffc9a7;
/*
* 0x01ffc9a7 ===
* bytes4(keccak256('supportsInterface(bytes4)'))
* bytes4(keccak256('supportsInterface(bytes4)')) == 0x01ffc9a7
*/
bytes4 public constant INTERFACE_ID_ERC165 = 0x01ffc9a7;
/**
* @dev a mapping of interface id to whether or not it's supported
* @dev A mapping of interface id to whether or not it's supported.
*/
mapping(bytes4 => bool) private _supportedInterfaces;
/**
* @dev A contract implementing SupportsInterfaceWithLookup
* implement ERC165 itself
* implement ERC165 itself.
*/
constructor () public {
_registerInterface(INTERFACE_ID_ERC165);
}
/**
* @dev implement supportsInterface(bytes4) using a lookup table
* @dev Implement supportsInterface(bytes4) using a lookup table.
*/
function supportsInterface(bytes4 interfaceId) external view returns (bool) {
return _supportedInterfaces[interfaceId];
}
/**
* @dev private method for registering an interface
* @dev Private method for registering an interface.
*/
function _registerInterface(bytes4 interfaceId) internal {
require(interfaceId != 0xffffffff);
require(interfaceId != 0xffffffff, "ERC165InterfacesSupported: invalid interface id");
_supportedInterfaces[interfaceId] = true;
}
}

View File

@ -1,4 +1,4 @@
pragma solidity ^0.5.2;
pragma solidity ^0.5.7;
contract ERC165NotSupported {
// solhint-disable-previous-line no-empty-blocks

View File

@ -1,4 +1,4 @@
pragma solidity ^0.5.2;
pragma solidity ^0.5.7;
import "../introspection/ERC165Checker.sol";

View File

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

View File

@ -0,0 +1,9 @@
pragma solidity ^0.5.7;
import "../drafts/ERC1820Implementer.sol";
contract ERC1820ImplementerMock is ERC1820Implementer {
function registerInterfaceForAddress(bytes32 interfaceHash, address account) public {
_registerInterfaceForAddress(interfaceHash, account);
}
}

View File

@ -1,4 +1,4 @@
pragma solidity ^0.5.2;
pragma solidity ^0.5.7;
import "../token/ERC20/ERC20Burnable.sol";

View File

@ -1,4 +1,4 @@
pragma solidity ^0.5.2;
pragma solidity ^0.5.7;
import "../token/ERC20/ERC20.sol";
import "../token/ERC20/ERC20Detailed.sol";

View File

@ -1,4 +1,4 @@
pragma solidity ^0.5.2;
pragma solidity ^0.5.7;
import "../token/ERC20/ERC20.sol";
import "../drafts/ERC1046/ERC20Metadata.sol";

View File

@ -1,4 +1,4 @@
pragma solidity ^0.5.2;
pragma solidity ^0.5.7;
import "../token/ERC20/ERC20Mintable.sol";
import "./MinterRoleMock.sol";

View File

@ -1,4 +1,4 @@
pragma solidity ^0.5.2;
pragma solidity ^0.5.7;
import "../token/ERC20/ERC20.sol";

View File

@ -1,4 +1,4 @@
pragma solidity ^0.5.2;
pragma solidity ^0.5.7;
import "../token/ERC20/ERC20Pausable.sol";
import "./PauserRoleMock.sol";

View File

@ -1,4 +1,4 @@
pragma solidity ^0.5.2;
pragma solidity ^0.5.7;
import "../drafts/ERC20Snapshot.sol";

View File

@ -1,4 +1,4 @@
pragma solidity ^0.5.2;
pragma solidity ^0.5.7;
import "../token/ERC721/ERC721Full.sol";
import "../token/ERC721/ERC721Mintable.sol";

View File

@ -1,4 +1,4 @@
pragma solidity ^0.5.2;
pragma solidity ^0.5.7;
import "../token/ERC721/ERC721Full.sol";
import "../token/ERC721/ERC721Mintable.sol";

View File

@ -1,4 +1,4 @@
pragma solidity ^0.5.2;
pragma solidity ^0.5.7;
import "../token/ERC721/ERC721.sol";

View File

@ -1,4 +1,4 @@
pragma solidity ^0.5.2;
pragma solidity ^0.5.7;
import "../token/ERC721/ERC721Pausable.sol";
import "./PauserRoleMock.sol";

View File

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

View File

@ -0,0 +1,26 @@
pragma solidity ^0.5.7;
import "../drafts/ERC777/ERC777.sol";
contract ERC777Mock is ERC777 {
constructor(
address initialHolder,
uint256 initialBalance,
string memory name,
string memory symbol,
uint256 granularity,
address[] memory defaultOperators
) public ERC777(name, symbol, granularity, defaultOperators) {
_mint(msg.sender, initialHolder, initialBalance, "", "");
}
function mintInternal (
address operator,
address to,
uint256 amount,
bytes memory userData,
bytes memory operatorData
) public {
_mint(operator, to, amount, userData, operatorData);
}
}

View File

@ -0,0 +1,147 @@
pragma solidity ^0.5.7;
import "../drafts/ERC777/IERC777.sol";
import "../drafts/ERC777/IERC777Sender.sol";
import "../drafts/ERC777/IERC777Recipient.sol";
import "../drafts/IERC1820Registry.sol";
import "../drafts/ERC1820Implementer.sol";
contract ERC777SenderRecipientMock is IERC777Sender, IERC777Recipient, ERC1820Implementer {
event TokensToSendCalled(
address operator,
address from,
address to,
uint256 amount,
bytes data,
bytes operatorData,
address token,
uint256 fromBalance,
uint256 toBalance
);
event TokensReceivedCalled(
address operator,
address from,
address to,
uint256 amount,
bytes data,
bytes operatorData,
address token,
uint256 fromBalance,
uint256 toBalance
);
bool private _shouldRevertSend;
bool private _shouldRevertReceive;
IERC1820Registry private _erc1820 = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);
bytes32 constant private TOKENS_SENDER_INTERFACE_HASH = keccak256("ERC777TokensSender");
bytes32 constant private TOKENS_RECIPIENT_INTERFACE_HASH = keccak256("ERC777TokensRecipient");
function tokensToSend(
address operator,
address from,
address to,
uint amount,
bytes calldata userData,
bytes calldata operatorData
) external {
if (_shouldRevertSend) {
revert();
}
IERC777 token = IERC777(msg.sender);
uint256 fromBalance = token.balanceOf(from);
// when called due to burn, to will be the zero address, which will have a balance of 0
uint256 toBalance = token.balanceOf(to);
emit TokensToSendCalled(
operator,
from,
to,
amount,
userData,
operatorData,
address(token),
fromBalance,
toBalance
);
}
function tokensReceived(
address operator,
address from,
address to,
uint amount,
bytes calldata userData,
bytes calldata operatorData
) external{
if (_shouldRevertReceive) {
revert();
}
IERC777 token = IERC777(msg.sender);
uint256 fromBalance = token.balanceOf(from);
// when called due to burn, to will be the zero address, which will have a balance of 0
uint256 toBalance = token.balanceOf(to);
emit TokensReceivedCalled(
operator,
from,
to,
amount,
userData,
operatorData,
address(token),
fromBalance,
toBalance
);
}
function senderFor(address account) public {
_registerInterfaceForAddress(TOKENS_SENDER_INTERFACE_HASH, account);
address self = address(this);
if (account == self) {
registerSender(self);
}
}
function registerSender(address sender) public {
_erc1820.setInterfaceImplementer(address(this), TOKENS_SENDER_INTERFACE_HASH, sender);
}
function recipientFor(address account) public {
_registerInterfaceForAddress(TOKENS_RECIPIENT_INTERFACE_HASH, account);
address self = address(this);
if (account == self) {
registerRecipient(self);
}
}
function registerRecipient(address recipient) public {
_erc1820.setInterfaceImplementer(address(this), TOKENS_RECIPIENT_INTERFACE_HASH, recipient);
}
function setShouldRevertSend(bool shouldRevert) public {
_shouldRevertSend = shouldRevert;
}
function setShouldRevertReceive(bool shouldRevert) public {
_shouldRevertReceive = shouldRevert;
}
function send(IERC777 token, address to, uint256 amount, bytes memory data) public {
// This is 777's send function, not the Solidity send function
token.send(to, amount, data); // solhint-disable-line check-send-result
}
function burn(IERC777 token, uint256 amount, bytes memory data) public {
token.burn(amount, data);
}
}

View File

@ -1,73 +0,0 @@
pragma solidity ^0.5.2;
contract EventEmitter {
event Argumentless();
event ShortUint(uint8 value);
event ShortInt(int8 value);
event LongUint(uint256 value);
event LongInt(int256 value);
event Address(address value);
event Boolean(bool value);
event String(string value);
event LongUintBooleanString(uint256 uintValue, bool booleanValue, string stringValue);
constructor (uint8 uintValue, bool booleanValue, string memory stringValue) public {
emit ShortUint(uintValue);
emit Boolean(booleanValue);
emit String(stringValue);
}
function emitArgumentless() public {
emit Argumentless();
}
function emitShortUint(uint8 value) public {
emit ShortUint(value);
}
function emitShortInt(int8 value) public {
emit ShortInt(value);
}
function emitLongUint(uint256 value) public {
emit LongUint(value);
}
function emitLongInt(int256 value) public {
emit LongInt(value);
}
function emitAddress(address value) public {
emit Address(value);
}
function emitBoolean(bool value) public {
emit Boolean(value);
}
function emitString(string memory value) public {
emit String(value);
}
function emitLongUintBooleanString(uint256 uintValue, bool booleanValue, string memory stringValue) public {
emit LongUintBooleanString(uintValue, booleanValue, stringValue);
}
function emitLongUintAndBoolean(uint256 uintValue, bool boolValue) public {
emit LongUint(uintValue);
emit Boolean(boolValue);
}
function emitStringAndEmitIndirectly(string memory value, IndirectEventEmitter emitter) public {
emit String(value);
emitter.emitStringIndirectly(value);
}
}
contract IndirectEventEmitter {
event IndirectString(string value);
function emitStringIndirectly(string memory value) public {
emit IndirectString(value);
}
}

View File

@ -1,23 +0,0 @@
pragma solidity ^0.5.2;
contract Failer {
uint256[] private array;
function dontFail() public pure {
// solhint-disable-previous-line no-empty-blocks
}
function failWithRevert() public pure {
revert();
}
function failWithThrow() public pure {
assert(false);
}
function failWithOutOfGas() public {
for (uint256 i = 0; i < 2**200; ++i) {
array.push(i);
}
}
}

View File

@ -1,4 +1,4 @@
pragma solidity ^0.5.2;
pragma solidity ^0.5.7;
import "../token/ERC20/IERC20.sol";
import "../crowdsale/distribution/FinalizableCrowdsale.sol";

View File

@ -1,4 +1,4 @@
pragma solidity ^0.5.2;
pragma solidity ^0.5.7;
import "../crowdsale/price/IncreasingPriceCrowdsale.sol";
import "../math/SafeMath.sol";

View File

@ -1,4 +1,4 @@
pragma solidity ^0.5.2;
pragma solidity ^0.5.7;
import "../token/ERC20/IERC20.sol";
import "../crowdsale/validation/IndividuallyCappedCrowdsale.sol";

View File

@ -1,4 +1,4 @@
pragma solidity ^0.5.2;
pragma solidity ^0.5.7;
import "../math/Math.sol";

View File

@ -1,4 +1,4 @@
pragma solidity ^0.5.2;
pragma solidity ^0.5.7;
import { MerkleProof } from "../cryptography/MerkleProof.sol";

View File

@ -1,4 +1,4 @@
pragma solidity ^0.5.2;
pragma solidity ^0.5.7;
import "../token/ERC20/ERC20Mintable.sol";
import "../crowdsale/emission/MintedCrowdsale.sol";

View File

@ -1,4 +1,4 @@
pragma solidity ^0.5.2;
pragma solidity ^0.5.7;
import "../access/roles/MinterRole.sol";

View File

@ -1,4 +1,4 @@
pragma solidity ^0.5.2;
pragma solidity ^0.5.7;
import "../ownership/Ownable.sol";

View File

@ -1,4 +1,4 @@
pragma solidity ^0.5.2;
pragma solidity ^0.5.7;
import "../ownership/Ownable.sol";

View File

@ -1,4 +1,4 @@
pragma solidity ^0.5.2;
pragma solidity ^0.5.7;
import "../token/ERC20/ERC20.sol";
import "../crowdsale/validation/PausableCrowdsale.sol";

View File

@ -1,4 +1,4 @@
pragma solidity ^0.5.2;
pragma solidity ^0.5.7;
import "../lifecycle/Pausable.sol";
import "./PauserRoleMock.sol";

View File

@ -1,4 +1,4 @@
pragma solidity ^0.5.2;
pragma solidity ^0.5.7;
import "../access/roles/PauserRole.sol";

View File

@ -1,4 +1,4 @@
pragma solidity ^0.5.2;
pragma solidity ^0.5.7;
import "../token/ERC20/IERC20.sol";
import "../crowdsale/distribution/PostDeliveryCrowdsale.sol";

View File

@ -1,4 +1,4 @@
pragma solidity ^0.5.2;
pragma solidity ^0.5.7;
import "../payment/PullPayment.sol";

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