Commit 9b9f26b4 by Francisco Giordano

Transpile 8225b2f5

parents
comment: off
coverage:
range: "100...100"
# EditorConfig is awesome: https://EditorConfig.org
# top-most EditorConfig file
root = true
[*]
charset = utf-8
end_of_line = lf
indent_style = space
insert_final_newline = true
trim_trailing_whitespace = false
max_line_length = 120
[*.sol]
indent_size = 4
[*.js]
indent_size = 2
[*.adoc]
max_line_length = 0
{
"extends" : [
"standard",
"plugin:promise/recommended",
],
"plugins": [
"mocha-no-only",
"promise",
],
"env": {
"browser" : true,
"node" : true,
"mocha" : true,
"jest" : true,
},
"globals" : {
"artifacts": false,
"contract": false,
"assert": false,
"web3": false,
"usePlugin": false,
"extendEnvironment": false,
},
"rules": {
// Strict mode
"strict": ["error", "global"],
// Code style
"array-bracket-spacing": ["off"],
"camelcase": ["error", {"properties": "always"}],
"comma-dangle": ["error", "always-multiline"],
"comma-spacing": ["error", {"before": false, "after": true}],
"dot-notation": ["error", {"allowKeywords": true, "allowPattern": ""}],
"eol-last": ["error", "always"],
"eqeqeq": ["error", "smart"],
"generator-star-spacing": ["error", "before"],
"indent": ["error", 2],
"linebreak-style": ["error", "unix"],
"max-len": ["error", 120, 2],
"no-debugger": "off",
"no-dupe-args": "error",
"no-dupe-keys": "error",
"no-mixed-spaces-and-tabs": ["error", "smart-tabs"],
"no-redeclare": ["error", {"builtinGlobals": true}],
"no-trailing-spaces": ["error", { "skipBlankLines": false }],
"no-undef": "error",
"no-use-before-define": "off",
"no-var": "error",
"object-curly-spacing": ["error", "always"],
"prefer-const": "error",
"quotes": ["error", "single"],
"semi": ["error", "always"],
"space-before-function-paren": ["error", "always"],
"mocha-no-only/mocha-no-only": ["error"],
"promise/always-return": "off",
"promise/avoid-new": "off",
},
"parserOptions": {
"ecmaVersion": 2018
}
}
*.sol linguist-language=Solidity
---
name: Bug report
about: Report a bug in OpenZeppelin Contracts
---
<!-- 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 Community Forum: https://forum.openzeppelin.com/. -->
**💻 Environment**
<!-- Tell us what version of OpenZeppelin Contracts you're using, and how you're using it: Truffle, Remix, etc. -->
**📝 Details**
<!-- Describe the problem you have been experiencing in more detail. Include as much information as you think is relevant. Keep in mind that transactions can fail for many reasons; context is key here. -->
**🔢 Code to reproduce bug**
<!-- We will be able to better help if you provide a minimal example that triggers the bug. -->
contact_links:
- name: Support request
url: https://forum.openzeppelin.com/c/support/contracts/18
about: Ask the community in the Community Forum
---
name: Feature request
about: Suggest an idea for OpenZeppelin Contracts
---
**🧐 Motivation**
<!-- Is your feature request related to a specific problem? Is it just a crazy idea? Tell us about it! -->
**📝 Details**
<!-- Please describe your feature request in detail. -->
<!-- Make sure that you have reviewed the OpenZeppelin Contributor Guidelines. -->
<!-- https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/CONTRIBUTING.md -->
<!-- 0. 🎉 Thank you for submitting a PR! -->
<!-- 1. Does this close any open issues? Please list them below. -->
<!-- Keep in mind that new features have a better chance of being merged fast if
they were first discussed and designed with the maintainers. If there is no
corresponding issue, please consider opening one for discussion first! -->
Fixes #
<!-- 2. Describe the changes introduced in this pull request. -->
<!-- Include any context necessary for understanding the PR's purpose. -->
<!-- 3. Before submitting, please make sure that you have:
- reviewed the OpenZeppelin Contributor Guidelines
(https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/CONTRIBUTING.md),
- added tests where applicable to test new functionality,
- made sure that your contracts are well-documented,
- run the Solidity linter (`npm run lint:sol`) and fixed any issues,
- run the JS linter and fixed any issues (`npm run lint:fix`), and
- updated the changelog, if applicable.
-->
# 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
- meta
# 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
name: Patch Upstream
on:
workflow_dispatch: {}
schedule:
- cron: '0 10 * * *'
jobs:
update:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
ref: upstream-patched
fetch-depth: 0
- run: bash -x scripts/merge-upstream.sh
name: Test
on:
push:
branches: [master]
pull_request: {}
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v1
with:
node-version: 10.x
- uses: actions/cache@v2
with:
path: ~/.npm
key: npm-${{ hashFiles('**/package-lock.json') }}
restore-keys: npm-
- run: npm ci
- run: npm run lint
- run: npm run test
coverage:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v1
with:
node-version: 10.x
- uses: actions/cache@v2
with:
path: ~/.npm
key: npm-${{ hashFiles('**/package-lock.json') }}
restore-keys: npm-
- run: npm ci
- run: npm run coverage
- uses: codecov/codecov-action@v1
name: Transpile
on:
push:
branches: [upstream-patched]
jobs:
transpile:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
fetch-depth: 0
- uses: actions/setup-node@v1
with:
node-version: 10.x
- uses: actions/cache@v2
with:
path: ~/.npm
key: npm-${{ hashFiles('**/package-lock.json') }}
restore-keys: npm-
- run: npm ci
- run: bash scripts/transpile.sh
*.swp
*.swo
# Logs
logs
*.log
# Runtime data
pids
*.pid
*.seed
allFiredEvents
scTopics
# Coverage directory used by tools like istanbul
coverage
coverage.json
coverageEnv
# node-waf configuration
.lock-wscript
# Dependency directory
node_modules
# Debug log from npm
npm-debug.log
# local env variables
.env
# truffle build directory
build/
# macOS
.DS_Store
# truffle
.node-xmlhttprequest-*
# IntelliJ IDE
.idea
# docs artifacts
docs/modules/api
# only used to package @openzeppelin/contracts
contracts/build/
contracts/README.md
# temporary artifact from solidity-coverage
allFiredEvents
.coverage_artifacts
.coverage_cache
.coverage_contracts
# buidler
cache
artifacts
module.exports = {
timeout: 4000,
};
module.exports = {
norpc: true,
testCommand: 'npm test',
compileCommand: 'npm run compile',
skipFiles: [
'mocks',
],
providerOptions: {
default_balance_ether: '10000000000000000000000000',
},
}
{
"extends": "solhint:recommended",
"rules": {
"func-order": "off",
"mark-callable-contracts": "off",
"no-empty-blocks": "off",
"compiler-version": ["error", "^0.6.0"],
"private-vars-leading-underscore": "error",
"reason-string": "off"
}
}
This diff is collapsed. Click to expand it.
# Contributor Covenant Code of Conduct
## Our Pledge
In the interest of fostering an open and welcoming environment, we as
contributors and maintainers pledge to making participation in our project and
our community a harassment-free experience for everyone, regardless of age, body
size, disability, ethnicity, sex characteristics, gender identity and expression,
level of experience, education, socio-economic status, nationality, personal
appearance, race, religion, or sexual identity and orientation.
## Our Standards
Examples of behavior that contributes to creating a positive environment
include:
* Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism
* Focusing on what is best for the community
* Showing empathy towards other community members
Examples of unacceptable behavior by participants include:
* The use of sexualized language or imagery and unwelcome sexual attention or
advances
* Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or electronic
address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
## Our Responsibilities
Project maintainers are responsible for clarifying the standards of acceptable
behavior and are expected to take appropriate and fair corrective action in
response to any instances of unacceptable behavior.
Project maintainers have the right and responsibility to remove, edit, or
reject comments, commits, code, wiki edits, issues, and other contributions
that are not aligned to this Code of Conduct, or to ban temporarily or
permanently any contributor for other behaviors that they deem inappropriate,
threatening, offensive, or harmful.
## Scope
This Code of Conduct applies both within project spaces and in public spaces
when an individual is representing the project or its community. Examples of
representing a project or community include using an official project e-mail
address, posting via an official social media account, or acting as an appointed
representative at an online or offline event. Representation of a project may be
further defined and clarified by project maintainers.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported by contacting the project team at maintainers@openzeppelin.org. All
complaints will be reviewed and investigated and will result in a response that
is deemed necessary and appropriate to the circumstances. The project team is
obligated to maintain confidentiality with regard to the reporter of an incident.
Further details of specific enforcement policies may be posted separately.
Project maintainers who do not follow or enforce the Code of Conduct in good
faith may face temporary or permanent repercussions as determined by other
members of the project's leadership.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
[homepage]: https://www.contributor-covenant.org
Contributing to OpenZeppelin Contracts
=======
We really appreciate and value contributions to OpenZeppelin Contracts. Please take 5' to review the items listed below to make sure that your contributions are merged as soon as possible.
## Contribution guidelines
Smart contracts manage value and are highly vulnerable to errors and attacks. We have very strict [guidelines], please make sure to review them!
## Creating Pull Requests (PRs)
As a contributor, you are expected to fork this repository, work on your own fork and then submit pull requests. The pull requests will be reviewed and eventually merged into the main repo. See ["Fork-a-Repo"](https://help.github.com/articles/fork-a-repo/) for how this works.
## A typical workflow
1) Make sure your fork is up to date with the main repository:
```
cd openzeppelin-contracts
git remote add upstream https://github.com/OpenZeppelin/openzeppelin-contracts.git
git fetch upstream
git pull --rebase upstream master
```
NOTE: The directory `openzeppelin-contracts` represents your fork's local copy.
2) Branch out from `master` into `fix/some-bug-#123`:
(Postfixing #123 will associate your PR with the issue #123 and make everyone's life easier =D)
```
git checkout -b fix/some-bug-#123
```
3) Make your changes, add your files, commit, and push to your fork.
```
git add SomeFile.js
git commit "Fix some bug #123"
git push origin fix/some-bug-#123
```
4) Run tests, linter, etc. This can be done by running local continuous integration and make sure it passes.
```bash
npm test
npm run lint
```
5) Go to [github.com/OpenZeppelin/openzeppelin-contracts](https://github.com/OpenZeppelin/openzeppelin-contracts) in your web browser and issue a new pull request.
*IMPORTANT* Read the PR template very carefully and make sure to follow all the instructions. These instructions
refer to some very important conditions that your PR must meet in order to be accepted, such as making sure that all tests pass, JS linting tests pass, Solidity linting tests pass, etc.
6) Maintainers will review your code and possibly ask for changes before your code is pulled in to the main repository. We'll check that all tests pass, review the coding style, and check for general code correctness. If everything is OK, we'll merge your pull request and your code will be part of OpenZeppelin.
*IMPORTANT* Please pay attention to the maintainer's feedback, since its a necessary step to keep up with the standards OpenZeppelin attains to.
## All set!
If you have any questions, feel free to post them to github.com/OpenZeppelin/openzeppelin-contracts/issues.
Finally, if you're looking to collaborate and want to find easy tasks to start, look at the issues we marked as ["Good first issue"](https://github.com/OpenZeppelin/openzeppelin-contracts/labels/good%20first%20issue).
Thanks for your time and code!
[guidelines]: GUIDELINES.md
Documentation is hosted at https://docs.openzeppelin.com/contracts.
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) is the
program that extracts the API Reference from source code.
The [`docs.openzeppelin.com`](https://github.com/OpenZeppelin/docs.openzeppelin.com)
repository hosts the configuration for the entire site, which includes
documentation for all of the OpenZeppelin projects.
To run the docs locally you should run `npm run docs:watch` on this
repository.
Design Guidelines
=======
These are some global design goals in OpenZeppelin.
#### D0 - Security in Depth
We strive to provide secure, tested, audited code. To achieve this, we need to match intention with function. Thus, documentation, code clarity, community review and security discussions are fundamental.
#### D1 - Simple and Modular
Simpler code means easier audits, and better understanding of what each component does. We look for small files, small contracts, and small functions. If you can separate a contract into two independent functionalities you should probably do it.
#### D2 - Naming Matters
We take our time with picking names. Code is going to be written once, and read hundreds of times. Renaming for clarity is encouraged.
#### D3 - Tests
Write tests for all your code. We encourage Test Driven Development so we know when our code is right. Even though not all code in the repository is tested at the moment, we aim to test every line of code in the future.
#### D4 - Check preconditions and post-conditions
A very important way to prevent vulnerabilities is to catch a contract’s inconsistent state as early as possible. This is why we want functions to check pre- and post-conditions for executing its logic. When writing code, ask yourself what you are expecting to be true before and after the function runs, and express it in code.
#### D5 - Code Consistency
Consistency on the way classes are used is paramount to an easier understanding of the library. The codebase should be as unified as possible. Read existing code and get inspired before you write your own. Follow the style guidelines. Don’t hesitate to ask for help on how to best write a specific piece of code.
#### D6 - Regular Audits
Following good programming practices is a way to reduce the risk of vulnerabilities, but professional code audits are still needed. We will perform regular code audits on major releases, and hire security professionals to provide independent review.
# Style Guidelines
The design guidelines have quite a high abstraction level. These style guidelines are more concrete and easier to apply, and also more opinionated. We value clean code and consistency, and those are prerequisites for us to include new code in the repository. Before proposing a change, please read these guidelines and take some time to familiarize yourself with the style of the existing codebase.
## Solidity code
In order to be consistent with all the other Solidity projects, we follow the
[official recommendations documented in the Solidity style guide](http://solidity.readthedocs.io/en/latest/style-guide.html).
Any exception or additions specific to our project are documented below.
* Try to avoid acronyms and abbreviations.
* All state variables should be private.
* Private state variables should have an underscore prefix.
```
contract TestContract {
uint256 private _privateVar;
uint256 internal _internalVar;
}
```
* Parameters must not be prefixed with an underscore.
```
function test(uint256 testParameter1, uint256 testParameter2) {
...
}
```
* Internal and private functions should have an underscore prefix.
```
function _testInternal() internal {
...
}
```
```
function _testPrivate() private {
...
}
```
* Events should be emitted immediately after the state change that they
represent, and consequently they should be named in past tense.
```
function _burn(address who, uint256 value) internal {
super._burn(who, value);
emit TokensBurned(who, value);
}
```
Some standards (e.g. ERC20) use present tense, and in those cases the
standard specification prevails.
* Interface names should have a capital I prefix.
```
interface IERC777 {
```
## Tests
* Tests Must be Written Elegantly
Tests are a good way to show how to use the library, and maintaining them is extremely necessary. Don't write long tests, write helper functions to make them be as short and concise as possible (they should take just a few lines each), and use good variable names.
* Tests Must not be Random
Inputs for tests should not be generated randomly. Accounts used to create test contracts are an exception, those can be random. Also, the type and structure of outputs should be checked.
The MIT License (MIT)
Copyright (c) 2016-2020 zOS Global Limited
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
# <img src="logo.svg" alt="OpenZeppelin" height="40px">
[![Docs](https://img.shields.io/badge/docs-%F0%9F%93%84-blue)](https://docs.openzeppelin.com/contracts)
[![NPM Package](https://img.shields.io/npm/v/@openzeppelin/contracts.svg)](https://www.npmjs.org/package/@openzeppelin/contracts)
[![Coverage Status](https://codecov.io/gh/OpenZeppelin/openzeppelin-contracts/graph/badge.svg)](https://codecov.io/gh/OpenZeppelin/openzeppelin-contracts)
**A library for secure smart contract development.** Build on a solid foundation of community-vetted code.
* Implementations of standards like [ERC20](https://docs.openzeppelin.com/contracts/erc20) and [ERC721](https://docs.openzeppelin.com/contracts/erc721).
* Flexible [role-based permissioning](https://docs.openzeppelin.com/contracts/access-control) scheme.
* Reusable [Solidity components](https://docs.openzeppelin.com/contracts/utilities) to build custom contracts and complex decentralized systems.
* First-class integration with the [Gas Station Network](https://docs.openzeppelin.com/contracts/gsn) for systems with no gas fees!
* [Audited](https://github.com/OpenZeppelin/openzeppelin-contracts/tree/master/audit) by leading security firms (_last full audit on v2.0.0_).
## Overview
### Installation
```console
$ npm install @openzeppelin/contracts
```
OpenZeppelin Contracts features a [stable API](https://docs.openzeppelin.com/contracts/releases-stability#api-stability), which means your contracts won't break unexpectedly when upgrading to a newer minor version.
### Usage
Once installed, you can use the contracts in the library by importing them:
```solidity
pragma solidity ^0.6.0;
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
contract MyCollectible is ERC721 {
constructor() ERC721("MyCollectible", "MCO") public {
}
}
```
_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. 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
The guides in the [docs site](https://docs.openzeppelin.com/contracts) will teach about different concepts, and how to use the related contracts that OpenZeppelin Contracts provides:
* [Access Control](https://docs.openzeppelin.com/contracts/access-control): decide who can perform each of the actions on your system.
* [Tokens](https://docs.openzeppelin.com/contracts/tokens): create tradeable assets or collectives, and distribute them via [Crowdsales](https://docs.openzeppelin.com/contracts/crowdsales).
* [Gas Station Network](https://docs.openzeppelin.com/contracts/gsn): let your users interact with your contracts without having to pay for gas themselves.
* [Utilities](https://docs.openzeppelin.com/contracts/utilities): generic useful tools, including non-overflowing math, signature verification, and trustless paying systems.
The [full API](https://docs.openzeppelin.com/contracts/api/token/ERC20) is also thoroughly documented, and serves as a great reference when developing your smart contract application. You can also ask for help or follow Contracts's development in the [community forum](https://forum.openzeppelin.com).
Finally, you may want to take a look at the [guides on our blog](https://blog.openzeppelin.com/guides), which cover several common use cases and good practices.. The following articles provide great background reading, though please note, some of the referenced tools have changed as the tooling in the ecosystem continues to rapidly evolve.
* [The Hitchhiker’s Guide to Smart Contracts in Ethereum](https://blog.openzeppelin.com/the-hitchhikers-guide-to-smart-contracts-in-ethereum-848f08001f05) will help you get an overview of the various tools available for smart contract development, and help you set up your environment.
* [A Gentle Introduction to Ethereum Programming, Part 1](https://blog.openzeppelin.com/a-gentle-introduction-to-ethereum-programming-part-1-783cc7796094) provides very useful information on an introductory level, including many basic concepts from the Ethereum platform.
* For a more in-depth dive, you may read the guide [Designing the Architecture for Your Ethereum Application](https://blog.openzeppelin.com/designing-the-architecture-for-your-ethereum-application-9cec086f8317), which discusses how to better structure your application and its relationship to the real world.
## Security
This project is maintained by [OpenZeppelin](https://openzeppelin.com), and developed following our high standards for code quality and security. OpenZeppelin is meant to provide tested and community-audited code, but please use common sense when doing anything that deals with real money! We take no responsibility for your implementation decisions and any security problems you might experience.
The core development principles and strategies that OpenZeppelin is based on include: security in depth, simple and modular code, clarity-driven naming conventions, comprehensive unit testing, pre-and-post-condition sanity checks, code consistency, and regular audits.
The latest audit was done on October 2018 on version 2.0.0.
Please report any security issues you find to security@openzeppelin.org.
## Contribute
OpenZeppelin exists thanks to its contributors. There are many ways you can participate and help build high quality software. Check out the [contribution guide](CONTRIBUTING.md)!
## License
OpenZeppelin is released under the [MIT License](LICENSE).
# Releasing
> Visit the documentation for [details about release schedule].
Start on an up-to-date `master` branch.
Create the release branch with `npm run release start minor`.
Publish a release candidate with `npm run release rc`.
Publish the final release with `npm run release final`.
Follow the general [OpenZeppelin release checklist].
[details about release schedule]: https://docs.openzeppelin.com/contracts/releases-stability
[OpenZeppelin release checklist]: https://github.com/OpenZeppelin/code-style/blob/master/RELEASE_CHECKLIST.md
## Merging the release branch
After the final release, the release branch should be merged back into `master`. This merge must not be squashed because it would lose the tagged release commit. Since the GitHub repo is set up to only allow squashed merges, the merge should be done locally and pushed.
Make sure to have the latest changes from `upstream` in your local release branch.
```
git checkout release-vX.Y.Z
git pull upstream
```
```
git checkout master
git merge --no-ff release-vX.Y.Z
git push upstream master
```
The release branch can then be deleted on GitHub.
const fs = require('fs');
const path = require('path');
usePlugin('solidity-coverage');
usePlugin('@nomiclabs/buidler-truffle5');
for (const f of fs.readdirSync(path.join(__dirname, 'buidler'))) {
require(path.join(__dirname, 'buidler', f));
}
module.exports = {
networks: {
buidlerevm: {
blockGasLimit: 10000000,
},
},
solc: {
version: '0.6.12',
},
};
const { BuidlerError } = require('@nomiclabs/buidler/internal/core/errors');
extendEnvironment(env => {
const { artifacts } = env;
env.artifacts = {
...artifacts,
require (name) {
try {
return artifacts.require(name + 'UpgradeSafeWithInit');
} catch (e) {
if (BuidlerError.isBuidlerError(e) && e.number === 700) {
return artifacts.require(name + 'UpgradeSafe');
} else {
throw e;
}
}
},
};
});
extendEnvironment(env => {
const { contract } = env;
env.contract = function (name, body) {
// remove the default account from the accounts list used in tests, in order
// to protect tests against accidentally passing due to the contract
// deployer being used subsequently as function caller
contract(name, accounts => body(accounts.slice(1)));
};
});
const { internalTask } = require('@nomiclabs/buidler/config');
const { TASK_TEST_GET_TEST_FILES } = require('@nomiclabs/buidler/builtin-tasks/task-names');
const glob = require('glob');
const path = require('path');
const { promisify } = require('util');
internalTask(TASK_TEST_GET_TEST_FILES)
.setAction(async ({ testFiles }, { config }) => {
if (testFiles.length !== 0) {
return testFiles;
}
return await promisify(glob)(
path.join(config.paths.tests, '**/*.js'),
{ ignore: [path.join(config.paths.tests, 'proxy/**/*')] },
);
});
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;
import "../Initializable.sol";
/*
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with GSN meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract ContextUpgradeSafe is __Initializable {
function __Context_init() internal __initializer {
__Context_init_unchained();
}
function __Context_init_unchained() internal __initializer {
}
function _msgSender() internal view virtual returns (address payable) {
return msg.sender;
}
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;
}
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;
import "./GSNRecipientUpgradeSafe.sol";
import "../math/SafeMathUpgradeSafe.sol";
import "../access/OwnableUpgradeSafe.sol";
import "../token/ERC20/SafeERC20UpgradeSafe.sol";
import "../token/ERC20/ERC20UpgradeSafe.sol";
import "../Initializable.sol";
/**
* @dev A xref:ROOT:gsn-strategies.adoc#gsn-strategies[GSN strategy] that charges transaction fees in a special purpose ERC20
* token, which we refer to as the gas payment token. The amount charged is exactly the amount of Ether charged to the
* recipient. This means that the token is essentially pegged to the value of Ether.
*
* The distribution strategy of the gas payment token to users is not defined by this contract. It's a mintable token
* whose only minter is the recipient, so the strategy must be implemented in a derived contract, making use of the
* internal {_mint} function.
*/
contract GSNRecipientERC20FeeUpgradeSafe is __Initializable, GSNRecipientUpgradeSafe {
using SafeERC20UpgradeSafe for __unstable__ERC20OwnedUpgradeSafe;
using SafeMathUpgradeSafe for uint256;
enum GSNRecipientERC20FeeErrorCodes {
INSUFFICIENT_BALANCE
}
__unstable__ERC20OwnedUpgradeSafe 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.
*/
function __GSNRecipientERC20Fee_init(string memory name, string memory symbol) internal __initializer {
__Context_init_unchained();
__GSNRecipient_init_unchained();
__GSNRecipientERC20Fee_init_unchained(name, symbol);
}
function __GSNRecipientERC20Fee_init_unchained(string memory name, string memory symbol) internal __initializer {
_token = new __unstable__ERC20OwnedUpgradeSafe();
_token.initialize(name, symbol);
}
/**
* @dev Returns the gas payment token.
*/
function token() public view returns (IERC20UpgradeSafe) {
return IERC20UpgradeSafe(_token);
}
/**
* @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 virtual {
_token.mint(account, amount);
}
/**
* @dev Ensures that only users with enough gas payment token balance can have transactions relayed through the GSN.
*/
function acceptRelayedCall(
address,
address from,
bytes memory,
uint256 transactionFee,
uint256 gasPrice,
uint256,
uint256,
bytes memory,
uint256 maxPossibleCharge
)
public
view
virtual
override
returns (uint256, bytes memory)
{
if (_token.balanceOf(from) < maxPossibleCharge) {
return _rejectRelayedCall(uint256(GSNRecipientERC20FeeErrorCodes.INSUFFICIENT_BALANCE));
}
return _approveRelayedCall(abi.encode(from, maxPossibleCharge, transactionFee, gasPrice));
}
/**
* @dev Implements the precharge to the user. The maximum possible charge (depending on gas limit, gas price, and
* fee) will be deducted from the user balance of gas payment token. Note that this is an overestimation of the
* 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 virtual override returns (bytes32) {
(address from, uint256 maxPossibleCharge) = abi.decode(context, (address, uint256));
// The maximum token charge is pre-charged from the user
_token.safeTransferFrom(from, address(this), maxPossibleCharge);
}
/**
* @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 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);
actualCharge = actualCharge.sub(overestimation);
// After the relayed call has been executed and the actual charge estimated, the excess pre-charge is returned
_token.safeTransfer(from, maxPossibleCharge.sub(actualCharge));
}
}
/**
* @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__ERC20OwnedUpgradeSafe is __Initializable, ERC20UpgradeSafe, OwnableUpgradeSafe {
function initialize(string memory name, string memory symbol) external __initializer {
____unstable__ERC20Owned_init(name, symbol);
}
uint256 private constant _UINT256_MAX = 2**256 - 1;
function ____unstable__ERC20Owned_init(string memory name, string memory symbol) internal __initializer {
__Context_init_unchained();
__ERC20_init_unchained(name, symbol);
__Ownable_init_unchained();
____unstable__ERC20Owned_init_unchained(name, symbol);
}
function ____unstable__ERC20Owned_init_unchained(string memory name, string memory symbol) internal __initializer { }
// The owner (GSNRecipientERC20Fee) can mint tokens
function mint(address account, uint256 amount) public onlyOwner {
_mint(account, amount);
}
// 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(tokenOwner, spender);
}
}
// 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(tokenOwner, spender, value);
}
}
function transferFrom(address sender, address recipient, uint256 amount) public override returns (bool) {
if (recipient == owner()) {
_transfer(sender, recipient, amount);
return true;
} else {
return super.transferFrom(sender, recipient, amount);
}
}
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;
import "./GSNRecipientUpgradeSafe.sol";
import "../cryptography/ECDSAUpgradeSafe.sol";
import "../Initializable.sol";
/**
* @dev A xref:ROOT:gsn-strategies.adoc#gsn-strategies[GSN strategy] that allows relayed transactions through when they are
* accompanied by the signature of a trusted signer. The intent is for this signature to be generated by a server that
* performs validations off-chain. Note that nothing is charged to the user in this scheme. Thus, the server should make
* sure to account for this in their economic and threat model.
*/
contract GSNRecipientSignatureUpgradeSafe is __Initializable, GSNRecipientUpgradeSafe {
using ECDSAUpgradeSafe for bytes32;
address private _trustedSigner;
enum GSNRecipientSignatureErrorCodes {
INVALID_SIGNER
}
/**
* @dev Sets the trusted signer that is going to be producing signatures to approve relayed calls.
*/
function __GSNRecipientSignature_init(address trustedSigner) internal __initializer {
__Context_init_unchained();
__GSNRecipient_init_unchained();
__GSNRecipientSignature_init_unchained(trustedSigner);
}
function __GSNRecipientSignature_init_unchained(address trustedSigner) internal __initializer {
require(trustedSigner != address(0), "GSNRecipientSignature: trusted signer is the zero address");
_trustedSigner = trustedSigner;
}
/**
* @dev Ensures that only transactions with a trusted signature can be relayed through the GSN.
*/
function acceptRelayedCall(
address relay,
address from,
bytes memory encodedFunction,
uint256 transactionFee,
uint256 gasPrice,
uint256 gasLimit,
uint256 nonce,
bytes memory approvalData,
uint256
)
public
view
virtual
override
returns (uint256, bytes memory)
{
bytes memory blob = abi.encodePacked(
relay,
from,
encodedFunction,
transactionFee,
gasPrice,
gasLimit,
nonce, // Prevents replays on RelayHub
getHubAddr(), // Prevents replays in multiple RelayHubs
address(this) // Prevents replays in multiple recipients
);
if (keccak256(blob).toEthSignedMessageHash().recover(approvalData) == _trustedSigner) {
return _approveRelayedCall();
} else {
return _rejectRelayedCall(uint256(GSNRecipientSignatureErrorCodes.INVALID_SIGNER));
}
}
function _preRelayedCall(bytes memory) internal virtual override returns (bytes32) { }
function _postRelayedCall(bytes memory, bool, uint256, bytes32) internal virtual override { }
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;
/**
* @dev Base interface for a contract that will be called via the GSN from {IRelayHub}.
*
* TIP: You don't need to write an implementation yourself! Inherit from {GSNRecipient} instead.
*/
interface IRelayRecipientUpgradeSafe {
/**
* @dev Returns the address of the {IRelayHub} instance this recipient interacts with.
*/
function getHubAddr() external view returns (address);
/**
* @dev Called by {IRelayHub} to validate if this recipient accepts being charged for a relayed call. Note that the
* recipient will be charged regardless of the execution result of the relayed call (i.e. if it reverts or not).
*
* The relay request was originated by `from` and will be served by `relay`. `encodedFunction` is the relayed call
* calldata, so its first four bytes are the function selector. The relayed call will be forwarded `gasLimit` gas,
* and the transaction executed with a gas price of at least `gasPrice`. ``relay``'s fee is `transactionFee`, and the
* recipient will be charged at most `maxPossibleCharge` (in wei). `nonce` is the sender's (`from`) nonce for
* replay attack protection in {IRelayHub}, and `approvalData` is a optional parameter that can be used to hold a signature
* over all or some of the previous values.
*
* Returns a tuple, where the first value is used to indicate approval (0) or rejection (custom non-zero error code,
* values 1 to 10 are reserved) and the second one is data to be passed to the other {IRelayRecipient} functions.
*
* {acceptRelayedCall} is called with 50k gas: if it runs out during execution, the request will be considered
* rejected. A regular revert will also trigger a rejection.
*/
function acceptRelayedCall(
address relay,
address from,
bytes calldata encodedFunction,
uint256 transactionFee,
uint256 gasPrice,
uint256 gasLimit,
uint256 nonce,
bytes calldata approvalData,
uint256 maxPossibleCharge
)
external
view
returns (uint256, bytes memory);
/**
* @dev Called by {IRelayHub} on approved relay call requests, before the relayed call is executed. This allows to e.g.
* pre-charge the sender of the transaction.
*
* `context` is the second value returned in the tuple by {acceptRelayedCall}.
*
* Returns a value to be passed to {postRelayedCall}.
*
* {preRelayedCall} is called with 100k gas: if it runs out during execution or otherwise reverts, the relayed call
* will not be executed, but the recipient will still be charged for the transaction's cost.
*/
function preRelayedCall(bytes calldata context) external returns (bytes32);
/**
* @dev Called by {IRelayHub} on approved relay call requests, after the relayed call is executed. This allows to e.g.
* charge the user for the relayed call costs, return any overcharges from {preRelayedCall}, or perform
* contract-specific bookkeeping.
*
* `context` is the second value returned in the tuple by {acceptRelayedCall}. `success` is the execution status of
* the relayed call. `actualCharge` is an estimate of how much the recipient will be charged for the transaction,
* not including any gas used by {postRelayedCall} itself. `preRetVal` is {preRelayedCall}'s return value.
*
*
* {postRelayedCall} is called with 100k gas: if it runs out during execution or otherwise reverts, the relayed call
* and the call to {preRelayedCall} will be reverted retroactively, but the recipient will still be charged for the
* transaction's cost.
*/
function postRelayedCall(bytes calldata context, bool success, uint256 actualCharge, bytes32 preRetVal) external;
}
= Gas Station Network (GSN)
[.readme-notice]
NOTE: This document is better viewed at https://docs.openzeppelin.com/contracts/api/gsn
This set of contracts provide all the tools required to make a contract callable via the https://gsn.openzeppelin.com[Gas Station Network].
TIP: If you're new to the GSN, head over to our xref:learn::sending-gasless-transactions.adoc[overview of the system] and basic guide to xref:ROOT:gsn.adoc[creating a GSN-capable contract].
The core contract a recipient must inherit from is {GSNRecipient}: it includes all necessary interfaces, as well as some helper methods to make interacting with the GSN easier.
Utilities to make writing xref:ROOT:gsn-strategies.adoc[GSN strategies] easy are available in {GSNRecipient}, or you can simply use one of our pre-made strategies:
* {GSNRecipientERC20Fee} charges the end user for gas costs in an application-specific xref:ROOT:tokens.adoc#ERC20[ERC20 token]
* {GSNRecipientSignature} accepts all relayed calls that have been signed by a trusted third party (e.g. a private key in a backend)
You can also take a look at the two contract interfaces that make up the GSN protocol: {IRelayRecipient} and {IRelayHub}, but you won't need to use those directly.
== Recipient
{{GSNRecipient}}
== Strategies
{{GSNRecipientSignature}}
{{GSNRecipientERC20Fee}}
== Protocol
{{IRelayRecipient}}
{{IRelayHub}}
pragma solidity >=0.4.24 <0.7.0;
/**
* @title Initializable
*
* @dev Helper contract to support initializer functions. To use it, replace
* the constructor with a function that has the `initializer` modifier.
* WARNING: Unlike constructors, initializer functions must be manually
* invoked. This applies both to deploying an Initializable contract, as well
* as extending an Initializable contract via inheritance.
* WARNING: When used with inheritance, manual care must be taken to not invoke
* a parent initializer twice, or ensure that all initializers are idempotent,
* because this is not dealt with automatically as with constructors.
*/
contract __Initializable {
/**
* @dev Indicates that the contract has been initialized.
*/
bool private initialized;
/**
* @dev Indicates that the contract is in the process of being initialized.
*/
bool private initializing;
/**
* @dev Modifier to use in the initializer function of a contract.
*/
modifier __initializer() {
require(initializing || isConstructor() || !initialized, "Contract instance has already been initialized");
bool isTopLevelCall = !initializing;
if (isTopLevelCall) {
initializing = true;
initialized = true;
}
_;
if (isTopLevelCall) {
initializing = false;
}
}
/// @dev Returns true if and only if the function is running in the constructor
function isConstructor() private view returns (bool) {
// extcodesize checks the size of the code stored in an address, and
// address returns the current address. Since the code is still not
// deployed when running a constructor, any checks on its code size will
// yield zero, making it an effective way to detect if a contract is
// under construction or not.
address self = address(this);
uint256 cs;
assembly { cs := extcodesize(self) }
return cs == 0;
}
// Reserved storage space to allow for layout changes in the future.
uint256[50] private ______gap;
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;
import "../utils/EnumerableSetUpgradeSafe.sol";
import "../utils/AddressUpgradeSafe.sol";
import "../GSN/ContextUpgradeSafe.sol";
import "../Initializable.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, msg.sender));
* ...
* }
* ```
*
* 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 {revokeRole}.
*
* 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}.
*
* WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to
* grant and revoke this role. Extra precautions should be taken to secure
* accounts that have been granted it.
*/
abstract contract AccessControlUpgradeSafe is __Initializable, ContextUpgradeSafe {
function __AccessControl_init() internal __initializer {
__Context_init_unchained();
__AccessControl_init_unchained();
}
function __AccessControl_init_unchained() internal __initializer {
}
using EnumerableSetUpgradeSafe for EnumerableSetUpgradeSafe.AddressSet;
using AddressUpgradeSafe for address;
struct RoleData {
EnumerableSetUpgradeSafe.AddressSet members;
bytes32 adminRole;
}
mapping (bytes32 => RoleData) private _roles;
bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;
/**
* @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`
*
* `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite
* {RoleAdminChanged} not being emitted signaling this.
*
* _Available since v3.1._
*/
event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);
/**
* @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.
*
* [WARNING]
* ====
* This function should only be called from the constructor when setting
* up the initial roles for the system.
*
* Using this function in any other way is effectively circumventing the admin
* system imposed by {AccessControl}.
* ====
*/
function _setupRole(bytes32 role, address account) internal virtual {
_grantRole(role, account);
}
/**
* @dev Sets `adminRole` as ``role``'s admin role.
*
* Emits a {RoleAdminChanged} event.
*/
function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {
emit RoleAdminChanged(role, _roles[role].adminRole, adminRole);
_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());
}
}
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;
import "../GSN/ContextUpgradeSafe.sol";
import "../Initializable.sol";
/**
* @dev Contract module which provides a basic access control mechanism, where
* 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.
*/
contract OwnableUpgradeSafe is __Initializable, ContextUpgradeSafe {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the deployer as the initial owner.
*/
function __Ownable_init() internal __initializer {
__Context_init_unchained();
__Ownable_init_unchained();
}
function __Ownable_init_unchained() internal __initializer {
address msgSender = _msgSender();
_owner = msgSender;
emit OwnershipTransferred(address(0), msgSender);
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view returns (address) {
return _owner;
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
require(_owner == _msgSender(), "Ownable: caller is not the 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.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby removing any functionality that is only available to the owner.
*/
function renounceOwnership() public virtual onlyOwner {
emit OwnershipTransferred(_owner, address(0));
_owner = address(0);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
emit OwnershipTransferred(_owner, newOwner);
_owner = newOwner;
}
}
= Access
[.readme-notice]
NOTE: This document is better viewed at https://docs.openzeppelin.com/contracts/api/access
Contract modules for authorization and access control mechanisms.
== Authorization
{{Ownable}}
{{AccessControl}}
== Timelock
{{TimelockController}}
==== Terminology
* *Operation:* A transaction (or a set of transactions) that is the subject of the timelock. It has to be scheduled by a proposer and executed by an executor. The timelock enforces a minimum delay between the proposition and the execution (see xref:access-control.adoc#operation_lifecycle[operation lifecycle]). If the operation contains multiple transactions (batch mode), they are executed atomically. Operations are identified by the hash of their content.
* *Operation status:*
** *Unset:* An operation that is not part of the timelock mechanism.
** *Pending:* An operation that has been scheduled, before the timer expires.
** *Ready:* An operation that has been scheduled, after the timer expires.
** *Done:* An operation that has been executed.
* *Predecessor*: An (optional) dependency between operations. An operation can depend on another operation (its predecessor), forcing the execution order of these two operations.
* *Role*:
** *Proposer:* An address (smart contract or EOA) that is in charge of scheduling (and cancelling) operations.
** *Executor:* An address (smart contract or EOA) that is in charge of executing operations.
==== Operation structure
Operation executed by the xref:api:access.adoc#TimelockController[`TimelockControler`] can contain one or multiple subsequent calls. Depending on whether you need to multiple calls to be executed atomically, you can either use simple or batched operations.
Both operations contain:
* *Target*, the address of the smart contract that the timelock should operate on.
* *Value*, in wei, that should be sent with the transaction. Most of the time this will be 0. Ether can be deposited before-end or passed along when executing the transaction.
* *Data*, containing the encoded function selector and parameters of the call. This can be produced using a number of tools. For example, a maintenance operation granting role `ROLE` to `ACCOUNT` can be encode using web3js as follows:
```javascript
const data = timelock.contract.methods.grantRole(ROLE, ACCOUNT).encodeABI()
```
* *Predecessor*, that specifies a dependency between operations. This dependency is optional. Use `bytes32(0)` if the operation does not have any dependency.
* *Salt*, used to disambiguate two otherwise identical operations. This can be any random value.
In the case of batched operations, `target`, `value` and `data` are specified as arrays, which must be of the same length.
==== Operation lifecycle
Timelocked operations are identified by a unique id (their hash) and follow a specific lifecycle:
`Unset` -> `Pending` -> `Pending` + `Ready` -> `Done`
* By calling xref:api:access.adoc#TimelockController-schedule-address-uint256-bytes-bytes32-bytes32-uint256-[`schedule`] (or xref:api:access.adoc#TimelockController-scheduleBatch-address---uint256---bytes---bytes32-bytes32-uint256-[`scheduleBatch`]), a proposer moves the operation from the `Unset` to the `Pending` state. This starts a timer that must be longer than the minimum delay. The timer expires at a timestamp accessible through the xref:api:access.adoc#TimelockController-getTimestamp-bytes32-[`getTimestamp`] method.
* Once the timer expires, the operation automatically gets the `Ready` state. At this point, it can be executed.
* By calling xref:api:access.adoc#TimelockController-TimelockController-execute-address-uint256-bytes-bytes32-bytes32-[`execute`] (or xref:api:access.adoc#TimelockController-executeBatch-address---uint256---bytes---bytes32-bytes32-[`executeBatch`]), an executor triggers the operation's underlying transactions and moves it to the `Done` state. If the operation has a predecessor, it has to be in the `Done` state for this transition to succeed.
* xref:api:access.adoc#TimelockController-TimelockController-cancel-bytes32-[`cancel`] allows proposers to cancel any `Pending` operation. This resets the operation to the `Unset` state. It is thus possible for a proposer to re-schedule an operation that has been cancelled. In this case, the timer restarts when the operation is re-scheduled.
Operations status can be queried using the functions:
* xref:api:access.adoc#TimelockController-isOperationPending-bytes32-[`isOperationPending(bytes32)`]
* xref:api:access.adoc#TimelockController-isOperationReady-bytes32-[`isOperationReady(bytes32)`]
* xref:api:access.adoc#TimelockController-isOperationDone-bytes32-[`isOperationDone(bytes32)`]
==== Roles
===== Admin
The admins are in charge of managing proposers and executors. For the timelock to be self-governed, this role should only be given to the timelock itself. Upon deployment, both the timelock and the deployer have this role. After further configuration and testing, the deployer can renounce this role such that all further maintenance operations have to go through the timelock process.
This role is identified by the *TIMELOCK_ADMIN_ROLE* value: `0x5f58e3a2316349923ce3780f8d587db2d72378aed66a8261c916544fa6846ca5`
===== Proposer
The proposers are in charge of scheduling (and cancelling) operations. This is a critical role, that should be given to governing entities. This could be an EOA, a multisig, or a DAO.
WARNING: *Proposer fight:* Having multiple proposers, while providing redundancy in case one becomes unavailable, can be dangerous. As proposer have their say on all operations, they could cancel operations they disagree with, including operations to remove them for the proposers.
This role is identified by the *PROPOSER_ROLE* value: `0xb09aa5aeb3702cfd50b6b62bc4532604938f21248a27a1d5ca736082b6819cc1`
===== Executor
The executors are in charge of executing the operations scheduled by the proposers once the timelock expires. Logic dictates that multisig or DAO that are proposers should also be executors in order to guarantee operations that have been scheduled will eventually be executed. However, having additional executor can reduce the cost (the executing transaction does not require validation by the multisig or DAO that proposed it), while ensuring whoever is in charge of execution cannot trigger actions that have not been scheduled by the proposers.
This role is identified by the *EXECUTOR_ROLE* value: `0xd8aa0f3194971a2a116679f7c2090f6939c8d4e01a2a8d7e41d55e5351469e63`
WARNING: A live contract without at least one proposer and one executor is locked. Make sure these roles are filled by reliable entities before the deployer renounces its administrative rights in favour of the timelock contract itself. See the {AccessControl} documentation to learn more about role management.
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;
/**
* @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.
*
* These functions can be used to verify that a message was signed by the holder
* of the private keys of a given address.
*/
library ECDSAUpgradeSafe {
/**
* @dev Returns the address that signed a hashed message (`hash`) with
* `signature`. This address can then be used for verification purposes.
*
* The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:
* 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.
*
* 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
* this is by receiving a hash of the original message (which may otherwise
* be too long), and then calling {toEthSignedMessageHash} on it.
*/
function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {
// Check the signature length
if (signature.length != 65) {
revert("ECDSA: invalid signature length");
}
// Divide the signature in r, s and v variables
bytes32 r;
bytes32 s;
uint8 v;
// ecrecover takes the signature parameters, and the only way to get them
// currently is to use assembly.
// solhint-disable-next-line no-inline-assembly
assembly {
r := mload(add(signature, 0x20))
s := mload(add(signature, 0x40))
v := byte(0, mload(add(signature, 0x60)))
}
// EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature
// unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines
// the valid range for s in (281): 0 < s < secp256k1n ÷ 2 + 1, and for v in (282): v ∈ {27, 28}. Most
// signatures from current libraries generate a unique signature with an s-value in the lower half order.
//
// If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value
// with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or
// vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept
// these malleable signatures as well.
require(uint256(s) <= 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0, "ECDSA: invalid signature 's' value");
require(v == 27 || v == 28, "ECDSA: invalid signature 'v' value");
// If the signature is valid (and not malleable), return the signer address
address signer = ecrecover(hash, v, r, s);
require(signer != address(0), "ECDSA: invalid signature");
return signer;
}
/**
* @dev Returns an Ethereum Signed Message, created from a `hash`. This
* replicates the behavior of the
* https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_sign[`eth_sign`]
* JSON-RPC method.
*
* See {recover}.
*/
function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {
// 32 is the length in bytes of hash,
// enforced by the type signature above
return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash));
}
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;
/**
* @dev These functions deal with verification of Merkle trees (hash trees),
*/
library MerkleProofUpgradeSafe {
/**
* @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree
* defined by `root`. For this, a `proof` must be provided, containing
* sibling hashes on the branch from the leaf to the root of the tree. Each
* pair of leaves and each pair of pre-images are assumed to be sorted.
*/
function verify(bytes32[] memory proof, bytes32 root, bytes32 leaf) internal pure returns (bool) {
bytes32 computedHash = leaf;
for (uint256 i = 0; i < proof.length; i++) {
bytes32 proofElement = proof[i];
if (computedHash <= proofElement) {
// Hash(current computed hash + current element of the proof)
computedHash = keccak256(abi.encodePacked(computedHash, proofElement));
} else {
// Hash(current element of the proof + current computed hash)
computedHash = keccak256(abi.encodePacked(proofElement, computedHash));
}
}
// Check if the computed hash (root) is equal to the provided root
return computedHash == root;
}
}
= Cryptography
[.readme-notice]
NOTE: This document is better viewed at https://docs.openzeppelin.com/contracts/api/cryptography
This collection of libraries provides simple and safe ways to use different cryptographic primitives.
== Libraries
{{ECDSA}}
{{MerkleProof}}
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.2;
/**
* @dev Library used to query support of an interface declared via {IERC165}.
*
* Note that these functions return the actual result of the query: they do not
* `revert` if an interface is not supported. It is up to the caller to decide
* what to do in these cases.
*/
library ERC165CheckerUpgradeSafe {
// As per the EIP-165 spec, no interface should ever match 0xffffffff
bytes4 private constant _INTERFACE_ID_INVALID = 0xffffffff;
/*
* bytes4(keccak256('supportsInterface(bytes4)')) == 0x01ffc9a7
*/
bytes4 private constant _INTERFACE_ID_ERC165 = 0x01ffc9a7;
/**
* @dev Returns true if `account` supports the {IERC165} interface,
*/
function supportsERC165(address account) internal view returns (bool) {
// Any contract that implements ERC165 must explicitly indicate support of
// InterfaceId_ERC165 and explicitly indicate non-support of InterfaceId_Invalid
return _supportsERC165Interface(account, _INTERFACE_ID_ERC165) &&
!_supportsERC165Interface(account, _INTERFACE_ID_INVALID);
}
/**
* @dev Returns true if `account` supports the interface defined by
* `interfaceId`. Support for {IERC165} itself is queried automatically.
*
* See {IERC165-supportsInterface}.
*/
function supportsInterface(address account, bytes4 interfaceId) internal view returns (bool) {
// query support of both ERC165 as per the spec and support of _interfaceId
return supportsERC165(account) &&
_supportsERC165Interface(account, interfaceId);
}
/**
* @dev Returns true if `account` supports all the interfaces defined in
* `interfaceIds`. Support for {IERC165} itself is queried automatically.
*
* Batch-querying can lead to gas savings by skipping repeated checks for
* {IERC165} support.
*
* See {IERC165-supportsInterface}.
*/
function supportsAllInterfaces(address account, bytes4[] memory interfaceIds) internal view returns (bool) {
// query support of ERC165 itself
if (!supportsERC165(account)) {
return false;
}
// query support of each interface in _interfaceIds
for (uint256 i = 0; i < interfaceIds.length; i++) {
if (!_supportsERC165Interface(account, interfaceIds[i])) {
return false;
}
}
// all interfaces supported
return true;
}
/**
* @notice Query if a contract implements an interface, does not check ERC165 support
* @param account The address of the contract to query for support of an interface
* @param interfaceId The interface identifier, as specified in ERC-165
* @return true if the contract at account indicates support of the interface with
* identifier interfaceId, false otherwise
* @dev Assumes that account contains a contract that supports ERC165, otherwise
* the behavior of this method is undefined. This precondition can be checked
* with {supportsERC165}.
* Interface identification is specified in ERC-165.
*/
function _supportsERC165Interface(address account, bytes4 interfaceId) private view returns (bool) {
// success determines whether the staticcall succeeded and result determines
// whether the contract at account indicates support of _interfaceId
(bool success, bool result) = _callERC165SupportsInterface(account, interfaceId);
return (success && result);
}
/**
* @notice Calls the function with selector 0x01ffc9a7 (ERC165) and suppresses throw
* @param account The address of the contract to query for support of an interface
* @param interfaceId The interface identifier, as specified in ERC-165
* @return success true if the STATICCALL succeeded, false otherwise
* @return result true if the STATICCALL succeeded and the contract at account
* indicates support of the interface with identifier interfaceId, false otherwise
*/
function _callERC165SupportsInterface(address account, bytes4 interfaceId)
private
view
returns (bool, bool)
{
bytes memory encodedParams = abi.encodeWithSelector(_INTERFACE_ID_ERC165, interfaceId);
(bool success, bytes memory result) = account.staticcall{ gas: 30000 }(encodedParams);
if (result.length < 32) return (false, false);
return (success, abi.decode(result, (bool)));
}
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;
import "./IERC165UpgradeSafe.sol";
import "../Initializable.sol";
/**
* @dev Implementation of the {IERC165} interface.
*
* Contracts may inherit from this and call {_registerInterface} to declare
* their support of an interface.
*/
contract ERC165UpgradeSafe is __Initializable, IERC165UpgradeSafe {
/*
* bytes4(keccak256('supportsInterface(bytes4)')) == 0x01ffc9a7
*/
bytes4 private constant _INTERFACE_ID_ERC165 = 0x01ffc9a7;
/**
* @dev Mapping of interface ids to whether or not it's supported.
*/
mapping(bytes4 => bool) private _supportedInterfaces;
function __ERC165_init() internal __initializer {
__ERC165_init_unchained();
}
function __ERC165_init_unchained() internal __initializer {
// Derived contracts need only register support for their own interfaces,
// we register support for ERC165 itself here
_registerInterface(_INTERFACE_ID_ERC165);
}
/**
* @dev See {IERC165-supportsInterface}.
*
* Time complexity O(1), guaranteed to always use less than 30 000 gas.
*/
function supportsInterface(bytes4 interfaceId) public view override returns (bool) {
return _supportedInterfaces[interfaceId];
}
/**
* @dev Registers the contract as an implementer of the interface defined by
* `interfaceId`. Support of the actual ERC165 interface is automatic and
* registering its interface id is not required.
*
* See {IERC165-supportsInterface}.
*
* Requirements:
*
* - `interfaceId` cannot be the ERC165 invalid interface (`0xffffffff`).
*/
function _registerInterface(bytes4 interfaceId) internal virtual {
require(interfaceId != 0xffffffff, "ERC165: invalid interface id");
_supportedInterfaces[interfaceId] = true;
}
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;
import "./IERC1820ImplementerUpgradeSafe.sol";
import "../Initializable.sol";
/**
* @dev Implementation of the {IERC1820Implementer} interface.
*
* Contracts may inherit from this and call {_registerInterfaceForAddress} to
* declare their willingness to be implementers.
* {IERC1820Registry-setInterfaceImplementer} should then be called for the
* registration to be complete.
*/
contract ERC1820ImplementerUpgradeSafe is __Initializable, IERC1820ImplementerUpgradeSafe {
function __ERC1820Implementer_init() internal __initializer {
__ERC1820Implementer_init_unchained();
}
function __ERC1820Implementer_init_unchained() internal __initializer {
}
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) public view override returns (bytes32) {
return _supportedInterfaces[interfaceHash][account] ? _ERC1820_ACCEPT_MAGIC : bytes32(0x00);
}
/**
* @dev Declares the contract as willing to be an implementer of
* `interfaceHash` for `account`.
*
* See {IERC1820Registry-setInterfaceImplementer} and
* {IERC1820Registry-interfaceHash}.
*/
function _registerInterfaceForAddress(bytes32 interfaceHash, address account) internal virtual {
_supportedInterfaces[interfaceHash][account] = true;
}
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;
/**
* @dev Interface of the ERC165 standard, as defined in the
* https://eips.ethereum.org/EIPS/eip-165[EIP].
*
* Implementers can declare support of contract interfaces, which can then be
* queried by others ({ERC165Checker}).
*
* For an implementation, see {ERC165}.
*/
interface IERC165UpgradeSafe {
/**
* @dev Returns true if this contract implements the interface defined by
* `interfaceId`. See the corresponding
* https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
* to learn more about how these ids are created.
*
* This function call must use less than 30 000 gas.
*/
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;
/**
* @dev Interface for an ERC1820 implementer, as defined in the
* https://eips.ethereum.org/EIPS/eip-1820#interface-implementation-erc1820implementerinterface[EIP].
* Used by contracts that will be registered as implementers in the
* {IERC1820Registry}.
*/
interface IERC1820ImplementerUpgradeSafe {
/**
* @dev Returns a special value (`ERC1820_ACCEPT_MAGIC`) if this contract
* implements `interfaceHash` for `account`.
*
* See {IERC1820Registry-setInterfaceImplementer}.
*/
function canImplementInterfaceForAddress(bytes32 interfaceHash, address account) external view returns (bytes32);
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;
/**
* @dev Interface of the global ERC1820 Registry, as defined in the
* https://eips.ethereum.org/EIPS/eip-1820[EIP]. Accounts may register
* implementers for interfaces in this registry, as well as query support.
*
* Implementers may be shared by multiple accounts, and can also implement more
* than a single interface for each account. Contracts can implement interfaces
* for themselves, but externally-owned accounts (EOA) must delegate this to a
* contract.
*
* {IERC165} interfaces can also be queried via the registry.
*
* For an in-depth explanation and source code analysis, see the EIP text.
*/
interface IERC1820RegistryUpgradeSafe {
/**
* @dev Sets `newManager` as the manager for `account`. A manager of an
* account is able to set interface implementers for it.
*
* By default, each account is its own manager. Passing a value of `0x0` in
* `newManager` will reset the manager to this initial state.
*
* Emits a {ManagerChanged} event.
*
* Requirements:
*
* - the caller must be the current manager for `account`.
*/
function setManager(address account, address newManager) external;
/**
* @dev Returns the manager for `account`.
*
* See {setManager}.
*/
function getManager(address account) external view returns (address);
/**
* @dev Sets the `implementer` contract as ``account``'s implementer for
* `interfaceHash`.
*
* `account` being the zero address is an alias for the caller's address.
* The zero address can also be used in `implementer` to remove an old one.
*
* See {interfaceHash} to learn how these are created.
*
* Emits an {InterfaceImplementerSet} event.
*
* Requirements:
*
* - the caller must be the current manager for `account`.
* - `interfaceHash` must not be an {IERC165} interface id (i.e. it must not
* end in 28 zeroes).
* - `implementer` must implement {IERC1820Implementer} and return true when
* queried for support, unless `implementer` is the caller. See
* {IERC1820Implementer-canImplementInterfaceForAddress}.
*/
function setInterfaceImplementer(address account, bytes32 interfaceHash, address implementer) external;
/**
* @dev Returns the implementer of `interfaceHash` for `account`. If no such
* implementer is registered, returns the zero address.
*
* If `interfaceHash` is an {IERC165} interface id (i.e. it ends with 28
* zeroes), `account` will be queried for support of it.
*
* `account` being the zero address is an alias for the caller's address.
*/
function getInterfaceImplementer(address account, bytes32 interfaceHash) external view returns (address);
/**
* @dev Returns the interface hash for an `interfaceName`, as defined in the
* corresponding
* https://eips.ethereum.org/EIPS/eip-1820#interface-name[section of the EIP].
*/
function interfaceHash(string calldata interfaceName) external pure returns (bytes32);
/**
* @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 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` 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` implements `interfaceId`, false otherwise.
*/
function implementsERC165InterfaceNoCache(address account, bytes4 interfaceId) external view returns (bool);
event InterfaceImplementerSet(address indexed account, bytes32 indexed interfaceHash, address indexed implementer);
event ManagerChanged(address indexed account, address indexed newManager);
}
= Introspection
[.readme-notice]
NOTE: This document is better viewed at https://docs.openzeppelin.com/contracts/api/introspection
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.
There are two main ways to approach this.
* Locally, where a contract implements `IERC165` and declares an interface, and a second one queries it directly via `ERC165Checker`.
* Globally, where a global and unique registry (`IERC1820Registry`) is used to register implementers of a certain interface (`IERC1820Implementer`). It is then the registry that is queried, which allows for more complex setups, like contracts implementing interfaces for externally-owned accounts.
Note that, in all cases, accounts simply _declare_ their interfaces, but they are not required to actually implement them. This mechanism can therefore be used to both prevent errors and allow for complex interactions (see `ERC777`), but it must not be relied on for security.
== Local
{{IERC165}}
{{ERC165}}
{{ERC165Checker}}
== Global
{{IERC1820Registry}}
{{IERC1820Implementer}}
{{ERC1820Implementer}}
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;
/**
* @dev Standard math utilities missing in the Solidity language.
*/
library MathUpgradeSafe {
/**
* @dev Returns the largest of two numbers.
*/
function max(uint256 a, uint256 b) internal pure returns (uint256) {
return a >= b ? a : b;
}
/**
* @dev Returns the smallest of two numbers.
*/
function min(uint256 a, uint256 b) internal pure returns (uint256) {
return a < b ? a : b;
}
/**
* @dev Returns the average of two numbers. The result is rounded towards
* zero.
*/
function average(uint256 a, uint256 b) internal pure returns (uint256) {
// (a + b) / 2 can overflow, so we distribute
return (a / 2) + (b / 2) + ((a % 2 + b % 2) / 2);
}
}
= Math
[.readme-notice]
NOTE: This document is better viewed at https://docs.openzeppelin.com/contracts/api/math
These are math-related utilities.
== Libraries
{{SafeMath}}
{{SignedSafeMath}}
{{Math}}
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;
/**
* @dev Wrappers over Solidity's arithmetic operations with added overflow
* checks.
*
* Arithmetic operations in Solidity wrap on overflow. This can easily result
* in bugs, because programmers usually assume that an overflow raises an
* error, which is the standard behavior in high level programming languages.
* `SafeMath` restores this intuition by reverting the transaction when an
* operation overflows.
*
* Using this library instead of the unchecked operations eliminates an entire
* class of bugs, so it's recommended to use it always.
*/
library SafeMathUpgradeSafe {
/**
* @dev Returns the addition of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `+` operator.
*
* Requirements:
*
* - Addition cannot overflow.
*/
function add(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a + b;
require(c >= a, "SafeMath: addition overflow");
return c;
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting on
* overflow (when the result is negative).
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
*
* - Subtraction cannot overflow.
*/
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
return sub(a, b, "SafeMath: subtraction overflow");
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting with custom message on
* overflow (when the result is negative).
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
*
* - Subtraction cannot overflow.
*/
function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b <= a, errorMessage);
uint256 c = a - b;
return c;
}
/**
* @dev Returns the multiplication of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `*` operator.
*
* Requirements:
*
* - Multiplication cannot overflow.
*/
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
// Gas optimization: this is cheaper than requiring 'a' not being zero, but the
// benefit is lost if 'b' is also tested.
// See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
if (a == 0) {
return 0;
}
uint256 c = a * b;
require(c / a == b, "SafeMath: multiplication overflow");
return c;
}
/**
* @dev Returns the integer division of two unsigned integers. Reverts on
* division by zero. The result is rounded towards zero.
*
* Counterpart to Solidity's `/` operator. Note: this function uses a
* `revert` opcode (which leaves remaining gas untouched) while Solidity
* uses an invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function div(uint256 a, uint256 b) internal pure returns (uint256) {
return div(a, b, "SafeMath: division by zero");
}
/**
* @dev Returns the integer division of two unsigned integers. Reverts with custom message on
* division by zero. The result is rounded towards zero.
*
* Counterpart to Solidity's `/` operator. Note: this function uses a
* `revert` opcode (which leaves remaining gas untouched) while Solidity
* uses an invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b > 0, errorMessage);
uint256 c = a / b;
// assert(a == b * c + a % b); // There is no case in which this doesn't hold
return c;
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* Reverts when dividing by zero.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function mod(uint256 a, uint256 b) internal pure returns (uint256) {
return mod(a, b, "SafeMath: modulo by zero");
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* Reverts with custom message when dividing by zero.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b != 0, errorMessage);
return a % b;
}
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;
/**
* @title SignedSafeMath
* @dev Signed math operations with safety checks that revert on error.
*/
library SignedSafeMathUpgradeSafe {
int256 constant private _INT256_MIN = -2**255;
/**
* @dev Returns the multiplication of two signed integers, reverting on
* overflow.
*
* Counterpart to Solidity's `*` operator.
*
* Requirements:
*
* - Multiplication cannot overflow.
*/
function mul(int256 a, int256 b) internal pure returns (int256) {
// Gas optimization: this is cheaper than requiring 'a' not being zero, but the
// benefit is lost if 'b' is also tested.
// See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
if (a == 0) {
return 0;
}
require(!(a == -1 && b == _INT256_MIN), "SignedSafeMath: multiplication overflow");
int256 c = a * b;
require(c / a == b, "SignedSafeMath: multiplication overflow");
return c;
}
/**
* @dev Returns the integer division of two signed integers. Reverts on
* division by zero. The result is rounded towards zero.
*
* Counterpart to Solidity's `/` operator. Note: this function uses a
* `revert` opcode (which leaves remaining gas untouched) while Solidity
* uses an invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
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");
int256 c = a / b;
return c;
}
/**
* @dev Returns the subtraction of two signed integers, reverting on
* overflow.
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
*
* - Subtraction cannot overflow.
*/
function sub(int256 a, int256 b) internal pure returns (int256) {
int256 c = a - b;
require((b >= 0 && c <= a) || (b < 0 && c > a), "SignedSafeMath: subtraction overflow");
return c;
}
/**
* @dev Returns the addition of two signed integers, reverting on
* overflow.
*
* Counterpart to Solidity's `+` operator.
*
* Requirements:
*
* - Addition cannot overflow.
*/
function add(int256 a, int256 b) internal pure returns (int256) {
int256 c = a + b;
require((b >= 0 && c >= a) || (b < 0 && c < a), "SignedSafeMath: addition overflow");
return c;
}
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;
import "../access/AccessControlUpgradeSafe.sol";
import "../Initializable.sol";
contract AccessControlMockUpgradeSafe is __Initializable, AccessControlUpgradeSafe {
function __AccessControlMock_init() internal __initializer {
__Context_init_unchained();
__AccessControl_init_unchained();
__AccessControlMock_init_unchained();
}
function __AccessControlMock_init_unchained() internal __initializer {
_setupRole(DEFAULT_ADMIN_ROLE, _msgSender());
}
function setRoleAdmin(bytes32 roleId, bytes32 adminRoleId) public {
_setRoleAdmin(roleId, adminRoleId);
}
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;
import "../utils/AddressUpgradeSafe.sol";
import "../Initializable.sol";
contract AddressImplUpgradeSafe is __Initializable {
function __AddressImpl_init() internal __initializer {
__AddressImpl_init_unchained();
}
function __AddressImpl_init_unchained() internal __initializer {
}
string public sharedAnswer;
event CallReturnValue(string data);
function isContract(address account) external view returns (bool) {
return AddressUpgradeSafe.isContract(account);
}
function sendValue(address payable receiver, uint256 amount) external {
AddressUpgradeSafe.sendValue(receiver, amount);
}
function functionCall(address target, bytes calldata data) external {
bytes memory returnData = AddressUpgradeSafe.functionCall(target, data);
emit CallReturnValue(abi.decode(returnData, (string)));
}
function functionCallWithValue(address target, bytes calldata data, uint256 value) external payable {
bytes memory returnData = AddressUpgradeSafe.functionCallWithValue(target, data, value);
emit CallReturnValue(abi.decode(returnData, (string)));
}
function functionStaticCall(address target, bytes calldata data) external {
bytes memory returnData = AddressUpgradeSafe.functionStaticCall(target, data);
emit CallReturnValue(abi.decode(returnData, (string)));
}
function functionDelegateCall(address target, bytes calldata data) external {
bytes memory returnData = AddressUpgradeSafe.functionDelegateCall(target, data);
emit CallReturnValue(abi.decode(returnData, (string)));
}
// sendValue's tests require the contract to hold Ether
receive () external payable { }
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;
import "../utils/ArraysUpgradeSafe.sol";
import "../Initializable.sol";
contract ArraysImplUpgradeSafe is __Initializable {
using ArraysUpgradeSafe for uint256[];
uint256[] private _array;
function __ArraysImpl_init(uint256[] memory array) internal __initializer {
__ArraysImpl_init_unchained(array);
}
function __ArraysImpl_init_unchained(uint256[] memory array) internal __initializer {
_array = array;
}
function findUpperBound(uint256 element) external view returns (uint256) {
return _array.findUpperBound(element);
}
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;
import "../Initializable.sol";
contract CallReceiverMockUpgradeSafe is __Initializable {
function __CallReceiverMock_init() internal __initializer {
__CallReceiverMock_init_unchained();
}
function __CallReceiverMock_init_unchained() internal __initializer {
}
string public sharedAnswer;
event MockFunctionCalled();
uint256[] private _array;
function mockFunction() public payable returns (string memory) {
emit MockFunctionCalled();
return "0x1234";
}
function mockFunctionNonPayable() public returns (string memory) {
emit MockFunctionCalled();
return "0x1234";
}
function mockStaticFunction() public pure returns (string memory) {
return "0x1234";
}
function mockFunctionRevertsNoReason() public payable {
revert();
}
function mockFunctionRevertsReason() public payable {
revert("CallReceiverMock: reverting");
}
function mockFunctionThrows() public payable {
assert(false);
}
function mockFunctionOutOfGas() public payable {
for (uint256 i = 0; ; ++i) {
_array.push(i);
}
}
function mockFunctionWritesStorage() public returns (string memory) {
sharedAnswer = "42";
return "0x1234";
}
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;
import "../Initializable.sol";
/**
* @dev Implementation contract with an admin() function made to clash with
* @dev TransparentUpgradeableProxy's to test correct functioning of the
* @dev Transparent Proxy feature.
*/
contract ClashingImplementationUpgradeSafe is __Initializable {
function __ClashingImplementation_init() internal __initializer {
__ClashingImplementation_init_unchained();
}
function __ClashingImplementation_init_unchained() internal __initializer {
}
function admin() external pure returns (address) {
return 0x0000000000000000000000000000000011111142;
}
function delegatedFunction() external pure returns (bool) {
return true;
}
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;
import "../payment/escrow/ConditionalEscrowUpgradeSafe.sol";
import "../Initializable.sol";
// mock class using ConditionalEscrow
contract ConditionalEscrowMockUpgradeSafe is __Initializable, ConditionalEscrowUpgradeSafe {
function __ConditionalEscrowMock_init() internal __initializer {
__Context_init_unchained();
__Ownable_init_unchained();
__Escrow_init_unchained();
__ConditionalEscrow_init_unchained();
__ConditionalEscrowMock_init_unchained();
}
function __ConditionalEscrowMock_init_unchained() internal __initializer {
}
mapping(address => bool) private _allowed;
function setAllowed(address payee, bool allowed) public {
_allowed[payee] = allowed;
}
function withdrawalAllowed(address payee) public view override returns (bool) {
return _allowed[payee];
}
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;
import "../GSN/ContextUpgradeSafe.sol";
import "../Initializable.sol";
contract ContextMockUpgradeSafe is __Initializable, ContextUpgradeSafe {
function __ContextMock_init() internal __initializer {
__Context_init_unchained();
__ContextMock_init_unchained();
}
function __ContextMock_init_unchained() internal __initializer {
}
event Sender(address sender);
function msgSender() public {
emit Sender(_msgSender());
}
event Data(bytes data, uint256 integerValue, string stringValue);
function msgData(uint256 integerValue, string memory stringValue) public {
emit Data(_msgData(), integerValue, stringValue);
}
}
contract ContextMockCallerUpgradeSafe is __Initializable {
function __ContextMockCaller_init() internal __initializer {
__ContextMockCaller_init_unchained();
}
function __ContextMockCaller_init_unchained() internal __initializer {
}
function callSender(ContextMockUpgradeSafe context) public {
context.msgSender();
}
function callData(ContextMockUpgradeSafe context, uint256 integerValue, string memory stringValue) public {
context.msgData(integerValue, stringValue);
}
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;
import "../utils/CountersUpgradeSafe.sol";
import "../Initializable.sol";
contract CountersImplUpgradeSafe is __Initializable {
function __CountersImpl_init() internal __initializer {
__CountersImpl_init_unchained();
}
function __CountersImpl_init_unchained() internal __initializer {
}
using CountersUpgradeSafe for CountersUpgradeSafe.Counter;
CountersUpgradeSafe.Counter private _counter;
function current() public view returns (uint256) {
return _counter.current();
}
function increment() public {
_counter.increment();
}
function decrement() public {
_counter.decrement();
}
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;
import "../utils/Create2UpgradeSafe.sol";
import "../introspection/ERC1820ImplementerUpgradeSafe.sol";
import "../Initializable.sol";
contract Create2ImplUpgradeSafe is __Initializable {
function __Create2Impl_init() internal __initializer {
__Create2Impl_init_unchained();
}
function __Create2Impl_init_unchained() internal __initializer {
}
function deploy(uint256 value, bytes32 salt, bytes memory code) public {
Create2UpgradeSafe.deploy(value, salt, code);
}
function deployERC1820Implementer(uint256 value, bytes32 salt) public {
// solhint-disable-next-line indent
Create2UpgradeSafe.deploy(value, salt, type(ERC1820ImplementerUpgradeSafe).creationCode);
}
function computeAddress(bytes32 salt, bytes32 codeHash) public view returns (address) {
return Create2UpgradeSafe.computeAddress(salt, codeHash);
}
function computeAddressWithDeployer(bytes32 salt, bytes32 codeHash, address deployer) public pure returns (address) {
return Create2UpgradeSafe.computeAddress(salt, codeHash, deployer);
}
receive() payable external {}
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;
import "../Initializable.sol";
abstract contract ImplUpgradeSafe is __Initializable {
function __Impl_init() internal __initializer {
__Impl_init_unchained();
}
function __Impl_init_unchained() internal __initializer {
}
function version() public pure virtual returns (string memory);
}
contract DummyImplementationUpgradeSafe is __Initializable {
function __DummyImplementation_init() internal __initializer {
__DummyImplementation_init_unchained();
}
function __DummyImplementation_init_unchained() internal __initializer {
}
uint256 public value;
string public text;
uint256[] public values;
function initializeNonPayable() public {
value = 10;
}
function initializePayable() payable public {
value = 100;
}
function initializeNonPayable(uint256 _value) public {
value = _value;
}
function initializePayable(uint256 _value) payable public {
value = _value;
}
function initialize(uint256 _value, string memory _text, uint256[] memory _values) public {
value = _value;
text = _text;
values = _values;
}
function get() public pure returns (bool) {
return true;
}
function version() public pure virtual returns (string memory) {
return "V1";
}
function reverts() public pure {
require(false);
}
}
contract DummyImplementationV2UpgradeSafe is __Initializable, DummyImplementationUpgradeSafe {
function __DummyImplementationV2_init() internal __initializer {
__DummyImplementation_init_unchained();
__DummyImplementationV2_init_unchained();
}
function __DummyImplementationV2_init_unchained() internal __initializer {
}
function migrate(uint256 newVal) payable public {
value = newVal;
}
function version() public pure override returns (string memory) {
return "V2";
}
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;
import "../cryptography/ECDSAUpgradeSafe.sol";
import "../Initializable.sol";
contract ECDSAMockUpgradeSafe is __Initializable {
function __ECDSAMock_init() internal __initializer {
__ECDSAMock_init_unchained();
}
function __ECDSAMock_init_unchained() internal __initializer {
}
using ECDSAUpgradeSafe for bytes32;
function recover(bytes32 hash, bytes memory signature) public pure returns (address) {
return hash.recover(signature);
}
function toEthSignedMessageHash(bytes32 hash) public pure returns (bytes32) {
return hash.toEthSignedMessageHash();
}
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;
import "../token/ERC1155/ERC1155BurnableUpgradeSafe.sol";
import "../Initializable.sol";
contract ERC1155BurnableMockUpgradeSafe is __Initializable, ERC1155BurnableUpgradeSafe {
function __ERC1155BurnableMock_init(string memory uri) internal __initializer {
__Context_init_unchained();
__ERC165_init_unchained();
__ERC1155_init_unchained(uri);
__ERC1155Burnable_init_unchained();
__ERC1155BurnableMock_init_unchained(uri);
}
function __ERC1155BurnableMock_init_unchained(string memory uri) internal __initializer { }
function mint(address to, uint256 id, uint256 value, bytes memory data) public {
_mint(to, id, value, data);
}
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;
import "../token/ERC1155/ERC1155UpgradeSafe.sol";
import "../Initializable.sol";
/**
* @title ERC1155Mock
* This mock just publicizes internal functions for testing purposes
*/
contract ERC1155MockUpgradeSafe is __Initializable, ERC1155UpgradeSafe {
function __ERC1155Mock_init(string memory uri) internal __initializer {
__Context_init_unchained();
__ERC165_init_unchained();
__ERC1155_init_unchained(uri);
__ERC1155Mock_init_unchained(uri);
}
function __ERC1155Mock_init_unchained(string memory uri) internal __initializer {
// solhint-disable-previous-line no-empty-blocks
}
function setURI(string memory newuri) public {
_setURI(newuri);
}
function mint(address to, uint256 id, uint256 value, bytes memory data) public {
_mint(to, id, value, data);
}
function mintBatch(address to, uint256[] memory ids, uint256[] memory values, bytes memory data) public {
_mintBatch(to, ids, values, data);
}
function burn(address owner, uint256 id, uint256 value) public {
_burn(owner, id, value);
}
function burnBatch(address owner, uint256[] memory ids, uint256[] memory values) public {
_burnBatch(owner, ids, values);
}
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;
import "./ERC1155MockUpgradeSafe.sol";
import "../token/ERC1155/ERC1155PausableUpgradeSafe.sol";
import "../Initializable.sol";
contract ERC1155PausableMockUpgradeSafe is __Initializable, ERC1155MockUpgradeSafe, ERC1155PausableUpgradeSafe {
function __ERC1155PausableMock_init(string memory uri) internal __initializer {
__Context_init_unchained();
__ERC165_init_unchained();
__ERC1155_init_unchained(uri);
__ERC1155Mock_init_unchained(uri);
__Pausable_init_unchained();
__ERC1155Pausable_init_unchained();
__ERC1155PausableMock_init_unchained(uri);
}
function __ERC1155PausableMock_init_unchained(string memory uri) internal __initializer { }
function pause() external {
_pause();
}
function unpause() external {
_unpause();
}
function _beforeTokenTransfer(
address operator,
address from,
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory data
)
internal virtual override(ERC1155UpgradeSafe, ERC1155PausableUpgradeSafe)
{
super._beforeTokenTransfer(operator, from, to, ids, amounts, data);
}
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;
import "../token/ERC1155/IERC1155ReceiverUpgradeSafe.sol";
import "./ERC165MockUpgradeSafe.sol";
import "../Initializable.sol";
contract ERC1155ReceiverMockUpgradeSafe is __Initializable, IERC1155ReceiverUpgradeSafe, ERC165MockUpgradeSafe {
bytes4 private _recRetval;
bool private _recReverts;
bytes4 private _batRetval;
bool private _batReverts;
event Received(address operator, address from, uint256 id, uint256 value, bytes data, uint256 gas);
event BatchReceived(address operator, address from, uint256[] ids, uint256[] values, bytes data, uint256 gas);
function __ERC1155ReceiverMock_init(
bytes4 recRetval,
bool recReverts,
bytes4 batRetval,
bool batReverts
) internal __initializer {
__ERC165_init_unchained();
__ERC165Mock_init_unchained();
__ERC1155ReceiverMock_init_unchained(recRetval, recReverts, batRetval, batReverts);
}
function __ERC1155ReceiverMock_init_unchained(
bytes4 recRetval,
bool recReverts,
bytes4 batRetval,
bool batReverts
) internal __initializer {
_recRetval = recRetval;
_recReverts = recReverts;
_batRetval = batRetval;
_batReverts = batReverts;
}
function onERC1155Received(
address operator,
address from,
uint256 id,
uint256 value,
bytes calldata data
)
external
override
returns(bytes4)
{
require(!_recReverts, "ERC1155ReceiverMock: reverting on receive");
emit Received(operator, from, id, value, data, gasleft());
return _recRetval;
}
function onERC1155BatchReceived(
address operator,
address from,
uint256[] calldata ids,
uint256[] calldata values,
bytes calldata data
)
external
override
returns(bytes4)
{
require(!_batReverts, "ERC1155ReceiverMock: reverting on batch receive");
emit BatchReceived(operator, from, ids, values, data, gasleft());
return _batRetval;
}
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;
import "../../introspection/IERC165UpgradeSafe.sol";
import "../../Initializable.sol";
/**
* https://eips.ethereum.org/EIPS/eip-214#specification
* From the specification:
* > Any attempts to make state-changing operations inside an execution instance with STATIC set to true will instead
* throw an exception.
* > These operations include [...], LOG0, LOG1, LOG2, [...]
*
* therefore, because this contract is staticcall'd we need to not emit events (which is how solidity-coverage works)
* solidity-coverage ignores the /mocks folder, so we duplicate its implementation here to avoid instrumenting it
*/
contract SupportsInterfaceWithLookupMockUpgradeSafe is __Initializable, IERC165UpgradeSafe {
/*
* 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.
*/
mapping(bytes4 => bool) private _supportedInterfaces;
/**
* @dev A contract implementing SupportsInterfaceWithLookup
* implement ERC165 itself.
*/
function __SupportsInterfaceWithLookupMock_init() internal __initializer {
__SupportsInterfaceWithLookupMock_init_unchained();
}
function __SupportsInterfaceWithLookupMock_init_unchained() internal __initializer {
_registerInterface(INTERFACE_ID_ERC165);
}
/**
* @dev Implement supportsInterface(bytes4) using a lookup table.
*/
function supportsInterface(bytes4 interfaceId) public view override returns (bool) {
return _supportedInterfaces[interfaceId];
}
/**
* @dev Private method for registering an interface.
*/
function _registerInterface(bytes4 interfaceId) internal {
require(interfaceId != 0xffffffff, "ERC165InterfacesSupported: invalid interface id");
_supportedInterfaces[interfaceId] = true;
}
}
contract ERC165InterfacesSupportedUpgradeSafe is __Initializable, SupportsInterfaceWithLookupMockUpgradeSafe {
function __ERC165InterfacesSupported_init(bytes4[] memory interfaceIds) internal __initializer {
__SupportsInterfaceWithLookupMock_init_unchained();
__ERC165InterfacesSupported_init_unchained(interfaceIds);
}
function __ERC165InterfacesSupported_init_unchained(bytes4[] memory interfaceIds) internal __initializer {
for (uint256 i = 0; i < interfaceIds.length; i++) {
_registerInterface(interfaceIds[i]);
}
}
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;
import "../../Initializable.sol";
contract ERC165NotSupportedUpgradeSafe is __Initializable { function __ERC165NotSupported_init() internal __initializer {
__ERC165NotSupported_init_unchained();
}
function __ERC165NotSupported_init_unchained() internal __initializer {
}
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;
import "../introspection/ERC165CheckerUpgradeSafe.sol";
import "../Initializable.sol";
contract ERC165CheckerMockUpgradeSafe is __Initializable {
function __ERC165CheckerMock_init() internal __initializer {
__ERC165CheckerMock_init_unchained();
}
function __ERC165CheckerMock_init_unchained() internal __initializer {
}
using ERC165CheckerUpgradeSafe for address;
function supportsERC165(address account) public view returns (bool) {
return account.supportsERC165();
}
function supportsInterface(address account, bytes4 interfaceId) public view returns (bool) {
return account.supportsInterface(interfaceId);
}
function supportsAllInterfaces(address account, bytes4[] memory interfaceIds) public view returns (bool) {
return account.supportsAllInterfaces(interfaceIds);
}
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;
import "../introspection/ERC165UpgradeSafe.sol";
import "../Initializable.sol";
contract ERC165MockUpgradeSafe is __Initializable, ERC165UpgradeSafe {
function __ERC165Mock_init() internal __initializer {
__ERC165_init_unchained();
__ERC165Mock_init_unchained();
}
function __ERC165Mock_init_unchained() internal __initializer {
}
function registerInterface(bytes4 interfaceId) public {
_registerInterface(interfaceId);
}
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;
import "../introspection/ERC1820ImplementerUpgradeSafe.sol";
import "../Initializable.sol";
contract ERC1820ImplementerMockUpgradeSafe is __Initializable, ERC1820ImplementerUpgradeSafe {
function __ERC1820ImplementerMock_init() internal __initializer {
__ERC1820Implementer_init_unchained();
__ERC1820ImplementerMock_init_unchained();
}
function __ERC1820ImplementerMock_init_unchained() internal __initializer {
}
function registerInterfaceForAddress(bytes32 interfaceHash, address account) public {
_registerInterfaceForAddress(interfaceHash, account);
}
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;
import "../token/ERC20/ERC20BurnableUpgradeSafe.sol";
import "../Initializable.sol";
contract ERC20BurnableMockUpgradeSafe is __Initializable, ERC20BurnableUpgradeSafe {
function __ERC20BurnableMock_init(
string memory name,
string memory symbol,
address initialAccount,
uint256 initialBalance
) internal __initializer {
__Context_init_unchained();
__ERC20_init_unchained(name, symbol);
__ERC20Burnable_init_unchained();
__ERC20BurnableMock_init_unchained(name, symbol, initialAccount, initialBalance);
}
function __ERC20BurnableMock_init_unchained(
string memory name,
string memory symbol,
address initialAccount,
uint256 initialBalance
) internal __initializer {
_mint(initialAccount, initialBalance);
}
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;
import "../token/ERC20/ERC20CappedUpgradeSafe.sol";
import "../Initializable.sol";
contract ERC20CappedMockUpgradeSafe is __Initializable, ERC20CappedUpgradeSafe {
function __ERC20CappedMock_init(string memory name, string memory symbol, uint256 cap) internal __initializer {
__Context_init_unchained();
__ERC20_init_unchained(name, symbol);
__ERC20Capped_init_unchained(cap);
__ERC20CappedMock_init_unchained(name, symbol, cap);
}
function __ERC20CappedMock_init_unchained(string memory name, string memory symbol, uint256 cap) internal __initializer { }
function mint(address to, uint256 tokenId) public {
_mint(to, tokenId);
}
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;
import "../token/ERC20/ERC20UpgradeSafe.sol";
import "../Initializable.sol";
contract ERC20DecimalsMockUpgradeSafe is __Initializable, ERC20UpgradeSafe {
function __ERC20DecimalsMock_init(string memory name, string memory symbol, uint8 decimals) internal __initializer {
__Context_init_unchained();
__ERC20_init_unchained(name, symbol);
__ERC20DecimalsMock_init_unchained(name, symbol, decimals);
}
function __ERC20DecimalsMock_init_unchained(string memory name, string memory symbol, uint8 decimals) internal __initializer {
_setupDecimals(decimals);
}
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;
import "../token/ERC20/ERC20UpgradeSafe.sol";
import "../Initializable.sol";
// mock class using ERC20
contract ERC20MockUpgradeSafe is __Initializable, ERC20UpgradeSafe {
function __ERC20Mock_init(
string memory name,
string memory symbol,
address initialAccount,
uint256 initialBalance
) internal __initializer {
__Context_init_unchained();
__ERC20_init_unchained(name, symbol);
__ERC20Mock_init_unchained(name, symbol, initialAccount, initialBalance);
}
function __ERC20Mock_init_unchained(
string memory name,
string memory symbol,
address initialAccount,
uint256 initialBalance
) internal __initializer {
_mint(initialAccount, initialBalance);
}
function mint(address account, uint256 amount) public {
_mint(account, amount);
}
function burn(address account, uint256 amount) public {
_burn(account, amount);
}
function transferInternal(address from, address to, uint256 value) public {
_transfer(from, to, value);
}
function approveInternal(address owner, address spender, uint256 value) public {
_approve(owner, spender, value);
}
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;
import "../token/ERC20/ERC20PausableUpgradeSafe.sol";
import "../Initializable.sol";
// mock class using ERC20Pausable
contract ERC20PausableMockUpgradeSafe is __Initializable, ERC20PausableUpgradeSafe {
function __ERC20PausableMock_init(
string memory name,
string memory symbol,
address initialAccount,
uint256 initialBalance
) internal __initializer {
__Context_init_unchained();
__ERC20_init_unchained(name, symbol);
__Pausable_init_unchained();
__ERC20Pausable_init_unchained();
__ERC20PausableMock_init_unchained(name, symbol, initialAccount, initialBalance);
}
function __ERC20PausableMock_init_unchained(
string memory name,
string memory symbol,
address initialAccount,
uint256 initialBalance
) internal __initializer {
_mint(initialAccount, initialBalance);
}
function pause() external {
_pause();
}
function unpause() external {
_unpause();
}
function mint(address to, uint256 amount) public {
_mint(to, amount);
}
function burn(address from, uint256 amount) public {
_burn(from, amount);
}
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;
import "../token/ERC20/ERC20SnapshotUpgradeSafe.sol";
import "../Initializable.sol";
contract ERC20SnapshotMockUpgradeSafe is __Initializable, ERC20SnapshotUpgradeSafe {
function __ERC20SnapshotMock_init(
string memory name,
string memory symbol,
address initialAccount,
uint256 initialBalance
) internal __initializer {
__Context_init_unchained();
__ERC20_init_unchained(name, symbol);
__ERC20Snapshot_init_unchained();
__ERC20SnapshotMock_init_unchained(name, symbol, initialAccount, initialBalance);
}
function __ERC20SnapshotMock_init_unchained(
string memory name,
string memory symbol,
address initialAccount,
uint256 initialBalance
) internal __initializer {
_mint(initialAccount, initialBalance);
}
function snapshot() public {
_snapshot();
}
function mint(address account, uint256 amount) public {
_mint(account, amount);
}
function burn(address account, uint256 amount) public {
_burn(account, amount);
}
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;
import "../token/ERC721/ERC721BurnableUpgradeSafe.sol";
import "../Initializable.sol";
contract ERC721BurnableMockUpgradeSafe is __Initializable, ERC721BurnableUpgradeSafe {
function __ERC721BurnableMock_init(string memory name, string memory symbol) internal __initializer {
__Context_init_unchained();
__ERC165_init_unchained();
__ERC721_init_unchained(name, symbol);
__ERC721Burnable_init_unchained();
__ERC721BurnableMock_init_unchained(name, symbol);
}
function __ERC721BurnableMock_init_unchained(string memory name, string memory symbol) internal __initializer { }
function mint(address to, uint256 tokenId) public {
_mint(to, tokenId);
}
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;
import "../token/ERC721/ERC721UpgradeSafe.sol";
import "../GSN/GSNRecipientUpgradeSafe.sol";
import "../GSN/GSNRecipientSignatureUpgradeSafe.sol";
import "../Initializable.sol";
/**
* @title ERC721GSNRecipientMock
* A simple ERC721 mock that has GSN support enabled
*/
contract ERC721GSNRecipientMockUpgradeSafe is __Initializable, ERC721UpgradeSafe, GSNRecipientUpgradeSafe, GSNRecipientSignatureUpgradeSafe {
function __ERC721GSNRecipientMock_init(string memory name, string memory symbol, address trustedSigner) internal __initializer {
__Context_init_unchained();
__ERC165_init_unchained();
__ERC721_init_unchained(name, symbol);
__GSNRecipient_init_unchained();
__GSNRecipientSignature_init_unchained(trustedSigner);
__ERC721GSNRecipientMock_init_unchained(name, symbol, trustedSigner);
}
function __ERC721GSNRecipientMock_init_unchained(string memory name, string memory symbol, address trustedSigner) internal __initializer { }
function mint(uint256 tokenId) public {
_mint(_msgSender(), tokenId);
}
function _msgSender() internal view override(ContextUpgradeSafe, GSNRecipientUpgradeSafe) returns (address payable) {
return GSNRecipientUpgradeSafe._msgSender();
}
function _msgData() internal view override(ContextUpgradeSafe, GSNRecipientUpgradeSafe) returns (bytes memory) {
return GSNRecipientUpgradeSafe._msgData();
}
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;
import "../token/ERC721/ERC721UpgradeSafe.sol";
import "../Initializable.sol";
/**
* @title ERC721Mock
* This mock just provides a public safeMint, mint, and burn functions for testing purposes
*/
contract ERC721MockUpgradeSafe is __Initializable, ERC721UpgradeSafe {
function __ERC721Mock_init(string memory name, string memory symbol) internal __initializer {
__Context_init_unchained();
__ERC165_init_unchained();
__ERC721_init_unchained(name, symbol);
__ERC721Mock_init_unchained(name, symbol);
}
function __ERC721Mock_init_unchained(string memory name, string memory symbol) internal __initializer { }
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);
}
function safeMint(address to, uint256 tokenId, bytes memory _data) public {
_safeMint(to, tokenId, _data);
}
function burn(uint256 tokenId) public {
_burn(tokenId);
}
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;
import "../token/ERC721/ERC721PausableUpgradeSafe.sol";
import "../Initializable.sol";
/**
* @title ERC721PausableMock
* This mock just provides a public mint, burn and exists functions for testing purposes
*/
contract ERC721PausableMockUpgradeSafe is __Initializable, ERC721PausableUpgradeSafe {
function __ERC721PausableMock_init(string memory name, string memory symbol) internal __initializer {
__Context_init_unchained();
__ERC165_init_unchained();
__ERC721_init_unchained(name, symbol);
__Pausable_init_unchained();
__ERC721Pausable_init_unchained();
__ERC721PausableMock_init_unchained(name, symbol);
}
function __ERC721PausableMock_init_unchained(string memory name, string memory symbol) internal __initializer { }
function mint(address to, uint256 tokenId) public {
super._mint(to, tokenId);
}
function burn(uint256 tokenId) public {
super._burn(tokenId);
}
function exists(uint256 tokenId) public view returns (bool) {
return super._exists(tokenId);
}
function pause() external {
_pause();
}
function unpause() external {
_unpause();
}
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;
import "../token/ERC721/IERC721ReceiverUpgradeSafe.sol";
import "../Initializable.sol";
contract ERC721ReceiverMockUpgradeSafe is __Initializable, IERC721ReceiverUpgradeSafe {
bytes4 private _retval;
bool private _reverts;
event Received(address operator, address from, uint256 tokenId, bytes data, uint256 gas);
function __ERC721ReceiverMock_init(bytes4 retval, bool reverts) internal __initializer {
__ERC721ReceiverMock_init_unchained(retval, reverts);
}
function __ERC721ReceiverMock_init_unchained(bytes4 retval, bool reverts) internal __initializer {
_retval = retval;
_reverts = reverts;
}
function onERC721Received(address operator, address from, uint256 tokenId, bytes memory data)
public override returns (bytes4)
{
require(!_reverts, "ERC721ReceiverMock: reverting");
emit Received(operator, from, tokenId, data, gasleft());
return _retval;
}
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;
import "../GSN/ContextUpgradeSafe.sol";
import "../token/ERC777/ERC777UpgradeSafe.sol";
import "../Initializable.sol";
contract ERC777MockUpgradeSafe is __Initializable, ContextUpgradeSafe, ERC777UpgradeSafe {
function __ERC777Mock_init(
address initialHolder,
uint256 initialBalance,
string memory name,
string memory symbol,
address[] memory defaultOperators
) internal __initializer {
__Context_init_unchained();
__ERC777_init_unchained(name, symbol, defaultOperators);
__ERC777Mock_init_unchained(initialHolder, initialBalance, name, symbol, defaultOperators);
}
function __ERC777Mock_init_unchained(
address initialHolder,
uint256 initialBalance,
string memory name,
string memory symbol,
address[] memory defaultOperators
) internal __initializer {
_mint(initialHolder, initialBalance, "", "");
}
function mintInternal (
address to,
uint256 amount,
bytes memory userData,
bytes memory operatorData
) public {
_mint(to, amount, userData, operatorData);
}
function approveInternal(address holder, address spender, uint256 value) public {
_approve(holder, spender, value);
}
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;
import "../GSN/ContextUpgradeSafe.sol";
import "../token/ERC777/IERC777UpgradeSafe.sol";
import "../token/ERC777/IERC777SenderUpgradeSafe.sol";
import "../token/ERC777/IERC777RecipientUpgradeSafe.sol";
import "../introspection/IERC1820RegistryUpgradeSafe.sol";
import "../introspection/ERC1820ImplementerUpgradeSafe.sol";
import "../Initializable.sol";
contract ERC777SenderRecipientMockUpgradeSafe is __Initializable, ContextUpgradeSafe, IERC777SenderUpgradeSafe, IERC777RecipientUpgradeSafe, ERC1820ImplementerUpgradeSafe {
function __ERC777SenderRecipientMock_init() internal __initializer {
__Context_init_unchained();
__ERC1820Implementer_init_unchained();
__ERC777SenderRecipientMock_init_unchained();
}
function __ERC777SenderRecipientMock_init_unchained() internal __initializer {
_erc1820 = IERC1820RegistryUpgradeSafe(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);
}
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;
IERC1820RegistryUpgradeSafe private _erc1820;
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,
uint256 amount,
bytes calldata userData,
bytes calldata operatorData
) external override {
if (_shouldRevertSend) {
revert();
}
IERC777UpgradeSafe token = IERC777UpgradeSafe(_msgSender());
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,
uint256 amount,
bytes calldata userData,
bytes calldata operatorData
) external override {
if (_shouldRevertReceive) {
revert();
}
IERC777UpgradeSafe token = IERC777UpgradeSafe(_msgSender());
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(IERC777UpgradeSafe 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(IERC777UpgradeSafe token, uint256 amount, bytes memory data) public {
token.burn(amount, data);
}
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;
import "../utils/EnumerableMapUpgradeSafe.sol";
import "../Initializable.sol";
contract EnumerableMapMockUpgradeSafe is __Initializable {
function __EnumerableMapMock_init() internal __initializer {
__EnumerableMapMock_init_unchained();
}
function __EnumerableMapMock_init_unchained() internal __initializer {
}
using EnumerableMapUpgradeSafe for EnumerableMapUpgradeSafe.UintToAddressMap;
event OperationResult(bool result);
EnumerableMapUpgradeSafe.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);
}
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;
import "../utils/EnumerableSetUpgradeSafe.sol";
import "../Initializable.sol";
// Bytes32Set
contract EnumerableBytes32SetMockUpgradeSafe is __Initializable {
function __EnumerableBytes32SetMock_init() internal __initializer {
__EnumerableBytes32SetMock_init_unchained();
}
function __EnumerableBytes32SetMock_init_unchained() internal __initializer {
}
using EnumerableSetUpgradeSafe for EnumerableSetUpgradeSafe.Bytes32Set;
event OperationResult(bool result);
EnumerableSetUpgradeSafe.Bytes32Set private _set;
function contains(bytes32 value) public view returns (bool) {
return _set.contains(value);
}
function add(bytes32 value) public {
bool result = _set.add(value);
emit OperationResult(result);
}
function remove(bytes32 value) public {
bool result = _set.remove(value);
emit OperationResult(result);
}
function length() public view returns (uint256) {
return _set.length();
}
function at(uint256 index) public view returns (bytes32) {
return _set.at(index);
}
}
// AddressSet
contract EnumerableAddressSetMockUpgradeSafe is __Initializable {
function __EnumerableAddressSetMock_init() internal __initializer {
__EnumerableAddressSetMock_init_unchained();
}
function __EnumerableAddressSetMock_init_unchained() internal __initializer {
}
using EnumerableSetUpgradeSafe for EnumerableSetUpgradeSafe.AddressSet;
event OperationResult(bool result);
EnumerableSetUpgradeSafe.AddressSet private _set;
function contains(address value) public view returns (bool) {
return _set.contains(value);
}
function add(address value) public {
bool result = _set.add(value);
emit OperationResult(result);
}
function remove(address value) public {
bool result = _set.remove(value);
emit OperationResult(result);
}
function length() public view returns (uint256) {
return _set.length();
}
function at(uint256 index) public view returns (address) {
return _set.at(index);
}
}
// UintSet
contract EnumerableUintSetMockUpgradeSafe is __Initializable {
function __EnumerableUintSetMock_init() internal __initializer {
__EnumerableUintSetMock_init_unchained();
}
function __EnumerableUintSetMock_init_unchained() internal __initializer {
}
using EnumerableSetUpgradeSafe for EnumerableSetUpgradeSafe.UintSet;
event OperationResult(bool result);
EnumerableSetUpgradeSafe.UintSet private _set;
function contains(uint256 value) public view returns (bool) {
return _set.contains(value);
}
function add(uint256 value) public {
bool result = _set.add(value);
emit OperationResult(result);
}
function remove(uint256 value) public {
bool result = _set.remove(value);
emit OperationResult(result);
}
function length() public view returns (uint256) {
return _set.length();
}
function at(uint256 index) public view returns (uint256) {
return _set.at(index);
}
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;
import "../Initializable.sol";
contract EtherReceiverMockUpgradeSafe is __Initializable {
function __EtherReceiverMock_init() internal __initializer {
__EtherReceiverMock_init_unchained();
}
function __EtherReceiverMock_init_unchained() internal __initializer {
}
bool private _acceptEther;
function setAcceptEther(bool acceptEther) public {
_acceptEther = acceptEther;
}
receive () external payable {
if (!_acceptEther) {
revert();
}
}
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;
import "../GSN/GSNRecipientUpgradeSafe.sol";
import "../GSN/GSNRecipientERC20FeeUpgradeSafe.sol";
import "../Initializable.sol";
contract GSNRecipientERC20FeeMockUpgradeSafe is __Initializable, GSNRecipientUpgradeSafe, GSNRecipientERC20FeeUpgradeSafe {
function __GSNRecipientERC20FeeMock_init(string memory name, string memory symbol) internal __initializer {
__Context_init_unchained();
__GSNRecipient_init_unchained();
__GSNRecipientERC20Fee_init_unchained(name, symbol);
__GSNRecipientERC20FeeMock_init_unchained(name, symbol);
}
function __GSNRecipientERC20FeeMock_init_unchained(string memory name, string memory symbol) internal __initializer { }
function mint(address account, uint256 amount) public {
_mint(account, amount);
}
event MockFunctionCalled(uint256 senderBalance);
function mockFunction() public {
emit MockFunctionCalled(token().balanceOf(_msgSender()));
}
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;
import "./ContextMockUpgradeSafe.sol";
import "../GSN/GSNRecipientUpgradeSafe.sol";
import "../Initializable.sol";
// By inheriting from GSNRecipient, Context's internal functions are overridden automatically
contract GSNRecipientMockUpgradeSafe is __Initializable, ContextMockUpgradeSafe, GSNRecipientUpgradeSafe {
function __GSNRecipientMock_init() internal __initializer {
__Context_init_unchained();
__ContextMock_init_unchained();
__GSNRecipient_init_unchained();
__GSNRecipientMock_init_unchained();
}
function __GSNRecipientMock_init_unchained() internal __initializer {
}
function withdrawDeposits(uint256 amount, address payable payee) public {
_withdrawDeposits(amount, payee);
}
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 override returns (bytes32) { }
function _postRelayedCall(bytes memory, bool, uint256, bytes32) internal override { }
function upgradeRelayHub(address newRelayHub) public {
return _upgradeRelayHub(newRelayHub);
}
function _msgSender() internal override(ContextUpgradeSafe, GSNRecipientUpgradeSafe) view virtual returns (address payable) {
return GSNRecipientUpgradeSafe._msgSender();
}
function _msgData() internal override(ContextUpgradeSafe, GSNRecipientUpgradeSafe) view virtual returns (bytes memory) {
return GSNRecipientUpgradeSafe._msgData();
}
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;
import "../GSN/GSNRecipientUpgradeSafe.sol";
import "../GSN/GSNRecipientSignatureUpgradeSafe.sol";
import "../Initializable.sol";
contract GSNRecipientSignatureMockUpgradeSafe is __Initializable, GSNRecipientUpgradeSafe, GSNRecipientSignatureUpgradeSafe {
function __GSNRecipientSignatureMock_init(address trustedSigner) internal __initializer {
__Context_init_unchained();
__GSNRecipient_init_unchained();
__GSNRecipientSignature_init_unchained(trustedSigner);
__GSNRecipientSignatureMock_init_unchained(trustedSigner);
}
function __GSNRecipientSignatureMock_init_unchained(address trustedSigner) internal __initializer { }
event MockFunctionCalled();
function mockFunction() public {
emit MockFunctionCalled();
}
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;
import "../proxy/InitializableUpgradeSafe.sol";
import "../Initializable.sol";
/**
* @title InitializableMock
* @dev This contract is a mock to test initializable functionality
*/
contract InitializableMockUpgradeSafe is __Initializable, InitializableUpgradeSafe {
function __InitializableMock_init() internal __initializer {
__Initializable_init_unchained();
__InitializableMock_init_unchained();
}
function __InitializableMock_init_unchained() internal __initializer {
}
bool public initializerRan;
uint256 public x;
function initialize() public initializer {
initializerRan = true;
}
function initializeNested() public initializer {
initialize();
}
function initializeWithX(uint256 _x) public payable initializer {
x = _x;
}
function nonInitializable(uint256 _x) public payable {
x = _x;
}
function fail() public pure {
require(false, "InitializableMock forced failure");
}
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;
import "../math/MathUpgradeSafe.sol";
import "../Initializable.sol";
contract MathMockUpgradeSafe is __Initializable {
function __MathMock_init() internal __initializer {
__MathMock_init_unchained();
}
function __MathMock_init_unchained() internal __initializer {
}
function max(uint256 a, uint256 b) public pure returns (uint256) {
return MathUpgradeSafe.max(a, b);
}
function min(uint256 a, uint256 b) public pure returns (uint256) {
return MathUpgradeSafe.min(a, b);
}
function average(uint256 a, uint256 b) public pure returns (uint256) {
return MathUpgradeSafe.average(a, b);
}
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;
import { MerkleProofUpgradeSafe } from "../cryptography/MerkleProofUpgradeSafe.sol";
import "../Initializable.sol";
contract MerkleProofWrapperUpgradeSafe is __Initializable {
function __MerkleProofWrapper_init() internal __initializer {
__MerkleProofWrapper_init_unchained();
}
function __MerkleProofWrapper_init_unchained() internal __initializer {
}
function verify(bytes32[] memory proof, bytes32 root, bytes32 leaf) public pure returns (bool) {
return MerkleProofUpgradeSafe.verify(proof, root, leaf);
}
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;
import "../proxy/InitializableUpgradeSafe.sol";
import "../Initializable.sol";
// Sample contracts showing upgradeability with multiple inheritance.
// Child contract inherits from Father and Mother contracts, and Father extends from Gramps.
//
// Human
// / \
// | Gramps
// | |
// Mother Father
// | |
// -- Child --
/**
* Sample base intializable contract that is a human
*/
contract SampleHumanUpgradeSafe is __Initializable, InitializableUpgradeSafe {
function __SampleHuman_init() internal __initializer {
__Initializable_init_unchained();
__SampleHuman_init_unchained();
}
function __SampleHuman_init_unchained() internal __initializer {
}
bool public isHuman;
function initialize() public initializer {
isHuman = true;
}
}
/**
* Sample base intializable contract that defines a field mother
*/
contract SampleMotherUpgradeSafe is __Initializable, InitializableUpgradeSafe, SampleHumanUpgradeSafe {
function __SampleMother_init() internal __initializer {
__Initializable_init_unchained();
__SampleHuman_init_unchained();
__SampleMother_init_unchained();
}
function __SampleMother_init_unchained() internal __initializer {
}
uint256 public mother;
function initialize(uint256 value) public initializer virtual {
SampleHumanUpgradeSafe.initialize();
mother = value;
}
}
/**
* Sample base intializable contract that defines a field gramps
*/
contract SampleGrampsUpgradeSafe is __Initializable, InitializableUpgradeSafe, SampleHumanUpgradeSafe {
function __SampleGramps_init() internal __initializer {
__Initializable_init_unchained();
__SampleHuman_init_unchained();
__SampleGramps_init_unchained();
}
function __SampleGramps_init_unchained() internal __initializer {
}
string public gramps;
function initialize(string memory value) public initializer virtual {
SampleHumanUpgradeSafe.initialize();
gramps = value;
}
}
/**
* Sample base intializable contract that defines a field father and extends from gramps
*/
contract SampleFatherUpgradeSafe is __Initializable, InitializableUpgradeSafe, SampleGrampsUpgradeSafe {
function __SampleFather_init() internal __initializer {
__Initializable_init_unchained();
__SampleHuman_init_unchained();
__SampleGramps_init_unchained();
__SampleFather_init_unchained();
}
function __SampleFather_init_unchained() internal __initializer {
}
uint256 public father;
function initialize(string memory _gramps, uint256 _father) public initializer {
SampleGrampsUpgradeSafe.initialize(_gramps);
father = _father;
}
}
/**
* Child extends from mother, father (gramps)
*/
contract SampleChildUpgradeSafe is __Initializable, InitializableUpgradeSafe, SampleMotherUpgradeSafe, SampleFatherUpgradeSafe {
function __SampleChild_init() internal __initializer {
__Initializable_init_unchained();
__SampleHuman_init_unchained();
__SampleMother_init_unchained();
__SampleGramps_init_unchained();
__SampleFather_init_unchained();
__SampleChild_init_unchained();
}
function __SampleChild_init_unchained() internal __initializer {
}
uint256 public child;
function initialize(uint256 _mother, string memory _gramps, uint256 _father, uint256 _child) public initializer {
SampleMotherUpgradeSafe.initialize(_mother);
SampleFatherUpgradeSafe.initialize(_gramps, _father);
child = _child;
}
}
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This source diff could not be displayed because it is too large. You can view the blob instead.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment