Compare commits
15 Commits
v4.0.0-bet
...
release-v4
| Author | SHA1 | Date | |
|---|---|---|---|
| a673994de5 | |||
| 9b0e27c98c | |||
| 90a72f9acd | |||
| 1ee939e7c4 | |||
| 59f33c1cc1 | |||
| d104ced953 | |||
| 1fd54698ff | |||
| 27fc833550 | |||
| 0b3e0d74b0 | |||
| d75b4cf613 | |||
| b1e0aa487d | |||
| 6505e28c40 | |||
| f07c39be8a | |||
| 69ca2ad676 | |||
| ae1e384a9a |
28
CHANGELOG.md
28
CHANGELOG.md
@ -1,23 +1,29 @@
|
||||
# Changelog
|
||||
|
||||
## 4.0.0
|
||||
## 4.0.0 (2021-03-23)
|
||||
|
||||
* Now targeting the 0.8.x line of Solidity compilers. For 0.6.x (resp 0.7.x) support, use version 3.4.0 (resp 3.4.0-solc-0.7) of OpenZeppelin.
|
||||
* `Context`: making `_msgData` return `bytes calldata` instead of `bytes memory` ([#2492](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2492))
|
||||
* `ERC20`: Removed the `_setDecimals` function and the storage slot associated to decimals. ([#2502](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2502))
|
||||
* `ERC20`: removed the `_setDecimals` function and the storage slot associated to decimals. ([#2502](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2502))
|
||||
* `Strings`: addition of a `toHexString` function. ([#2504](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2504))
|
||||
* `EnumerableMap`: change implementation to optimize for `key → value` lookups instead of enumeration. ([#2518](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2518))
|
||||
* `GSN`: Deprecate GSNv1 support in favor of upcomming support for GSNv2. ([#2521](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2521))
|
||||
* `ERC165`: Remove uses of storage in the base ERC165 implementation. ERC165 based contracts now use storage-less virtual functions. Old behaviour remains available in the `ERC165Storage` extension. ([#2505](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2505))
|
||||
* `Initializable`: Make initializer check stricter during construction. ([#2531](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2531))
|
||||
* `GSN`: deprecate GSNv1 support in favor of upcoming support for GSNv2. ([#2521](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2521))
|
||||
* `ERC165`: remove uses of storage in the base ERC165 implementation. ERC165 based contracts now use storage-less virtual functions. Old behavior remains available in the `ERC165Storage` extension. ([#2505](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2505))
|
||||
* `Initializable`: make initializer check stricter during construction. ([#2531](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2531))
|
||||
* `ERC721`: remove enumerability of tokens from the base implementation. This feature is now provided separately through the `ERC721Enumerable` extension. ([#2511](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2511))
|
||||
* `AccessControl`: removed enumerability by default for a more lightweight contract. It is now opt-in through `AccessControlEnumerable`. ([#2512](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2512))
|
||||
* Meta Transactions: add `ERC2771Context` and a `MinimalForwarder` for meta-transactions. ([#2508](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2508))
|
||||
* Overall reorganisation of the contract folder to improve clarity and discoverability. ([#2503](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2503))
|
||||
* `ERC20Capped`: optimize gas usage of by enforcing te check directly in `_mint`. ([#2524](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2524))
|
||||
* Overall reorganization of the contract folder to improve clarity and discoverability. ([#2503](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2503))
|
||||
* `ERC20Capped`: optimize gas usage by enforcing the check directly in `_mint`. ([#2524](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2524))
|
||||
* Rename `UpgradeableProxy` to `ERC1967Proxy`. ([#2547](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2547))
|
||||
* `ERC777`: Optimize the gas costs of the constructor. ([#2551](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2551))
|
||||
* `ERC721TokenUri`: Add a new extension ERC721TokenUri that implements the tokenURI behavior as it was available in 3.4.0. ([#2555](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2555))
|
||||
* `ERC777`: optimize the gas costs of the constructor. ([#2551](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2551))
|
||||
* `ERC721URIStorage`: add a new extension that implements the `_setTokenURI` behavior as it was available in 3.4.0. ([#2555](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2555))
|
||||
* `AccessControl`: added ERC165 interface detection. ([#2562](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2562))
|
||||
* `ERC1155`: make `uri` public so overloading function can call it using super. ([#2576](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2576))
|
||||
|
||||
### Bug fixes for beta releases
|
||||
|
||||
* `AccessControlEnumerable`: Fixed `renounceRole` not updating enumerable set of addresses for a role. ([#2572](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2572))
|
||||
|
||||
### How to upgrade from 3.x
|
||||
|
||||
@ -29,6 +35,10 @@ npx openzeppelin-contracts-migrate-imports
|
||||
|
||||
Make sure you're using git or another version control system to be able to recover from any potential error in our script.
|
||||
|
||||
### How to upgrade from 4.0-beta.x
|
||||
|
||||
Some further changes have been done between the different beta iterations. Transitions made during this period are configured in the `migrate-imports` script. Consequently, you can upgrade from any previous 4.0-beta.x version using the same script as described in the *How to upgrade from 3.x* section.
|
||||
|
||||
## 3.4.0 (2021-02-02)
|
||||
|
||||
* `BeaconProxy`: added new kind of proxy that allows simultaneous atomic upgrades. ([#2411](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2411))
|
||||
|
||||
@ -3,6 +3,18 @@
|
||||
pragma solidity ^0.8.0;
|
||||
|
||||
import "../utils/Context.sol";
|
||||
import "../utils/introspection/ERC165.sol";
|
||||
|
||||
/**
|
||||
* @dev External interface of AccessControl declared to support ERC165 detection.
|
||||
*/
|
||||
interface IAccessControl {
|
||||
function hasRole(bytes32 role, address account) external view returns (bool);
|
||||
function getRoleAdmin(bytes32 role) external view returns (bytes32);
|
||||
function grantRole(bytes32 role, address account) external;
|
||||
function revokeRole(bytes32 role, address account) external;
|
||||
function renounceRole(bytes32 role, address account) external;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Contract module that allows children to implement role-based access
|
||||
@ -42,7 +54,7 @@ import "../utils/Context.sol";
|
||||
* grant and revoke this role. Extra precautions should be taken to secure
|
||||
* accounts that have been granted it.
|
||||
*/
|
||||
abstract contract AccessControl is Context {
|
||||
abstract contract AccessControl is Context, IAccessControl, ERC165 {
|
||||
struct RoleData {
|
||||
mapping (address => bool) members;
|
||||
bytes32 adminRole;
|
||||
@ -79,10 +91,18 @@ abstract contract AccessControl is Context {
|
||||
*/
|
||||
event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);
|
||||
|
||||
/**
|
||||
* @dev See {IERC165-supportsInterface}.
|
||||
*/
|
||||
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
|
||||
return interfaceId == type(IAccessControl).interfaceId
|
||||
|| super.supportsInterface(interfaceId);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Returns `true` if `account` has been granted `role`.
|
||||
*/
|
||||
function hasRole(bytes32 role, address account) public view returns (bool) {
|
||||
function hasRole(bytes32 role, address account) public view override returns (bool) {
|
||||
return _roles[role].members[account];
|
||||
}
|
||||
|
||||
@ -92,7 +112,7 @@ abstract contract AccessControl is Context {
|
||||
*
|
||||
* To change a role's admin, use {_setRoleAdmin}.
|
||||
*/
|
||||
function getRoleAdmin(bytes32 role) public view returns (bytes32) {
|
||||
function getRoleAdmin(bytes32 role) public view override returns (bytes32) {
|
||||
return _roles[role].adminRole;
|
||||
}
|
||||
|
||||
@ -106,7 +126,7 @@ abstract contract AccessControl is Context {
|
||||
*
|
||||
* - the caller must have ``role``'s admin role.
|
||||
*/
|
||||
function grantRole(bytes32 role, address account) public virtual {
|
||||
function grantRole(bytes32 role, address account) public virtual override {
|
||||
require(hasRole(getRoleAdmin(role), _msgSender()), "AccessControl: sender must be an admin to grant");
|
||||
|
||||
_grantRole(role, account);
|
||||
@ -121,7 +141,7 @@ abstract contract AccessControl is Context {
|
||||
*
|
||||
* - the caller must have ``role``'s admin role.
|
||||
*/
|
||||
function revokeRole(bytes32 role, address account) public virtual {
|
||||
function revokeRole(bytes32 role, address account) public virtual override {
|
||||
require(hasRole(getRoleAdmin(role), _msgSender()), "AccessControl: sender must be an admin to revoke");
|
||||
|
||||
_revokeRole(role, account);
|
||||
@ -141,7 +161,7 @@ abstract contract AccessControl is Context {
|
||||
*
|
||||
* - the caller must be `account`.
|
||||
*/
|
||||
function renounceRole(bytes32 role, address account) public virtual {
|
||||
function renounceRole(bytes32 role, address account) public virtual override {
|
||||
require(account == _msgSender(), "AccessControl: can only renounce roles for self");
|
||||
|
||||
_revokeRole(role, account);
|
||||
|
||||
@ -5,14 +5,30 @@ pragma solidity ^0.8.0;
|
||||
import "./AccessControl.sol";
|
||||
import "../utils/structs/EnumerableSet.sol";
|
||||
|
||||
/**
|
||||
* @dev External interface of AccessControlEnumerable declared to support ERC165 detection.
|
||||
*/
|
||||
interface IAccessControlEnumerable {
|
||||
function getRoleMember(bytes32 role, uint256 index) external view returns (address);
|
||||
function getRoleMemberCount(bytes32 role) external view returns (uint256);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Extension of {AccessControl} that allows enumerating the members of each role.
|
||||
*/
|
||||
abstract contract AccessControlEnumerable is AccessControl {
|
||||
abstract contract AccessControlEnumerable is IAccessControlEnumerable, AccessControl {
|
||||
using EnumerableSet for EnumerableSet.AddressSet;
|
||||
|
||||
mapping (bytes32 => EnumerableSet.AddressSet) private _roleMembers;
|
||||
|
||||
/**
|
||||
* @dev See {IERC165-supportsInterface}.
|
||||
*/
|
||||
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
|
||||
return interfaceId == type(IAccessControlEnumerable).interfaceId
|
||||
|| super.supportsInterface(interfaceId);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Returns one of the accounts that have `role`. `index` must be a
|
||||
* value between 0 and {getRoleMemberCount}, non-inclusive.
|
||||
@ -25,7 +41,7 @@ abstract contract AccessControlEnumerable is AccessControl {
|
||||
* https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]
|
||||
* for more information.
|
||||
*/
|
||||
function getRoleMember(bytes32 role, uint256 index) public view returns (address) {
|
||||
function getRoleMember(bytes32 role, uint256 index) public view override returns (address) {
|
||||
return _roleMembers[role].at(index);
|
||||
}
|
||||
|
||||
@ -33,7 +49,7 @@ abstract contract AccessControlEnumerable is AccessControl {
|
||||
* @dev Returns the number of accounts that have `role`. Can be used
|
||||
* together with {getRoleMember} to enumerate all bearers of a role.
|
||||
*/
|
||||
function getRoleMemberCount(bytes32 role) public view returns (uint256) {
|
||||
function getRoleMemberCount(bytes32 role) public view override returns (uint256) {
|
||||
return _roleMembers[role].length();
|
||||
}
|
||||
|
||||
@ -53,6 +69,14 @@ abstract contract AccessControlEnumerable is AccessControl {
|
||||
_roleMembers[role].remove(account);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Overload {renounceRole} to track enumerable memberships
|
||||
*/
|
||||
function renounceRole(bytes32 role, address account) public virtual override {
|
||||
super.renounceRole(role, account);
|
||||
_roleMembers[role].remove(account);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Overload {_setupRole} to track enumerable memberships
|
||||
*/
|
||||
|
||||
@ -2,9 +2,9 @@
|
||||
|
||||
pragma solidity ^0.8.0;
|
||||
|
||||
import "./Address.sol";
|
||||
import "./Context.sol";
|
||||
import "./math/SafeMath.sol";
|
||||
import "../utils/Address.sol";
|
||||
import "../utils/Context.sol";
|
||||
import "../utils/math/SafeMath.sol";
|
||||
|
||||
/**
|
||||
* @title PaymentSplitter
|
||||
10
contracts/finance/README.adoc
Normal file
10
contracts/finance/README.adoc
Normal file
@ -0,0 +1,10 @@
|
||||
= Finance
|
||||
|
||||
[.readme-notice]
|
||||
NOTE: This document is better viewed at https://docs.openzeppelin.com/contracts/api/finance
|
||||
|
||||
This directory includes primitives for financial systems. We currently only offer the {PaymentSplitter} contract, but we want to grow this directory so we welcome ideas.
|
||||
|
||||
== PaymentSplitter
|
||||
|
||||
{{PaymentSplitter}}
|
||||
@ -1,7 +1,7 @@
|
||||
= Governance
|
||||
|
||||
[.readme-notice]
|
||||
NOTE: This document is better viewed at https://docs.openzeppelin.com/contracts/api/access
|
||||
NOTE: This document is better viewed at https://docs.openzeppelin.com/contracts/api/governance
|
||||
|
||||
This directory includes primitives for on-chain governance. We currently only offer the {TimelockController} contract, that can be used as a component in a governance systems to introduce a delay between a proposal and its execution.
|
||||
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
|
||||
pragma solidity ^0.8.0;
|
||||
|
||||
import "../utils/Initializable.sol";
|
||||
import "../proxy/utils/Initializable.sol";
|
||||
|
||||
/**
|
||||
* @title InitializableMock
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
|
||||
pragma solidity ^0.8.0;
|
||||
|
||||
import "../utils/Initializable.sol";
|
||||
import "../proxy/utils/Initializable.sol";
|
||||
|
||||
// Sample contracts showing upgradeability with multiple inheritance.
|
||||
// Child contract inherits from Father and Mother contracts, and Father extends from Gramps.
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
|
||||
pragma solidity ^0.8.0;
|
||||
|
||||
import "../utils/Initializable.sol";
|
||||
import "../proxy/utils/Initializable.sol";
|
||||
|
||||
contract Implementation1 is Initializable {
|
||||
uint internal _value;
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
|
||||
pragma solidity ^0.8.0;
|
||||
|
||||
import "../utils/Initializable.sol";
|
||||
import "../proxy/utils/Initializable.sol";
|
||||
|
||||
/**
|
||||
* @title MigratableMockV1
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@openzeppelin/contracts",
|
||||
"description": "Secure Smart Contract library for Solidity",
|
||||
"version": "4.0.0-beta.1",
|
||||
"version": "4.0.0",
|
||||
"files": [
|
||||
"**/*.sol",
|
||||
"/build/contracts/*.json",
|
||||
|
||||
@ -40,3 +40,7 @@ CAUTION: Using upgradeable proxies correctly and securely is a difficult task th
|
||||
== Minimal Clones
|
||||
|
||||
{{Clones}}
|
||||
|
||||
== Utils
|
||||
|
||||
{{Initializable}}
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
// solhint-disable-next-line compiler-version
|
||||
pragma solidity ^0.8.0;
|
||||
|
||||
import "./Address.sol";
|
||||
import "../../utils/Address.sol";
|
||||
|
||||
/**
|
||||
* @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed
|
||||
@ -55,7 +55,7 @@ contract ERC1155 is Context, ERC165, IERC1155, IERC1155MetadataURI {
|
||||
* Clients calling this function must replace the `\{id\}` substring with the
|
||||
* actual token type ID.
|
||||
*/
|
||||
function uri(uint256) external view virtual override returns (string memory) {
|
||||
function uri(uint256) public view virtual override returns (string memory) {
|
||||
return _uri;
|
||||
}
|
||||
|
||||
|
||||
@ -89,6 +89,13 @@ contract ERC1155PresetMinterPauser is Context, AccessControlEnumerable, ERC1155B
|
||||
_unpause();
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev See {IERC165-supportsInterface}.
|
||||
*/
|
||||
function supportsInterface(bytes4 interfaceId) public view virtual override(AccessControlEnumerable, ERC1155) returns (bool) {
|
||||
return super.supportsInterface(interfaceId);
|
||||
}
|
||||
|
||||
function _beforeTokenTransfer(
|
||||
address operator,
|
||||
address from,
|
||||
|
||||
@ -223,7 +223,7 @@ contract ERC721 is Context, ERC165, IERC721, IERC721Metadata {
|
||||
* @dev Safely mints `tokenId` and transfers it to `to`.
|
||||
*
|
||||
* Requirements:
|
||||
d*
|
||||
*
|
||||
* - `tokenId` must not exist.
|
||||
* - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
|
||||
*
|
||||
|
||||
@ -39,7 +39,7 @@ NOTE: This core set of contracts is designed to be unopinionated, allowing devel
|
||||
|
||||
{{ERC721Burnable}}
|
||||
|
||||
{{ERC721TokenUri}}
|
||||
{{ERC721URIStorage}}
|
||||
|
||||
== Presets
|
||||
|
||||
|
||||
@ -5,7 +5,7 @@ pragma solidity ^0.8.0;
|
||||
import "../ERC721.sol";
|
||||
|
||||
/**
|
||||
* @dev ERC721 token with storage based token uri management.
|
||||
* @dev ERC721 token with storage based token URI management.
|
||||
*/
|
||||
abstract contract ERC721URIStorage is ERC721 {
|
||||
using Strings for uint256;
|
||||
|
||||
@ -110,7 +110,7 @@ contract ERC721PresetMinterPauserAutoId is Context, AccessControlEnumerable, ERC
|
||||
/**
|
||||
* @dev See {IERC165-supportsInterface}.
|
||||
*/
|
||||
function supportsInterface(bytes4 interfaceId) public view virtual override(ERC721, ERC721Enumerable) returns (bool) {
|
||||
function supportsInterface(bytes4 interfaceId) public view virtual override(AccessControlEnumerable, ERC721, ERC721Enumerable) returns (bool) {
|
||||
return super.supportsInterface(interfaceId);
|
||||
}
|
||||
}
|
||||
|
||||
@ -40,6 +40,14 @@ Finally, {Create2} contains all necessary utilities to safely use the https://bl
|
||||
|
||||
{{EIP712}}
|
||||
|
||||
== Escrow
|
||||
|
||||
{{ConditionalEscrow}}
|
||||
|
||||
{{Escrow}}
|
||||
|
||||
{{RefundEscrow}}
|
||||
|
||||
== Introspection
|
||||
|
||||
This set of interfaces and contracts deal with https://en.wikipedia.org/wiki/Type_introspection[type introspection] of contracts, that is, examining which functions can be called on them. This is usually referred to as a contract's _interface_.
|
||||
@ -84,7 +92,3 @@ Note that, in all cases, accounts simply _declare_ their interfaces, but they ar
|
||||
{{Counters}}
|
||||
|
||||
{{Strings}}
|
||||
|
||||
== Other
|
||||
|
||||
{{Initializable}}
|
||||
|
||||
1634
package-lock.json
generated
1634
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "openzeppelin-solidity",
|
||||
"description": "Secure Smart Contract library for Solidity",
|
||||
"version": "4.0.0-beta.1",
|
||||
"version": "4.0.0",
|
||||
"files": [
|
||||
"/contracts/**/*.sol",
|
||||
"/build/contracts/*.json",
|
||||
@ -75,6 +75,5 @@
|
||||
"solidity-coverage": "^0.7.11",
|
||||
"solidity-docgen": "^0.5.3",
|
||||
"web3": "^1.3.0"
|
||||
},
|
||||
"dependencies": {}
|
||||
}
|
||||
}
|
||||
|
||||
@ -30,7 +30,8 @@ const pathUpdates = {
|
||||
'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': 'utils/PaymentSplitter.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',
|
||||
@ -40,12 +41,13 @@ const pathUpdates = {
|
||||
'proxy/BeaconProxy.sol': 'proxy/beacon/BeaconProxy.sol',
|
||||
// 'proxy/Clones.sol': undefined,
|
||||
'proxy/IBeacon.sol': 'proxy/beacon/IBeacon.sol',
|
||||
'proxy/Initializable.sol': 'utils/Initializable.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': undefined,
|
||||
'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',
|
||||
|
||||
@ -23,23 +23,21 @@ const ignorePatternsSubtrees = ignorePatterns
|
||||
.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);
|
||||
if (filenames.length !== 1) {
|
||||
throw new Error(`There should only be one file in ${buildinfo}`);
|
||||
}
|
||||
const solcOutput = readJSON(path.join(buildinfo, filenames[0])).output;
|
||||
|
||||
const artifactsDir = 'build/contracts';
|
||||
|
||||
let n = 0;
|
||||
|
||||
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;
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,11 +1,15 @@
|
||||
const { expectEvent, expectRevert } = require('@openzeppelin/test-helpers');
|
||||
const { expect } = require('chai');
|
||||
|
||||
const { shouldSupportInterfaces } = require('../utils/introspection/SupportsInterface.behavior');
|
||||
|
||||
const DEFAULT_ADMIN_ROLE = '0x0000000000000000000000000000000000000000000000000000000000000000';
|
||||
const ROLE = web3.utils.soliditySha3('ROLE');
|
||||
const OTHER_ROLE = web3.utils.soliditySha3('OTHER_ROLE');
|
||||
|
||||
function shouldBehaveLikeAccessControl (errorPrefix, admin, authorized, other, otherAdmin, otherAuthorized) {
|
||||
shouldSupportInterfaces(['AccessControl']);
|
||||
|
||||
describe('default admin', function () {
|
||||
it('deployer has default admin role', async function () {
|
||||
expect(await this.accessControl.hasRole(DEFAULT_ADMIN_ROLE, admin)).to.equal(true);
|
||||
@ -156,6 +160,8 @@ function shouldBehaveLikeAccessControl (errorPrefix, admin, authorized, other, o
|
||||
}
|
||||
|
||||
function shouldBehaveLikeAccessControlEnumerable (errorPrefix, admin, authorized, other, otherAdmin, otherAuthorized) {
|
||||
shouldSupportInterfaces(['AccessControlEnumerable']);
|
||||
|
||||
describe('enumerating', function () {
|
||||
it('role bearers can be enumerated', async function () {
|
||||
await this.accessControl.grantRole(ROLE, authorized, { from: admin });
|
||||
@ -173,6 +179,13 @@ function shouldBehaveLikeAccessControlEnumerable (errorPrefix, admin, authorized
|
||||
|
||||
expect(bearers).to.have.members([authorized, otherAuthorized]);
|
||||
});
|
||||
it('role enumeration should be in sync after renounceRole call', async function () {
|
||||
expect(await this.accessControl.getRoleMemberCount(ROLE)).to.bignumber.equal('0');
|
||||
await this.accessControl.grantRole(ROLE, admin, { from: admin });
|
||||
expect(await this.accessControl.getRoleMemberCount(ROLE)).to.bignumber.equal('1');
|
||||
await this.accessControl.renounceRole(ROLE, admin, { from: admin });
|
||||
expect(await this.accessControl.getRoleMemberCount(ROLE)).to.bignumber.equal('0');
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
const { BN, constants, expectEvent, expectRevert } = require('@openzeppelin/test-helpers');
|
||||
const { ZERO_ADDRESS } = constants;
|
||||
const { shouldSupportInterfaces } = require('../../../utils/introspection/SupportsInterface.behavior');
|
||||
|
||||
const { expect } = require('chai');
|
||||
|
||||
@ -24,6 +25,8 @@ contract('ERC1155PresetMinterPauser', function (accounts) {
|
||||
this.token = await ERC1155PresetMinterPauser.new(uri, { from: deployer });
|
||||
});
|
||||
|
||||
shouldSupportInterfaces(['ERC1155', 'AccessControl', 'AccessControlEnumerable']);
|
||||
|
||||
it('deployer has the default admin role', async function () {
|
||||
expect(await this.token.getRoleMemberCount(DEFAULT_ADMIN_ROLE)).to.be.bignumber.equal('1');
|
||||
expect(await this.token.getRoleMember(DEFAULT_ADMIN_ROLE, 0)).to.equal(deployer);
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
const { BN, constants, expectEvent, expectRevert } = require('@openzeppelin/test-helpers');
|
||||
const { ZERO_ADDRESS } = constants;
|
||||
const { shouldSupportInterfaces } = require('../../../utils/introspection/SupportsInterface.behavior');
|
||||
|
||||
const { expect } = require('chai');
|
||||
|
||||
@ -19,6 +20,8 @@ contract('ERC721PresetMinterPauserAutoId', function (accounts) {
|
||||
this.token = await ERC721PresetMinterPauserAutoId.new(name, symbol, baseURI, { from: deployer });
|
||||
});
|
||||
|
||||
shouldSupportInterfaces(['ERC721', 'ERC721Enumerable', 'AccessControl', 'AccessControlEnumerable']);
|
||||
|
||||
it('token has correct name', async function () {
|
||||
expect(await this.token.name()).to.equal(name);
|
||||
});
|
||||
|
||||
@ -39,6 +39,17 @@ const INTERFACES = {
|
||||
'onERC1155Received(address,address,uint256,uint256,bytes)',
|
||||
'onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)',
|
||||
],
|
||||
AccessControl: [
|
||||
'hasRole(bytes32,address)',
|
||||
'getRoleAdmin(bytes32)',
|
||||
'grantRole(bytes32,address)',
|
||||
'revokeRole(bytes32,address)',
|
||||
'renounceRole(bytes32,address)',
|
||||
],
|
||||
AccessControlEnumerable: [
|
||||
'getRoleMember(bytes32,uint256)',
|
||||
'getRoleMemberCount(bytes32)',
|
||||
],
|
||||
};
|
||||
|
||||
const INTERFACE_IDS = {};
|
||||
@ -54,7 +65,7 @@ for (const k of Object.getOwnPropertyNames(INTERFACES)) {
|
||||
function shouldSupportInterfaces (interfaces = []) {
|
||||
describe('Contract interface', function () {
|
||||
beforeEach(function () {
|
||||
this.contractUnderTest = this.mock || this.token || this.holder;
|
||||
this.contractUnderTest = this.mock || this.token || this.holder || this.accessControl;
|
||||
});
|
||||
|
||||
for (const k of interfaces) {
|
||||
|
||||
Reference in New Issue
Block a user