Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
122 commits
Select commit Hold shift + click to select a range
4307e5b
Replace error strings with custom errors
ernestognw May 18, 2023
ddf387c
Lint
ernestognw May 18, 2023
0800e32
Finish original list of errors
ernestognw May 19, 2023
199093b
Finish missing require statements
ernestognw May 19, 2023
d3703bd
Self review
ernestognw May 19, 2023
11931ca
Finish revert statements
ernestognw May 19, 2023
bb3a12f
Applied spreadsheet suggestion
ernestognw May 19, 2023
9f58996
Refactor Address.sol
ernestognw May 19, 2023
a76e4b6
Finish custom errors replacement
ernestognw May 19, 2023
c65b76b
Fix SignatureChecker
ernestognw May 20, 2023
f58c06b
Add account to `GovernorAlreadyCastVote` error
ernestognw May 21, 2023
810468d
Finish access, finance, and governance testing
ernestognw May 22, 2023
adbe841
Fix proxy tests
ernestognw May 22, 2023
c29e041
First round of reviews
ernestognw May 22, 2023
bc00094
Fix tests for ERC20 and ERC1155 tokens
ernestognw May 23, 2023
faf33a4
Lint
ernestognw May 23, 2023
cdbea1e
Bump Pragma to 0.8.19
ernestognw May 23, 2023
77eee99
Finish token tests
ernestognw May 23, 2023
ba42df6
Fix ERC20Capped
ernestognw May 23, 2023
c31e10d
Fix Address tests
ernestognw May 23, 2023
b3b7e08
Advancements on utils
ernestognw May 24, 2023
960066b
Fix utils test
ernestognw May 24, 2023
b815a4f
Remove unnecessary test file
ernestognw May 24, 2023
99347e4
Fix conflicts with master
ernestognw May 24, 2023
d7d3f90
Lint
ernestognw May 24, 2023
5bc0812
Add changeset
ernestognw May 24, 2023
3276d35
Fix generation script
ernestognw May 24, 2023
23a7be2
Fix flaky Create2 test
ernestognw May 24, 2023
3f4f84a
Update comment in Ownable
ernestognw May 24, 2023
3dc21e2
Add `Unset` state to TimelockController
ernestognw May 24, 2023
1c119f7
Replace `GovernorMissingETA` with `GovernorProposalNotQueued`
ernestognw May 24, 2023
6541481
Revert interface changes to MinimalForwarder
ernestognw May 24, 2023
9c71d9c
Remove ERC-6093 from token interfaces
ernestognw May 24, 2023
5f8417b
Replace `msg.sender` with `_msgSender()` in ERC721Wrapper
ernestognw May 24, 2023
55f0eef
Make `onRevert` view visilibity
ernestognw May 24, 2023
5fe9511
Change Ownable2Step's error for invalid ownership acceptance
ernestognw May 24, 2023
c927bc3
Replace SafeERC20's domain
ernestognw May 25, 2023
0a5bb3f
Merge branch 'next-v5.0' into lib-839-custom-errors
ernestognw May 25, 2023
eac424e
Lint fix
ernestognw May 25, 2023
e11f4fa
Merge branch 'next-v5.0' into lib-839-custom-errors
ernestognw May 29, 2023
5dc5ada
Fix checkpoint tests
ernestognw May 29, 2023
44535a2
Enabled all tests
ernestognw May 29, 2023
0d1d6c0
Remove GovernorDuplicatedProposal error
ernestognw May 29, 2023
07d4fc9
Merge branch 'next-v5.0' into lib-839-custom-errors
ernestognw May 29, 2023
058b672
Lint
ernestognw May 29, 2023
1d63212
Update contracts/governance/IGovernor.sol
ernestognw May 30, 2023
276331c
Update contracts/utils/Address.sol
ernestognw May 30, 2023
28e2e16
Round of review
ernestognw May 30, 2023
2b0ce34
Merge branch 'next-v5.0' into lib-839-custom-errors
ernestognw May 30, 2023
4946dd9
Rename AccessContol renounce error and parameter
ernestognw May 31, 2023
3173d53
Rename `Unsuccessful` -> `Failed`
ernestognw May 31, 2023
6c8d0e1
Merge Address failed call errors
ernestognw May 31, 2023
cb79ab3
Rename *FailedLowLevelCall to *FailedCall
ernestognw May 31, 2023
be68001
Round of review
ernestognw Jun 1, 2023
f02af6e
Change token paused errors
ernestognw Jun 1, 2023
2d735e6
Fix tests
ernestognw Jun 1, 2023
2ecfd14
Round of review
ernestognw Jun 1, 2023
b3af988
Round of review
ernestognw Jun 1, 2023
c862ca5
More review
ernestognw Jun 1, 2023
5069bdf
Fixed example in StorageSlot.sol
ernestognw Jun 1, 2023
48fe940
Changed Checkpoint error
ernestognw Jun 1, 2023
c15fbf8
Added value to StringsInsufficientHexLength
ernestognw Jun 1, 2023
a10ee8b
Added `useCheckedNonce` for Nonces
ernestognw Jun 1, 2023
8d62e91
Merge branch 'master' into lib-839-custom-errors
ernestognw Jun 1, 2023
861d341
Replace ERC20DecreasedAllowance for SafeERC20
ernestognw Jun 1, 2023
61a6026
Merge branch 'master' into lib-839-custom-errors
ernestognw Jun 2, 2023
c796d15
Improved MinimalForwarder errors
ernestognw Jun 2, 2023
6a9c40f
Merge branch 'master' into lib-839-custom-errors
ernestognw Jun 2, 2023
a4063c9
Review
ernestognw Jun 2, 2023
5876d1c
Remove mutable variables in ERC1155 tests
ernestognw Jun 2, 2023
6d8c498
Remove unnecessary error
ernestognw Jun 2, 2023
219923b
Rename `Inexistent` to `Nonexistent`
ernestognw Jun 2, 2023
1fa5acc
Rename AccessControlDefaultAdminRules errors
ernestognw Jun 2, 2023
602df5a
Overflown -> Overflowed
ernestognw Jun 2, 2023
4a14bec
Simplified SafeCast errors
ernestognw Jun 2, 2023
ff12505
Review round
ernestognw Jun 2, 2023
65ad2e5
Lint
ernestognw Jun 2, 2023
91bdb7c
Mooar review
ernestognw Jun 3, 2023
a33a4c8
Revert ERC721 changes
ernestognw Jun 3, 2023
2253c40
Rename Paused errors by using a library
ernestognw Jun 3, 2023
892dbcc
Lint
ernestognw Jun 3, 2023
028f383
Fix tests
ernestognw Jun 5, 2023
9c70af8
Review suggestions
ernestognw Jun 5, 2023
7647774
Move Pausable errors to its own file
ernestognw Jun 6, 2023
45ce67f
Merge branch 'master' into lib-839-custom-errors
ernestognw Jun 6, 2023
11092da
Moar suggestions
ernestognw Jun 6, 2023
6009844
Moar suggestions
ernestognw Jun 6, 2023
55433e7
Improved custom error matcher
ernestognw Jun 7, 2023
4dac3c7
Lint
ernestognw Jun 7, 2023
aa44323
Merge branch 'master' into lib-839-custom-errors
ernestognw Jun 7, 2023
cb4594f
Merge branch 'master' into lib-839-custom-errors
ernestognw Jun 7, 2023
6df52b0
Simplify custom error matcher regex
ernestognw Jun 7, 2023
ce83461
Attempt to remove the optimizations branch check for custom errors
ernestognw Jun 7, 2023
e5475a2
Simplify custom error matcher
ernestognw Jun 8, 2023
03f1152
Revert ERC1155Supply _update order
ernestognw Jun 8, 2023
7e320a7
Merge branch 'master' into lib-839-custom-errors
ernestognw Jun 8, 2023
0e158b5
Update GUIDELINES.md
ernestognw Jun 8, 2023
f1717a6
Use verifyCallResult in Timelock
ernestognw Jun 9, 2023
db4bcf9
Fix TimelockController tests
ernestognw Jun 9, 2023
e0949a3
Add domain to DoubleEndedQueue errors
ernestognw Jun 9, 2023
46904d7
Suggestions
ernestognw Jun 9, 2023
3a74c47
Change Pausable error names
ernestognw Jun 9, 2023
7bf1afc
Remove address context from UUPSUnauthorizedCallContext
ernestognw Jun 9, 2023
13dd54a
More suggestions
ernestognw Jun 9, 2023
c97d95c
Remove errorPrefix in AccessControl tests
Amxx Jun 9, 2023
fc1e4b0
Remove errorPrefix in ERC20 tests
Amxx Jun 9, 2023
27b15e3
move ERC20Permit.test.js out of draft
Amxx Jun 9, 2023
2ad6e65
Remove errorPrefix in ERC721 tests
Amxx Jun 9, 2023
9304b9b
Fix test
ernestognw Jun 9, 2023
d4f7071
Remove Pausable.errors.sol library
ernestognw Jun 9, 2023
88cf256
Applied suggestions
ernestognw Jun 9, 2023
4432ee6
More suggestions
ernestognw Jun 9, 2023
b2aaf9e
Remove _custom revert functions
ernestognw Jun 9, 2023
d5815a8
Fix tests
ernestognw Jun 9, 2023
d4e27a0
increase gas for test
frangio Jun 9, 2023
73ac6dd
document unspecified revert, and add custom error check
Amxx Jun 12, 2023
8994817
document bubbling of panic code
Amxx Jun 12, 2023
c1c6a75
Update contracts/utils/Address.sol
ernestognw Jun 12, 2023
3da76b0
Update test/helpers/customError.js
ernestognw Jun 12, 2023
4aa35c8
Remove `bitsize` from SafeCastOverflowed cast errors
ernestognw Jun 12, 2023
007d6b0
Lint
ernestognw Jun 12, 2023
1cd28fe
Merge branch 'master' into lib-839-custom-errors
ernestognw Jun 12, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Replace error strings with custom errors
  • Loading branch information
