Commit fd4b3fb1 by Francisco Giordano

Merge branch 'upstream-v3.3-patched' into upstream-v3.3-solc-0.7-patched

parents 40a15c04 8385b8a2
name: Merge upstream
on:
workflow_dispatch: {}
schedule:
- cron: '0 10 * * *'
jobs:
update:
runs-on: ubuntu-latest
steps:
- uses: rokroskar/workflow-run-cleanup-action@v0.2.2
env:
GITHUB_TOKEN: ${{github.token}}
- uses: actions/checkout@v2
with:
ref: upstream-patched
fetch-depth: 0
ssh-key: ${{secrets.DEPLOY_KEY}}
- run: bash scripts/upgradeable/git-user-config.sh
- run: bash scripts/upgradeable/merge-upstream.sh
- run: git push
...@@ -23,23 +23,6 @@ jobs: ...@@ -23,23 +23,6 @@ jobs:
restore-keys: npm-v2- restore-keys: npm-v2-
- run: npm ci - run: npm ci
if: steps.cache.outputs.cache-hit != 'true' if: steps.cache.outputs.cache-hit != 'true'
- run: npm run lint - run: bash scripts/upgradeable/transpile.sh
if: github.event_name == 'pull_request'
- run: npm run test - 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
id: cache
with:
path: '**/node_modules'
key: npm-v2-${{ hashFiles('**/package-lock.json') }}
restore-keys: npm-v2-
- run: npm ci
if: steps.cache.outputs.cache-hit != 'true'
- run: npm run coverage
- uses: codecov/codecov-action@v1
name: Transpile
on:
workflow_dispatch: {}
push:
branches: [upstream-patched]
jobs:
transpile:
runs-on: ubuntu-latest
steps:
- uses: rokroskar/workflow-run-cleanup-action@v0.2.2
env:
GITHUB_TOKEN: ${{github.token}}
- uses: actions/checkout@v2
with:
ref: upstream-patched
fetch-depth: 0
ssh-key: ${{secrets.DEPLOY_KEY}}
- uses: actions/setup-node@v1
with:
node-version: 10.x
- uses: actions/cache@v2
id: cache
with:
path: '**/node_modules'
key: npm-v2-${{ hashFiles('**/package-lock.json') }}
restore-keys: npm-v2-
- run: npm ci
if: steps.cache.outputs.cache-hit != 'true'
- run: bash scripts/upgradeable/git-user-config.sh
- run: bash scripts/upgradeable/transpile-onto.sh master origin/master
- run: git push origin master
# Changelog for Upgradeable variant
## 3.2.0 (2020-11-11)
* First release of Upgradeable variant, replacing Ethereum Package variant which is now deprecated.
### Upgrading from OpenZeppelin Contracts Ethereum Package
* The dependency on `@openzeppelin/contracts-ethereum-package` should be replaced by `@openzeppelin/contracts-upgradeable`.
* All contracts, interfaces, and libraries now have an `Upgradeable` suffix, instead of the `UpgradeSafe` suffix that only contracts used to have. The only exception is the `Initializable` contract which retains its original name.
* `Address``AddressUpgradeable`
* `ERC20UpgradeSafe``ERC20Upgradeable`
* This change improves compatibility with the main OpenZeppelin Contracts package, allowing both to be used side by side.
* Solidity files are now also suffixed, to keep the Solidity convention of equal file and contract name.
* `access/Ownable.sol``access/OwnableUpgradeable.sol`
* Import paths no longer include `/contracts/`.
* `@openzeppelin/contracts-ethereum-package/contracts/access/Ownable.sol``@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol`
# Changelog # Changelog
## 3.3.0 (2020-11-26) ## 3.3.0 (2020-11-26)
......
# <img src="logo.svg" alt="OpenZeppelin" height="40px"> # <img src="icon.svg" alt="OpenZeppelin" height="40px" align="left"> OpenZeppelin Contracts Upgradeable
[![Docs](https://img.shields.io/badge/docs-%F0%9F%93%84-blue)](https://docs.openzeppelin.com/contracts) [![Docs](https://img.shields.io/badge/docs-%F0%9F%93%84-blue)](https://docs.openzeppelin.com/contracts/upgradeable)
[![NPM Package](https://img.shields.io/npm/v/@openzeppelin/contracts.svg)](https://www.npmjs.org/package/@openzeppelin/contracts) [![NPM Package](https://img.shields.io/npm/v/@openzeppelin/contracts-upgradeable.svg)](https://www.npmjs.org/package/@openzeppelin/contracts-upgradeable)
[![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. This repository hosts the Upgradeable variant of [OpenZeppelin Contracts], meant for use in upgradeable contracts. This variant is available as separate package called `@openzeppelin/contracts-upgradeable`.
* Implementations of standards like [ERC20](https://docs.openzeppelin.com/contracts/erc20) and [ERC721](https://docs.openzeppelin.com/contracts/erc721). [OpenZeppelin Contracts]: https://github.com/OpenZeppelin/openzeppelin-contracts
* 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. It follows all of the rules for [Writing Upgradeable Contracts]: constructors are replaced by initializer functions, state variables are initialized in initializer functions, and we additionally check for storage incompatibilities across minor versions.
* 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_). [Writing Upgradeable Contracts]: https://docs.openzeppelin.com/upgrades-plugins/writing-upgradeable
## Overview ## Overview
### Installation ### Installation
```console ```console
$ npm install @openzeppelin/contracts $ npm install @openzeppelin/contracts-upgradeable
``` ```
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 ### Usage
Once installed, you can use the contracts in the library by importing them: The package replicates the structure of the main OpenZeppelin Contracts package, but every file and contract has the suffix `Upgradeable`.
```solidity ```diff
pragma solidity ^0.7.0; -import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
+import "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol";
-contract MyCollectible is ERC721 {
+contract MyCollectible is ERC721Upgradeable {
```
import "@openzeppelin/contracts/token/ERC721/ERC721.sol"; Constructors are replaced by internal initializer functions following the naming convention `__{ContractName}_init`. Since these are internal, you must always define your own public initializer function and call the parent initializer of the contract you extend.
contract MyCollectible is ERC721 { ```diff
constructor() ERC721("MyCollectible", "MCO") { - constructor() ERC721("MyCollectible", "MCO") public {
} + function initialize() initializer public {
} + __ERC721_init("MyCollectible", "MCO");
}
``` ```
> **Caution**
>
> Use with multiple inheritance requires special care. Initializer functions are not linearized by the compiler like constructors. Because of this, each `__{ContractName}_init` function embeds the linearized calls to all parent initializers. As a consequence, calling two of these `init` functions can potentially initialize the same contract twice.
>
> The function `__{ContractName}_init_unchained` found in every contract is the initializer function minus the calls to parent initializers, and can be used to avoid the double initialization problem, but doing this manually is not recommended. We hope to be able to implement safety checks for this in future versions of the Upgrades Plugins.
_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._ _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. 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.
......
# Technical notes about the Upgradeable repository
## [Branches](https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable/branches)
### `upstream-patched`
Contains a patched version of the vanilla Contracts repo. It adds the scripts to transpile and GitHub Actions for it to work automatically, changes the package name, etc.
Eventually it may also include small changes to the Solidity code, such as reordering of state variables, in order to ensure storage compatibility.
It's an important goal that this branch should be easy to merge with the vanilla Contracts repo, avoiding merge conflicts as much as possible. This is necessary to reduce manual intervention and ensure automation runs smoothly.
### `master`
Contains the actual transpiled code, which is generated automatically based on `upstream-patched`. The contents of this branch should never be manually changed, because they will be overwritten automatically with the transpiled version of `upstream-patched`. Instead, changes should be made in `upstream-patched`.
### `upstream-v3.2.0-patched`, `release-v3.2.0`
I created thes branches in order to release `v3.2.0`, because the `master` branch was already ahead. The first is vanilla v3.2.0 with `upstream-patched` rebased onto it. The second is the transpiled version built using the script shown below.
## [Actions Workflows](https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable/actions)
### [Merge upstream](/.github/workflows/merge-upstream.yml)
All this does is fetch the latest changes from vanilla Contracts repo, tries to merge them into `upstream-patched`, and then pushes the updated branch. If the merge has conflicts, the worfklow will fail. We should be notified of this so that we can manually run the merge and resolve the conflicts. This should not happen often.
Runs on a schedule every morning. Can also be triggered manually from the Actions page.
### [Transpile](/.github/workflows/transpile.yml)
Runs every time `upstream-patched` is pushed to (for example as part of the Merge upstream workflow), transpiles the contents of that branch, and pushes the results as a new commit on the `master` branch.
### [Test](/.github/workflows/test.yml)
Runs normal Contracts tests on the `master` and `release-v*` branches.
## Scripts
### `transpile-onto.sh`
```
bash scripts/upgradeable/transpile-onto.sh <target> [base]
```
Transpiles the contents of the current git branch and commits the result as a new commit on branch `<target>`. If branch `<target>` doesn't exist, it will copy the commit history of `[base]` (this is used in GitHub Actions, but is usually not necessary locally).
This script can be used manually to build transpiled versions of specific commits, or branches other than the `master` Contracts branch.
const { BuidlerError } = require('@nomiclabs/buidler/internal/core/errors');
extendEnvironment(env => {
const { artifacts } = env;
env.artifacts = {
...artifacts,
require (name) {
for (const suffix of ['UpgradeableWithInit', 'Upgradeable', '']) {
try {
return artifacts.require(name + suffix);
} catch (e) {
if (BuidlerError.isBuidlerError(e) && e.number === 700 && suffix !== '') {
continue;
} else {
throw e;
}
}
}
throw new Error('Unreachable');
},
};
});
// adds storageLayout to solc outputSelection, necessary for storage gaps
const { internalTask } = require('@nomiclabs/buidler/config');
const { TASK_COMPILE_GET_COMPILER_INPUT } = require('@nomiclabs/buidler/builtin-tasks/task-names');
internalTask(TASK_COMPILE_GET_COMPILER_INPUT, async (args, bre, runSuper) => {
const input = await runSuper();
input.settings.outputSelection['*']['*'].push('storageLayout');
return input;
});
// ignores the proxy tests
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/**/*')] },
);
});
{ {
"name": "@openzeppelin/contracts", "name": "@openzeppelin/contracts-upgradeable",
"description": "Secure Smart Contract library for Solidity", "description": "Secure Smart Contract library for Solidity",
"version": "3.3.0-solc-0.7", "version": "3.3.0-solc-0.7",
"files": [ "files": [
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
}, },
"repository": { "repository": {
"type": "git", "type": "git",
"url": "https://github.com/OpenZeppelin/openzeppelin-contracts.git" "url": "https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable.git"
}, },
"keywords": [ "keywords": [
"solidity", "solidity",
...@@ -27,7 +27,7 @@ ...@@ -27,7 +27,7 @@
"author": "OpenZeppelin Community <maintainers@openzeppelin.org>", "author": "OpenZeppelin Community <maintainers@openzeppelin.org>",
"license": "MIT", "license": "MIT",
"bugs": { "bugs": {
"url": "https://github.com/OpenZeppelin/openzeppelin-contracts/issues" "url": "https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable/issues"
}, },
"homepage": "https://openzeppelin.com/contracts/" "homepage": "https://openzeppelin.com/contracts/"
} }
= Using with Upgrades = Using with Upgrades
If your contract is going to be deployed with upgradeability, such as using the xref:upgrades-plugins::index.adoc[OpenZeppelin Upgrades Plugins], you will need to use the Upgrade Safe variant of OpenZeppelin Contracts. If your contract is going to be deployed with upgradeability, such as using the xref:upgrades-plugins::index.adoc[OpenZeppelin Upgrades Plugins], you will need to use the Upgradeable variant of OpenZeppelin Contracts.
This variant is available as a separate package called `@openzeppelin/contracts-upgradeable`, which is hosted in the repository https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable[OpenZeppelin/openzeppelin-contracts-upgradeable]. This variant is available as a separate package called `@openzeppelin/contracts-upgradeable`, which is hosted in the repository https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable[OpenZeppelin/openzeppelin-contracts-upgradeable].
...@@ -66,6 +66,6 @@ The function `+__{ContractName}_init_unchained+` found in every contract is the ...@@ -66,6 +66,6 @@ The function `+__{ContractName}_init_unchained+` found in every contract is the
=== Storage Gaps === Storage Gaps
You may notice that every contract includes a state variable named `+__gap+`. This is empty reserved space in storage that is put in place in Upgrade Safe contracts. It allows us to freely add new state variables in the future without compromising the storage compatibility with existing deployments. You may notice that every contract includes a state variable named `+__gap+`. This is empty reserved space in storage that is put in place in Upgradeable contracts. It allows us to freely add new state variables in the future without compromising the storage compatibility with existing deployments.
It isn't safe to simply add a state variable because it "shifts down" all of the state variables below in the inheritance chain. This makes the storage layouts incompatible, as explained in xref:upgrades-plugins::writing-upgradeable.adoc#modifying-your-contracts[Writing Upgradeable Contracts]. The size of the `+__gap+` array is calculated so that the amount of storage used by a contract always adds up to the same number (in this case 50 storage slots). It isn't safe to simply add a state variable because it "shifts down" all of the state variables below in the inheritance chain. This makes the storage layouts incompatible, as explained in xref:upgrades-plugins::writing-upgradeable.adoc#modifying-your-contracts[Writing Upgradeable Contracts]. The size of the `+__gap+` array is calculated so that the amount of storage used by a contract always adds up to the same number (in this case 50 storage slots).
<?xml version="1.0" encoding="UTF-8"?>
<svg width="180px" height="200px" viewBox="0 0 180 200" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 53.2 (72643) - https://sketchapp.com -->
<title>OZ_icon_color</title>
<desc>Created with Sketch.</desc>
<g id="presentación" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="OZ_icon_color">
<path d="M179.670444,199.932333 L179.670444,147.932333 L123.270887,147.932333 C107.93329,147.932333 93.7259335,156.016333 85.8704806,169.214333 L67.5860074,199.932333 L179.670444,199.932333 Z" id="Stroke-1" fill="#63D2F9"></path>
<polygon id="Stroke-3" fill="#4E5EE4" points="0.166292052 0.1667 0.166292052 52.1667 148.717863 52.1667 179.670543 0.1667"></polygon>
<path d="M71.2615009,81.4347667 L0.329855823,199.932433 L60.7619445,199.932433 L145.583534,58.1667667 L112.212665,58.1667667 C95.4274159,58.1667667 79.8768799,67.0024333 71.2615009,81.4347667 Z" id="Stroke-5" fill="#63B0F9"></path>
</g>
</g>
</svg>
\ No newline at end of file
{ {
"private": true,
"name": "openzeppelin-solidity", "name": "openzeppelin-solidity",
"description": "Secure Smart Contract library for Solidity", "description": "Secure Smart Contract library for Solidity",
"version": "3.3.0-solc-0.7", "version": "3.3.0-solc-0.7",
...@@ -6,6 +7,7 @@ ...@@ -6,6 +7,7 @@
"/contracts/**/*.sol", "/contracts/**/*.sol",
"/build/contracts/*.json", "/build/contracts/*.json",
"!/contracts/mocks", "!/contracts/mocks",
"!/contracts/proxy",
"/test/behaviors" "/test/behaviors"
], ],
"scripts": { "scripts": {
......
#!/usr/bin/env bash
set -euo pipefail -x
git config user.name 'github-actions'
git config user.email '41898282+github-actions[bot]@users.noreply.github.com'
#!/usr/bin/env bash
set -euo pipefail -x
git fetch 'https://github.com/OpenZeppelin/openzeppelin-contracts.git'
git merge FETCH_HEAD -m 'Merge upstream openzeppelin-contracts into upstream-patched'
#!/usr/bin/env bash
set -euo pipefail
if [ $# -lt 1 ]; then
echo "usage: bash $0 <target> [base]" >&2
exit 1
fi
set -x
target="$1"
base="${2-}"
bash scripts/upgradeable/transpile.sh
commit="$(git rev-parse --short HEAD)"
branch="$(git rev-parse --abbrev-ref HEAD)"
git add contracts
git checkout --quiet --detach
if git rev-parse --quiet --verify "$target"; then
git reset --soft "$target"
git checkout "$target"
else
git checkout --orphan "$target"
if [ -n "$base" ]; then
git reset --soft "$base"
fi
fi
if ! git diff --quiet --cached; then
git commit -m "Transpile $commit"
fi
git checkout "$branch"
#!/usr/bin/env bash
set -euo pipefail -x
npm run compile
# -D: delete original and excluded files
# -i: use included Initializable
# -x: exclude all proxy contracts
# -p: emit public initializer
npx @openzeppelin/upgrade-safe-transpiler -D \
-i contracts/proxy/Initializable.sol \
-x 'contracts/proxy/**/*' \
-p 'contracts/presets/**/*'
// a different comment!
const { deployRelayHub } = require('@openzeppelin/gsn-helpers'); const { deployRelayHub } = require('@openzeppelin/gsn-helpers');
before('deploy GSN RelayHub', async function () { before('deploy GSN RelayHub', async function () {
......
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