编译器
0.8.23+commit.f704f362
文件 1 的 2:Ownable.sol
pragma solidity ^0.8.23;
contract Ownable {
bytes32 internal constant OWNER_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;
event AdminChanged(address previousAdmin, address newAdmin);
constructor() {
assert(OWNER_SLOT == bytes32(uint256(keccak256("eip1967.proxy.admin")) - 1));
_setOwner(msg.sender);
}
function owner() external view returns (address) {
return _owner();
}
function setOwner(address newOwner) external onlyOwner {
_setOwner(newOwner);
}
function _owner() internal view returns (address ownerOut) {
bytes32 position = OWNER_SLOT;
assembly {
ownerOut := sload(position)
}
}
function _setOwner(address newOwner) internal {
emit AdminChanged(_owner(), newOwner);
bytes32 position = OWNER_SLOT;
assembly {
sstore(position, newOwner)
}
}
function _onlyOwner() internal view {
require(msg.sender == _owner(), "ARM: Only owner can call this function.");
}
modifier onlyOwner() {
_onlyOwner();
_;
}
}
文件 2 的 2:Proxy.sol
pragma solidity ^0.8.23;
import {Ownable} from "./Ownable.sol";
contract Proxy is Ownable {
bytes32 internal constant IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
event Upgraded(address indexed implementation);
function initialize(address _logic, address _initOwner, bytes calldata _data) public onlyOwner {
require(_implementation() == address(0));
assert(IMPLEMENTATION_SLOT == bytes32(uint256(keccak256("eip1967.proxy.implementation")) - 1));
_upgradeTo(_logic);
if (_data.length > 0) {
(bool success,) = _logic.delegatecall(_data);
require(success);
}
_setOwner(_initOwner);
}
function admin() external view returns (address) {
return _owner();
}
function implementation() external view returns (address) {
return _implementation();
}
function upgradeTo(address newImplementation) external onlyOwner {
_upgradeTo(newImplementation);
}
function upgradeToAndCall(address newImplementation, bytes calldata data) external onlyOwner {
_upgradeTo(newImplementation);
(bool success,) = newImplementation.delegatecall(data);
require(success);
}
fallback() external {
_delegate(_implementation());
}
function _delegate(address _impl) internal {
assembly {
calldatacopy(0, 0, calldatasize())
let result := delegatecall(gas(), _impl, 0, calldatasize(), 0, 0)
returndatacopy(0, 0, returndatasize())
switch result
case 0 { revert(0, returndatasize()) }
default { return(0, returndatasize()) }
}
}
function _implementation() internal view returns (address impl) {
bytes32 slot = IMPLEMENTATION_SLOT;
assembly {
impl := sload(slot)
}
}
function _upgradeTo(address newImplementation) internal {
require(newImplementation.code.length > 0, "Cannot set a proxy implementation to a non-contract address");
bytes32 slot = IMPLEMENTATION_SLOT;
assembly {
sstore(slot, newImplementation)
}
emit Upgraded(newImplementation);
}
}
{
"compilationTarget": {
"src/contracts/Proxy.sol": "Proxy"
},
"evmVersion": "paris",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": [
":contracts/=src/contracts/",
":forge-std/=lib/forge-std/src/",
":script/=script/",
":test/=test/",
":utils/=src/contracts/utils/"
]
}
[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"previousAdmin","type":"address"},{"indexed":false,"internalType":"address","name":"newAdmin","type":"address"}],"name":"AdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"implementation","type":"address"}],"name":"Upgraded","type":"event"},{"stateMutability":"nonpayable","type":"fallback"},{"inputs":[],"name":"admin","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"implementation","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_logic","type":"address"},{"internalType":"address","name":"_initOwner","type":"address"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"setOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newImplementation","type":"address"}],"name":"upgradeTo","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newImplementation","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"upgradeToAndCall","outputs":[],"stateMutability":"nonpayable","type":"function"}]