ernestognw committed May 19, 2023
commit 4307e5be4857dd523864dd943e1a5bc7e285ab76
74 changes: 62 additions & 12 deletions contracts/access/AccessControlDefaultAdminRules.sol
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (access/AccessControlDefaultAdminRules.sol)

pragma solidity ^0.8.0;
pragma solidity ^0.8.18;

import "./AccessControl.sol";
import "./IAccessControlDefaultAdminRules.sol";
Expand Down Expand Up @@ -49,11 +49,50 @@ abstract contract AccessControlDefaultAdminRules is IAccessControlDefaultAdminRu
uint48 private _pendingDelay;
uint48 private _pendingDelaySchedule; // 0 == unset

/**
* @dev The new default admin is not a valid default admin.
*/
error AccessControlInvalidDefaultAdmin(address defaultAdmin);

/**
* @dev Role can't be granted.
*/
error AccessControlForbiddenGrant(bytes32 role);

/**
* @dev Role can't be revoked.
*/
error AccessControlForbiddenRevoke(bytes32 role);

/**
* @dev The `DEFAULT_ADMIN_ROLE` should be only held by one account.
*/
error AccessControlEnforcedDefaultAdminUniqueness();

/**
* @dev The `DEFAULT_ADMIN_ROLE` can only be managed by itself.
*/
error AccessControlEnforcedDefaultAdminManagement();

