Compare commits
111 Commits
v4.9.2
...
frangio-pa
| Author | SHA1 | Date | |
|---|---|---|---|
| 0251ffbded | |||
| da258a58ae | |||
| ac48658397 | |||
| 06861dce54 | |||
| 37270eb08a | |||
| 621b867b1a | |||
| 04342118dc | |||
| 874c2d3c02 | |||
| d6a8b2ccd7 | |||
| 023894deef | |||
| f29307cfe0 | |||
| 8cab922347 | |||
| cb4bf950df | |||
| c44c220254 | |||
| da89c438f1 | |||
| a7a94c7746 | |||
| 1e0e4e20bb | |||
| 6ddacdbde8 | |||
| dac2457a80 | |||
| b66c77a1fc | |||
| 9fa550c62f | |||
| 2271e2c58d | |||
| 365aca6d60 | |||
| 1d0dbcf9ab | |||
| 1f4e33fb72 | |||
| fc19a7947c | |||
| c95a445130 | |||
| 1a77a508f9 | |||
| 002a7c8812 | |||
| cd48b3eab3 | |||
| 6724873895 | |||
| c014c8f148 | |||
| ff85c7b0eb | |||
| 05ef6924ac | |||
| 2477534260 | |||
| ac5480e7ca | |||
| ef103f37e4 | |||
| 5cc1ea0a39 | |||
| 7cc2cbfeb5 | |||
| 604025400f | |||
| d6c7cee321 | |||
| fe08f58c69 | |||
| b425a72240 | |||
| 08fd777f6d | |||
| e73f90fa9d | |||
| cc04263170 | |||
| 1d5bcd04e7 | |||
| d9474327a4 | |||
| df2778f38e | |||
| 4fd2f8be33 | |||
| 85696d80ad | |||
| 6c14de4f0c | |||
| 253bfa68c2 | |||
| ffceb3cd98 | |||
| eecd5e15c7 | |||
| 2d1da295e6 | |||
| 3902a410f1 | |||
| 5cef83d2c7 | |||
| 30256fa838 | |||
| 2ee1da12c4 | |||
| 4c713f8cea | |||
| 7bb5592ad5 | |||
| 15c5c71795 | |||
| 4448c13c3c | |||
| 5420879d9b | |||
| 25edd3cd62 | |||
| 238d17cab9 | |||
| 5955d8e85b | |||
| 09329f8a18 | |||
| cbc6145f5f | |||
| 13d5e0466a | |||
| 7e814a3074 | |||
| a1d57bac50 | |||
| 11d65442b3 | |||
| dfef6a68ee | |||
| 0f10efe232 | |||
| 96b95592c3 | |||
| 8de6eba8a3 | |||
| 1642b6639b | |||
| 3ec4307c8a | |||
| f355bd3a2a | |||
| 3e1b25a5cf | |||
| f7b236dca8 | |||
| e5dbc7435e | |||
| 9a2e4cb3a7 | |||
| d095542fa4 | |||
| dff520afae | |||
| 2d05db171a | |||
| e919d96ff2 | |||
| 54c31ad98b | |||
| 5ad74c6d10 | |||
| c5d040beb9 | |||
| 30c3c6c16e | |||
| 147dc89054 | |||
| 7c6e289782 | |||
| d210847e28 | |||
| a290e13099 | |||
| 97bba5adaa | |||
| fbbaf3365b | |||
| 4147005b0c | |||
| 81dbe643a0 | |||
| 9cbe8b340c | |||
| 3c80a42866 | |||
| e2d2ebc8fc | |||
| bc8f442d00 | |||
| 4a9db80cb9 | |||
| 887985413c | |||
| b18cf4ba42 | |||
| 39a752e398 | |||
| 6ff283bebc | |||
| 1cf4db9615 |
5
.changeset/angry-ties-switch.md
Normal file
5
.changeset/angry-ties-switch.md
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
'openzeppelin-solidity': major
|
||||
---
|
||||
|
||||
`TimelockController`: Changed the role architecture to use `DEFAULT_ADMIN_ROLE` as the admin for all roles, instead of the bespoke `TIMELOCK_ADMIN_ROLE` that was used previously. This aligns with the general recommendation for `AccessControl` and makes the addition of new roles easier. Accordingly, the `admin` parameter and timelock will now be granted `DEFAULT_ADMIN_ROLE` instead of `TIMELOCK_ADMIN_ROLE`. ([#3799](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3799))
|
||||
@ -1,5 +0,0 @@
|
||||
---
|
||||
'openzeppelin-solidity': patch
|
||||
---
|
||||
|
||||
`Initializable`: optimize `_disableInitializers` by using `!=` instead of `<`. ([#3787](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3787))
|
||||
4
.changeset/big-plums-cover.md
Normal file
4
.changeset/big-plums-cover.md
Normal file
@ -0,0 +1,4 @@
|
||||
---
|
||||
'openzeppelin-solidity': major
|
||||
---
|
||||
Use `abi.encodeCall` in place of `abi.encodeWithSelector` and `abi.encodeWithSignature` for improved type-checking of parameters
|
||||
5
.changeset/blue-horses-do.md
Normal file
5
.changeset/blue-horses-do.md
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
'openzeppelin-solidity': major
|
||||
---
|
||||
|
||||
`ERC2771Forwarder`: Added `deadline` for expiring transactions, batching, and more secure handling of `msg.value`.
|
||||
5
.changeset/blue-scissors-design.md
Normal file
5
.changeset/blue-scissors-design.md
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
'openzeppelin-solidity': minor
|
||||
---
|
||||
|
||||
`Math`: Make `ceilDiv` to revert on 0 division even if the numerator is 0
|
||||
5
.changeset/bright-tomatoes-sing.md
Normal file
5
.changeset/bright-tomatoes-sing.md
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
'openzeppelin-solidity': major
|
||||
---
|
||||
|
||||
`ERC20`, `ERC1155`: Deleted `_beforeTokenTransfer` and `_afterTokenTransfer` hooks, added a new internal `_update` function for customizations, and refactored all extensions using those hooks to use `_update` instead. ([#3838](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3838), [#3876](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3876))
|
||||
5
.changeset/chilled-spiders-attack.md
Normal file
5
.changeset/chilled-spiders-attack.md
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
'openzeppelin-solidity': major
|
||||
---
|
||||
|
||||
`ERC1155Supply`: add a `totalSupply()` function that returns the total amount of token circulating, this change will restrict the total tokens minted across all ids to 2\*\*256-1 .
|
||||
5
.changeset/clever-pumas-beg.md
Normal file
5
.changeset/clever-pumas-beg.md
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
'openzeppelin-solidity': major
|
||||
---
|
||||
|
||||
`Ownable`: Add an `initialOwner` parameter to the constructor, making the ownership initialization explicit.
|
||||
@ -1,5 +0,0 @@
|
||||
---
|
||||
'openzeppelin-solidity': minor
|
||||
---
|
||||
|
||||
`ReentrancyGuard`: Add a `_reentrancyGuardEntered` function to expose the guard status. ([#3714](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3714))
|
||||
@ -1,5 +0,0 @@
|
||||
---
|
||||
'openzeppelin-solidity': patch
|
||||
---
|
||||
|
||||
`Ownable2Step`: make `acceptOwnership` public virtual to enable usecases that require overriding it. ([#3960](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3960))
|
||||
@ -1,5 +0,0 @@
|
||||
---
|
||||
'openzeppelin-solidity': minor
|
||||
---
|
||||
|
||||
`ERC721Wrapper`: add a new extension of the `ERC721` token which wraps an underlying token. Deposit and withdraw guarantee that the ownership of each token is backed by a corresponding underlying token with the same identifier.
|
||||
5
.changeset/eighty-crabs-listen.md
Normal file
5
.changeset/eighty-crabs-listen.md
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
'openzeppelin-solidity': patch
|
||||
---
|
||||
|
||||
Optimize `Strings.equal`
|
||||
@ -1,5 +0,0 @@
|
||||
---
|
||||
'openzeppelin-solidity': minor
|
||||
---
|
||||
|
||||
`EnumerableMap`: add a `keys()` function that returns an array containing all the keys. ([#3920](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3920))
|
||||
@ -1,5 +0,0 @@
|
||||
---
|
||||
'openzeppelin-solidity': patch
|
||||
---
|
||||
|
||||
`UUPSUpgradeable.sol`: Change visibility to the functions `upgradeTo ` and `upgradeToAndCall ` from `external` to `public`.
|
||||
@ -1,5 +0,0 @@
|
||||
---
|
||||
'openzeppelin-solidity': patch
|
||||
---
|
||||
|
||||
`TimelockController`: Add the `CallSalt` event to emit on operation schedule.
|
||||
5
.changeset/flat-bottles-wonder.md
Normal file
5
.changeset/flat-bottles-wonder.md
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
'openzeppelin-solidity': minor
|
||||
---
|
||||
|
||||
Replace some uses of `abi.encodePacked` with clearer alternatives (e.g. `bytes.concat`, `string.concat`).
|
||||
@ -1,5 +0,0 @@
|
||||
---
|
||||
'openzeppelin-solidity': minor
|
||||
---
|
||||
|
||||
`Governor`: add a public `cancel(uint256)` function.
|
||||
5
.changeset/four-adults-knock.md
Normal file
5
.changeset/four-adults-knock.md
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
'openzeppelin-solidity': patch
|
||||
---
|
||||
|
||||
`ECDSA`: Use unchecked arithmetic for the `tryRecover` function that receives the `r` and `vs` short-signature fields separately.
|
||||
@ -1,5 +0,0 @@
|
||||
---
|
||||
'openzeppelin-solidity': minor
|
||||
---
|
||||
|
||||
`Governor`: Enable timestamp operation for blockchains without a stable block time. This is achieved by connecting a Governor's internal clock to match a voting token's EIP-6372 interface.
|
||||
5
.changeset/fresh-birds-kiss.md
Normal file
5
.changeset/fresh-birds-kiss.md
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
'openzeppelin-solidity': major
|
||||
---
|
||||
|
||||
`Checkpoints`: library moved from `utils` to `utils/structs`
|
||||
@ -1,5 +0,0 @@
|
||||
---
|
||||
'openzeppelin-solidity': patch
|
||||
---
|
||||
|
||||
Reformatted codebase with latest version of Prettier Solidity. ([#3898](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3898))
|
||||
@ -1,5 +0,0 @@
|
||||
---
|
||||
'openzeppelin-solidity': minor
|
||||
---
|
||||
|
||||
`Strings`: add `equal` method. ([#3774](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3774))
|
||||
5
.changeset/grumpy-bulldogs-call.md
Normal file
5
.changeset/grumpy-bulldogs-call.md
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
'openzeppelin-solidity': major
|
||||
---
|
||||
|
||||
`Governor`: Optimized use of storage for proposal data
|
||||
5
.changeset/grumpy-worms-tease.md
Normal file
5
.changeset/grumpy-worms-tease.md
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
'openzeppelin-solidity': major
|
||||
---
|
||||
|
||||
`ERC1967Utils`: Refactor the `ERC1967Upgrade` abstract contract as a library.
|
||||
5
.changeset/happy-falcons-walk.md
Normal file
5
.changeset/happy-falcons-walk.md
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
'openzeppelin-solidity': major
|
||||
---
|
||||
|
||||
`TransparentUpgradeableProxy`: Admin is now stored in an immutable variable (set during construction) to avoid unnecessary storage reads on every proxy call. This removed the ability to ever change the admin. Transfer of the upgrade capability is exclusively handled through the ownership of the `ProxyAdmin`.
|
||||
@ -1,5 +0,0 @@
|
||||
---
|
||||
'openzeppelin-solidity': minor
|
||||
---
|
||||
|
||||
`IERC5313`: Add an interface for EIP-5313 that is now final.
|
||||
@ -1,5 +0,0 @@
|
||||
---
|
||||
'openzeppelin-solidity': patch
|
||||
---
|
||||
|
||||
`Math`: optimize `log256` rounding check. ([#3745](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3745))
|
||||
5
.changeset/heavy-drinks-fail.md
Normal file
5
.changeset/heavy-drinks-fail.md
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
'openzeppelin-solidity': major
|
||||
---
|
||||
|
||||
`ERC20`: Remove `Approval` event previously emitted in `transferFrom` to indicate that part of the allowance was consumed. With this change, allowances are no longer reconstructible from events. See the code for guidelines on how to re-enable this event if needed.
|
||||
5
.changeset/hip-beds-provide.md
Normal file
5
.changeset/hip-beds-provide.md
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
'openzeppelin-solidity': major
|
||||
---
|
||||
|
||||
Move the logic to validate ERC-1822 during an upgrade from `ERC1967Utils` to `UUPSUpgradeable`.
|
||||
5
.changeset/hot-coins-judge.md
Normal file
5
.changeset/hot-coins-judge.md
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
'openzeppelin-solidity': minor
|
||||
---
|
||||
|
||||
`Arrays`: Add `unsafeMemoryAccess` helpers to read from a memory array without checking the length.
|
||||
5
.changeset/hot-plums-approve.md
Normal file
5
.changeset/hot-plums-approve.md
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
'openzeppelin-solidity': minor
|
||||
---
|
||||
|
||||
`GovernorTimelockControl`: Clean up timelock id on execution for gas refund.
|
||||
@ -1,5 +0,0 @@
|
||||
---
|
||||
'openzeppelin-solidity': patch
|
||||
---
|
||||
|
||||
`ERC20Votes`: optimize by using unchecked arithmetic. ([#3748](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3748))
|
||||
5
.changeset/little-falcons-build.md
Normal file
5
.changeset/little-falcons-build.md
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
'openzeppelin-solidity': minor
|
||||
---
|
||||
|
||||
`EIP712`: Add internal getters for the name and version strings
|
||||
@ -1,5 +0,0 @@
|
||||
---
|
||||
'openzeppelin-solidity': patch
|
||||
---
|
||||
|
||||
`Multicall`: annotate `multicall` function as upgrade safe to not raise a flag for its delegatecall. ([#3961](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3961))
|
||||
@ -1,5 +0,0 @@
|
||||
---
|
||||
'openzeppelin-solidity': minor
|
||||
---
|
||||
|
||||
`IERC4906`: Add an interface for ERC-4906 that is now Final.
|
||||
5
.changeset/lovely-geckos-hide.md
Normal file
5
.changeset/lovely-geckos-hide.md
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
'openzeppelin-solidity': major
|
||||
---
|
||||
|
||||
Replace revert strings and require statements with custom errors.
|
||||
5
.changeset/mean-walls-watch.md
Normal file
5
.changeset/mean-walls-watch.md
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
'openzeppelin-solidity': major
|
||||
---
|
||||
|
||||
`Nonces`: Added a new contract to keep track of user nonces. Used for signatures in `ERC20Permit`, `ERC20Votes`, and `ERC721Votes`. ([#3816](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3816))
|
||||
6
.changeset/mighty-donuts-smile.md
Normal file
6
.changeset/mighty-donuts-smile.md
Normal file
@ -0,0 +1,6 @@
|
||||
---
|
||||
'openzeppelin-solidity': patch
|
||||
---
|
||||
|
||||
`Governor`: Add validation in ERC1155 and ERC721 receiver hooks to ensure Governor is the executor.
|
||||
|
||||
@ -1,5 +0,0 @@
|
||||
---
|
||||
'openzeppelin-solidity': minor
|
||||
---
|
||||
|
||||
`StorageSlot`: Add support for `string` and `bytes`.
|
||||
@ -1,5 +0,0 @@
|
||||
---
|
||||
'openzeppelin-solidity': patch
|
||||
---
|
||||
|
||||
`ERC20Pausable`, `ERC721Pausable`, `ERC1155Pausable`: Add note regarding missing public pausing functionality
|
||||
@ -1,5 +0,0 @@
|
||||
---
|
||||
'openzeppelin-solidity': minor
|
||||
---
|
||||
|
||||
`Votes`, `ERC20Votes`, `ERC721Votes`: support timestamp checkpointing using EIP-6372.
|
||||
5
.changeset/orange-apes-draw.md
Normal file
5
.changeset/orange-apes-draw.md
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
'openzeppelin-solidity': major
|
||||
---
|
||||
|
||||
Switched to using explicit Solidity import statements. Some previously available symbols may now have to be separately imported.
|
||||
@ -1,5 +0,0 @@
|
||||
---
|
||||
'openzeppelin-solidity': minor
|
||||
---
|
||||
|
||||
`ERC4626`: Add mitigation to the inflation attack through virtual shares and assets.
|
||||
@ -1,5 +0,0 @@
|
||||
---
|
||||
'openzeppelin-solidity': minor
|
||||
---
|
||||
|
||||
`Strings`: add `toString` method for signed integers. ([#3773](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3773))
|
||||
@ -1,5 +0,0 @@
|
||||
---
|
||||
'openzeppelin-solidity': minor
|
||||
---
|
||||
|
||||
`ERC20Wrapper`: Make the `underlying` variable private and add a public accessor.
|
||||
5
.changeset/red-dots-fold.md
Normal file
5
.changeset/red-dots-fold.md
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
'openzeppelin-solidity': major
|
||||
---
|
||||
|
||||
Overrides are now used internally for a number of functions that were previously hardcoded to their default implementation in certain locations: `ERC1155Supply.totalSupply`, `ERC721.ownerOf`, `ERC721.balanceOf` and `ERC721.totalSupply` in `ERC721Enumerable`, `ERC20.totalSupply` in `ERC20FlashMint`, and `ERC1967._getImplementation` in `ERC1967Proxy`.
|
||||
5
.changeset/rotten-insects-wash.md
Normal file
5
.changeset/rotten-insects-wash.md
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
'openzeppelin-solidity': major
|
||||
---
|
||||
|
||||
`ProxyAdmin`: Removed `getProxyAdmin` and `getProxyImplementation` getters. ([#3820](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3820))
|
||||
5
.changeset/serious-books-lie.md
Normal file
5
.changeset/serious-books-lie.md
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
'openzeppelin-solidity': patch
|
||||
---
|
||||
|
||||
`ERC1155`: Optimize array allocation.
|
||||
5
.changeset/short-eels-enjoy.md
Normal file
5
.changeset/short-eels-enjoy.md
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
'openzeppelin-solidity': major
|
||||
---
|
||||
|
||||
Bump minimum compiler version required to 0.8.19
|
||||
@ -1,5 +0,0 @@
|
||||
---
|
||||
'openzeppelin-solidity': minor
|
||||
---
|
||||
|
||||
`EIP712`: add EIP-5267 support for better domain discovery.
|
||||
@ -1,5 +0,0 @@
|
||||
---
|
||||
'openzeppelin-solidity': minor
|
||||
---
|
||||
|
||||
`AccessControlDefaultAdminRules`: Add an extension of `AccessControl` with additional security rules for the `DEFAULT_ADMIN_ROLE`.
|
||||
7
.changeset/silly-bees-beam.md
Normal file
7
.changeset/silly-bees-beam.md
Normal file
@ -0,0 +1,7 @@
|
||||
---
|
||||
'openzeppelin-solidity': major
|
||||
---
|
||||
|
||||
`ERC20Votes`: Changed internal vote accounting to reusable `Votes` module previously used by `ERC721Votes`. Removed implicit `ERC20Permit` inheritance. Note that the `DOMAIN_SEPARATOR` getter was previously guaranteed to be available for `ERC20Votes` contracts, but is no longer available unless `ERC20Permit` is explicitly used; ERC-5267 support is included in `ERC20Votes` with `EIP712` and is recommended as an alternative.
|
||||
|
||||
pr: #3816
|
||||
@ -1,5 +0,0 @@
|
||||
---
|
||||
'openzeppelin-solidity': minor
|
||||
---
|
||||
|
||||
`SignatureChecker`: Add `isValidERC1271SignatureNow` for checking a signature directly against a smart contract using ERC-1271.
|
||||
5
.changeset/slimy-penguins-attack.md
Normal file
5
.changeset/slimy-penguins-attack.md
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
'openzeppelin-solidity': major
|
||||
---
|
||||
|
||||
`TransparentUpgradeableProxy`: Removed `admin` and `implementation` getters, which were only callable by the proxy owner and thus not very useful. ([#3820](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3820))
|
||||
@ -1,5 +0,0 @@
|
||||
---
|
||||
'openzeppelin-solidity': patch
|
||||
---
|
||||
|
||||
`ECDSA`: Add a function `toDataWithIntendedValidatorHash` that encodes data with version 0x00 following EIP-191.
|
||||
@ -1,5 +0,0 @@
|
||||
---
|
||||
'openzeppelin-solidity': minor
|
||||
---
|
||||
|
||||
`SafeERC20`: Add a `forceApprove` function to improve compatibility with tokens behaving like USDT.
|
||||
5
.changeset/smooth-books-wink.md
Normal file
5
.changeset/smooth-books-wink.md
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
'openzeppelin-solidity': major
|
||||
---
|
||||
|
||||
`ERC1155`: Remove check for address zero in `balanceOf`.
|
||||
5
.changeset/spotty-hotels-type.md
Normal file
5
.changeset/spotty-hotels-type.md
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
'openzeppelin-solidity': patch
|
||||
---
|
||||
|
||||
`ERC721Consecutive`: Add a `_firstConsecutiveId` internal function that can be overridden to change the id of the first token minted through `_mintConsecutive`.
|
||||
@ -1,5 +0,0 @@
|
||||
---
|
||||
'openzeppelin-solidity': minor
|
||||
---
|
||||
|
||||
`ERC1967Upgrade`: removed contract-wide `oz-upgrades-unsafe-allow delegatecall` annotation, replaced by granular annotation in `UUPSUpgradeable`.
|
||||
5
.changeset/swift-bags-divide.md
Normal file
5
.changeset/swift-bags-divide.md
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
'openzeppelin-solidity': patch
|
||||
---
|
||||
|
||||
`Governor`: Add a mechanism to restrict the address of the proposer using a suffix in the description.
|
||||
@ -1,5 +0,0 @@
|
||||
---
|
||||
'openzeppelin-solidity': patch
|
||||
---
|
||||
|
||||
`MerkleProof`: optimize by using unchecked arithmetic. ([#3745](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3745))
|
||||
5
.changeset/tasty-tomatoes-turn.md
Normal file
5
.changeset/tasty-tomatoes-turn.md
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
'openzeppelin-solidity': major
|
||||
---
|
||||
|
||||
`Strings`: Rename `toString(int256)` to `toStringSigned(int256)`.
|
||||
@ -1,7 +0,0 @@
|
||||
---
|
||||
'openzeppelin-solidity': minor
|
||||
---
|
||||
|
||||
`ERC20Wrapper`: self wrapping and deposit by the wrapper itself are now explicitelly forbiden.
|
||||
|
||||
commit: 3214f6c25
|
||||
5
.changeset/thin-camels-matter.md
Normal file
5
.changeset/thin-camels-matter.md
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
'openzeppelin-solidity': minor
|
||||
---
|
||||
|
||||
`ERC1155`: Bubble errors triggered in the `onERC1155Received` and `onERC1155BatchReceived` hooks.
|
||||
@ -1,5 +0,0 @@
|
||||
---
|
||||
'openzeppelin-solidity': minor
|
||||
---
|
||||
|
||||
`ECDSA`: optimize bytes32 computation by using assembly instead of `abi.encodePacked`.
|
||||
@ -1,5 +0,0 @@
|
||||
---
|
||||
'openzeppelin-solidity': minor
|
||||
---
|
||||
|
||||
`ERC721URIStorage`: Emit ERC-4906 `MetadataUpdate` in `_setTokenURI`.
|
||||
5
.changeset/tough-drinks-hammer.md
Normal file
5
.changeset/tough-drinks-hammer.md
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
'openzeppelin-solidity': patch
|
||||
---
|
||||
|
||||
`ERC1155`: Optimize array accesses by skipping bounds checking when unnecessary.
|
||||
5
.changeset/violet-dancers-cough.md
Normal file
5
.changeset/violet-dancers-cough.md
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
'openzeppelin-solidity': minor
|
||||
---
|
||||
|
||||
Remove the `override` specifier from functions that only override a single interface function.
|
||||
@ -1,5 +0,0 @@
|
||||
---
|
||||
'openzeppelin-solidity': minor
|
||||
---
|
||||
|
||||
`ShortStrings`: Added a library for handling short strings in a gas efficient way, with fallback to storage for longer strings.
|
||||
@ -1,5 +0,0 @@
|
||||
---
|
||||
'openzeppelin-solidity': minor
|
||||
---
|
||||
|
||||
`SignatureChecker`: Allow return data length greater than 32 from EIP-1271 signers.
|
||||
5
.changeset/wild-windows-trade.md
Normal file
5
.changeset/wild-windows-trade.md
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
'openzeppelin-solidity': major
|
||||
---
|
||||
|
||||
`SafeERC20`: Refactor `safeDecreaseAllowance` and `safeIncreaseAllowance` to support USDT-like tokens.
|
||||
@ -1,5 +0,0 @@
|
||||
---
|
||||
'openzeppelin-solidity': minor
|
||||
---
|
||||
|
||||
`UUPSUpgradeable`: added granular `oz-upgrades-unsafe-allow-reachable` annotation to improve upgrade safety checks on latest version of the Upgrades Plugins (starting with `@openzeppelin/upgrades-core@1.21.0`).
|
||||
13
.github/workflows/checks.yml
vendored
13
.github/workflows/checks.yml
vendored
@ -4,6 +4,7 @@ on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- next-v*
|
||||
- release-v*
|
||||
pull_request: {}
|
||||
workflow_dispatch: {}
|
||||
@ -12,6 +13,9 @@ concurrency:
|
||||
group: checks-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
env:
|
||||
NODE_OPTIONS: --max_old_space_size=5120
|
||||
|
||||
jobs:
|
||||
lint:
|
||||
runs-on: ubuntu-latest
|
||||
@ -25,7 +29,6 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
FORCE_COLOR: 1
|
||||
NODE_OPTIONS: --max_old_space_size=4096
|
||||
GAS: true
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
@ -56,8 +59,6 @@ jobs:
|
||||
run: bash scripts/upgradeable/transpile.sh
|
||||
- name: Run tests
|
||||
run: npm run test
|
||||
env:
|
||||
NODE_OPTIONS: --max_old_space_size=4096
|
||||
- name: Check linearisation of the inheritance graph
|
||||
run: npm run test:inheritance
|
||||
- name: Check storage layout
|
||||
@ -85,8 +86,6 @@ jobs:
|
||||
- name: Set up environment
|
||||
uses: ./.github/actions/setup
|
||||
- run: npm run coverage
|
||||
env:
|
||||
NODE_OPTIONS: --max_old_space_size=4096
|
||||
- uses: codecov/codecov-action@v3
|
||||
with:
|
||||
token: ${{ secrets.CODECOV_TOKEN }}
|
||||
@ -101,13 +100,15 @@ jobs:
|
||||
- uses: crytic/slither-action@v0.3.0
|
||||
with:
|
||||
node-version: 18.15
|
||||
slither-version: 0.9.3
|
||||
|
||||
codespell:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Run CodeSpell
|
||||
uses: codespell-project/actions-codespell@v1.0
|
||||
uses: codespell-project/actions-codespell@v2.0
|
||||
with:
|
||||
check_hidden: true
|
||||
check_filenames: true
|
||||
skip: package-lock.json,*.pdf
|
||||
|
||||
8
.github/workflows/release-cycle.yml
vendored
8
.github/workflows/release-cycle.yml
vendored
@ -192,6 +192,8 @@ jobs:
|
||||
pull-requests: write
|
||||
if: needs.state.outputs.merge == 'true'
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
MERGE_BRANCH: merge/${{ github.ref_name }}
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
@ -200,7 +202,9 @@ jobs:
|
||||
uses: ./.github/actions/setup
|
||||
- run: bash scripts/git-user-config.sh
|
||||
- name: Create branch to merge
|
||||
run: bash scripts/release/workflow/prepare-release-merge.sh
|
||||
run: |
|
||||
git checkout -B "$MERGE_BRANCH" "$GITHUB_REF_NAME"
|
||||
git push -f origin "$MERGE_BRANCH"
|
||||
- name: Create PR back to master
|
||||
uses: actions/github-script@v6
|
||||
with:
|
||||
@ -208,7 +212,7 @@ jobs:
|
||||
await github.rest.pulls.create({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
head: 'merge/${{ github.ref_name }}',
|
||||
head: process.env.MERGE_BRANCH,
|
||||
base: 'master',
|
||||
title: '${{ format('Merge {0} branch', github.ref_name) }}'
|
||||
});
|
||||
|
||||
@ -9,6 +9,7 @@
|
||||
"modifier-name-mixedcase": "error",
|
||||
"private-vars-leading-underscore": "error",
|
||||
"var-name-mixedcase": "error",
|
||||
"imports-on-top": "error"
|
||||
"imports-on-top": "error",
|
||||
"no-global-import": "error"
|
||||
}
|
||||
}
|
||||
|
||||
109
CHANGELOG.md
109
CHANGELOG.md
@ -1,5 +1,114 @@
|
||||
# Changelog
|
||||
|
||||
## Unreleased
|
||||
|
||||
> **Warning** Version 5.0 is under active development and should not be used. Install the releases from npm or use the version tags in the repository.
|
||||
|
||||
### Removals
|
||||
|
||||
The following contracts, libraries and functions were removed:
|
||||
|
||||
- `Address.isContract` (because of its ambiguous nature and potential for misuse)
|
||||
- `Checkpoints.History`
|
||||
- `Counters`
|
||||
- `ERC20Snapshot`
|
||||
- `ERC20VotesComp`
|
||||
- `ERC165Storage` (in favor of inheritance based approach)
|
||||
- `ERC777`
|
||||
- `ERC1820Implementer`
|
||||
- `GovernorVotesComp`
|
||||
- `GovernorProposalThreshold` (deprecated since 4.4)
|
||||
- `PaymentSplitter`
|
||||
- `PullPayment`
|
||||
- `SafeMath`
|
||||
- `SignedSafeMath`
|
||||
- `Timers`
|
||||
- `TokenTimelock` (in favor of `VestingWallet`)
|
||||
- All escrow contracts (`Escrow`, `ConditionalEscrow` and `RefundEscrow`)
|
||||
- All cross-chain contracts, including `AccessControlCrossChain` and all the vendored bridge interfaces
|
||||
- All presets in favor of [OpenZeppelin Contracts Wizard](https://wizard.openzeppelin.com/)
|
||||
|
||||
These removals were implemented in the following PRs: [#3637](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3637), [#3880](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3880), [#3945](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3945), [#4258](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/4258), [#4276](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/4276), [#4289](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/4289)
|
||||
|
||||
### How to upgrade from 4.x
|
||||
|
||||
#### ERC20, ERC721, and ERC1155
|
||||
|
||||
These breaking changes will require modifications to ERC20, ERC721, and ERC1155 contracts, since the `_afterTokenTransfer` and `_beforeTokenTransfer` functions were removed. Any customization made through those hooks should now be done overriding the new `_update` function instead.
|
||||
|
||||
Minting and burning are implemented by `_update` and customizations should be done by overriding this function as well. `_mint` and `_burn` are no longer virtual (meaning they are not overridable) to guard against possible inconsistencies.
|
||||
|
||||
For example, a contract using `ERC20`'s `_beforeTokenTransfer` hook would have to be changed in the following way.
|
||||
|
||||
```diff
|
||||
- function _beforeTokenTransfer(
|
||||
+ function _update(
|
||||
address from,
|
||||
address to,
|
||||
uint256 amount
|
||||
) internal virtual override {
|
||||
- super._beforeTokenTransfer(from, to, amount);
|
||||
require(!condition(), "ERC20: wrong condition");
|
||||
+ super._update(from, to, amount);
|
||||
}
|
||||
```
|
||||
|
||||
#### ERC165Storage
|
||||
|
||||
Users that were registering EIP-165 interfaces with `_registerInterface` from `ERC165Storage` should instead do so so by overriding the `supportsInterface` function as seen below:
|
||||
|
||||
```solidity
|
||||
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
|
||||
return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);
|
||||
}
|
||||
```
|
||||
|
||||
## 4.9.2 (2023-06-16)
|
||||
|
||||
- `MerkleProof`: Fix a bug in `processMultiProof` and `processMultiProofCalldata` that allows proving arbitrary leaves if the tree contains a node with value 0 at depth 1.
|
||||
|
||||
## 4.9.1 (2023-06-07)
|
||||
|
||||
- `Governor`: Add a mechanism to restrict the address of the proposer using a suffix in the description.
|
||||
|
||||
## 4.9.0 (2023-05-23)
|
||||
|
||||
- `ReentrancyGuard`: Add a `_reentrancyGuardEntered` function to expose the guard status. ([#3714](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3714))
|
||||
- `ERC721Wrapper`: add a new extension of the `ERC721` token which wraps an underlying token. Deposit and withdraw guarantee that the ownership of each token is backed by a corresponding underlying token with the same identifier. ([#3863](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3863))
|
||||
- `EnumerableMap`: add a `keys()` function that returns an array containing all the keys. ([#3920](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3920))
|
||||
- `Governor`: add a public `cancel(uint256)` function. ([#3983](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3983))
|
||||
- `Governor`: Enable timestamp operation for blockchains without a stable block time. This is achieved by connecting a Governor's internal clock to match a voting token's EIP-6372 interface. ([#3934](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3934))
|
||||
- `Strings`: add `equal` method. ([#3774](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3774))
|
||||
- `IERC5313`: Add an interface for EIP-5313 that is now final. ([#4013](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/4013))
|
||||
- `IERC4906`: Add an interface for ERC-4906 that is now Final. ([#4012](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/4012))
|
||||
- `StorageSlot`: Add support for `string` and `bytes`. ([#4008](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/4008))
|
||||
- `Votes`, `ERC20Votes`, `ERC721Votes`: support timestamp checkpointing using EIP-6372. ([#3934](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3934))
|
||||
- `ERC4626`: Add mitigation to the inflation attack through virtual shares and assets. ([#3979](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3979))
|
||||
- `Strings`: add `toString` method for signed integers. ([#3773](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3773))
|
||||
- `ERC20Wrapper`: Make the `underlying` variable private and add a public accessor. ([#4029](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/4029))
|
||||
- `EIP712`: add EIP-5267 support for better domain discovery. ([#3969](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3969))
|
||||
- `AccessControlDefaultAdminRules`: Add an extension of `AccessControl` with additional security rules for the `DEFAULT_ADMIN_ROLE`. ([#4009](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/4009))
|
||||
- `SignatureChecker`: Add `isValidERC1271SignatureNow` for checking a signature directly against a smart contract using ERC-1271. ([#3932](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3932))
|
||||
- `SafeERC20`: Add a `forceApprove` function to improve compatibility with tokens behaving like USDT. ([#4067](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/4067))
|
||||
- `ERC1967Upgrade`: removed contract-wide `oz-upgrades-unsafe-allow delegatecall` annotation, replaced by granular annotation in `UUPSUpgradeable`. ([#3971](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3971))
|
||||
- `ERC20Wrapper`: self wrapping and deposit by the wrapper itself are now explicitly forbidden. ([#4100](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/4100))
|
||||
- `ECDSA`: optimize bytes32 computation by using assembly instead of `abi.encodePacked`. ([#3853](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3853))
|
||||
- `ERC721URIStorage`: Emit ERC-4906 `MetadataUpdate` in `_setTokenURI`. ([#4012](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/4012))
|
||||
- `ShortStrings`: Added a library for handling short strings in a gas efficient way, with fallback to storage for longer strings. ([#4023](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/4023))
|
||||
- `SignatureChecker`: Allow return data length greater than 32 from EIP-1271 signers. ([#4038](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/4038))
|
||||
- `UUPSUpgradeable`: added granular `oz-upgrades-unsafe-allow-reachable` annotation to improve upgrade safety checks on latest version of the Upgrades Plugins (starting with `@openzeppelin/upgrades-core@1.21.0`). ([#3971](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3971))
|
||||
- `Initializable`: optimize `_disableInitializers` by using `!=` instead of `<`. ([#3787](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3787))
|
||||
- `Ownable2Step`: make `acceptOwnership` public virtual to enable usecases that require overriding it. ([#3960](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3960))
|
||||
- `UUPSUpgradeable.sol`: Change visibility to the functions `upgradeTo ` and `upgradeToAndCall ` from `external` to `public`. ([#3959](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3959))
|
||||
- `TimelockController`: Add the `CallSalt` event to emit on operation schedule. ([#4001](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/4001))
|
||||
- Reformatted codebase with latest version of Prettier Solidity. ([#3898](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3898))
|
||||
- `Math`: optimize `log256` rounding check. ([#3745](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3745))
|
||||
- `ERC20Votes`: optimize by using unchecked arithmetic. ([#3748](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3748))
|
||||
- `Multicall`: annotate `multicall` function as upgrade safe to not raise a flag for its delegatecall. ([#3961](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3961))
|
||||
- `ERC20Pausable`, `ERC721Pausable`, `ERC1155Pausable`: Add note regarding missing public pausing functionality ([#4007](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/4007))
|
||||
- `ECDSA`: Add a function `toDataWithIntendedValidatorHash` that encodes data with version 0x00 following EIP-191. ([#4063](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/4063))
|
||||
- `MerkleProof`: optimize by using unchecked arithmetic. ([#3745](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3745))
|
||||
|
||||
### Breaking changes
|
||||
|
||||
- `EIP712`: Addition of ERC5267 support requires support for user defined value types, which was released in Solidity version 0.8.8. This requires a pragma change from `^0.8.0` to `^0.8.8`.
|
||||
|
||||
@ -114,4 +114,30 @@ In addition to the official Solidity Style Guide we have a number of other conve
|
||||
interface IERC777 {
|
||||
```
|
||||
|
||||
* Contracts not intended to be used standalone should be marked abstract
|
||||
so they are required to be inherited to other contracts.
|
||||
|
||||
```solidity
|
||||
abstract contract AccessControl is ..., {
|
||||
```
|
||||
|
||||
* Unchecked arithmetic blocks should contain comments explaining why overflow is guaranteed not to happen. If the reason is immediately apparent from the line above the unchecked block, the comment may be omitted.
|
||||
|
||||
* Custom errors should be declared following the [EIP-6093](https://eips.ethereum.org/EIPS/eip-6093) rationale whenever reasonable. Also, consider the following:
|
||||
|
||||
* The domain prefix should be picked in the following order:
|
||||
1. Use `ERC<number>` if the error is a violation of an ERC specification.
|
||||
2. Use the name of the underlying component where it belongs (eg. `Governor`, `ECDSA`, or `Timelock`).
|
||||
|
||||
* The location of custom errors should be decided in the following order:
|
||||
1. Take the errors from their underlying ERCs if they're already defined.
|
||||
2. Declare the errors in the underlying interface/library if the error makes sense in its context.
|
||||
3. Declare the error in the implementation if the underlying interface/library is not suitable to do so (eg. interface/library already specified in an ERC).
|
||||
4. Declare the error in an extension if the error only happens in such extension or child contracts.
|
||||
|
||||
* Custom error names should not be declared twice along the library to avoid duplicated identifier declarations when inheriting from multiple contracts.
|
||||
|
||||
* Solidity function overrides should follow the rules listed below in order to avoid introducing unintended consequences due to the interaction with multiple inheritance:
|
||||
|
||||
1. When overriding a function `foo`, always invoke `super.foo`, and pass the same arguments that were received.
|
||||
2. Never use `super` outside of an override, or for a function other than the one being overridden.
|
||||
|
||||
23
README.md
23
README.md
@ -1,3 +1,6 @@
|
||||
> **Warning**
|
||||
> Version 5.0 is under active development. The code in this branch is not recommended for use.
|
||||
|
||||
# <img src="logo.svg" alt="OpenZeppelin" height="40px">
|
||||
|
||||
[](https://www.npmjs.org/package/@openzeppelin/contracts)
|
||||
@ -20,22 +23,32 @@
|
||||
|
||||
### Installation
|
||||
|
||||
#### Hardhat, Truffle (npm)
|
||||
|
||||
```
|
||||
$ npm install @openzeppelin/contracts
|
||||
```
|
||||
|
||||
OpenZeppelin Contracts features a [stable API](https://docs.openzeppelin.com/contracts/releases-stability#api-stability), which means that your contracts won't break unexpectedly when upgrading to a newer minor version.
|
||||
|
||||
An alternative to npm is to use the GitHub repository (`openzeppelin/openzeppelin-contracts`) to retrieve the contracts. When doing this, make sure to specify the tag for a release such as `v4.5.0`, instead of using the `master` branch.
|
||||
#### Foundry (git)
|
||||
|
||||
> **Warning** When installing via git, it is a common error to use the `master` branch. This is a development branch that should be avoided in favor of tagged releases. The release process involves security measures that the `master` branch does not guarantee.
|
||||
|
||||
> **Warning** Foundry installs the latest version initially, but subsequent `forge update` commands will use the `master` branch.
|
||||
|
||||
```
|
||||
$ forge install OpenZeppelin/openzeppelin-contracts
|
||||
```
|
||||
|
||||
### Usage
|
||||
|
||||
Once installed, you can use the contracts in the library by importing them:
|
||||
|
||||
```solidity
|
||||
pragma solidity ^0.8.0;
|
||||
pragma solidity ^0.8.19;
|
||||
|
||||
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
|
||||
import {ERC721} from "@openzeppelin/contracts/token/ERC721/ERC721.sol";
|
||||
|
||||
contract MyCollectible is ERC721 {
|
||||
constructor() ERC721("MyCollectible", "MCO") {
|
||||
@ -67,7 +80,9 @@ Finally, you may want to take a look at the [guides on our blog](https://blog.op
|
||||
|
||||
This project is maintained by [OpenZeppelin](https://openzeppelin.com) with the goal of providing a secure and reliable library of smart contract components for the ecosystem. We address security through risk management in various areas such as engineering and open source best practices, scoping and API design, multi-layered review processes, and incident response preparedness.
|
||||
|
||||
The security policy is detailed in [`SECURITY.md`](./SECURITY.md), and specifies how you can report security vulnerabilities, which versions will receive security patches, and how to stay informed about them. We run a [bug bounty program on Immunefi](https://immunefi.com/bounty/openzeppelin) to reward the responsible disclosure of vulnerabilities.
|
||||
The [OpenZeppelin Contracts Security Center](https://contracts.openzeppelin.com/security) contains more details about the secure development process.
|
||||
|
||||
The security policy is detailed in [`SECURITY.md`](./SECURITY.md) as well, and specifies how you can report security vulnerabilities, which versions will receive security patches, and how to stay informed about them. We run a [bug bounty program on Immunefi](https://immunefi.com/bounty/openzeppelin) to reward the responsible disclosure of vulnerabilities.
|
||||
|
||||
The engineering guidelines we follow to promote project quality can be found in [`GUIDELINES.md`](./GUIDELINES.md).
|
||||
|
||||
|
||||
Binary file not shown.
@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
pragma solidity ^0.8.0;
|
||||
pragma solidity ^0.8.19;
|
||||
|
||||
import "../patched/access/AccessControlDefaultAdminRules.sol";
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
pragma solidity ^0.8.0;
|
||||
pragma solidity ^0.8.19;
|
||||
|
||||
import "../patched/access/AccessControl.sol";
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
pragma solidity ^0.8.0;
|
||||
pragma solidity ^0.8.19;
|
||||
|
||||
import "../patched/utils/structs/DoubleEndedQueue.sol";
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
pragma solidity ^0.8.0;
|
||||
pragma solidity ^0.8.19;
|
||||
|
||||
import "../patched/token/ERC20/ERC20.sol";
|
||||
import "../patched/token/ERC20/extensions/ERC20Permit.sol";
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
pragma solidity ^0.8.0;
|
||||
pragma solidity ^0.8.19;
|
||||
|
||||
import "../patched/token/ERC20/extensions/ERC20Permit.sol";
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
pragma solidity ^0.8.0;
|
||||
pragma solidity ^0.8.19;
|
||||
|
||||
import "../patched/token/ERC20/extensions/ERC20Wrapper.sol";
|
||||
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
|
||||
import "../patched/interfaces/IERC3156FlashBorrower.sol";
|
||||
|
||||
pragma solidity ^0.8.0;
|
||||
pragma solidity ^0.8.19;
|
||||
|
||||
contract ERC3156FlashBorrowerHarness is IERC3156FlashBorrower {
|
||||
bytes32 somethingToReturn;
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
pragma solidity ^0.8.0;
|
||||
pragma solidity ^0.8.19;
|
||||
|
||||
import "../patched/token/ERC721/ERC721.sol";
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
pragma solidity ^0.8.0;
|
||||
pragma solidity ^0.8.19;
|
||||
|
||||
import "../patched/interfaces/IERC721Receiver.sol";
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
pragma solidity ^0.8.0;
|
||||
pragma solidity ^0.8.19;
|
||||
|
||||
import "../patched/utils/structs/EnumerableMap.sol";
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
pragma solidity ^0.8.0;
|
||||
pragma solidity ^0.8.19;
|
||||
|
||||
import "../patched/utils/structs/EnumerableSet.sol";
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.2;
|
||||
pragma solidity ^0.8.19;
|
||||
|
||||
import "../patched/proxy/utils/Initializable.sol";
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
pragma solidity ^0.8.0;
|
||||
pragma solidity ^0.8.19;
|
||||
|
||||
import "../patched/access/Ownable2Step.sol";
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
pragma solidity ^0.8.0;
|
||||
pragma solidity ^0.8.19;
|
||||
|
||||
import "../patched/access/Ownable.sol";
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
pragma solidity ^0.8.0;
|
||||
pragma solidity ^0.8.19;
|
||||
|
||||
import "../patched/security/Pausable.sol";
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
pragma solidity ^0.8.0;
|
||||
pragma solidity ^0.8.19;
|
||||
|
||||
import "../patched/governance/TimelockController.sol";
|
||||
|
||||
|
||||
@ -12,44 +12,23 @@ use rule onlyGrantCanGrant filtered {
|
||||
│ Helpers │
|
||||
└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
*/
|
||||
definition timeSanity(env e) returns bool =
|
||||
e.block.timestamp > 0 && e.block.timestamp + defaultAdminDelay(e) < max_uint48();
|
||||
|
||||
function max_uint48() returns mathint {
|
||||
return (1 << 48) - 1;
|
||||
}
|
||||
definition delayChangeWaitSanity(env e, uint48 newDelay) returns bool =
|
||||
e.block.timestamp + delayChangeWait_(e, newDelay) < max_uint48();
|
||||
|
||||
function nonZeroAccount(address account) returns bool {
|
||||
return account != 0;
|
||||
}
|
||||
definition isSet(uint48 schedule) returns bool =
|
||||
schedule != 0;
|
||||
|
||||
function timeSanity(env e) returns bool {
|
||||
return
|
||||
e.block.timestamp > 0 && // Avoids 0 schedules
|
||||
e.block.timestamp + defaultAdminDelay(e) < max_uint48();
|
||||
}
|
||||
definition hasPassed(env e, uint48 schedule) returns bool =
|
||||
schedule < e.block.timestamp;
|
||||
|
||||
function delayChangeWaitSanity(env e, uint48 newDelay) returns bool {
|
||||
return e.block.timestamp + delayChangeWait_(e, newDelay) < max_uint48();
|
||||
}
|
||||
definition increasingDelaySchedule(env e, uint48 newDelay) returns mathint =
|
||||
e.block.timestamp + min(newDelay, defaultAdminDelayIncreaseWait());
|
||||
|
||||
function isSet(uint48 schedule) returns bool {
|
||||
return schedule != 0;
|
||||
}
|
||||
|
||||
function hasPassed(env e, uint48 schedule) returns bool {
|
||||
return schedule < e.block.timestamp;
|
||||
}
|
||||
|
||||
function min(uint48 a, uint48 b) returns mathint {
|
||||
return a < b ? a : b;
|
||||
}
|
||||
|
||||
function increasingDelaySchedule(env e, uint48 newDelay) returns mathint {
|
||||
return e.block.timestamp + min(newDelay, defaultAdminDelayIncreaseWait());
|
||||
}
|
||||
|
||||
function decreasingDelaySchedule(env e, uint48 newDelay) returns mathint {
|
||||
return e.block.timestamp + defaultAdminDelay(e) - newDelay;
|
||||
}
|
||||
definition decreasingDelaySchedule(env e, uint48 newDelay) returns mathint =
|
||||
e.block.timestamp + defaultAdminDelay(e) - newDelay;
|
||||
|
||||
/*
|
||||
┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
|
||||
@ -57,11 +36,10 @@ function decreasingDelaySchedule(env e, uint48 newDelay) returns mathint {
|
||||
└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
*/
|
||||
invariant defaultAdminConsistency(address account)
|
||||
defaultAdmin() == account <=> hasRole(DEFAULT_ADMIN_ROLE(), account)
|
||||
(account == defaultAdmin() && account != 0) <=> hasRole(DEFAULT_ADMIN_ROLE(), account)
|
||||
{
|
||||
preserved {
|
||||
// defaultAdmin() returns the zero address when there's no default admin
|
||||
require nonZeroAccount(account);
|
||||
preserved with (env e) {
|
||||
require nonzerosender(e);
|
||||
}
|
||||
}
|
||||
|
||||
@ -72,10 +50,12 @@ invariant defaultAdminConsistency(address account)
|
||||
*/
|
||||
invariant singleDefaultAdmin(address account, address another)
|
||||
hasRole(DEFAULT_ADMIN_ROLE(), account) && hasRole(DEFAULT_ADMIN_ROLE(), another) => another == account
|
||||
// We filter here because we couldn't find a way to force Certora to have an initial state with
|
||||
// only one DEFAULT_ADMIN_ROLE enforced, so a counter example is a different default admin since inception
|
||||
// triggering the transfer, which is known to be impossible by definition.
|
||||
filtered { f -> f.selector != acceptDefaultAdminTransfer().selector }
|
||||
{
|
||||
preserved {
|
||||
requireInvariant defaultAdminConsistency(account);
|
||||
requireInvariant defaultAdminConsistency(another);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
|
||||
@ -118,7 +98,8 @@ rule revokeRoleEffect(env e, bytes32 role) {
|
||||
"roles can only be revoked by their owner except for the default admin role";
|
||||
|
||||
// effect
|
||||
assert success => !hasRole(role, account), "role is revoked";
|
||||
assert success => !hasRole(role, account),
|
||||
"role is revoked";
|
||||
|
||||
// no side effect
|
||||
assert hasOtherRoleBefore != hasOtherRoleAfter => (role == otherRole && account == otherAccount),
|
||||
@ -137,35 +118,59 @@ rule renounceRoleEffect(env e, bytes32 role) {
|
||||
address account;
|
||||
address otherAccount;
|
||||
|
||||
bool hasOtherRoleBefore = hasRole(otherRole, otherAccount);
|
||||
uint48 scheduleBefore = pendingDefaultAdminSchedule_();
|
||||
bool hasOtherRoleBefore = hasRole(otherRole, otherAccount);
|
||||
address adminBefore = defaultAdmin();
|
||||
address pendingAdminBefore = pendingDefaultAdmin_();
|
||||
uint48 scheduleBefore = pendingDefaultAdminSchedule_();
|
||||
|
||||
renounceRole@withrevert(e, role, account);
|
||||
bool success = !lastReverted;
|
||||
|
||||
bool hasOtherRoleAfter = hasRole(otherRole, otherAccount);
|
||||
bool hasOtherRoleAfter = hasRole(otherRole, otherAccount);
|
||||
address adminAfter = defaultAdmin();
|
||||
address pendingAdminAfter = pendingDefaultAdmin_();
|
||||
uint48 scheduleAfter = pendingDefaultAdminSchedule_();
|
||||
|
||||
// liveness
|
||||
assert success <=> (
|
||||
account == e.msg.sender &&
|
||||
(
|
||||
role != DEFAULT_ADMIN_ROLE() ||
|
||||
account != adminBefore ||
|
||||
(
|
||||
role != DEFAULT_ADMIN_ROLE()
|
||||
) || (
|
||||
role == DEFAULT_ADMIN_ROLE() &&
|
||||
pendingAdminBefore == 0 &&
|
||||
isSet(scheduleBefore) &&
|
||||
hasPassed(e, scheduleBefore)
|
||||
)
|
||||
)
|
||||
), "an account only can renounce by itself with a delay for the default admin role";
|
||||
),
|
||||
"an account only can renounce by itself with a delay for the default admin role";
|
||||
|
||||
// effect
|
||||
assert success => !hasRole(role, account), "role is renounced";
|
||||
assert success => !hasRole(role, account),
|
||||
"role is renounced";
|
||||
|
||||
assert success => (
|
||||
(
|
||||
role == DEFAULT_ADMIN_ROLE() &&
|
||||
account == adminBefore
|
||||
) ? (
|
||||
adminAfter == 0 &&
|
||||
pendingAdminAfter == 0 &&
|
||||
scheduleAfter == 0
|
||||
) : (
|
||||
adminAfter == adminBefore &&
|
||||
pendingAdminAfter == pendingAdminBefore &&
|
||||
scheduleAfter == scheduleBefore
|
||||
)
|
||||
),
|
||||
"renouncing default admin role cleans state iff called by previous admin";
|
||||
|
||||
// no side effect
|
||||
assert hasOtherRoleBefore != hasOtherRoleAfter => (role == otherRole && account == otherAccount),
|
||||
assert hasOtherRoleBefore != hasOtherRoleAfter => (
|
||||
role == otherRole &&
|
||||
account == otherAccount
|
||||
),
|
||||
"no other role is affected";
|
||||
}
|
||||
|
||||
@ -175,10 +180,6 @@ rule renounceRoleEffect(env e, bytes32 role) {
|
||||
└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
*/
|
||||
rule noDefaultAdminChange(env e, method f, calldataarg args) {
|
||||
require nonZeroAccount(e.msg.sender);
|
||||
requireInvariant defaultAdminConsistency(defaultAdmin());
|
||||
requireInvariant singleDefaultAdmin(e.msg.sender, defaultAdmin());
|
||||
|
||||
address adminBefore = defaultAdmin();
|
||||
f(e, args);
|
||||
address adminAfter = defaultAdmin();
|
||||
@ -186,18 +187,17 @@ rule noDefaultAdminChange(env e, method f, calldataarg args) {
|
||||
assert adminBefore != adminAfter => (
|
||||
f.selector == acceptDefaultAdminTransfer().selector ||
|
||||
f.selector == renounceRole(bytes32,address).selector
|
||||
), "default admin is only affected by accepting an admin transfer or renoucing";
|
||||
),
|
||||
"default admin is only affected by accepting an admin transfer or renoucing";
|
||||
}
|
||||
|
||||
/*
|
||||
┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
|
||||
│ Rule: pendingDefaultAdmin is only affected by beginning, accepting or canceling an admin transfer │
|
||||
│ Rule: pendingDefaultAdmin is only affected by beginning, completing (accept or renounce), or canceling an admin │
|
||||
│ transfer │
|
||||
└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
*/
|
||||
rule noPendingDefaultAdminChange(env e, method f, calldataarg args) {
|
||||
requireInvariant defaultAdminConsistency(defaultAdmin());
|
||||
requireInvariant singleDefaultAdmin(e.msg.sender, defaultAdmin());
|
||||
|
||||
address pendingAdminBefore = pendingDefaultAdmin_();
|
||||
address scheduleBefore = pendingDefaultAdminSchedule_();
|
||||
f(e, args);
|
||||
@ -210,8 +210,10 @@ rule noPendingDefaultAdminChange(env e, method f, calldataarg args) {
|
||||
) => (
|
||||
f.selector == beginDefaultAdminTransfer(address).selector ||
|
||||
f.selector == acceptDefaultAdminTransfer().selector ||
|
||||
f.selector == cancelDefaultAdminTransfer().selector
|
||||
), "pending admin and its schedule is only affected by beginning, accepting or cancelling an admin transfer";
|
||||
f.selector == cancelDefaultAdminTransfer().selector ||
|
||||
f.selector == renounceRole(bytes32,address).selector
|
||||
),
|
||||
"pending admin and its schedule is only affected by beginning, completing, or cancelling an admin transfer";
|
||||
}
|
||||
|
||||
/*
|
||||
@ -224,7 +226,8 @@ rule noDefaultAdminDelayChange(env e, method f, calldataarg args) {
|
||||
f(e, args);
|
||||
uint48 delayAfter = defaultAdminDelay(e);
|
||||
|
||||
assert delayBefore == delayAfter, "delay can't be changed atomically by any function";
|
||||
assert delayBefore == delayAfter,
|
||||
"delay can't be changed atomically by any function";
|
||||
}
|
||||
|
||||
/*
|
||||
@ -240,7 +243,8 @@ rule noPendingDefaultAdminDelayChange(env e, method f, calldataarg args) {
|
||||
assert pendingDelayBefore != pendingDelayAfter => (
|
||||
f.selector == changeDefaultAdminDelay(uint48).selector ||
|
||||
f.selector == rollbackDefaultAdminDelay().selector
|
||||
), "pending delay is only affected by changeDefaultAdminDelay or rollbackDefaultAdminDelay";
|
||||
),
|
||||
"pending delay is only affected by changeDefaultAdminDelay or rollbackDefaultAdminDelay";
|
||||
}
|
||||
|
||||
/*
|
||||
@ -263,10 +267,10 @@ rule noDefaultAdminDelayIncreaseWaitChange(env e, method f, calldataarg args) {
|
||||
└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
*/
|
||||
rule beginDefaultAdminTransfer(env e, address newAdmin) {
|
||||
require nonpayable(e);
|
||||
require timeSanity(e);
|
||||
requireInvariant defaultAdminConsistency(defaultAdmin());
|
||||
requireInvariant singleDefaultAdmin(e.msg.sender, defaultAdmin());
|
||||
require nonpayable(e);
|
||||
require nonzerosender(e);
|
||||
requireInvariant defaultAdminConsistency(e.msg.sender);
|
||||
|
||||
beginDefaultAdminTransfer@withrevert(e, newAdmin);
|
||||
bool success = !lastReverted;
|
||||
@ -288,18 +292,24 @@ rule beginDefaultAdminTransfer(env e, address newAdmin) {
|
||||
└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
*/
|
||||
rule pendingDefaultAdminDelayEnforced(env e1, env e2, method f, calldataarg args, address newAdmin) {
|
||||
require e1.block.timestamp < e2.block.timestamp;
|
||||
require e1.block.timestamp <= e2.block.timestamp;
|
||||
|
||||
uint48 delayBefore = defaultAdminDelay(e1);
|
||||
address adminBefore = defaultAdmin();
|
||||
|
||||
// There might be a better way to generalize this without requiring `beginDefaultAdminTransfer`, but currently
|
||||
// it's the only way in which we can attest that only `delayBefore` has passed before a change.
|
||||
beginDefaultAdminTransfer(e1, newAdmin);
|
||||
f(e2, args);
|
||||
|
||||
address adminAfter = defaultAdmin();
|
||||
|
||||
assert adminAfter == newAdmin => ((e2.block.timestamp >= e1.block.timestamp + delayBefore) || adminBefore == newAdmin),
|
||||
"A delay can't change in less than applied schedule";
|
||||
// change can only happen towards the newAdmin, with the delay
|
||||
assert adminAfter != adminBefore => (
|
||||
adminAfter == newAdmin &&
|
||||
e2.block.timestamp >= e1.block.timestamp + delayBefore
|
||||
),
|
||||
"The admin can only change after the enforced delay and to the previously scheduled new admin";
|
||||
}
|
||||
|
||||
/*
|
||||
@ -309,17 +319,19 @@ rule pendingDefaultAdminDelayEnforced(env e1, env e2, method f, calldataarg args
|
||||
*/
|
||||
rule acceptDefaultAdminTransfer(env e) {
|
||||
require nonpayable(e);
|
||||
requireInvariant defaultAdminConsistency(defaultAdmin());
|
||||
requireInvariant singleDefaultAdmin(e.msg.sender, defaultAdmin());
|
||||
|
||||
address pendingAdminBefore = pendingDefaultAdmin_();
|
||||
uint48 scheduleAfter = pendingDefaultAdminSchedule_();
|
||||
uint48 scheduleBefore = pendingDefaultAdminSchedule_();
|
||||
|
||||
acceptDefaultAdminTransfer@withrevert(e);
|
||||
bool success = !lastReverted;
|
||||
|
||||
// liveness
|
||||
assert success <=> e.msg.sender == pendingAdminBefore && isSet(scheduleAfter) && hasPassed(e, scheduleAfter),
|
||||
assert success <=> (
|
||||
e.msg.sender == pendingAdminBefore &&
|
||||
isSet(scheduleBefore) &&
|
||||
hasPassed(e, scheduleBefore)
|
||||
),
|
||||
"only the pending default admin can accept the role after the schedule has been set and passed";
|
||||
|
||||
// effect
|
||||
@ -338,8 +350,8 @@ rule acceptDefaultAdminTransfer(env e) {
|
||||
*/
|
||||
rule cancelDefaultAdminTransfer(env e) {
|
||||
require nonpayable(e);
|
||||
requireInvariant defaultAdminConsistency(defaultAdmin());
|
||||
requireInvariant singleDefaultAdmin(e.msg.sender, defaultAdmin());
|
||||
require nonzerosender(e);
|
||||
requireInvariant defaultAdminConsistency(e.msg.sender);
|
||||
|
||||
cancelDefaultAdminTransfer@withrevert(e);
|
||||
bool success = !lastReverted;
|
||||
@ -361,11 +373,11 @@ rule cancelDefaultAdminTransfer(env e) {
|
||||
└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
*/
|
||||
rule changeDefaultAdminDelay(env e, uint48 newDelay) {
|
||||
require nonpayable(e);
|
||||
require timeSanity(e);
|
||||
require nonpayable(e);
|
||||
require nonzerosender(e);
|
||||
require delayChangeWaitSanity(e, newDelay);
|
||||
requireInvariant defaultAdminConsistency(defaultAdmin());
|
||||
requireInvariant singleDefaultAdmin(e.msg.sender, defaultAdmin());
|
||||
requireInvariant defaultAdminConsistency(e.msg.sender);
|
||||
|
||||
uint48 delayBefore = defaultAdminDelay(e);
|
||||
|
||||
@ -377,7 +389,9 @@ rule changeDefaultAdminDelay(env e, uint48 newDelay) {
|
||||
"only the current default admin can begin a delay change";
|
||||
|
||||
// effect
|
||||
assert success => pendingDelay_(e) == newDelay, "pending delay is set";
|
||||
assert success => pendingDelay_(e) == newDelay,
|
||||
"pending delay is set";
|
||||
|
||||
assert success => (
|
||||
pendingDelaySchedule_(e) > e.block.timestamp ||
|
||||
delayBefore == newDelay || // Interpreted as decreasing, x - x = 0
|
||||
@ -392,17 +406,22 @@ rule changeDefaultAdminDelay(env e, uint48 newDelay) {
|
||||
└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
*/
|
||||
rule pendingDelayWaitEnforced(env e1, env e2, method f, calldataarg args, uint48 newDelay) {
|
||||
require e1.block.timestamp < e2.block.timestamp;
|
||||
require e1.block.timestamp <= e2.block.timestamp;
|
||||
|
||||
uint48 delayBefore = defaultAdminDelay(e1);
|
||||
|
||||
changeDefaultAdminDelay(e1, newDelay);
|
||||
f(e2, args);
|
||||
|
||||
uint48 delayAfter = defaultAdminDelay(e2);
|
||||
|
||||
mathint delayWait = newDelay > delayBefore ? increasingDelaySchedule(e1, newDelay) : decreasingDelaySchedule(e1, newDelay);
|
||||
|
||||
assert delayAfter == newDelay => (e2.block.timestamp >= delayWait || delayBefore == newDelay),
|
||||
"A delay can't change in less than applied schedule";
|
||||
assert delayAfter != delayBefore => (
|
||||
delayAfter == newDelay &&
|
||||
e2.block.timestamp >= delayWait
|
||||
),
|
||||
"A delay can only change after the applied schedule";
|
||||
}
|
||||
|
||||
/*
|
||||
@ -427,8 +446,8 @@ rule pendingDelayWait(env e, uint48 newDelay) {
|
||||
*/
|
||||
rule rollbackDefaultAdminDelay(env e) {
|
||||
require nonpayable(e);
|
||||
requireInvariant defaultAdminConsistency(defaultAdmin());
|
||||
requireInvariant singleDefaultAdmin(e.msg.sender, defaultAdmin());
|
||||
require nonzerosender(e);
|
||||
requireInvariant defaultAdminConsistency(e.msg.sender);
|
||||
|
||||
rollbackDefaultAdminDelay@withrevert(e);
|
||||
bool success = !lastReverted;
|
||||
@ -443,58 +462,3 @@ rule rollbackDefaultAdminDelay(env e) {
|
||||
assert success => pendingDelaySchedule_(e) == 0,
|
||||
"Pending default admin delay is reset";
|
||||
}
|
||||
|
||||
/*
|
||||
┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
|
||||
│ Rule: pending default admin and the delay can only change along with their corresponding schedules │
|
||||
└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
*/
|
||||
rule pendingValueAndScheduleCoupling(env e, address newAdmin, uint48 newDelay) {
|
||||
requireInvariant defaultAdminConsistency(defaultAdmin());
|
||||
requireInvariant singleDefaultAdmin(e.msg.sender, defaultAdmin());
|
||||
|
||||
// Pending admin
|
||||
address pendingAdminBefore = pendingDefaultAdmin_();
|
||||
uint48 pendingAdminScheduleBefore = pendingDefaultAdminSchedule_();
|
||||
|
||||
beginDefaultAdminTransfer(e, newAdmin);
|
||||
|
||||
address pendingAdminAfter = pendingDefaultAdmin_();
|
||||
uint48 pendingAdminScheduleAfter = pendingDefaultAdminSchedule_();
|
||||
|
||||
assert (
|
||||
pendingAdminScheduleBefore != pendingDefaultAdminSchedule_() &&
|
||||
pendingAdminBefore == pendingAdminAfter
|
||||
) => newAdmin == pendingAdminBefore, "pending admin stays the same if the new admin set is the same";
|
||||
|
||||
assert (
|
||||
pendingAdminBefore != pendingAdminAfter &&
|
||||
pendingAdminScheduleBefore == pendingDefaultAdminSchedule_()
|
||||
) => (
|
||||
// Schedule doesn't change if:
|
||||
// - The defaultAdminDelay was reduced to a value such that added to the block.timestamp is equal to previous schedule
|
||||
e.block.timestamp + defaultAdminDelay(e) == pendingAdminScheduleBefore
|
||||
), "pending admin stays the same if a default admin transfer is begun on accepted edge cases";
|
||||
|
||||
// Pending delay
|
||||
address pendingDelayBefore = pendingDelay_(e);
|
||||
uint48 pendingDelayScheduleBefore = pendingDelaySchedule_(e);
|
||||
|
||||
changeDefaultAdminDelay(e, newDelay);
|
||||
|
||||
address pendingDelayAfter = pendingDelay_(e);
|
||||
uint48 pendingDelayScheduleAfter = pendingDelaySchedule_(e);
|
||||
|
||||
assert (
|
||||
pendingDelayScheduleBefore != pendingDelayScheduleAfter &&
|
||||
pendingDelayBefore == pendingDelayAfter
|
||||
) => newDelay == pendingDelayBefore || pendingDelayBefore == 0, "pending delay stays the same if the new delay set is the same";
|
||||
|
||||
assert (
|
||||
pendingDelayBefore != pendingDelayAfter &&
|
||||
pendingDelayScheduleBefore == pendingDelayScheduleAfter
|
||||
) => (
|
||||
increasingDelaySchedule(e, newDelay) == pendingDelayScheduleBefore ||
|
||||
decreasingDelaySchedule(e, newDelay) == pendingDelayScheduleBefore
|
||||
), "pending delay stays the same if a default admin transfer is begun on accepted edge cases";
|
||||
}
|
||||
|
||||
@ -1 +1,10 @@
|
||||
// environment
|
||||
definition nonpayable(env e) returns bool = e.msg.value == 0;
|
||||
definition nonzerosender(env e) returns bool = e.msg.sender != 0;
|
||||
|
||||
// constants
|
||||
definition max_uint48() returns mathint = (1 << 48) - 1;
|
||||
|
||||
// math
|
||||
definition min(mathint a, mathint b) returns mathint = a < b ? a : b;
|
||||
definition max(mathint a, mathint b) returns mathint = a > b ? a : b;
|
||||
|
||||
@ -1,12 +1,12 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
// OpenZeppelin Contracts (last updated v4.8.0) (access/AccessControl.sol)
|
||||
// OpenZeppelin Contracts (last updated v4.9.0) (access/AccessControl.sol)
|
||||
|
||||
pragma solidity ^0.8.0;
|
||||
pragma solidity ^0.8.19;
|
||||
|
||||
import "./IAccessControl.sol";
|
||||
import "../utils/Context.sol";
|
||||
import "../utils/Strings.sol";
|
||||
import "../utils/introspection/ERC165.sol";
|
||||
import {IAccessControl} from "./IAccessControl.sol";
|
||||
import {Context} from "../utils/Context.sol";
|
||||
import {Strings} from "../utils/Strings.sol";
|
||||
import {ERC165} from "../utils/introspection/ERC165.sol";
|
||||
|
||||
/**
|
||||
* @dev Contract module that allows children to implement role-based access
|
||||
@ -82,7 +82,7 @@ abstract contract AccessControl is Context, IAccessControl, ERC165 {
|
||||
/**
|
||||
* @dev Returns `true` if `account` has been granted `role`.
|
||||
*/
|
||||
function hasRole(bytes32 role, address account) public view virtual override returns (bool) {
|
||||
function hasRole(bytes32 role, address account) public view virtual returns (bool) {
|
||||
return _roles[role].members[account];
|
||||
}
|
||||
|
||||
@ -107,16 +107,7 @@ abstract contract AccessControl is Context, IAccessControl, ERC165 {
|
||||
*/
|
||||
function _checkRole(bytes32 role, address account) internal view virtual {
|
||||
if (!hasRole(role, account)) {
|
||||
revert(
|
||||
string(
|
||||
abi.encodePacked(
|
||||
"AccessControl: account ",
|
||||
Strings.toHexString(account),
|
||||
" is missing role ",
|
||||
Strings.toHexString(uint256(role), 32)
|
||||
)
|
||||
)
|
||||
);
|
||||
revert AccessControlUnauthorizedAccount(account, role);
|
||||
}
|
||||
}
|
||||
|
||||
@ -126,7 +117,7 @@ abstract contract AccessControl is Context, IAccessControl, ERC165 {
|
||||
*
|
||||
* To change a role's admin, use {_setRoleAdmin}.
|
||||
*/
|
||||
function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) {
|
||||
function getRoleAdmin(bytes32 role) public view virtual returns (bytes32) {
|
||||
return _roles[role].adminRole;
|
||||
}
|
||||
|
||||
@ -142,7 +133,7 @@ abstract contract AccessControl is Context, IAccessControl, ERC165 {
|
||||
*
|
||||
* May emit a {RoleGranted} event.
|
||||
*/
|
||||
function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {
|
||||
function grantRole(bytes32 role, address account) public virtual onlyRole(getRoleAdmin(role)) {
|
||||
_grantRole(role, account);
|
||||
}
|
||||
|
||||
@ -157,7 +148,7 @@ abstract contract AccessControl is Context, IAccessControl, ERC165 {
|
||||
*
|
||||
* May emit a {RoleRevoked} event.
|
||||
*/
|
||||
function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {
|
||||
function revokeRole(bytes32 role, address account) public virtual onlyRole(getRoleAdmin(role)) {
|
||||
_revokeRole(role, account);
|
||||
}
|
||||
|
||||
@ -173,38 +164,16 @@ abstract contract AccessControl is Context, IAccessControl, ERC165 {
|
||||
*
|
||||
* Requirements:
|
||||
*
|
||||
* - the caller must be `account`.
|
||||
* - the caller must be `callerConfirmation`.
|
||||
*
|
||||
* May emit a {RoleRevoked} event.
|
||||
*/
|
||||
function renounceRole(bytes32 role, address account) public virtual override {
|
||||
require(account == _msgSender(), "AccessControl: can only renounce roles for self");
|
||||
function renounceRole(bytes32 role, address callerConfirmation) public virtual {
|
||||
if (callerConfirmation != _msgSender()) {
|
||||
revert AccessControlBadConfirmation();
|
||||
}
|
||||
|
||||
_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.
|
||||
*
|
||||
* May emit a {RoleGranted} event.
|
||||
*
|
||||
* [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}.
|
||||
* ====
|
||||
*
|
||||
* NOTE: This function is deprecated in favor of {_grantRole}.
|
||||
*/
|
||||
function _setupRole(bytes32 role, address account) internal virtual {
|
||||
_grantRole(role, account);
|
||||
_revokeRole(role, callerConfirmation);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -1,45 +0,0 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
// OpenZeppelin Contracts (last updated v4.6.0) (access/AccessControlCrossChain.sol)
|
||||
|
||||
pragma solidity ^0.8.4;
|
||||
|
||||
import "./AccessControl.sol";
|
||||
import "../crosschain/CrossChainEnabled.sol";
|
||||
|
||||
/**
|
||||
* @dev An extension to {AccessControl} with support for cross-chain access management.
|
||||
* For each role, is extension implements an equivalent "aliased" role that is used for
|
||||
* restricting calls originating from other chains.
|
||||
*
|
||||
* For example, if a function `myFunction` is protected by `onlyRole(SOME_ROLE)`, and
|
||||
* if an address `x` has role `SOME_ROLE`, it would be able to call `myFunction` directly.
|
||||
* A wallet or contract at the same address on another chain would however not be able
|
||||
* to call this function. In order to do so, it would require to have the role
|
||||
* `_crossChainRoleAlias(SOME_ROLE)`.
|
||||
*
|
||||
* This aliasing is required to protect against multiple contracts living at the same
|
||||
* address on different chains but controlled by conflicting entities.
|
||||
*
|
||||
* _Available since v4.6._
|
||||
*/
|
||||
abstract contract AccessControlCrossChain is AccessControl, CrossChainEnabled {
|
||||
bytes32 public constant CROSSCHAIN_ALIAS = keccak256("CROSSCHAIN_ALIAS");
|
||||
|
||||
/**
|
||||
* @dev See {AccessControl-_checkRole}.
|
||||
*/
|
||||
function _checkRole(bytes32 role) internal view virtual override {
|
||||
if (_isCrossChain()) {
|
||||
_checkRole(_crossChainRoleAlias(role), _crossChainSender());
|
||||
} else {
|
||||
super._checkRole(role);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Returns the aliased role corresponding to `role`.
|
||||
*/
|
||||
function _crossChainRoleAlias(bytes32 role) internal pure virtual returns (bytes32) {
|
||||
return role ^ CROSSCHAIN_ALIAS;
|
||||
}
|
||||
}
|
||||
@ -1,12 +1,13 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
// OpenZeppelin Contracts (last updated v4.8.0) (access/AccessControlDefaultAdminRules.sol)
|
||||
// OpenZeppelin Contracts (last updated v4.9.0) (access/AccessControlDefaultAdminRules.sol)
|
||||
|
||||
pragma solidity ^0.8.0;
|
||||
pragma solidity ^0.8.19;
|
||||
|
||||
import "./AccessControl.sol";
|
||||
import "./IAccessControlDefaultAdminRules.sol";
|
||||
import "../utils/math/SafeCast.sol";
|
||||
import "../interfaces/IERC5313.sol";
|
||||
import {AccessControl, IAccessControl} from "./AccessControl.sol";
|
||||
import {IAccessControlDefaultAdminRules} from "./IAccessControlDefaultAdminRules.sol";
|
||||
import {SafeCast} from "../utils/math/SafeCast.sol";
|
||||
import {Math} from "../utils/math/Math.sol";
|
||||
import {IERC5313} from "../interfaces/IERC5313.sol";
|
||||
|
||||
/**
|
||||
* @dev Extension of {AccessControl} that allows specifying special rules to manage
|
||||
@ -53,7 +54,9 @@ abstract contract AccessControlDefaultAdminRules is IAccessControlDefaultAdminRu
|
||||
* @dev Sets the initial values for {defaultAdminDelay} and {defaultAdmin} address.
|
||||
*/
|
||||
constructor(uint48 initialDelay, address initialDefaultAdmin) {
|
||||
require(initialDefaultAdmin != address(0), "AccessControl: 0 default admin");
|
||||
if (initialDefaultAdmin == address(0)) {
|
||||
revert AccessControlInvalidDefaultAdmin(address(0));
|
||||
}
|
||||
_currentDelay = initialDelay;
|
||||
_grantRole(DEFAULT_ADMIN_ROLE, initialDefaultAdmin);
|
||||
}
|
||||
@ -80,7 +83,9 @@ abstract contract AccessControlDefaultAdminRules is IAccessControlDefaultAdminRu
|
||||
* @dev See {AccessControl-grantRole}. Reverts for `DEFAULT_ADMIN_ROLE`.
|
||||
*/
|
||||
function grantRole(bytes32 role, address account) public virtual override(AccessControl, IAccessControl) {
|
||||
require(role != DEFAULT_ADMIN_ROLE, "AccessControl: can't directly grant default admin role");
|
||||
if (role == DEFAULT_ADMIN_ROLE) {
|
||||
revert AccessControlEnforcedDefaultAdminRules();
|
||||
}
|
||||
super.grantRole(role, account);
|
||||
}
|
||||
|
||||
@ -88,7 +93,9 @@ abstract contract AccessControlDefaultAdminRules is IAccessControlDefaultAdminRu
|
||||
* @dev See {AccessControl-revokeRole}. Reverts for `DEFAULT_ADMIN_ROLE`.
|
||||
*/
|
||||
function revokeRole(bytes32 role, address account) public virtual override(AccessControl, IAccessControl) {
|
||||
require(role != DEFAULT_ADMIN_ROLE, "AccessControl: can't directly revoke default admin role");
|
||||
if (role == DEFAULT_ADMIN_ROLE) {
|
||||
revert AccessControlEnforcedDefaultAdminRules();
|
||||
}
|
||||
super.revokeRole(role, account);
|
||||
}
|
||||
|
||||
@ -106,12 +113,12 @@ abstract contract AccessControlDefaultAdminRules is IAccessControlDefaultAdminRu
|
||||
* non-administrated role.
|
||||
*/
|
||||
function renounceRole(bytes32 role, address account) public virtual override(AccessControl, IAccessControl) {
|
||||
if (role == DEFAULT_ADMIN_ROLE) {
|
||||
if (role == DEFAULT_ADMIN_ROLE && account == defaultAdmin()) {
|
||||
(address newDefaultAdmin, uint48 schedule) = pendingDefaultAdmin();
|
||||
require(
|
||||
newDefaultAdmin == address(0) && _isScheduleSet(schedule) && _hasSchedulePassed(schedule),
|
||||
"AccessControl: only can renounce in two delayed steps"
|
||||
);
|
||||
if (newDefaultAdmin != address(0) || !_isScheduleSet(schedule) || !_hasSchedulePassed(schedule)) {
|
||||
revert AccessControlEnforcedDefaultAdminDelay(schedule);
|
||||
}
|
||||
delete _pendingDefaultAdminSchedule;
|
||||
}
|
||||
super.renounceRole(role, account);
|
||||
}
|
||||
@ -127,7 +134,9 @@ abstract contract AccessControlDefaultAdminRules is IAccessControlDefaultAdminRu
|
||||
*/
|
||||
function _grantRole(bytes32 role, address account) internal virtual override {
|
||||
if (role == DEFAULT_ADMIN_ROLE) {
|
||||
require(defaultAdmin() == address(0), "AccessControl: default admin already granted");
|
||||
if (defaultAdmin() != address(0)) {
|
||||
revert AccessControlEnforcedDefaultAdminRules();
|
||||
}
|
||||
_currentDefaultAdmin = account;
|
||||
}
|
||||
super._grantRole(role, account);
|
||||
@ -137,7 +146,7 @@ abstract contract AccessControlDefaultAdminRules is IAccessControlDefaultAdminRu
|
||||
* @dev See {AccessControl-_revokeRole}.
|
||||
*/
|
||||
function _revokeRole(bytes32 role, address account) internal virtual override {
|
||||
if (role == DEFAULT_ADMIN_ROLE && account == _currentDefaultAdmin) {
|
||||
if (role == DEFAULT_ADMIN_ROLE && account == defaultAdmin()) {
|
||||
delete _currentDefaultAdmin;
|
||||
}
|
||||
super._revokeRole(role, account);
|
||||
@ -147,7 +156,9 @@ abstract contract AccessControlDefaultAdminRules is IAccessControlDefaultAdminRu
|
||||
* @dev See {AccessControl-_setRoleAdmin}. Reverts for `DEFAULT_ADMIN_ROLE`.
|
||||
*/
|
||||
function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual override {
|
||||
require(role != DEFAULT_ADMIN_ROLE, "AccessControl: can't violate default admin rules");
|
||||
if (role == DEFAULT_ADMIN_ROLE) {
|
||||
revert AccessControlEnforcedDefaultAdminRules();
|
||||
}
|
||||
super._setRoleAdmin(role, adminRole);
|
||||
}
|
||||
|
||||
@ -235,7 +246,10 @@ abstract contract AccessControlDefaultAdminRules is IAccessControlDefaultAdminRu
|
||||
*/
|
||||
function acceptDefaultAdminTransfer() public virtual {
|
||||
(address newDefaultAdmin, ) = pendingDefaultAdmin();
|
||||
require(_msgSender() == newDefaultAdmin, "AccessControl: pending admin must accept");
|
||||
if (_msgSender() != newDefaultAdmin) {
|
||||
// Enforce newDefaultAdmin explicit acceptance.
|
||||
revert AccessControlInvalidDefaultAdmin(_msgSender());
|
||||
}
|
||||
_acceptDefaultAdminTransfer();
|
||||
}
|
||||
|
||||
@ -246,7 +260,9 @@ abstract contract AccessControlDefaultAdminRules is IAccessControlDefaultAdminRu
|
||||
*/
|
||||
function _acceptDefaultAdminTransfer() internal virtual {
|
||||
(address newAdmin, uint48 schedule) = pendingDefaultAdmin();
|
||||
require(_isScheduleSet(schedule) && _hasSchedulePassed(schedule), "AccessControl: transfer delay not passed");
|
||||
if (!_isScheduleSet(schedule) || !_hasSchedulePassed(schedule)) {
|
||||
revert AccessControlEnforcedDefaultAdminDelay(schedule);
|
||||
}
|
||||
_revokeRole(DEFAULT_ADMIN_ROLE, defaultAdmin());
|
||||
_grantRole(DEFAULT_ADMIN_ROLE, newAdmin);
|
||||
delete _pendingDefaultAdmin;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user