文件 1 的 1:TransparentUpgradeableProxy.sol
pragma solidity ^0.8.9;
abstract contract Proxy {
fallback() external payable {
_fallback();
}
receive() external payable {
_fallback();
}
function _implementation() internal view virtual returns (address);
function _delegate(address implementation) internal {
assembly {
calldatacopy(0, 0, calldatasize())
let result := delegatecall(
gas(),
implementation,
0,
calldatasize(),
0,
0
)
let retSz := returndatasize()
returndatacopy(0, 0, retSz)
switch result
case 0 {
revert(0, retSz)
}
default {
return(0, retSz)
}
}
}
function _beforeFallback() internal virtual {}
function _fallback() internal {
_beforeFallback();
_delegate(_implementation());
}
}
library ZOSLibAddress {
function isContract(address account) internal view returns (bool) {
uint256 size;
assembly {
size := extcodesize(account)
}
return size > 0;
}
}
contract BaseUpgradeabilityProxy is Proxy {
event Upgraded(address indexed implementation);
bytes32 internal constant IMPLEMENTATION_SLOT =
0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
function _implementation() internal view override returns (address impl) {
bytes32 slot = IMPLEMENTATION_SLOT;
assembly {
impl := sload(slot)
}
}
function _upgradeTo(address newImplementation) internal {
_setImplementation(newImplementation);
emit Upgraded(newImplementation);
}
function _setImplementation(address newImplementation) internal {
require(
ZOSLibAddress.isContract(newImplementation),
"Cannot set a proxy implementation to a non-contract address"
);
bytes32 slot = IMPLEMENTATION_SLOT;
assembly {
sstore(slot, newImplementation)
}
}
}
contract TransparentUpgradeableProxy is BaseUpgradeabilityProxy {
bytes32 internal constant ADMIN_SLOT =
0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;
constructor(
address logic,
address newAdmin,
bytes memory data
) payable {
assert(
IMPLEMENTATION_SLOT ==
bytes32(uint256(keccak256("eip1967.proxy.implementation")) - 1)
);
assert(
ADMIN_SLOT == bytes32(uint256(keccak256("eip1967.proxy.admin")) - 1)
);
_setAdmin(newAdmin);
_setImplementation(logic);
if (data.length > 0) {
(bool success, ) = logic.delegatecall(data);
require(success);
}
}
event AdminChanged(address previousAdmin, address newAdmin);
modifier ifAdmin() {
if (msg.sender == _admin()) {
_;
} else {
_fallback();
}
}
function admin() external ifAdmin returns (address) {
return _admin();
}
function implementation() external ifAdmin returns (address) {
return _implementation();
}
function changeAdmin(address newAdmin) external ifAdmin {
require(
newAdmin != address(0),
"Cannot change the admin of a proxy to the zero address"
);
emit AdminChanged(_admin(), newAdmin);
_setAdmin(newAdmin);
}
function upgradeTo(address newImplementation) external ifAdmin {
_upgradeTo(newImplementation);
}
function upgradeToAndCall(address newImplementation, bytes calldata data)
external
payable
ifAdmin
{
_upgradeTo(newImplementation);
(bool success, ) = newImplementation.delegatecall(data);
require(success);
}
function _admin() internal view returns (address adm) {
bytes32 slot = ADMIN_SLOT;
assembly {
adm := sload(slot)
}
}
function _setAdmin(address newAdmin) internal {
bytes32 slot = ADMIN_SLOT;
assembly {
sstore(slot, newAdmin)
}
}
function _beforeFallback() internal override {
require(
msg.sender != _admin(),
"Cannot call fallback function from the proxy admin"
);
super._beforeFallback();
}
}
{
"compilationTarget": {
"TransparentUpgradeableProxy.sol": "TransparentUpgradeableProxy"
},
"evmVersion": "cancun",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": []
}