Description:
Proxy contract enabling upgradeable smart contract patterns. Delegates calls to an implementation contract.
Blockchain: Ethereum
Source Code: View Code On The Blockchain
Solidity Source Code:
{"Address.sol":{"content":"// SPDX-License-Identifier: MIT\r
\r
pragma solidity ^0.8.20;\r
\r
/**\r
* @dev Collection of functions related to the address type\r
*/\r
library Address {\r
/**\r
* @dev Returns true if `account` is a contract.\r
*\r
* [IMPORTANT]\r
* ====\r
* It is unsafe to assume that an address for which this function returns\r
* false is an externally-owned account (EOA) and not a contract.\r
*\r
* Among others, `isContract` will return false for the following\r
* types of addresses:\r
*\r
* - an externally-owned account\r
* - a contract in construction\r
* - an address where a contract will be created\r
* - an address where a contract lived, but was destroyed\r
* ====\r
*/\r
function isContract(address account) internal view returns (bool) {\r
// According to EIP-1052, 0x0 is the value returned for not-yet created accounts\r
// and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned\r
// for accounts without code, i.e. `keccak256(\u0027\u0027)`\r
bytes32 codehash;\r
bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;\r
// solhint-disable-next-line no-inline-assembly\r
assembly { codehash := extcodehash(account) }\r
return (codehash != accountHash \u0026\u0026 codehash != 0x0);\r
}\r
\r
/**\r
* @dev Replacement for Solidity\u0027s `transfer`: sends `amount` wei to\r
* `recipient`, forwarding all available gas and reverting on errors.\r
*\r
* https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\r
* of certain opcodes, possibly making contracts go over the 2300 gas limit\r
* imposed by `transfer`, making them unable to receive funds via\r
* `transfer`. {sendValue} removes this limitation.\r
*\r
* https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\r
*\r
* IMPORTANT: because control is transferred to `recipient`, care must be\r
* taken to not create reentrancy vulnerabilities. Consider using\r
* {ReentrancyGuard} or the\r
* https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\r
*/\r
function sendValue(address payable recipient, uint256 amount) internal {\r
require(address(this).balance \u003e= amount, "Address: insufficient balance");\r
\r
// solhint-disable-next-line avoid-low-level-calls, avoid-call-value\r
(bool success, ) = recipient.call{ value: amount }("");\r
require(success, "Address: unable to send value, recipient may have reverted");\r
}\r
\r
/**\r
* @dev Performs a Solidity function call using a low level `call`. A\r
* plain`call` is an unsafe replacement for a function call: use this\r
* function instead.\r
*\r
* If `target` reverts with a revert reason, it is bubbled up by this\r
* function (like regular Solidity function calls).\r
*\r
* Returns the raw returned data. To convert to the expected return value,\r
* use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\r
*\r
* Requirements:\r
*\r
* - `target` must be a contract.\r
* - calling `target` with `data` must not revert.\r
*\r
* _Available since v3.1._\r
*/\r
function functionCall(address target, bytes memory data) internal returns (bytes memory) {\r
return functionCall(target, data, "Address: low-level call failed");\r
}\r
\r
/**\r
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\r
* `errorMessage` as a fallback revert reason when `target` reverts.\r
*\r
* _Available since v3.1._\r
*/\r
function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\r
return _functionCallWithValue(target, data, 0, errorMessage);\r
}\r
\r
/**\r
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\r
* but also transferring `value` wei to `target`.\r
*\r
* Requirements:\r
*\r
* - the calling contract must have an ETH balance of at least `value`.\r
* - the called Solidity function must be `payable`.\r
*\r
* _Available since v3.1._\r
*/\r
function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\r
return functionCallWithValue(target, data, value, "Address: low-level call with value failed");\r
}\r
\r
/**\r
* @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\r
* with `errorMessage` as a fallback revert reason when `target` reverts.\r
*\r
* _Available since v3.1._\r
*/\r
function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\r
require(address(this).balance \u003e= value, "Address: insufficient balance for call");\r
return _functionCallWithValue(target, data, value, errorMessage);\r
}\r
\r
function _functionCallWithValue(address target, bytes memory data, uint256 weiValue, string memory errorMessage) private returns (bytes memory) {\r
require(isContract(target), "Address: call to non-contract");\r
\r
// solhint-disable-next-line avoid-low-level-calls\r
(bool success, bytes memory returndata) = target.call{ value: weiValue }(data);\r
if (success) {\r
return returndata;\r
} else {\r
// Look for revert reason and bubble it up if present\r
if (returndata.length \u003e 0) {\r
// The easiest way to bubble the revert reason is using memory via assembly\r
\r
// solhint-disable-next-line no-inline-assembly\r
assembly {\r
let returndata_size := mload(returndata)\r
revert(add(32, returndata), returndata_size)\r
}\r
} else {\r
revert(errorMessage);\r
}\r
}\r
}\r
}"},"AdminUpgradeabilityProxy.sol":{"content":"/**\r
* SPDX-License-Identifier: MIT\r
*\r
* Copyright (c) 2018 zOS Global Limited.\r
*\r
* Permission is hereby granted, free of charge, to any person obtaining a copy\r
* of this software and associated documentation files (the "Software"), to deal\r
* in the Software without restriction, including without limitation the rights\r
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
* copies of the Software, and to permit persons to whom the Software is\r
* furnished to do so, subject to the following conditions:\r
*\r
* The above copyright notice and this permission notice shall be included in\r
* copies or substantial portions of the Software.\r
*\r
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
* SOFTWARE.\r
*/\r
\r
pragma solidity ^0.8.20;\r
\r
import { UpgradeabilityProxy } from "./UpgradeabilityProxy.sol";\r
\r
/**\r
* @notice This contract combines an upgradeability proxy with an authorization\r
* mechanism for administrative tasks.\r
* @dev Forked from https://github.com/zeppelinos/zos-lib/blob/8a16ef3ad17ec7430e3a9d2b5e3f39b8204f8c8d/contracts/upgradeability/AdminUpgradeabilityProxy.sol\r
* Modifications:\r
* 1. Reformat, conform to Solidity 0.6 syntax, and add error messages (5/13/20)\r
* 2. Remove ifAdmin modifier from admin() and implementation() (5/13/20)\r
*/\r
contract AdminUpgradeabilityProxy is UpgradeabilityProxy {\r
/**\r
* @dev Emitted when the administration has been transferred.\r
* @param previousAdmin Address of the previous admin.\r
* @param newAdmin Address of the new admin.\r
*/\r
event AdminChanged(address previousAdmin, address newAdmin);\r
\r
/**\r
* @dev Storage slot with the admin of the contract.\r
* This is the keccak-256 hash of "org.zeppelinos.proxy.admin", and is\r
* validated in the constructor.\r
*/\r
bytes32\r
private constant ADMIN_SLOT = 0x10d6a54a4754c8869d6886b5f5d7fbfa5b4522237ea5c60d11bc4e7a1ff9390b;\r
\r
/**\r
* @dev Modifier to check whether the `msg.sender` is the admin.\r
* If it is, it will run the function. Otherwise, it will delegate the call\r
* to the implementation.\r
*/\r
modifier ifAdmin() {\r
if (msg.sender == _admin()) {\r
_;\r
} else {\r
_fallback();\r
}\r
}\r
\r
/**\r
* @dev Contract constructor.\r
* It sets the `msg.sender` as the proxy administrator.\r
* @param implementationContract address of the initial implementation.\r
*/\r
constructor(address implementationContract)\r
public\r
UpgradeabilityProxy(implementationContract)\r
{\r
assert(ADMIN_SLOT == keccak256("org.zeppelinos.proxy.admin"));\r
\r
_setAdmin(msg.sender);\r
}\r
\r
/**\r
* @return The address of the proxy admin.\r
*/\r
function admin() external view returns (address) {\r
return _admin();\r
}\r
\r
/**\r
* @return The address of the implementation.\r
*/\r
function implementation() external view returns (address) {\r
return _implementation();\r
}\r
\r
/**\r
* @dev Changes the admin of the proxy.\r
* Only the current admin can call this function.\r
* @param newAdmin Address to transfer proxy administration to.\r
*/\r
function changeAdmin(address newAdmin) external ifAdmin {\r
require(\r
newAdmin != address(0),\r
"Cannot change the admin of a proxy to the zero address"\r
);\r
emit AdminChanged(_admin(), newAdmin);\r
_setAdmin(newAdmin);\r
}\r
\r
/**\r
* @dev Upgrade the backing implementation of the proxy.\r
* Only the admin can call this function.\r
* @param newImplementation Address of the new implementation.\r
*/\r
function upgradeTo(address newImplementation) external ifAdmin {\r
_upgradeTo(newImplementation);\r
}\r
\r
/**\r
* @dev Upgrade the backing implementation of the proxy and call a function\r
* on the new implementation.\r
* This is useful to initialize the proxied contract.\r
* @param newImplementation Address of the new implementation.\r
* @param data Data to send as msg.data in the low level call.\r
* It should include the signature and the parameters of the function to be\r
* called, as described in\r
* https://solidity.readthedocs.io/en/develop/abi-spec.html#function-selector-and-argument-encoding.\r
*/\r
function upgradeToAndCall(address newImplementation, bytes calldata data)\r
external\r
payable\r
ifAdmin\r
{\r
_upgradeTo(newImplementation);\r
// prettier-ignore\r
// solhint-disable-next-line avoid-low-level-calls\r
(bool success,) = address(this).call{value: msg.value}(data);\r
// solhint-disable-next-line reason-string\r
require(success);\r
}\r
\r
/**\r
* @return adm The admin slot.\r
*/\r
function _admin() internal view returns (address adm) {\r
bytes32 slot = ADMIN_SLOT;\r
\r
assembly {\r
adm := sload(slot)\r
}\r
}\r
\r
/**\r
* @dev Sets the address of the proxy admin.\r
* @param newAdmin Address of the new proxy admin.\r
*/\r
function _setAdmin(address newAdmin) internal {\r
bytes32 slot = ADMIN_SLOT;\r
\r
assembly {\r
sstore(slot, newAdmin)\r
}\r
}\r
\r
/**\r
* @dev Only fall back when the sender is not the admin.\r
*/\r
function _willFallback() internal override {\r
require(\r
msg.sender != _admin(),\r
"Cannot call fallback function from the proxy admin"\r
);\r
super._willFallback();\r
}\r
}"},"FiatTokenProxy.sol":{"content":"/**\r
* SPDX-License-Identifier: MIT\r
*\r
* Copyright (c) 2018-2020 CENTRE SECZ\r
*\r
* Permission is hereby granted, free of charge, to any person obtaining a copy\r
* of this software and associated documentation files (the "Software"), to deal\r
* in the Software without restriction, including without limitation the rights\r
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
* copies of the Software, and to permit persons to whom the Software is\r
* furnished to do so, subject to the following conditions:\r
*\r
* The above copyright notice and this permission notice shall be included in\r
* copies or substantial portions of the Software.\r
*\r
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
* SOFTWARE.\r
*/\r
\r
pragma solidity ^0.8.20;\r
\r
import {\r
AdminUpgradeabilityProxy\r
} from "./AdminUpgradeabilityProxy.sol";\r
\r
/**\r
* @title FiatTokenProxy\r
* @dev This contract proxies FiatToken calls and enables FiatToken upgrades\r
*/\r
contract FiatTokenProxy is AdminUpgradeabilityProxy {\r
constructor(address implementationContract)\r
public\r
AdminUpgradeabilityProxy(implementationContract)\r
{}\r
}"},"Proxy.sol":{"content":"/**\r
* SPDX-License-Identifier: MIT\r
*\r
* Copyright (c) 2018 zOS Global Limited.\r
*\r
* Permission is hereby granted, free of charge, to any person obtaining a copy\r
* of this software and associated documentation files (the "Software"), to deal\r
* in the Software without restriction, including without limitation the rights\r
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
* copies of the Software, and to permit persons to whom the Software is\r
* furnished to do so, subject to the following conditions:\r
*\r
* The above copyright notice and this permission notice shall be included in\r
* copies or substantial portions of the Software.\r
*\r
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
* SOFTWARE.\r
*/\r
\r
pragma solidity ^0.8.20;\r
\r
/**\r
* @notice Implements delegation of calls to other contracts, with proper\r
* forwarding of return values and bubbling of failures.\r
* It defines a fallback function that delegates all calls to the address\r
* returned by the abstract _implementation() internal function.\r
* @dev Forked from https://github.com/zeppelinos/zos-lib/blob/8a16ef3ad17ec7430e3a9d2b5e3f39b8204f8c8d/contracts/upgradeability/Proxy.sol\r
* Modifications:\r
* 1. Reformat and conform to Solidity 0.6 syntax (5/13/20)\r
*/\r
abstract contract Proxy {\r
/**\r
* @dev Fallback function.\r
* Implemented entirely in `_fallback`.\r
*/\r
fallback() external payable {\r
_fallback();\r
}\r
\r
/**\r
* @return The Address of the implementation.\r
*/\r
function _implementation() internal virtual view returns (address);\r
\r
/**\r
* @dev Delegates execution to an implementation contract.\r
* This is a low level function that doesn\u0027t return to its internal call site.\r
* It will return to the external caller whatever the implementation returns.\r
* @param implementation Address to delegate.\r
*/\r
function _delegate(address implementation) internal {\r
assembly {\r
// Copy msg.data. We take full control of memory in this inline assembly\r
// block because it will not return to Solidity code. We overwrite the\r
// Solidity scratch pad at memory position 0.\r
calldatacopy(0, 0, calldatasize())\r
\r
// Call the implementation.\r
// out and outsize are 0 because we don\u0027t know the size yet.\r
let result := delegatecall(\r
gas(),\r
implementation,\r
0,\r
calldatasize(),\r
0,\r
0\r
)\r
\r
// Copy the returned data.\r
returndatacopy(0, 0, returndatasize())\r
\r
switch result\r
// delegatecall returns 0 on error.\r
case 0 {\r
revert(0, returndatasize())\r
}\r
default {\r
return(0, returndatasize())\r
}\r
}\r
}\r
\r
/**\r
* @dev Function that is run as the first thing in the fallback function.\r
* Can be redefined in derived contracts to add functionality.\r
* Redefinitions must call super._willFallback().\r
*/\r
function _willFallback() internal virtual {}\r
\r
/**\r
* @dev fallback implementation.\r
* Extracted to enable manual triggering.\r
*/\r
function _fallback() internal {\r
_willFallback();\r
_delegate(_implementation());\r
}\r
}"},"UpgradeabilityProxy.sol":{"content":"/**\r
* SPDX-License-Identifier: MIT\r
*\r
* Copyright (c) 2018 zOS Global Limited.\r
*\r
* Permission is hereby granted, free of charge, to any person obtaining a copy\r
* of this software and associated documentation files (the "Software"), to deal\r
* in the Software without restriction, including without limitation the rights\r
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
* copies of the Software, and to permit persons to whom the Software is\r
* furnished to do so, subject to the following conditions:\r
*\r
* The above copyright notice and this permission notice shall be included in\r
* copies or substantial portions of the Software.\r
*\r
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
* SOFTWARE.\r
*/\r
\r
pragma solidity ^0.8.20;\r
\r
import { Proxy } from "./Proxy.sol";\r
import { Address } from "./Address.sol";\r
\r
/**\r
* @notice This contract implements a proxy that allows to change the\r
* implementation address to which it will delegate.\r
* Such a change is called an implementation upgrade.\r
* @dev Forked from https://github.com/zeppelinos/zos-lib/blob/8a16ef3ad17ec7430e3a9d2b5e3f39b8204f8c8d/contracts/upgradeability/UpgradeabilityProxy.sol\r
* Modifications:\r
* 1. Reformat, conform to Solidity 0.6 syntax, and add error messages (5/13/20)\r
* 2. Use Address utility library from the latest OpenZeppelin (5/13/20)\r
*/\r
contract UpgradeabilityProxy is Proxy {\r
/**\r
* @dev Emitted when the implementation is upgraded.\r
* @param implementation Address of the new implementation.\r
*/\r
event Upgraded(address implementation);\r
\r
/**\r
* @dev Storage slot with the address of the current implementation.\r
* This is the keccak-256 hash of "org.zeppelinos.proxy.implementation", and is\r
* validated in the constructor.\r
*/\r
bytes32\r
private constant IMPLEMENTATION_SLOT = 0x7050c9e0f4ca769c69bd3a8ef740bc37934f8e2c036e5a723fd8ee048ed3f8c3;\r
\r
/**\r
* @dev Contract constructor.\r
* @param implementationContract Address of the initial implementation.\r
*/\r
constructor(address implementationContract) public {\r
assert(\r
IMPLEMENTATION_SLOT ==\r
keccak256("org.zeppelinos.proxy.implementation")\r
);\r
\r
_setImplementation(implementationContract);\r
}\r
\r
/**\r
* @dev Returns the current implementation.\r
* @return impl Address of the current implementation\r
*/\r
function _implementation() internal override view returns (address impl) {\r
bytes32 slot = IMPLEMENTATION_SLOT;\r
assembly {\r
impl := sload(slot)\r
}\r
}\r
\r
/**\r
* @dev Upgrades the proxy to a new implementation.\r
* @param newImplementation Address of the new implementation.\r
*/\r
function _upgradeTo(address newImplementation) internal {\r
_setImplementation(newImplementation);\r
emit Upgraded(newImplementation);\r
}\r
\r
/**\r
* @dev Sets the implementation address of the proxy.\r
* @param newImplementation Address of the new implementation.\r
*/\r
function _setImplementation(address newImplementation) private {\r
require(\r
Address.isContract(newImplementation),\r
"Cannot set a proxy implementation to a non-contract address"\r
);\r
\r
bytes32 slot = IMPLEMENTATION_SLOT;\r
\r
assembly {\r
sstore(slot, newImplementation)\r
}\r
}\r
}"}}
Submitted on: 2025-10-28 12:28:24
Comments
Log in to comment.
No comments yet.