diff --git a/.github/workflows/checks.yml b/.github/workflows/checks.yml index b0f8a8916..1800f12a1 100644 --- a/.github/workflows/checks.yml +++ b/.github/workflows/checks.yml @@ -14,6 +14,7 @@ concurrency: jobs: lint: + if: github.repository != 'OpenZeppelin/openzeppelin-contracts-upgradeable' runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 @@ -33,8 +34,10 @@ jobs: ENABLE_GAS_REPORT: true - run: npm run test:inheritance - run: npm run test:generation + if: github.repository != 'OpenZeppelin/openzeppelin-contracts-upgradeable' coverage: + if: github.repository != 'OpenZeppelin/openzeppelin-contracts-upgradeable' runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 @@ -46,6 +49,7 @@ jobs: - uses: codecov/codecov-action@v3 slither: + if: github.repository != 'OpenZeppelin/openzeppelin-contracts-upgradeable' runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 diff --git a/CHANGELOG.md b/CHANGELOG.md index 6bb906218..1ee50f71f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,7 @@ * `TimelockController`: Migrate `_call` to `_execute` and allow inheritance and overriding similar to `Governor`. ([#3317](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3317)) * `CrossChainEnabledPolygonChild`: replace the `require` statement with the custom error `NotCrossChainCall`. ([#3380](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3380)) * `ERC20FlashMint`: Add customizable flash fee receiver. ([#3327](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3327)) - * `ERC20TokenizedVault`: add an extension of `ERC20` that implements the ERC4626 Tokenized Vault Standard. ([#3171](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3171)) + * `ERC4626`: add an extension of `ERC20` that implements the ERC4626 Tokenized Vault Standard. ([#3171](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3171)) * `SafeERC20`: add `safePermit` as mitigation against phantom permit functions. ([#3280](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3280)) * `Math`: add a `mulDiv` function that can round the result either up or down. ([#3171](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3171)) * `Math`: Add a `sqrt` function to compute square roots of integers, rounding either up or down. ([#3242](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3242)) diff --git a/contracts/mocks/ERC20TokenizedVaultMock.sol b/contracts/mocks/ERC4626Mock.sol similarity index 69% rename from contracts/mocks/ERC20TokenizedVaultMock.sol rename to contracts/mocks/ERC4626Mock.sol index 1aabd94ef..71cefacaa 100644 --- a/contracts/mocks/ERC20TokenizedVaultMock.sol +++ b/contracts/mocks/ERC4626Mock.sol @@ -2,15 +2,15 @@ pragma solidity ^0.8.0; -import "../token/ERC20/extensions/ERC20TokenizedVault.sol"; +import "../token/ERC20/extensions/ERC4626.sol"; // mock class using ERC20 -contract ERC20TokenizedVaultMock is ERC20TokenizedVault { +contract ERC4626Mock is ERC4626 { constructor( IERC20Metadata asset, string memory name, string memory symbol - ) ERC20(name, symbol) ERC20TokenizedVault(asset) {} + ) ERC20(name, symbol) ERC4626(asset) {} function mockMint(address account, uint256 amount) public { _mint(account, amount); diff --git a/contracts/token/ERC20/README.adoc b/contracts/token/ERC20/README.adoc index dd1845f07..ae2ce3644 100644 --- a/contracts/token/ERC20/README.adoc +++ b/contracts/token/ERC20/README.adoc @@ -24,7 +24,7 @@ Additionally there are multiple custom extensions, including: * {ERC20Votes}: support for voting and vote delegation. * {ERC20VotesComp}: support for voting and vote delegation (compatible with Compound's token, with uint96 restrictions). * {ERC20Wrapper}: wrapper to create an ERC20 backed by another ERC20, with deposit and withdraw methods. Useful in conjunction with {ERC20Votes}. -* {ERC20TokenizedVault}: tokenized vault that manages shares (represented as ERC20) that are backed by assets (another ERC20). +* {ERC4626}: tokenized vault that manages shares (represented as ERC20) that are backed by assets (another ERC20). Finally, there are some utilities to interact with ERC20 contracts in various ways. @@ -63,7 +63,7 @@ NOTE: This core set of contracts is designed to be unopinionated, allowing devel {{ERC20FlashMint}} -{{ERC20TokenizedVault}} +{{ERC4626}} == Draft EIPs diff --git a/contracts/token/ERC20/extensions/ERC20TokenizedVault.sol b/contracts/token/ERC20/extensions/ERC4626.sol similarity index 94% rename from contracts/token/ERC20/extensions/ERC20TokenizedVault.sol rename to contracts/token/ERC20/extensions/ERC4626.sol index e1aaab83e..b3aaa1a11 100644 --- a/contracts/token/ERC20/extensions/ERC20TokenizedVault.sol +++ b/contracts/token/ERC20/extensions/ERC4626.sol @@ -18,7 +18,7 @@ import "../../../utils/math/Math.sol"; * * _Available since v4.7._ */ -abstract contract ERC20TokenizedVault is ERC20, IERC4626 { +abstract contract ERC4626 is ERC20, IERC4626 { using Math for uint256; IERC20Metadata private immutable _asset; @@ -92,7 +92,7 @@ abstract contract ERC20TokenizedVault is ERC20, IERC4626 { /** @dev See {IERC4262-deposit} */ function deposit(uint256 assets, address receiver) public virtual override returns (uint256) { - require(assets <= maxDeposit(receiver), "ERC20TokenizedVault: deposit more than max"); + require(assets <= maxDeposit(receiver), "ERC4626: deposit more than max"); uint256 shares = previewDeposit(assets); _deposit(_msgSender(), receiver, assets, shares); @@ -102,7 +102,7 @@ abstract contract ERC20TokenizedVault is ERC20, IERC4626 { /** @dev See {IERC4262-mint} */ function mint(uint256 shares, address receiver) public virtual override returns (uint256) { - require(shares <= maxMint(receiver), "ERC20TokenizedVault: mint more than max"); + require(shares <= maxMint(receiver), "ERC4626: mint more than max"); uint256 assets = previewMint(shares); _deposit(_msgSender(), receiver, assets, shares); @@ -116,7 +116,7 @@ abstract contract ERC20TokenizedVault is ERC20, IERC4626 { address receiver, address owner ) public virtual override returns (uint256) { - require(assets <= maxWithdraw(owner), "ERC20TokenizedVault: withdraw more than max"); + require(assets <= maxWithdraw(owner), "ERC4626: withdraw more than max"); uint256 shares = previewWithdraw(assets); _withdraw(_msgSender(), receiver, owner, assets, shares); @@ -130,7 +130,7 @@ abstract contract ERC20TokenizedVault is ERC20, IERC4626 { address receiver, address owner ) public virtual override returns (uint256) { - require(shares <= maxRedeem(owner), "ERC20TokenizedVault: redeem more than max"); + require(shares <= maxRedeem(owner), "ERC4626: redeem more than max"); uint256 assets = previewRedeem(shares); _withdraw(_msgSender(), receiver, owner, assets, shares); diff --git a/hardhat.config.js b/hardhat.config.js index 1fbf856b2..4a0676fd5 100644 --- a/hardhat.config.js +++ b/hardhat.config.js @@ -30,10 +30,15 @@ const argv = require('yargs/yargs')() choices: [ 'production', 'development' ], default: 'development', }, + ir: { + alias: 'enableIR', + type: 'boolean', + default: false, + }, compiler: { alias: 'compileVersion', type: 'string', - default: '0.8.9', + default: '0.8.13', }, coinmarketcap: { alias: 'coinmarketcapApiKey', @@ -65,6 +70,7 @@ module.exports = { enabled: withOptimizations, runs: 200, }, + viaIR: withOptimizations && argv.ir, }, }, networks: { diff --git a/scripts/checks/generation.sh b/scripts/checks/generation.sh index 165c35a06..00d609f94 100755 --- a/scripts/checks/generation.sh +++ b/scripts/checks/generation.sh @@ -3,4 +3,4 @@ set -euo pipefail npm run generate -git diff --quiet --exit-code +git diff -R --exit-code diff --git a/scripts/generate/run.js b/scripts/generate/run.js index 5ebb1b37a..0072653d0 100755 --- a/scripts/generate/run.js +++ b/scripts/generate/run.js @@ -7,7 +7,7 @@ function getVersion (path) { try { return fs .readFileSync(path, 'utf8') - .match(/\/\/ OpenZeppelin Contracts \(last updated v\d+\.\d+\.\d+\)/)[0]; + .match(/\/\/ OpenZeppelin Contracts \(last updated v[^)]+\)/)[0]; } catch (err) { return null; } diff --git a/test/governance/TimelockController.test.js b/test/governance/TimelockController.test.js index 12abcac8c..2274bb0a4 100644 --- a/test/governance/TimelockController.test.js +++ b/test/governance/TimelockController.test.js @@ -201,7 +201,7 @@ contract('TimelockController', function (accounts) { ); }); - it('prevent non-proposer from commiting', async function () { + it('prevent non-proposer from committing', async function () { await expectRevert( this.mock.schedule( this.operation.target, @@ -438,7 +438,7 @@ contract('TimelockController', function (accounts) { ); }); - it('prevent non-proposer from commiting', async function () { + it('prevent non-proposer from committing', async function () { await expectRevert( this.mock.scheduleBatch( this.operation.targets, diff --git a/test/token/ERC20/extensions/ERC20TokenizedVault.test.js b/test/token/ERC20/extensions/ERC4626.test.js similarity index 98% rename from test/token/ERC20/extensions/ERC20TokenizedVault.test.js rename to test/token/ERC20/extensions/ERC4626.test.js index 0c20570d7..63b995f40 100644 --- a/test/token/ERC20/extensions/ERC20TokenizedVault.test.js +++ b/test/token/ERC20/extensions/ERC4626.test.js @@ -2,12 +2,12 @@ const { BN, constants, expectEvent, expectRevert } = require('@openzeppelin/test const { expect } = require('chai'); const ERC20DecimalsMock = artifacts.require('ERC20DecimalsMock'); -const ERC20TokenizedVaultMock = artifacts.require('ERC20TokenizedVaultMock'); +const ERC4626Mock = artifacts.require('ERC4626Mock'); const parseToken = (token) => (new BN(token)).mul(new BN('1000000000000')); const parseShare = (share) => (new BN(share)).mul(new BN('1000000000000000000')); -contract('ERC20TokenizedVault', function (accounts) { +contract('ERC4626', function (accounts) { const [ holder, recipient, spender, other, user1, user2 ] = accounts; const name = 'My Token'; @@ -15,7 +15,7 @@ contract('ERC20TokenizedVault', function (accounts) { beforeEach(async function () { this.token = await ERC20DecimalsMock.new(name, symbol, 12); - this.vault = await ERC20TokenizedVaultMock.new(this.token.address, name + ' Vault', symbol + 'V'); + this.vault = await ERC4626Mock.new(this.token.address, name + ' Vault', symbol + 'V'); await this.token.mint(holder, web3.utils.toWei('100')); await this.token.approve(this.vault.address, constants.MAX_UINT256, { from: holder }); @@ -227,7 +227,7 @@ contract('ERC20TokenizedVault', function (accounts) { await expectRevert.unspecified(this.vault.previewDeposit(parseToken(1))); await expectRevert( this.vault.deposit(parseToken(1), recipient, { from: holder }), - 'ERC20TokenizedVault: deposit more than max', + 'ERC4626: deposit more than max', ); }); @@ -400,7 +400,7 @@ contract('ERC20TokenizedVault', function (accounts) { it('multiple mint, deposit, redeem & withdrawal', async function () { // test designed with both asset using similar decimals this.token = await ERC20DecimalsMock.new(name, symbol, 18); - this.vault = await ERC20TokenizedVaultMock.new(this.token.address, name + ' Vault', symbol + 'V'); + this.vault = await ERC4626Mock.new(this.token.address, name + ' Vault', symbol + 'V'); await this.token.mint(user1, 4000); await this.token.mint(user2, 7001);