/**
* @dev The `DEFAULT_ADMIN_ROLE` must be accepted by the pending default admin.
*/
error AccessControlEnforcedDefaultAdminAcceptance();

/**
* @dev The new admin is not a default admin.
*
* NOTE: Schedule can be 0 indicating there's no transfer scheduled.
*/
error AccessControlEnforcedDefaultAdminDelay(uint48 schedule);

/**
* @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);
}
Expand All @@ -80,15 +119,19 @@ 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 AccessControlForbiddenGrant(DEFAULT_ADMIN_ROLE);
}
super.grantRole(role, account);
}

/**
* @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 AccessControlForbiddenRevoke(DEFAULT_ADMIN_ROLE);
}
super.revokeRole(role, account);
}

Expand All @@ -108,10 +151,9 @@ abstract contract AccessControlDefaultAdminRules is IAccessControlDefaultAdminRu
function renounceRole(bytes32 role, address account) public virtual override(AccessControl, IAccessControl) {
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);
Expand All @@ -128,7 +170,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 AccessControlEnforcedDefaultAdminUniqueness();
}
_currentDefaultAdmin = account;
}
super._grantRole(role, account);
Expand All @@ -148,7 +192,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 AccessControlEnforcedDefaultAdminManagement();
}
super._setRoleAdmin(role, adminRole);
}

Expand Down Expand Up @@ -236,7 +282,9 @@ abstract contract AccessControlDefaultAdminRules is IAccessControlDefaultAdminRu
*/
function acceptDefaultAdminTransfer() public virtual {
(address newDefaultAdmin, ) = pendingDefaultAdmin();
require(_msgSender() == newDefaultAdmin, "AccessControl: pending admin must accept");
if (_msgSender() != newDefaultAdmin) {
revert AccessControlEnforcedDefaultAdminAcceptance();
}
_acceptDefaultAdminTransfer();
}

