Replace error strings with custom errors (#4261)
This commit is contained in:
@ -17,6 +17,11 @@ pragma solidity ^0.8.19;
|
||||
* _Available since v3.4._
|
||||
*/
|
||||
library Clones {
|
||||
/**
|
||||
* @dev A clone instance deployment failed.
|
||||
*/
|
||||
error ERC1167FailedCreateClone();
|
||||
|
||||
/**
|
||||
* @dev Deploys and returns the address of a clone that mimics the behaviour of `implementation`.
|
||||
*
|
||||
@ -32,7 +37,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();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -52,7 +59,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 ERC1167FailedCreateClone();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -26,6 +26,26 @@ abstract contract ERC1967Upgrade is IERC1967 {
|
||||
*/
|
||||
bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
|
||||
|
||||
/**
|
||||
* @dev The `implementation` of the proxy is invalid.
|
||||
*/
|
||||
error ERC1967InvalidImplementation(address implementation);
|
||||
|
||||
/**
|
||||
* @dev The `admin` of the proxy is invalid.
|
||||
*/
|
||||
error ERC1967InvalidAdmin(address admin);
|
||||
|
||||
/**
|
||||
* @dev The `beacon` of the proxy is invalid.
|
||||
*/
|
||||
error ERC1967InvalidBeacon(address beacon);
|
||||
|
||||
/**
|
||||
* @dev The storage `slot` is unsupported as a UUID.
|
||||
*/
|
||||
error ERC1967UnsupportedProxiableUUID(bytes32 slot);
|
||||
|
||||
/**
|
||||
* @dev Returns the current implementation address.
|
||||
*/
|
||||
@ -37,7 +57,9 @@ abstract contract ERC1967Upgrade is IERC1967 {
|
||||
* @dev Stores a new address in the EIP1967 implementation slot.
|
||||
*/
|
||||
function _setImplementation(address newImplementation) private {
|
||||
require(newImplementation.code.length > 0, "ERC1967: new implementation is not a contract");
|
||||
if (newImplementation.code.length == 0) {
|
||||
revert ERC1967InvalidImplementation(newImplementation);
|
||||
}
|
||||
StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;
|
||||
}
|
||||
|
||||
@ -76,9 +98,12 @@ abstract contract ERC1967Upgrade is IERC1967 {
|
||||
_setImplementation(newImplementation);
|
||||
} else {
|
||||
try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {
|
||||
require(slot == _IMPLEMENTATION_SLOT, "ERC1967Upgrade: unsupported proxiableUUID");
|
||||
if (slot != _IMPLEMENTATION_SLOT) {
|
||||
revert ERC1967UnsupportedProxiableUUID(slot);
|
||||
}
|
||||
} catch {
|
||||
revert("ERC1967Upgrade: new implementation is not UUPS");
|
||||
// The implementation is not UUPS
|
||||
revert ERC1967InvalidImplementation(newImplementation);
|
||||
}
|
||||
_upgradeToAndCall(newImplementation, data, forceCall);
|
||||
}
|
||||
@ -106,7 +131,9 @@ abstract contract ERC1967Upgrade is IERC1967 {
|
||||
* @dev Stores a new address in the EIP1967 admin slot.
|
||||
*/
|
||||
function _setAdmin(address newAdmin) private {
|
||||
require(newAdmin != address(0), "ERC1967: new admin is the zero address");
|
||||
if (newAdmin == address(0)) {
|
||||
revert ERC1967InvalidAdmin(address(0));
|
||||
}
|
||||
StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin;
|
||||
}
|
||||
|
||||
@ -137,11 +164,15 @@ abstract contract ERC1967Upgrade is IERC1967 {
|
||||
* @dev Stores a new beacon in the EIP1967 beacon slot.
|
||||
*/
|
||||
function _setBeacon(address newBeacon) private {
|
||||
require(newBeacon.code.length > 0, "ERC1967: new beacon is not a contract");
|
||||
require(
|
||||
IBeacon(newBeacon).implementation().code.length > 0,
|
||||
"ERC1967: beacon implementation is not a contract"
|
||||
);
|
||||
if (newBeacon.code.length == 0) {
|
||||
revert ERC1967InvalidBeacon(newBeacon);
|
||||
}
|
||||
|
||||
address beaconImplementation = IBeacon(newBeacon).implementation();
|
||||
if (beaconImplementation.code.length == 0) {
|
||||
revert ERC1967InvalidImplementation(beaconImplementation);
|
||||
}
|
||||
|
||||
StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon;
|
||||
}
|
||||
|
||||
|
||||
@ -15,6 +15,11 @@ import "../../access/Ownable.sol";
|
||||
contract UpgradeableBeacon is IBeacon, Ownable {
|
||||
address private _implementation;
|
||||
|
||||
/**
|
||||
* @dev The `implementation` of the beacon is invalid.
|
||||
*/
|
||||
error BeaconInvalidImplementation(address implementation);
|
||||
|
||||
/**
|
||||
* @dev Emitted when the implementation returned by the beacon is changed.
|
||||
*/
|
||||
@ -57,7 +62,9 @@ contract UpgradeableBeacon is IBeacon, Ownable {
|
||||
* - `newImplementation` must be a contract.
|
||||
*/
|
||||
function _setImplementation(address newImplementation) private {
|
||||
require(newImplementation.code.length > 0, "UpgradeableBeacon: implementation is not a contract");
|
||||
if (newImplementation.code.length == 0) {
|
||||
revert BeaconInvalidImplementation(newImplementation);
|
||||
}
|
||||
_implementation = newImplementation;
|
||||
}
|
||||
}
|
||||
|
||||
@ -52,6 +52,16 @@ interface ITransparentUpgradeableProxy is IERC1967 {
|
||||
* render the admin operations inaccessible, which could prevent upgradeability. Transparency may also be compromised.
|
||||
*/
|
||||
contract TransparentUpgradeableProxy is ERC1967Proxy {
|
||||
/**
|
||||
* @dev The proxy caller is the current admin, and can't fallback to the proxy target.
|
||||
*/
|
||||
error ProxyDeniedAdminAccess();
|
||||
|
||||
/**
|
||||
* @dev msg.value is not 0.
|
||||
*/
|
||||
error ProxyNonPayableFunction();
|
||||
|
||||
/**
|
||||
* @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and
|
||||
* optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.
|
||||
@ -74,7 +84,7 @@ contract TransparentUpgradeableProxy is ERC1967Proxy {
|
||||
} else if (selector == ITransparentUpgradeableProxy.changeAdmin.selector) {
|
||||
ret = _dispatchChangeAdmin();
|
||||
} else {
|
||||
revert("TransparentUpgradeableProxy: admin cannot fallback to proxy target");
|
||||
revert ProxyDeniedAdminAccess();
|
||||
}
|
||||
assembly {
|
||||
return(add(ret, 0x20), mload(ret))
|
||||
@ -127,6 +137,8 @@ contract TransparentUpgradeableProxy is ERC1967Proxy {
|
||||
* non-payability of function implemented through dispatchers while still allowing value to pass through.
|
||||
*/
|
||||
function _requireZeroValue() private {
|
||||
require(msg.value == 0);
|
||||
if (msg.value != 0) {
|
||||
revert ProxyNonPayableFunction();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -67,6 +67,16 @@ abstract contract Initializable {
|
||||
*/
|
||||
bool private _initializing;
|
||||
|
||||
/**
|
||||
* @dev The contract is already initialized.
|
||||
*/
|
||||
error AlreadyInitialized();
|
||||
|
||||
/**
|
||||
* @dev The contract is not initializing.
|
||||
*/
|
||||
error NotInitializing();
|
||||
|
||||
/**
|
||||
* @dev Triggered when the contract has been initialized or reinitialized.
|
||||
*/
|
||||
@ -83,10 +93,9 @@ abstract contract Initializable {
|
||||
*/
|
||||
modifier initializer() {
|
||||
bool isTopLevelCall = !_initializing;
|
||||
require(
|
||||
(isTopLevelCall && _initialized < 1) || (address(this).code.length == 0 && _initialized == 1),
|
||||
"Initializable: contract is already initialized"
|
||||
);
|
||||
if (!(isTopLevelCall && _initialized < 1) && !(address(this).code.length == 0 && _initialized == 1)) {
|
||||
revert AlreadyInitialized();
|
||||
}
|
||||
_initialized = 1;
|
||||
if (isTopLevelCall) {
|
||||
_initializing = true;
|
||||
@ -117,7 +126,9 @@ abstract contract Initializable {
|
||||
* Emits an {Initialized} event.
|
||||
*/
|
||||
modifier reinitializer(uint8 version) {
|
||||
require(!_initializing && _initialized < version, "Initializable: contract is already initialized");
|
||||
if (_initializing || _initialized >= version) {
|
||||
revert AlreadyInitialized();
|
||||
}
|
||||
_initialized = version;
|
||||
_initializing = true;
|
||||
_;
|
||||
@ -130,7 +141,9 @@ abstract contract Initializable {
|
||||
* {initializer} and {reinitializer} modifiers, directly or indirectly.
|
||||
*/
|
||||
modifier onlyInitializing() {
|
||||
require(_initializing, "Initializable: contract is not initializing");
|
||||
if (!_initializing) {
|
||||
revert NotInitializing();
|
||||
}
|
||||
_;
|
||||
}
|
||||
|
||||
@ -143,7 +156,9 @@ abstract contract Initializable {
|
||||
* Emits an {Initialized} event the first time it is successfully executed.
|
||||
*/
|
||||
function _disableInitializers() internal virtual {
|
||||
require(!_initializing, "Initializable: contract is initializing");
|
||||
if (_initializing) {
|
||||
revert AlreadyInitialized();
|
||||
}
|
||||
if (_initialized != type(uint8).max) {
|
||||
_initialized = type(uint8).max;
|
||||
emit Initialized(type(uint8).max);
|
||||
|
||||
@ -22,6 +22,11 @@ abstract contract UUPSUpgradeable is IERC1822Proxiable, ERC1967Upgrade {
|
||||
/// @custom:oz-upgrades-unsafe-allow state-variable-immutable state-variable-assignment
|
||||
address private immutable __self = address(this);
|
||||
|
||||
/**
|
||||
* @dev The call is from an unauthorized context.
|
||||
*/
|
||||
error UUPSUnauthorizedCallContext(address context);
|
||||
|
||||
/**
|
||||
* @dev Check that the execution is being performed through a delegatecall call and that the execution context is
|
||||
* a proxy contract with an implementation (as defined in ERC1967) pointing to self. This should only be the case
|
||||
@ -30,8 +35,15 @@ abstract contract UUPSUpgradeable is IERC1822Proxiable, ERC1967Upgrade {
|
||||
* fail.
|
||||
*/
|
||||
modifier onlyProxy() {
|
||||
require(address(this) != __self, "Function must be called through delegatecall");
|
||||
require(_getImplementation() == __self, "Function must be called through active proxy");
|
||||
if (address(this) == __self) {
|
||||
// Must be called through delegatecall
|
||||
revert UUPSUnauthorizedCallContext(address(this));
|
||||
}
|
||||
address implementation = _getImplementation();
|
||||
if (implementation != __self) {
|
||||
// Must be called through an active proxy
|
||||
revert UUPSUnauthorizedCallContext(implementation);
|
||||
}
|
||||
_;
|
||||
}
|
||||
|
||||
@ -40,7 +52,10 @@ abstract contract UUPSUpgradeable is IERC1822Proxiable, ERC1967Upgrade {
|
||||
* callable on the implementing contract but not through proxies.
|
||||
*/
|
||||
modifier notDelegated() {
|
||||
require(address(this) == __self, "UUPSUpgradeable: must not be called through delegatecall");
|
||||
if (address(this) != __self) {
|
||||
// Must not be called through delegatecall
|
||||
revert UUPSUnauthorizedCallContext(address(this));
|
||||
}
|
||||
_;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user