Transpile 7bce2b72
This commit is contained in:
43
scripts/gen-nav.js
Normal file
43
scripts/gen-nav.js
Normal file
@ -0,0 +1,43 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
const path = require('path');
|
||||
const proc = require('child_process');
|
||||
const startCase = require('lodash.startcase');
|
||||
|
||||
const baseDir = process.argv[2];
|
||||
|
||||
const files = proc.execFileSync(
|
||||
'find', [baseDir, '-type', 'f'], { encoding: 'utf8' },
|
||||
).split('\n').filter(s => s !== '');
|
||||
|
||||
console.log('.API');
|
||||
|
||||
function getPageTitle (directory) {
|
||||
switch (directory) {
|
||||
case 'metatx':
|
||||
return 'Meta Transactions';
|
||||
case 'common':
|
||||
return 'Common (Tokens)';
|
||||
default:
|
||||
return startCase(directory);
|
||||
}
|
||||
}
|
||||
|
||||
const links = files.map((file) => {
|
||||
const doc = file.replace(baseDir, '');
|
||||
const title = path.parse(file).name;
|
||||
|
||||
return {
|
||||
xref: `* xref:${doc}[${getPageTitle(title)}]`,
|
||||
title,
|
||||
};
|
||||
});
|
||||
|
||||
// Case-insensitive sort based on titles (so 'token/ERC20' gets sorted as 'erc20')
|
||||
const sortedLinks = links.sort(function (a, b) {
|
||||
return a.title.toLowerCase().localeCompare(b.title.toLowerCase(), undefined, { numeric: true });
|
||||
});
|
||||
|
||||
for (const link of sortedLinks) {
|
||||
console.log(link.xref);
|
||||
}
|
||||
44
scripts/inheritanceOrdering.js
Normal file
44
scripts/inheritanceOrdering.js
Normal file
@ -0,0 +1,44 @@
|
||||
const path = require('path');
|
||||
const graphlib = require('graphlib');
|
||||
const { findAll } = require('solidity-ast/utils');
|
||||
const { _: artifacts } = require('yargs').argv;
|
||||
|
||||
for (const artifact of artifacts) {
|
||||
const { output: solcOutput } = require(path.resolve(__dirname, '..', artifact));
|
||||
|
||||
const graph = new graphlib.Graph({ directed: true });
|
||||
const names = {};
|
||||
const linearized = [];
|
||||
|
||||
for (const source in solcOutput.contracts) {
|
||||
for (const contractDef of findAll('ContractDefinition', solcOutput.sources[source].ast)) {
|
||||
names[contractDef.id] = contractDef.name;
|
||||
linearized.push(contractDef.linearizedBaseContracts);
|
||||
|
||||
contractDef.linearizedBaseContracts.forEach((c1, i, contracts) => contracts.slice(i + 1).forEach(c2 => {
|
||||
graph.setEdge(c1, c2);
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
/// graphlib.alg.findCycles will not find minimal cycles.
|
||||
/// We are only interested int cycles of lengths 2 (needs proof)
|
||||
graph.nodes().forEach((x, i, nodes) => nodes
|
||||
.slice(i + 1)
|
||||
.filter(y => graph.hasEdge(x, y) && graph.hasEdge(y, x))
|
||||
.map(y => {
|
||||
console.log(`Conflict between ${names[x]} and ${names[y]} detected in the following dependency chains:`);
|
||||
linearized
|
||||
.filter(chain => chain.includes(parseInt(x)) && chain.includes(parseInt(y)))
|
||||
.forEach(chain => {
|
||||
const comp = chain.indexOf(parseInt(x)) < chain.indexOf(parseInt(y)) ? '>' : '<';
|
||||
console.log(`- ${names[x]} ${comp} ${names[y]} in ${names[chain.find(Boolean)]}`);
|
||||
// console.log(`- ${names[x]} ${comp} ${names[y]}: ${chain.reverse().map(id => names[id]).join(', ')}`);
|
||||
});
|
||||
process.exitCode = 1;
|
||||
}));
|
||||
}
|
||||
|
||||
if (!process.exitCode) {
|
||||
console.log('Contract ordering is consistent.');
|
||||
}
|
||||
177
scripts/migrate-imports.js
Executable file
177
scripts/migrate-imports.js
Executable file
@ -0,0 +1,177 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
const { promises: fs } = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
const pathUpdates = {
|
||||
// 'access/AccessControl.sol': undefined,
|
||||
// 'access/Ownable.sol': undefined,
|
||||
'access/TimelockController.sol': 'governance/TimelockController.sol',
|
||||
'cryptography/ECDSA.sol': 'utils/cryptography/ECDSA.sol',
|
||||
'cryptography/MerkleProof.sol': 'utils/cryptography/MerkleProof.sol',
|
||||
'drafts/EIP712.sol': 'utils/cryptography/draft-EIP712.sol',
|
||||
'drafts/ERC20Permit.sol': 'token/ERC20/extensions/draft-ERC20Permit.sol',
|
||||
'drafts/IERC20Permit.sol': 'token/ERC20/extensions/draft-IERC20Permit.sol',
|
||||
'GSN/Context.sol': 'utils/Context.sol',
|
||||
// 'GSN/GSNRecipientERC20Fee.sol': undefined,
|
||||
// 'GSN/GSNRecipientSignature.sol': undefined,
|
||||
// 'GSN/GSNRecipient.sol': undefined,
|
||||
// 'GSN/IRelayHub.sol': undefined,
|
||||
// 'GSN/IRelayRecipient.sol': undefined,
|
||||
'introspection/ERC165Checker.sol': 'utils/introspection/ERC165Checker.sol',
|
||||
'introspection/ERC165.sol': 'utils/introspection/ERC165.sol',
|
||||
'introspection/ERC1820Implementer.sol': 'utils/introspection/ERC1820Implementer.sol',
|
||||
'introspection/IERC165.sol': 'utils/introspection/IERC165.sol',
|
||||
'introspection/IERC1820Implementer.sol': 'utils/introspection/IERC1820Implementer.sol',
|
||||
'introspection/IERC1820Registry.sol': 'utils/introspection/IERC1820Registry.sol',
|
||||
'math/Math.sol': 'utils/math/Math.sol',
|
||||
'math/SafeMath.sol': 'utils/math/SafeMath.sol',
|
||||
'math/SignedSafeMath.sol': 'utils/math/SignedSafeMath.sol',
|
||||
'payment/escrow/ConditionalEscrow.sol': 'utils/escrow/ConditionalEscrow.sol',
|
||||
'payment/escrow/Escrow.sol': 'utils/escrow/Escrow.sol',
|
||||
'payment/escrow/RefundEscrow.sol': 'utils/escrow/RefundEscrow.sol',
|
||||
'payment/PaymentSplitter.sol': 'finance/PaymentSplitter.sol',
|
||||
'utils/PaymentSplitter.sol': 'finance/PaymentSplitter.sol',
|
||||
'payment/PullPayment.sol': 'security/PullPayment.sol',
|
||||
'presets/ERC1155PresetMinterPauser.sol': 'token/ERC1155/presets/ERC1155PresetMinterPauser.sol',
|
||||
'presets/ERC20PresetFixedSupply.sol': 'token/ERC20/presets/ERC20PresetFixedSupply.sol',
|
||||
'presets/ERC20PresetMinterPauser.sol': 'token/ERC20/presets/ERC20PresetMinterPauser.sol',
|
||||
'presets/ERC721PresetMinterPauserAutoId.sol': 'token/ERC721/presets/ERC721PresetMinterPauserAutoId.sol',
|
||||
'presets/ERC777PresetFixedSupply.sol': 'token/ERC777/presets/ERC777PresetFixedSupply.sol',
|
||||
// 'proxy/BeaconProxy.sol': 'proxy/beacon/BeaconProxy.sol',
|
||||
// 'proxy/Clones.sol': undefined,
|
||||
// 'proxy/IBeacon.sol': 'proxy/beacon/IBeacon.sol',
|
||||
'proxy/Initializable.sol': 'proxy/utils/Initializable.sol',
|
||||
'utils/Initializable.sol': 'proxy/utils/Initializable.sol',
|
||||
// 'proxy/ProxyAdmin.sol': 'proxy/transparent/ProxyAdmin.sol',
|
||||
// 'proxy/Proxy.sol': undefined,
|
||||
// 'proxy/TransparentUpgradeableProxy.sol': 'proxy/transparent/TransparentUpgradeableProxy.sol',
|
||||
// 'proxy/UpgradeableBeacon.sol': 'proxy/beacon/UpgradeableBeacon.sol',
|
||||
// 'proxy/UpgradeableProxy.sol': 'proxy/ERC1967/ERC1967Proxy.sol',
|
||||
'token/ERC1155/ERC1155Burnable.sol': 'token/ERC1155/extensions/ERC1155Burnable.sol',
|
||||
'token/ERC1155/ERC1155Holder.sol': 'token/ERC1155/utils/ERC1155Holder.sol',
|
||||
'token/ERC1155/ERC1155Pausable.sol': 'token/ERC1155/extensions/ERC1155Pausable.sol',
|
||||
'token/ERC1155/ERC1155Receiver.sol': 'token/ERC1155/utils/ERC1155Receiver.sol',
|
||||
// 'token/ERC1155/ERC1155.sol': undefined,
|
||||
'token/ERC1155/IERC1155MetadataURI.sol': 'token/ERC1155/extensions/IERC1155MetadataURI.sol',
|
||||
// 'token/ERC1155/IERC1155Receiver.sol': undefined,
|
||||
// 'token/ERC1155/IERC1155.sol': undefined,
|
||||
'token/ERC20/ERC20Burnable.sol': 'token/ERC20/extensions/ERC20Burnable.sol',
|
||||
'token/ERC20/ERC20Capped.sol': 'token/ERC20/extensions/ERC20Capped.sol',
|
||||
'token/ERC20/ERC20Pausable.sol': 'token/ERC20/extensions/ERC20Pausable.sol',
|
||||
'token/ERC20/ERC20Snapshot.sol': 'token/ERC20/extensions/ERC20Snapshot.sol',
|
||||
// 'token/ERC20/ERC20.sol': undefined,
|
||||
// 'token/ERC20/IERC20.sol': undefined,
|
||||
'token/ERC20/SafeERC20.sol': 'token/ERC20/utils/SafeERC20.sol',
|
||||
'token/ERC20/TokenTimelock.sol': 'token/ERC20/utils/TokenTimelock.sol',
|
||||
'token/ERC721/ERC721Burnable.sol': 'token/ERC721/extensions/ERC721Burnable.sol',
|
||||
'token/ERC721/ERC721Holder.sol': 'token/ERC721/utils/ERC721Holder.sol',
|
||||
'token/ERC721/ERC721Pausable.sol': 'token/ERC721/extensions/ERC721Pausable.sol',
|
||||
// 'token/ERC721/ERC721.sol': undefined,
|
||||
'token/ERC721/IERC721Enumerable.sol': 'token/ERC721/extensions/IERC721Enumerable.sol',
|
||||
'token/ERC721/IERC721Metadata.sol': 'token/ERC721/extensions/IERC721Metadata.sol',
|
||||
// 'token/ERC721/IERC721Receiver.sol': undefined,
|
||||
// 'token/ERC721/IERC721.sol': undefined,
|
||||
// 'token/ERC777/ERC777.sol': undefined,
|
||||
// 'token/ERC777/IERC777Recipient.sol': undefined,
|
||||
// 'token/ERC777/IERC777Sender.sol': undefined,
|
||||
// 'token/ERC777/IERC777.sol': undefined,
|
||||
// 'utils/Address.sol': undefined,
|
||||
// 'utils/Arrays.sol': undefined,
|
||||
// 'utils/Context.sol': undefined,
|
||||
// 'utils/Counters.sol': undefined,
|
||||
// 'utils/Create2.sol': undefined,
|
||||
'utils/EnumerableMap.sol': 'utils/structs/EnumerableMap.sol',
|
||||
'utils/EnumerableSet.sol': 'utils/structs/EnumerableSet.sol',
|
||||
'utils/Pausable.sol': 'security/Pausable.sol',
|
||||
'utils/ReentrancyGuard.sol': 'security/ReentrancyGuard.sol',
|
||||
'utils/SafeCast.sol': 'utils/math/SafeCast.sol',
|
||||
// 'utils/Strings.sol': undefined,
|
||||
};
|
||||
|
||||
async function main (paths = [ 'contracts' ]) {
|
||||
const files = await listFilesRecursively(paths, /\.sol$/);
|
||||
|
||||
const updatedFiles = [];
|
||||
for (const file of files) {
|
||||
if (await updateFile(file, updateImportPaths)) {
|
||||
updatedFiles.push(file);
|
||||
}
|
||||
}
|
||||
|
||||
if (updatedFiles.length > 0) {
|
||||
console.log(`${updatedFiles.length} file(s) were updated`);
|
||||
for (const c of updatedFiles) {
|
||||
console.log('-', c);
|
||||
}
|
||||
} else {
|
||||
console.log('No files were updated');
|
||||
}
|
||||
}
|
||||
|
||||
async function listFilesRecursively (paths, filter) {
|
||||
const queue = paths;
|
||||
const files = [];
|
||||
|
||||
while (queue.length > 0) {
|
||||
const top = queue.shift();
|
||||
const stat = await fs.stat(top);
|
||||
if (stat.isFile()) {
|
||||
if (top.match(filter)) {
|
||||
files.push(top);
|
||||
}
|
||||
} else if (stat.isDirectory()) {
|
||||
for (const name of await fs.readdir(top)) {
|
||||
queue.push(path.join(top, name));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return files;
|
||||
}
|
||||
|
||||
async function updateFile (file, update) {
|
||||
const content = await fs.readFile(file, 'utf8');
|
||||
const updatedContent = update(content);
|
||||
if (updatedContent !== content) {
|
||||
await fs.writeFile(file, updatedContent);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function updateImportPaths (source) {
|
||||
for (const [ oldPath, newPath ] of Object.entries(pathUpdates)) {
|
||||
source = source.replace(
|
||||
path.join('@openzeppelin/contracts', oldPath),
|
||||
path.join('@openzeppelin/contracts', newPath),
|
||||
);
|
||||
source = source.replace(
|
||||
path.join('@openzeppelin/contracts-upgradeable', getUpgradeablePath(oldPath)),
|
||||
path.join('@openzeppelin/contracts-upgradeable', getUpgradeablePath(newPath)),
|
||||
);
|
||||
}
|
||||
|
||||
return source;
|
||||
}
|
||||
|
||||
function getUpgradeablePath (file) {
|
||||
const { dir, name, ext } = path.parse(file);
|
||||
const upgradeableName = name + 'Upgradeable';
|
||||
return path.format({ dir, ext, name: upgradeableName });
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
pathUpdates,
|
||||
updateImportPaths,
|
||||
getUpgradeablePath,
|
||||
};
|
||||
|
||||
if (require.main === module) {
|
||||
const args = process.argv.length > 2 ? process.argv.slice(2) : undefined;
|
||||
main(args).catch(e => {
|
||||
console.error(e);
|
||||
process.exit(1);
|
||||
});
|
||||
}
|
||||
12
scripts/prepack.sh
Executable file
12
scripts/prepack.sh
Executable file
@ -0,0 +1,12 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -euo pipefail
|
||||
shopt -s globstar
|
||||
|
||||
# cross platform `mkdir -p`
|
||||
node -e 'fs.mkdirSync("build/contracts", { recursive: true })'
|
||||
|
||||
cp artifacts/contracts/**/*.json build/contracts
|
||||
rm build/contracts/*.dbg.json
|
||||
|
||||
node scripts/remove-ignored-artifacts.js
|
||||
15
scripts/prepare-contracts-package.sh
Executable file
15
scripts/prepare-contracts-package.sh
Executable file
@ -0,0 +1,15 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# cd to the root of the repo
|
||||
cd "$(git rev-parse --show-toplevel)"
|
||||
|
||||
# avoids re-compilation during publishing of both packages
|
||||
if [[ ! -v ALREADY_COMPILED ]]; then
|
||||
npm run clean
|
||||
npm run prepare
|
||||
npm run prepack
|
||||
fi
|
||||
|
||||
cp README.md contracts/
|
||||
mkdir contracts/build contracts/build/contracts
|
||||
cp -r build/contracts/*.json contracts/build/contracts
|
||||
16
scripts/prepare-docs-solc.js
Normal file
16
scripts/prepare-docs-solc.js
Normal file
@ -0,0 +1,16 @@
|
||||
const hre = require('hardhat');
|
||||
|
||||
const { getCompilersDir } = require('hardhat/internal/util/global-dir');
|
||||
const { CompilerDownloader } = require('hardhat/internal/solidity/compiler/downloader');
|
||||
const { Compiler } = require('hardhat/internal/solidity/compiler');
|
||||
|
||||
const [{ version }] = hre.config.solidity.compilers;
|
||||
|
||||
async function getSolc () {
|
||||
const downloader = new CompilerDownloader(await getCompilersDir(), { forceSolcJs: true });
|
||||
const { compilerPath } = await downloader.getDownloadedCompilerPath(version);
|
||||
const compiler = new Compiler(compilerPath);
|
||||
return compiler.getSolc();
|
||||
}
|
||||
|
||||
module.exports = Object.assign(getSolc(), { __esModule: true });
|
||||
21
scripts/prepare-docs.sh
Executable file
21
scripts/prepare-docs.sh
Executable file
@ -0,0 +1,21 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -o errexit
|
||||
|
||||
OUTDIR=docs/modules/api/pages/
|
||||
|
||||
if [ ! -d node_modules ]; then
|
||||
npm ci
|
||||
fi
|
||||
|
||||
rm -rf "$OUTDIR"
|
||||
|
||||
solidity-docgen \
|
||||
-t docs \
|
||||
-o "$OUTDIR" \
|
||||
-e contracts/mocks,contracts/examples \
|
||||
--output-structure readmes \
|
||||
--helpers ./docs/helpers.js \
|
||||
--solc-module ./scripts/prepare-docs-solc.js
|
||||
|
||||
node scripts/gen-nav.js "$OUTDIR" > "$OUTDIR/../nav.adoc"
|
||||
153
scripts/release/release.sh
Executable file
153
scripts/release/release.sh
Executable file
@ -0,0 +1,153 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Exit script as soon as a command fails.
|
||||
set -o errexit
|
||||
|
||||
# Default the prerelease version suffix to rc
|
||||
: ${PRERELEASE_SUFFIX:=rc}
|
||||
|
||||
log() {
|
||||
# Print to stderr to prevent this from being 'returned'
|
||||
echo "$@" > /dev/stderr
|
||||
}
|
||||
|
||||
current_version() {
|
||||
echo "v$(node --print --eval "require('./package.json').version")"
|
||||
}
|
||||
|
||||
current_release_branch() {
|
||||
v="$(current_version)" # 3.3.0-rc.0
|
||||
vf="${v%-"$PRERELEASE_SUFFIX".*}" # 3.3.0
|
||||
r="${vf%.*}" # 3.3
|
||||
echo "release-$r"
|
||||
}
|
||||
|
||||
assert_current_branch() {
|
||||
current_branch="$(git symbolic-ref --short HEAD)"
|
||||
expected_branch="$1"
|
||||
if [[ "$current_branch" != "$expected_branch" ]]; then
|
||||
log "Current branch '$current_branch' is not '$expected_branch'"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
push_release_branch_and_tag() {
|
||||
git push upstream "$(current_release_branch)" "$(current_version)"
|
||||
}
|
||||
|
||||
publish() {
|
||||
dist_tag="$1"
|
||||
|
||||
log "Publishing openzeppelin-solidity on npm"
|
||||
npm publish --tag "$dist_tag" --otp "$(prompt_otp)"
|
||||
|
||||
log "Publishing @openzeppelin/contracts on npm"
|
||||
cd contracts
|
||||
env ALREADY_COMPILED= \
|
||||
npm publish --tag "$dist_tag" --otp "$(prompt_otp)"
|
||||
cd ..
|
||||
|
||||
if [[ "$dist_tag" == "latest" ]]; then
|
||||
otp="$(prompt_otp)"
|
||||
npm dist-tag rm --otp "$otp" openzeppelin-solidity next
|
||||
npm dist-tag rm --otp "$otp" @openzeppelin/contracts next
|
||||
fi
|
||||
}
|
||||
|
||||
push_and_publish() {
|
||||
dist_tag="$1"
|
||||
|
||||
log "Pushing release branch and tags to upstream"
|
||||
push_release_branch_and_tag
|
||||
|
||||
publish "$dist_tag"
|
||||
}
|
||||
|
||||
prompt_otp() {
|
||||
log -n "Enter npm 2FA token: "
|
||||
read -r otp
|
||||
echo "$otp"
|
||||
}
|
||||
|
||||
environment_check() {
|
||||
if ! git remote get-url upstream &> /dev/null; then
|
||||
log "No 'upstream' remote found"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if npm whoami &> /dev/null; then
|
||||
log "Will publish as '$(npm whoami)'"
|
||||
else
|
||||
log "Not logged in into npm, run 'npm login' first"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
environment_check
|
||||
|
||||
if [[ "$*" == "push" ]]; then
|
||||
push_and_publish next
|
||||
|
||||
elif [[ "$*" == "start minor" ]]; then
|
||||
log "Creating new minor pre-release"
|
||||
|
||||
assert_current_branch master
|
||||
|
||||
# Create temporary release branch
|
||||
git checkout -b release-temp
|
||||
|
||||
# This bumps minor and adds prerelease suffix, commits the changes, and tags the commit
|
||||
npm version preminor --preid="$PRERELEASE_SUFFIX"
|
||||
|
||||
# Rename the release branch
|
||||
git branch --move "$(current_release_branch)"
|
||||
|
||||
push_and_publish next
|
||||
|
||||
elif [[ "$*" == "start major" ]]; then
|
||||
log "Creating new major pre-release"
|
||||
|
||||
assert_current_branch master
|
||||
|
||||
# Create temporary release branch
|
||||
git checkout -b release-temp
|
||||
|
||||
# This bumps major and adds prerelease suffix, commits the changes, and tags the commit
|
||||
npm version premajor --preid="$PRERELEASE_SUFFIX"
|
||||
|
||||
# Rename the release branch
|
||||
git branch --move "$(current_release_branch)"
|
||||
|
||||
push_and_publish next
|
||||
|
||||
elif [[ "$*" == "rc" ]]; then
|
||||
log "Bumping pre-release"
|
||||
|
||||
assert_current_branch "$(current_release_branch)"
|
||||
|
||||
# Bumps prerelease number, commits and tags
|
||||
npm version prerelease
|
||||
|
||||
push_and_publish next
|
||||
|
||||
elif [[ "$*" == "final" ]]; then
|
||||
# Update changelog release date, remove prerelease suffix, tag, push to git, publish in npm, remove next dist-tag
|
||||
log "Creating final release"
|
||||
|
||||
assert_current_branch "$(current_release_branch)"
|
||||
|
||||
# This will remove the prerelease suffix from the version
|
||||
npm version patch
|
||||
|
||||
push_release_branch_and_tag
|
||||
|
||||
push_and_publish latest
|
||||
|
||||
npm deprecate 'openzeppelin-solidity@>=4.0.0' "This package is now published as @openzeppelin/contracts. Please change your dependency."
|
||||
|
||||
log "Remember to merge the release branch into master and push upstream"
|
||||
|
||||
else
|
||||
log "Unknown command: '$*'"
|
||||
exit 1
|
||||
fi
|
||||
16
scripts/release/synchronize-versions.js
Executable file
16
scripts/release/synchronize-versions.js
Executable file
@ -0,0 +1,16 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
// Synchronizes the version in contracts/package.json with the one in package.json.
|
||||
// This is run automatically when npm version is run.
|
||||
|
||||
const fs = require('fs');
|
||||
const cp = require('child_process');
|
||||
|
||||
setVersion('contracts/package.json');
|
||||
|
||||
function setVersion (file) {
|
||||
const json = JSON.parse(fs.readFileSync(file));
|
||||
json.version = process.env.npm_package_version;
|
||||
fs.writeFileSync(file, JSON.stringify(json, null, 2) + '\n');
|
||||
cp.execFileSync('git', ['add', file]);
|
||||
}
|
||||
34
scripts/release/update-changelog-release-date.js
Executable file
34
scripts/release/update-changelog-release-date.js
Executable file
@ -0,0 +1,34 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
// Sets the release date of the current release in the changelog.
|
||||
// This is run automatically when npm version is run.
|
||||
|
||||
const fs = require('fs');
|
||||
const cp = require('child_process');
|
||||
|
||||
const suffix = process.env.PRERELEASE_SUFFIX || 'rc';
|
||||
|
||||
const changelog = fs.readFileSync('CHANGELOG.md', 'utf8');
|
||||
|
||||
// The changelog entry to be updated looks like this:
|
||||
// ## Unreleased
|
||||
// We need to add the version and release date in a YYYY-MM-DD format, so that it looks like this:
|
||||
// ## 2.5.3 (2019-04-25)
|
||||
|
||||
const pkg = require('../../package.json');
|
||||
const version = pkg.version.replace(new RegExp('-' + suffix + '\\..*'), '');
|
||||
|
||||
const header = new RegExp(`^## (Unreleased|${version})$`, 'm');
|
||||
|
||||
if (!header.test(changelog)) {
|
||||
console.error('Missing changelog entry');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const newHeader = pkg.version.indexOf(suffix) === -1
|
||||
? `## ${version} (${new Date().toISOString().split('T')[0]})`
|
||||
: `## ${version}`;
|
||||
|
||||
fs.writeFileSync('CHANGELOG.md', changelog.replace(header, newHeader));
|
||||
|
||||
cp.execSync('git add CHANGELOG.md', { stdio: 'inherit' });
|
||||
35
scripts/release/update-comment.js
Executable file
35
scripts/release/update-comment.js
Executable file
@ -0,0 +1,35 @@
|
||||
#!/usr/bin/env node
|
||||
const fs = require('fs');
|
||||
const proc = require('child_process');
|
||||
const semver = require('semver');
|
||||
const run = (cmd, ...args) => proc.execFileSync(cmd, args, { encoding: 'utf8' }).trim();
|
||||
|
||||
const gitStatus = run('git', 'status', '--porcelain', '-uno', 'contracts/**/*.sol');
|
||||
if (gitStatus.length > 0) {
|
||||
console.error('Contracts directory is not clean');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const { version } = require('../../package.json');
|
||||
|
||||
// Get latest tag according to semver.
|
||||
const [ tag ] = run('git', 'tag')
|
||||
.split(/\r?\n/)
|
||||
.filter(v => semver.lt(semver.coerce(v), version)) // only consider older tags, ignore current prereleases
|
||||
.sort(semver.rcompare);
|
||||
|
||||
// Ordering tag → HEAD is important here.
|
||||
const files = run('git', 'diff', tag, 'HEAD', '--name-only', 'contracts/**/*.sol')
|
||||
.split(/\r?\n/)
|
||||
.filter(file => file && !file.match(/mock/i));
|
||||
|
||||
for (const file of files) {
|
||||
const current = fs.readFileSync(file, 'utf8');
|
||||
const updated = current.replace(
|
||||
/(\/\/ SPDX-License-Identifier:.*)$(\n\/\/ OpenZeppelin Contracts .*$)?/m,
|
||||
`$1\n// OpenZeppelin Contracts (last updated v${version}) (${file.replace('contracts/', '')})`,
|
||||
);
|
||||
fs.writeFileSync(file, updated);
|
||||
}
|
||||
|
||||
run('git', 'add', '--update', 'contracts');
|
||||
9
scripts/release/version.sh
Executable file
9
scripts/release/version.sh
Executable file
@ -0,0 +1,9 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -o errexit
|
||||
|
||||
scripts/release/update-changelog-release-date.js
|
||||
scripts/release/synchronize-versions.js
|
||||
scripts/release/update-comment.js
|
||||
|
||||
oz-docs update-version
|
||||
45
scripts/remove-ignored-artifacts.js
Normal file
45
scripts/remove-ignored-artifacts.js
Normal file
@ -0,0 +1,45 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
// This script removes the build artifacts of ignored contracts.
|
||||
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const match = require('micromatch');
|
||||
|
||||
function readJSON (path) {
|
||||
return JSON.parse(fs.readFileSync(path));
|
||||
}
|
||||
|
||||
const pkgFiles = readJSON('package.json').files;
|
||||
|
||||
// Get only negated patterns.
|
||||
const ignorePatterns = pkgFiles
|
||||
.filter(pat => pat.startsWith('!'))
|
||||
// Remove the negation part. Makes micromatch usage more intuitive.
|
||||
.map(pat => pat.slice(1));
|
||||
|
||||
const ignorePatternsSubtrees = ignorePatterns
|
||||
// Add **/* to ignore all files contained in the directories.
|
||||
.concat(ignorePatterns.map(pat => path.join(pat, '**/*')))
|
||||
.map(p => p.replace(/^\//, ''));
|
||||
|
||||
const artifactsDir = 'build/contracts';
|
||||
const buildinfo = 'artifacts/build-info';
|
||||
const filenames = fs.readdirSync(buildinfo);
|
||||
|
||||
let n = 0;
|
||||
|
||||
for (const filename of filenames) {
|
||||
const solcOutput = readJSON(path.join(buildinfo, filename)).output;
|
||||
for (const sourcePath in solcOutput.contracts) {
|
||||
const ignore = match.any(sourcePath, ignorePatternsSubtrees);
|
||||
if (ignore) {
|
||||
for (const contract in solcOutput.contracts[sourcePath]) {
|
||||
fs.unlinkSync(path.join(artifactsDir, contract + '.json'));
|
||||
n += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
console.error(`Removed ${n} mock artifacts`);
|
||||
6
scripts/upgradeable/git-user-config.sh
Normal file
6
scripts/upgradeable/git-user-config.sh
Normal file
@ -0,0 +1,6 @@
|
||||
#!/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'
|
||||
31
scripts/upgradeable/merge-upstream.sh
Normal file
31
scripts/upgradeable/merge-upstream.sh
Normal file
@ -0,0 +1,31 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
: "${REF:="$(git rev-parse --symbolic-full-name HEAD)"}"
|
||||
|
||||
if [[ "$REF" != refs/heads/* ]]; then
|
||||
echo "$REF is not a branch" >&2
|
||||
exit 1
|
||||
elif [[ "$REF" == refs/heads/patches ]]; then
|
||||
REF=refs/heads/master
|
||||
fi
|
||||
|
||||
set -x
|
||||
|
||||
input="${REF#refs/heads/}"
|
||||
upstream="${input#patched/}"
|
||||
branch="patched/$upstream"
|
||||
|
||||
git checkout "$branch" 2>/dev/null || git checkout -b "$branch" origin/patches --no-track
|
||||
|
||||
git fetch 'https://github.com/OpenZeppelin/openzeppelin-contracts.git' master
|
||||
merge_base="$(git merge-base origin/patches FETCH_HEAD)"
|
||||
|
||||
git fetch 'https://github.com/OpenZeppelin/openzeppelin-contracts.git' "$upstream"
|
||||
# Check that patches is not ahead of the upstream branch we're merging.
|
||||
if ! git merge-base --is-ancestor "$merge_base" FETCH_HEAD; then
|
||||
echo "The patches branch is ahead of $upstream" >&2
|
||||
exit 1
|
||||
fi
|
||||
git merge origin/patches FETCH_HEAD -m "Merge upstream $upstream into $branch"
|
||||
@ -0,0 +1,13 @@
|
||||
diff --git a/contracts/mocks/MulticallTokenMockUpgradeable.sol b/contracts/mocks/MulticallTokenMockUpgradeable.sol
|
||||
index d06c8722..6211da1f 100644
|
||||
--- a/contracts/mocks/MulticallTokenMockUpgradeable.sol
|
||||
+++ b/contracts/mocks/MulticallTokenMockUpgradeable.sol
|
||||
@@ -9,7 +9,7 @@ import "../proxy/utils/Initializable.sol";
|
||||
contract MulticallTokenMockUpgradeable is Initializable, ERC20MockUpgradeable, MulticallUpgradeable {
|
||||
function __MulticallTokenMock_init(uint256 initialBalance) internal onlyInitializing {
|
||||
__Context_init_unchained();
|
||||
- __ERC20_init_unchained(name, symbol);
|
||||
+ __ERC20_init_unchained("MulticallToken", "BCT");
|
||||
__ERC20Mock_init_unchained("MulticallToken", "BCT", msg.sender, initialBalance);
|
||||
__Multicall_init_unchained();
|
||||
__MulticallTokenMock_init_unchained(initialBalance);
|
||||
@ -0,0 +1,17 @@
|
||||
diff --git a/contracts/token/ERC20/extensions/ERC20VotesUpgradeable.sol b/contracts/token/ERC20/extensions/ERC20VotesUpgradeable.sol
|
||||
index a7a9af54..0b7f838d 100644
|
||||
--- a/contracts/token/ERC20/extensions/ERC20VotesUpgradeable.sol
|
||||
+++ b/contracts/token/ERC20/extensions/ERC20VotesUpgradeable.sol
|
||||
@@ -24,12 +24,6 @@ import "../../../proxy/utils/Initializable.sol";
|
||||
* _Available since v4.2._
|
||||
*/
|
||||
abstract contract ERC20VotesUpgradeable is Initializable, IVotesUpgradeable, ERC20PermitUpgradeable {
|
||||
- function __ERC20Votes_init() internal onlyInitializing {
|
||||
- __Context_init_unchained();
|
||||
- __EIP712_init_unchained(name, "1");
|
||||
- __ERC20Votes_init_unchained();
|
||||
- }
|
||||
-
|
||||
function __ERC20Votes_init_unchained() internal onlyInitializing {
|
||||
}
|
||||
struct Checkpoint {
|
||||
@ -0,0 +1,18 @@
|
||||
diff --git a/contracts/token/ERC20/extensions/ERC20VotesCompUpgradeable.sol b/contracts/token/ERC20/extensions/ERC20VotesCompUpgradeable.sol
|
||||
index 6f1f8182..0f09ea48 100644
|
||||
--- a/contracts/token/ERC20/extensions/ERC20VotesCompUpgradeable.sol
|
||||
+++ b/contracts/token/ERC20/extensions/ERC20VotesCompUpgradeable.sol
|
||||
@@ -25,13 +25,6 @@ import "../../../proxy/utils/Initializable.sol";
|
||||
* _Available since v4.2._
|
||||
*/
|
||||
abstract contract ERC20VotesCompUpgradeable is Initializable, ERC20VotesUpgradeable {
|
||||
- function __ERC20VotesComp_init() internal onlyInitializing {
|
||||
- __Context_init_unchained();
|
||||
- __EIP712_init_unchained(name, "1");
|
||||
- __ERC20Votes_init_unchained();
|
||||
- __ERC20VotesComp_init_unchained();
|
||||
- }
|
||||
-
|
||||
function __ERC20VotesComp_init_unchained() internal onlyInitializing {
|
||||
}
|
||||
/**
|
||||
159
scripts/upgradeable/patch/05-fix-governor-initializers.patch
Normal file
159
scripts/upgradeable/patch/05-fix-governor-initializers.patch
Normal file
@ -0,0 +1,159 @@
|
||||
diff --git a/contracts/governance/compatibility/GovernorCompatibilityBravoUpgradeable.sol b/contracts/governance/compatibility/GovernorCompatibilityBravoUpgradeable.sol
|
||||
index 1f6895a6..86518b84 100644
|
||||
--- a/contracts/governance/compatibility/GovernorCompatibilityBravoUpgradeable.sol
|
||||
+++ b/contracts/governance/compatibility/GovernorCompatibilityBravoUpgradeable.sol
|
||||
@@ -21,7 +21,6 @@ abstract contract GovernorCompatibilityBravoUpgradeable is Initializable, IGover
|
||||
function __GovernorCompatibilityBravo_init() internal onlyInitializing {
|
||||
__Context_init_unchained();
|
||||
__ERC165_init_unchained();
|
||||
- __EIP712_init_unchained(name_, version());
|
||||
__IGovernor_init_unchained();
|
||||
__IGovernorTimelock_init_unchained();
|
||||
__IGovernorCompatibilityBravo_init_unchained();
|
||||
diff --git a/contracts/governance/extensions/GovernorCountingSimpleUpgradeable.sol b/contracts/governance/extensions/GovernorCountingSimpleUpgradeable.sol
|
||||
index 4873166b..6a88e6b4 100644
|
||||
--- a/contracts/governance/extensions/GovernorCountingSimpleUpgradeable.sol
|
||||
+++ b/contracts/governance/extensions/GovernorCountingSimpleUpgradeable.sol
|
||||
@@ -14,7 +14,6 @@ abstract contract GovernorCountingSimpleUpgradeable is Initializable, GovernorUp
|
||||
function __GovernorCountingSimple_init() internal onlyInitializing {
|
||||
__Context_init_unchained();
|
||||
__ERC165_init_unchained();
|
||||
- __EIP712_init_unchained(name_, version());
|
||||
__IGovernor_init_unchained();
|
||||
__GovernorCountingSimple_init_unchained();
|
||||
}
|
||||
diff --git a/contracts/governance/extensions/GovernorTimelockCompoundUpgradeable.sol b/contracts/governance/extensions/GovernorTimelockCompoundUpgradeable.sol
|
||||
index c6ed355a..9236c546 100644
|
||||
--- a/contracts/governance/extensions/GovernorTimelockCompoundUpgradeable.sol
|
||||
+++ b/contracts/governance/extensions/GovernorTimelockCompoundUpgradeable.sol
|
||||
@@ -96,7 +96,6 @@ abstract contract GovernorTimelockCompoundUpgradeable is Initializable, IGoverno
|
||||
function __GovernorTimelockCompound_init(ICompoundTimelockUpgradeable timelockAddress) internal onlyInitializing {
|
||||
__Context_init_unchained();
|
||||
__ERC165_init_unchained();
|
||||
- __EIP712_init_unchained(name_, version());
|
||||
__IGovernor_init_unchained();
|
||||
__IGovernorTimelock_init_unchained();
|
||||
__GovernorTimelockCompound_init_unchained(timelockAddress);
|
||||
diff --git a/contracts/governance/extensions/GovernorTimelockControlUpgradeable.sol b/contracts/governance/extensions/GovernorTimelockControlUpgradeable.sol
|
||||
index 3d6a5de5..ad5f505e 100644
|
||||
--- a/contracts/governance/extensions/GovernorTimelockControlUpgradeable.sol
|
||||
+++ b/contracts/governance/extensions/GovernorTimelockControlUpgradeable.sol
|
||||
@@ -33,7 +33,6 @@ abstract contract GovernorTimelockControlUpgradeable is Initializable, IGovernor
|
||||
function __GovernorTimelockControl_init(TimelockControllerUpgradeable timelockAddress) internal onlyInitializing {
|
||||
__Context_init_unchained();
|
||||
__ERC165_init_unchained();
|
||||
- __EIP712_init_unchained(name_, version());
|
||||
__IGovernor_init_unchained();
|
||||
__IGovernorTimelock_init_unchained();
|
||||
__GovernorTimelockControl_init_unchained(timelockAddress);
|
||||
diff --git a/contracts/governance/extensions/GovernorVotesCompUpgradeable.sol b/contracts/governance/extensions/GovernorVotesCompUpgradeable.sol
|
||||
index cc83b3ed..5398f15b 100644
|
||||
--- a/contracts/governance/extensions/GovernorVotesCompUpgradeable.sol
|
||||
+++ b/contracts/governance/extensions/GovernorVotesCompUpgradeable.sol
|
||||
@@ -17,7 +17,6 @@ abstract contract GovernorVotesCompUpgradeable is Initializable, GovernorUpgrade
|
||||
function __GovernorVotesComp_init(ERC20VotesCompUpgradeable token_) internal onlyInitializing {
|
||||
__Context_init_unchained();
|
||||
__ERC165_init_unchained();
|
||||
- __EIP712_init_unchained(name_, version());
|
||||
__IGovernor_init_unchained();
|
||||
__GovernorVotesComp_init_unchained(token_);
|
||||
}
|
||||
diff --git a/contracts/governance/extensions/GovernorVotesQuorumFractionUpgradeable.sol b/contracts/governance/extensions/GovernorVotesQuorumFractionUpgradeable.sol
|
||||
index 5d7a88bc..39f97903 100644
|
||||
--- a/contracts/governance/extensions/GovernorVotesQuorumFractionUpgradeable.sol
|
||||
+++ b/contracts/governance/extensions/GovernorVotesQuorumFractionUpgradeable.sol
|
||||
@@ -19,7 +19,6 @@ abstract contract GovernorVotesQuorumFractionUpgradeable is Initializable, Gover
|
||||
function __GovernorVotesQuorumFraction_init(uint256 quorumNumeratorValue) internal onlyInitializing {
|
||||
__Context_init_unchained();
|
||||
__ERC165_init_unchained();
|
||||
- __EIP712_init_unchained(name_, version());
|
||||
__IGovernor_init_unchained();
|
||||
__GovernorVotesQuorumFraction_init_unchained(quorumNumeratorValue);
|
||||
}
|
||||
diff --git a/contracts/governance/extensions/GovernorVotesUpgradeable.sol b/contracts/governance/extensions/GovernorVotesUpgradeable.sol
|
||||
index cdfd0ae7..48408d9c 100644
|
||||
--- a/contracts/governance/extensions/GovernorVotesUpgradeable.sol
|
||||
+++ b/contracts/governance/extensions/GovernorVotesUpgradeable.sol
|
||||
@@ -18,7 +18,6 @@ abstract contract GovernorVotesUpgradeable is Initializable, GovernorUpgradeable
|
||||
function __GovernorVotes_init(IVotesUpgradeable tokenAddress) internal onlyInitializing {
|
||||
__Context_init_unchained();
|
||||
__ERC165_init_unchained();
|
||||
- __EIP712_init_unchained(name_, version());
|
||||
__IGovernor_init_unchained();
|
||||
__GovernorVotes_init_unchained(tokenAddress);
|
||||
}
|
||||
diff --git a/contracts/governance/extensions/GovernorProposalThresholdUpgradeable.sol b/contracts/governance/extensions/GovernorProposalThresholdUpgradeable.sol
|
||||
index c66ebc16..3bba9501 100644
|
||||
--- a/contracts/governance/extensions/GovernorProposalThresholdUpgradeable.sol
|
||||
+++ b/contracts/governance/extensions/GovernorProposalThresholdUpgradeable.sol
|
||||
@@ -14,7 +14,6 @@ abstract contract GovernorProposalThresholdUpgradeable is Initializable, Governo
|
||||
function __GovernorProposalThreshold_init() internal onlyInitializing {
|
||||
__Context_init_unchained();
|
||||
__ERC165_init_unchained();
|
||||
- __EIP712_init_unchained(name_, version());
|
||||
__IGovernor_init_unchained();
|
||||
__GovernorProposalThreshold_init_unchained();
|
||||
}
|
||||
diff --git a/contracts/governance/extensions/GovernorSettingsUpgradeable.sol b/contracts/governance/extensions/GovernorSettingsUpgradeable.sol
|
||||
index fbbb5ec1..06e8b9dd 100644
|
||||
--- a/contracts/governance/extensions/GovernorSettingsUpgradeable.sol
|
||||
+++ b/contracts/governance/extensions/GovernorSettingsUpgradeable.sol
|
||||
@@ -30,7 +30,6 @@ abstract contract GovernorSettingsUpgradeable is Initializable, GovernorUpgradea
|
||||
) internal onlyInitializing {
|
||||
__Context_init_unchained();
|
||||
__ERC165_init_unchained();
|
||||
- __EIP712_init_unchained(name_, version());
|
||||
__IGovernor_init_unchained();
|
||||
__GovernorSettings_init_unchained(initialVotingDelay, initialVotingPeriod, initialProposalThreshold);
|
||||
}
|
||||
diff --git a/contracts/mocks/wizard/MyGovernor1Upgradeable.sol b/contracts/mocks/wizard/MyGovernor1Upgradeable.sol
|
||||
index df6ccdaf..db9998ed 100644
|
||||
--- a/contracts/mocks/wizard/MyGovernor1Upgradeable.sol
|
||||
+++ b/contracts/mocks/wizard/MyGovernor1Upgradeable.sol
|
||||
@@ -18,7 +18,7 @@ contract MyGovernor1Upgradeable is
|
||||
function __MyGovernor1_init(IVotesUpgradeable _token, TimelockControllerUpgradeable _timelock) internal onlyInitializing {
|
||||
__Context_init_unchained();
|
||||
__ERC165_init_unchained();
|
||||
- __EIP712_init_unchained(name_, version());
|
||||
+ __EIP712_init_unchained("MyGovernor", version());
|
||||
__IGovernor_init_unchained();
|
||||
__IGovernorTimelock_init_unchained();
|
||||
__Governor_init_unchained("MyGovernor");
|
||||
diff --git a/contracts/mocks/wizard/MyGovernor2Upgradeable.sol b/contracts/mocks/wizard/MyGovernor2Upgradeable.sol
|
||||
index b07261a4..4ec9b6ce 100644
|
||||
--- a/contracts/mocks/wizard/MyGovernor2Upgradeable.sol
|
||||
+++ b/contracts/mocks/wizard/MyGovernor2Upgradeable.sol
|
||||
@@ -20,7 +20,7 @@ contract MyGovernor2Upgradeable is
|
||||
function __MyGovernor2_init(IVotesUpgradeable _token, TimelockControllerUpgradeable _timelock) internal onlyInitializing {
|
||||
__Context_init_unchained();
|
||||
__ERC165_init_unchained();
|
||||
- __EIP712_init_unchained(name_, version());
|
||||
+ __EIP712_init_unchained("MyGovernor", version());
|
||||
__IGovernor_init_unchained();
|
||||
__IGovernorTimelock_init_unchained();
|
||||
__Governor_init_unchained("MyGovernor");
|
||||
diff --git a/contracts/mocks/wizard/MyGovernor3Upgradeable.sol b/contracts/mocks/wizard/MyGovernor3Upgradeable.sol
|
||||
index 223ccb94..e05b6ce7 100644
|
||||
--- a/contracts/mocks/wizard/MyGovernor3Upgradeable.sol
|
||||
+++ b/contracts/mocks/wizard/MyGovernor3Upgradeable.sol
|
||||
@@ -18,7 +18,7 @@ contract MyGovernorUpgradeable is
|
||||
function __MyGovernor_init(IVotesUpgradeable _token, TimelockControllerUpgradeable _timelock) internal onlyInitializing {
|
||||
__Context_init_unchained();
|
||||
__ERC165_init_unchained();
|
||||
- __EIP712_init_unchained(name_, version());
|
||||
+ __EIP712_init_unchained("MyGovernor", version());
|
||||
__IGovernor_init_unchained();
|
||||
__IGovernorTimelock_init_unchained();
|
||||
__IGovernorCompatibilityBravo_init_unchained();
|
||||
diff --git a/contracts/governance/extensions/GovernorPreventLateQuorumUpgradeable.sol b/contracts/governance/extensions/GovernorPreventLateQuorumUpgradeable.sol
|
||||
index 9b48de71..c28f3b50 100644
|
||||
--- a/contracts/governance/extensions/GovernorPreventLateQuorumUpgradeable.sol
|
||||
+++ b/contracts/governance/extensions/GovernorPreventLateQuorumUpgradeable.sol
|
||||
@@ -38,7 +38,6 @@ abstract contract GovernorPreventLateQuorumUpgradeable is Initializable, Governo
|
||||
function __GovernorPreventLateQuorum_init(uint64 initialVoteExtension) internal onlyInitializing {
|
||||
__Context_init_unchained();
|
||||
__ERC165_init_unchained();
|
||||
- __EIP712_init_unchained(name_, version());
|
||||
__IGovernor_init_unchained();
|
||||
__GovernorPreventLateQuorum_init_unchained(initialVoteExtension);
|
||||
}
|
||||
38
scripts/upgradeable/transpile-onto.sh
Normal file
38
scripts/upgradeable/transpile-onto.sh
Normal file
@ -0,0 +1,38 @@
|
||||
#!/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 -q --verify "$target"; then
|
||||
git reset --soft "$target"
|
||||
git checkout "$target"
|
||||
else
|
||||
git checkout --orphan "$target"
|
||||
if [ -n "$base" ] && git rev-parse -q --verify "$base"; then
|
||||
git reset --soft "$base"
|
||||
fi
|
||||
fi
|
||||
|
||||
if ! git diff --quiet --cached; then
|
||||
git commit -m "Transpile $commit"
|
||||
fi
|
||||
|
||||
git checkout "$branch"
|
||||
22
scripts/upgradeable/transpile.sh
Normal file
22
scripts/upgradeable/transpile.sh
Normal file
@ -0,0 +1,22 @@
|
||||
#!/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 except Clones library
|
||||
# -p: emit public initializer
|
||||
npx @openzeppelin/upgrade-safe-transpiler@latest -D \
|
||||
-i contracts/proxy/utils/Initializable.sol \
|
||||
-x 'contracts/proxy/**/*' \
|
||||
-x '!contracts/proxy/Clones.sol' \
|
||||
-x '!contracts/proxy/ERC1967/ERC1967{Storage,Upgrade}.sol' \
|
||||
-x '!contracts/proxy/utils/UUPSUpgradeable.sol' \
|
||||
-x '!contracts/proxy/beacon/IBeacon.sol' \
|
||||
-p 'contracts/**/presets/**/*'
|
||||
|
||||
for p in scripts/upgradeable/patch/*.patch; do
|
||||
git apply "$p"
|
||||
done
|
||||
Reference in New Issue
Block a user