Expand All @@ -247,7 +295,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;
Expand Down
20 changes: 17 additions & 3 deletions contracts/access/Ownable.sol
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)

pragma solidity ^0.8.0;
pragma solidity ^0.8.18;

import "../utils/Context.sol";

Expand All @@ -20,6 +20,16 @@ import "../utils/Context.sol";
abstract contract Ownable is Context {
address private _owner;

/**
* @dev Caller is not the owner.
*/
error OwnableUnauthorized(address caller);

/**
* @dev Caller is not a valid owner.
*/
error OwnableInvalidOwner(address owner);

event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

/**
Expand Down Expand Up @@ -48,7 +58,9 @@ abstract contract Ownable is Context {
* @dev Throws if the sender is not the owner.
*/
function _checkOwner() internal view virtual {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
if (owner() != _msgSender()) {
revert OwnableUnauthorized(_msgSender());
}
}

/**
Expand All @@ -67,7 +79,9 @@ abstract contract Ownable is Context {
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
if (newOwner == address(0)) {
revert OwnableInvalidOwner(address(0));
}
_transferOwnership(newOwner);
}

Expand Down
162 changes: 162 additions & 0 deletions contracts/interfaces/draft-IERC6093.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.18;

/**
* @dev Standard ERC20 Errors
* Interface of the ERC6093 custom errors for ERC20 tokens
* as defined in https://eips.ethereum.org/EIPS/eip-6093
*/
interface ERC20Errors {
/**
* @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.
* @param sender Address whose tokens are being transferred.
* @param balance Current balance for the interacting account.
* @param needed Minimum amount required to perform a transfer.
*/
error ERC20InsufficientBalance(address sender, uint256 balance, uint256 needed);

/**
* @dev Indicates a failure with the token `sender`. Used in transfers.
* @param sender Address whose tokens are being transferred.
*/
error ERC20InvalidSender(address sender);

/**
* @dev Indicates a failure with the token `receiver`. Used in transfers.
* @param receiver Address to which tokens are being transferred.
*/
error ERC20InvalidReceiver(address receiver);

/**
* @dev Indicates a failure with the `spender`’s `allowance`. Used in transfers.
* @param spender Address that may be allowed to operate on tokens without being their owner.
* @param allowance Amount of tokens a `spender` is allowed to operate with.
* @param needed Minimum amount required to perform a transfer.
*/
error ERC20InsufficientAllowance(address spender, uint256 allowance, uint256 needed);

/**
* @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.
* @param approver Address initiating an approval operation.
*/
error ERC20InvalidApprover(address approver);

/**
* @dev Indicates a failure with the `spender` to be approved. Used in approvals.
* @param spender Address that may be allowed to operate on tokens without being their owner.
*/
error ERC20InvalidSpender(address spender);
}

/**
* @dev Standard ERC721 Errors
* Interface of the ERC6093 custom errors for ERC721 tokens
* as defined in https://eips.ethereum.org/EIPS/eip-6093
*/
interface ERC721Errors {
/**
* @dev Indicates that an address can't be an owner. For example, `address(0)` is a forbidden owner in EIP-20.
* Used in balance queries.
* @param owner Address of the current owner of a token.
*/
error ERC721InvalidOwner(address owner);

/**
* @dev Indicates a `tokenId` whose `owner` is the zero address.
* @param tokenId Identifier number of a token.
*/
error ERC721InexistentToken(uint256 tokenId);

/**
* @dev Indicates an error related to the ownership over a particular token. Used in transfers.
* @param sender Address whose tokens are being transferred.
* @param tokenId Identifier number of a token.
* @param owner Address of the current owner of a token.
*/
error ERC721IncorrectOwner(address sender, uint256 tokenId, address owner);

/**
* @dev Indicates a failure with the token `sender`. Used in transfers.
* @param sender Address whose tokens are being transferred.
*/
error ERC721InvalidSender(address sender);

/**
* @dev Indicates a failure with the token `receiver`. Used in transfers.
* @param receiver Address to which tokens are being transferred.
*/
error ERC721InvalidReceiver(address receiver);

/**
* @dev Indicates a failure with the `operator`’s approval. Used in transfers.
* @param operator Address that may be allowed to operate on tokens without being their owner.
* @param tokenId Identifier number of a token.
*/
error ERC721InsufficientApproval(address operator, uint256 tokenId);

/**
* @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.
* @param approver Address initiating an approval operation.
*/
error ERC721InvalidApprover(address approver);

/**
* @dev Indicates a failure with the `operator` to be approved. Used in approvals.
* @param operator Address that may be allowed to operate on tokens without being their owner.
*/
error ERC721InvalidOperator(address operator);
}

/**
* @dev Standard ERC1155 Errors
* Interface of the ERC6093 custom errors for ERC1155 tokens
* as defined in https://eips.ethereum.org/EIPS/eip-6093
*/
interface ERC1155Errors {
/**
* @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.
* @param sender Address whose tokens are being transferred.
* @param balance Current balance for the interacting account.
* @param needed Minimum amount required to perform a transfer.
*/
error ERC1155InsufficientBalance(address sender, uint256 balance, uint256 needed, uint256 tokenId);

/**
* @dev Indicates a failure with the token `sender`. Used in transfers.
* @param sender Address whose tokens are being transferred.
*/
error ERC1155InvalidSender(address sender);

/**
* @dev Indicates a failure with the token `receiver`. Used in transfers.
* @param receiver Address to which tokens are being transferred.
*/
error ERC1155InvalidReceiver(address receiver);

/**
* @dev Indicates a failure with the `operator`’s approval. Used in transfers.
* @param operator Address that may be allowed to operate on tokens without being their owner.
* @param tokenId Identifier number of a token.
*/
error ERC1155InsufficientApproval(address operator, uint256 tokenId);

/**
* @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.
* @param approver Address initiating an approval operation.
*/
error ERC1155InvalidApprover(address approver);

/**
* @dev Indicates a failure with the `operator` to be approved. Used in approvals.
* @param operator Address that may be allowed to operate on tokens without being their owner.
*/
error ERC1155InvalidOperator(address operator);

/**
* @dev Indicates an array length mismatch between ids and values in a safeBatchTransferFrom operation.
* Used in batch transfers.
* @param idsLength Length of the array of token identifiers
* @param valuesLength Length of the array of token amounts
*/
error ERC1155InvalidArrayLength(uint256 idsLength, uint256 valuesLength);
}
20 changes: 17 additions & 3 deletions contracts/proxy/Clones.sol
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (proxy/Clones.sol)

pragma solidity ^0.8.0;
pragma solidity ^0.8.18;

/**
* @dev https://eips.ethereum.org/EIPS/eip-1167[EIP 1167] is a standard for
Expand All @@ -17,6 +17,16 @@ pragma solidity ^0.8.0;
* _Available since v3.4._
*/
library Clones {
/**
* @dev A `CREATE` clone instance deployment failed.
*/
error ERC1167FailedCreateClone();

/**
* @dev A `CREATE2` clone instance deployment failed.
*/
error ERC1167FailedCreate2Clone();

/**
* @dev Deploys and returns the address of a clone that mimics the behaviour of `implementation`.
*
Expand All @@ -32,7 +42,9 @@ library Clones {
mstore(0x20, or(shl(0x78, implementation), 0x5af43d82803e903d91602b57fd5bf3))
instance := create(0, 0x09, 0x37)
}
require(instance != address(0), "ERC1167: create failed");
if (instance == address(0)) {
revert ERC1167FailedCreateClone();
}
}

/**
Expand All @@ -52,7 +64,9 @@ library Clones {
mstore(0x20, or(shl(0x78, implementation), 0x5af43d82803e903d91602b57fd5bf3))
instance := create2(0, 0x09, 0x37, salt)
}
require(instance != address(0), "ERC1167: create2 failed");
if (instance == address(0)) {
revert ERC1167FailedCreate2Clone();
}
}

/**
Expand Down
Loading