编译器
0.6.12+commit.27d51765
文件 1 的 9:Addresses.sol
pragma solidity ^0.6.12;
import "Identity.sol";
library Addresses {
function isContract(address account) internal view returns (bool) {
uint256 size;
assembly {
size := extcodesize(account)
}
return size > 0;
}
function performEthTransfer(address recipient, uint256 amount) internal {
(bool success, ) = recipient.call{value: amount}("");
require(success, "ETH_TRANSFER_FAILED");
}
function safeTokenContractCall(address tokenAddress, bytes memory callData) internal {
require(isContract(tokenAddress), "BAD_TOKEN_ADDRESS");
(bool success, bytes memory returndata) = tokenAddress.call(callData);
require(success, string(returndata));
if (returndata.length > 0) {
require(abi.decode(returndata, (bool)), "TOKEN_OPERATION_FAILED");
}
}
function validateContractId(address contractAddress, bytes32 expectedIdHash) internal view {
require(isContract(contractAddress), "ADDRESS_NOT_CONTRACT");
string memory actualContractId = Identity(contractAddress).identify();
require(
keccak256(abi.encodePacked(actualContractId)) == expectedIdHash,
"UNEXPECTED_CONTRACT_IDENTIFIER"
);
}
}
文件 2 的 9:Governance.sol
pragma solidity ^0.6.12;
import "MGovernance.sol";
struct GovernanceInfoStruct {
mapping(address => bool) effectiveGovernors;
address candidateGovernor;
bool initialized;
}
abstract contract Governance is MGovernance {
event LogNominatedGovernor(address nominatedGovernor);
event LogNewGovernorAccepted(address acceptedGovernor);
event LogRemovedGovernor(address removedGovernor);
event LogNominationCancelled();
function getGovernanceInfo() internal view virtual returns (GovernanceInfoStruct storage);
function initGovernance() internal {
GovernanceInfoStruct storage gub = getGovernanceInfo();
require(!gub.initialized, "ALREADY_INITIALIZED");
gub.initialized = true;
addGovernor(msg.sender);
emit LogNominatedGovernor(msg.sender);
emit LogNewGovernorAccepted(msg.sender);
}
function _isGovernor(address user) internal view override returns (bool) {
GovernanceInfoStruct storage gub = getGovernanceInfo();
return gub.effectiveGovernors[user];
}
function _cancelNomination() internal onlyGovernance {
GovernanceInfoStruct storage gub = getGovernanceInfo();
if (gub.candidateGovernor != address(0x0)) {
gub.candidateGovernor = address(0x0);
emit LogNominationCancelled();
}
}
function _nominateNewGovernor(address newGovernor) internal onlyGovernance {
GovernanceInfoStruct storage gub = getGovernanceInfo();
require(newGovernor != address(0x0), "BAD_ADDRESS");
require(!_isGovernor(newGovernor), "ALREADY_GOVERNOR");
require(gub.candidateGovernor == address(0x0), "OTHER_CANDIDATE_PENDING");
gub.candidateGovernor = newGovernor;
emit LogNominatedGovernor(newGovernor);
}
function addGovernor(address newGovernor) private {
require(!_isGovernor(newGovernor), "ALREADY_GOVERNOR");
GovernanceInfoStruct storage gub = getGovernanceInfo();
gub.effectiveGovernors[newGovernor] = true;
}
function _acceptGovernance() internal {
GovernanceInfoStruct storage gub = getGovernanceInfo();
require(msg.sender == gub.candidateGovernor, "ONLY_CANDIDATE_GOVERNOR");
addGovernor(gub.candidateGovernor);
gub.candidateGovernor = address(0x0);
emit LogNewGovernorAccepted(msg.sender);
}
function _removeGovernor(address governorForRemoval) internal onlyGovernance {
require(msg.sender != governorForRemoval, "GOVERNOR_SELF_REMOVE");
GovernanceInfoStruct storage gub = getGovernanceInfo();
require(_isGovernor(governorForRemoval), "NOT_GOVERNOR");
gub.effectiveGovernors[governorForRemoval] = false;
emit LogRemovedGovernor(governorForRemoval);
}
}
文件 3 的 9:GovernanceStorage.sol
pragma solidity ^0.6.12;
import {GovernanceInfoStruct} from "Governance.sol";
contract GovernanceStorage {
mapping(string => GovernanceInfoStruct) internal governanceInfo;
}
文件 4 的 9:Identity.sol
pragma solidity ^0.6.12;
interface Identity {
function identify() external pure returns (string memory);
}
文件 5 的 9:MGovernance.sol
pragma solidity ^0.6.12;
abstract contract MGovernance {
function _isGovernor(address user) internal view virtual returns (bool);
modifier onlyGovernance() {
require(_isGovernor(msg.sender), "ONLY_GOVERNANCE");
_;
}
}
文件 6 的 9:Proxy.sol
pragma solidity ^0.6.12;
import "ProxyGovernance.sol";
import "ProxyStorage.sol";
import "StorageSlots.sol";
import "Addresses.sol";
contract Proxy is ProxyStorage, ProxyGovernance, StorageSlots {
event ImplementationUpgraded(address indexed implementation, bytes initializer);
event ImplementationAdded(address indexed implementation, bytes initializer, bool finalize);
event ImplementationRemoved(address indexed implementation, bytes initializer, bool finalize);
event FinalizedImplementation(address indexed implementation);
using Addresses for address;
string public constant PROXY_VERSION = "3.0.1";
constructor(uint256 upgradeActivationDelay) public {
initGovernance();
setUpgradeActivationDelay(upgradeActivationDelay);
}
function setUpgradeActivationDelay(uint256 delayInSeconds) private {
bytes32 slot = UPGRADE_DELAY_SLOT;
assembly {
sstore(slot, delayInSeconds)
}
}
function getUpgradeActivationDelay() public view returns (uint256 delay) {
bytes32 slot = UPGRADE_DELAY_SLOT;
assembly {
delay := sload(slot)
}
return delay;
}
function implementation() public view returns (address _implementation) {
bytes32 slot = IMPLEMENTATION_SLOT;
assembly {
_implementation := sload(slot)
}
}
function implementationIsFrozen() private returns (bool) {
address _implementation = implementation();
if (_implementation == address(0x0)) {
return false;
}
(bool success, bytes memory returndata) = _implementation.delegatecall(
abi.encodeWithSignature("isFrozen()")
);
require(success, string(returndata));
return abi.decode(returndata, (bool));
}
function initialize(
bytes calldata
) external pure {
revert("CANNOT_CALL_INITIALIZE");
}
modifier notFinalized() {
require(isNotFinalized(), "IMPLEMENTATION_FINALIZED");
_;
}
modifier notFrozen() {
require(!implementationIsFrozen(), "STATE_IS_FROZEN");
_;
}
receive() external payable {
revert("CONTRACT_NOT_EXPECTED_TO_RECEIVE");
}
fallback() external payable {
address _implementation = implementation();
require(_implementation != address(0x0), "MISSING_IMPLEMENTATION");
assembly {
calldatacopy(0, 0, calldatasize())
let result := delegatecall(gas(), _implementation, 0, calldatasize(), 0, 0)
returndatacopy(0, 0, returndatasize())
switch result
case 0 {
revert(0, returndatasize())
}
default {
return(0, returndatasize())
}
}
}
function setImplementation(address newImplementation) private {
bytes32 slot = IMPLEMENTATION_SLOT;
assembly {
sstore(slot, newImplementation)
}
}
function isNotFinalized() public view returns (bool notFinal) {
bytes32 slot = FINALIZED_STATE_SLOT;
uint256 slotValue;
assembly {
slotValue := sload(slot)
}
notFinal = (slotValue == 0);
}
function setFinalizedFlag() private {
bytes32 slot = FINALIZED_STATE_SLOT;
assembly {
sstore(slot, 0x1)
}
}
function addImplementation(
address newImplementation,
bytes calldata data,
bool finalize
) external onlyGovernance {
require(newImplementation.isContract(), "ADDRESS_NOT_CONTRACT");
bytes32 implVectorHash = keccak256(abi.encode(newImplementation, data, finalize));
uint256 activationTime = block.timestamp + getUpgradeActivationDelay();
enabledTime[implVectorHash] = activationTime;
emit ImplementationAdded(newImplementation, data, finalize);
}
function removeImplementation(
address removedImplementation,
bytes calldata data,
bool finalize
) external onlyGovernance {
bytes32 implVectorHash = keccak256(abi.encode(removedImplementation, data, finalize));
uint256 activationTime = enabledTime[implVectorHash];
require(activationTime > 0, "UNKNOWN_UPGRADE_INFORMATION");
delete enabledTime[implVectorHash];
emit ImplementationRemoved(removedImplementation, data, finalize);
}
function upgradeTo(
address newImplementation,
bytes calldata data,
bool finalize
) external payable onlyGovernance notFinalized notFrozen {
bytes32 implVectorHash = keccak256(abi.encode(newImplementation, data, finalize));
uint256 activationTime = enabledTime[implVectorHash];
require(activationTime > 0, "UNKNOWN_UPGRADE_INFORMATION");
require(newImplementation.isContract(), "ADDRESS_NOT_CONTRACT");
require(
activationTime <= block.timestamp || implementation() == address(0x0),
"UPGRADE_NOT_ENABLED_YET"
);
setImplementation(newImplementation);
(bool success, bytes memory returndata) = newImplementation.delegatecall(
abi.encodeWithSelector(this.initialize.selector, data)
);
require(success, string(returndata));
(success, returndata) = newImplementation.delegatecall(
abi.encodeWithSignature("isFrozen()")
);
require(success, "CALL_TO_ISFROZEN_REVERTED");
require(!abi.decode(returndata, (bool)), "NEW_IMPLEMENTATION_FROZEN");
if (finalize) {
setFinalizedFlag();
emit FinalizedImplementation(newImplementation);
}
emit ImplementationUpgraded(newImplementation, data);
}
}
文件 7 的 9:ProxyGovernance.sol
pragma solidity ^0.6.12;
import "Governance.sol";
import "GovernanceStorage.sol";
contract ProxyGovernance is GovernanceStorage, Governance {
string public constant PROXY_GOVERNANCE_TAG = "StarkEx.Proxy.2019.GovernorsInformation";
function getGovernanceInfo() internal view override returns (GovernanceInfoStruct storage) {
return governanceInfo[PROXY_GOVERNANCE_TAG];
}
function proxyIsGovernor(address user) external view returns (bool) {
return _isGovernor(user);
}
function proxyNominateNewGovernor(address newGovernor) external {
_nominateNewGovernor(newGovernor);
}
function proxyRemoveGovernor(address governorForRemoval) external {
_removeGovernor(governorForRemoval);
}
function proxyAcceptGovernance() external {
_acceptGovernance();
}
function proxyCancelNomination() external {
_cancelNomination();
}
}
文件 8 的 9:ProxyStorage.sol
pragma solidity ^0.6.12;
import "GovernanceStorage.sol";
contract ProxyStorage is GovernanceStorage {
mapping(address => bytes32) internal initializationHash_DEPRECATED;
mapping(bytes32 => uint256) internal enabledTime;
mapping(bytes32 => bool) internal initialized;
}
文件 9 的 9:StorageSlots.sol
pragma solidity ^0.6.12;
contract StorageSlots {
bytes32 internal constant IMPLEMENTATION_SLOT =
0x177667240aeeea7e35eabe3a35e18306f336219e1386f7710a6bf8783f761b24;
bytes32 internal constant CALL_PROXY_IMPL_SLOT =
0x7184681641399eb4ad2fdb92114857ee6ff239f94ad635a1779978947b8843be;
bytes32 internal constant FINALIZED_STATE_SLOT =
0x7d433c6f837e8f93009937c466c82efbb5ba621fae36886d0cac433c5d0aa7d2;
bytes32 public constant UPGRADE_DELAY_SLOT =
0xc21dbb3089fcb2c4f4c6a67854ab4db2b0f233ea4b21b21f912d52d18fc5db1f;
}
{
"compilationTarget": {
"Proxy.sol": "Proxy"
},
"evmVersion": "istanbul",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": []
}
[{"inputs":[{"internalType":"uint256","name":"upgradeActivationDelay","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"implementation","type":"address"}],"name":"FinalizedImplementation","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"implementation","type":"address"},{"indexed":false,"internalType":"bytes","name":"initializer","type":"bytes"},{"indexed":false,"internalType":"bool","name":"finalize","type":"bool"}],"name":"ImplementationAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"implementation","type":"address"},{"indexed":false,"internalType":"bytes","name":"initializer","type":"bytes"},{"indexed":false,"internalType":"bool","name":"finalize","type":"bool"}],"name":"ImplementationRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"implementation","type":"address"},{"indexed":false,"internalType":"bytes","name":"initializer","type":"bytes"}],"name":"ImplementationUpgraded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"acceptedGovernor","type":"address"}],"name":"LogNewGovernorAccepted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"nominatedGovernor","type":"address"}],"name":"LogNominatedGovernor","type":"event"},{"anonymous":false,"inputs":[],"name":"LogNominationCancelled","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"removedGovernor","type":"address"}],"name":"LogRemovedGovernor","type":"event"},{"stateMutability":"payable","type":"fallback"},{"inputs":[],"name":"PROXY_GOVERNANCE_TAG","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PROXY_VERSION","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"UPGRADE_DELAY_SLOT","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newImplementation","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"},{"internalType":"bool","name":"finalize","type":"bool"}],"name":"addImplementation","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getUpgradeActivationDelay","outputs":[{"internalType":"uint256","name":"delay","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"implementation","outputs":[{"internalType":"address","name":"_implementation","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"","type":"bytes"}],"name":"initialize","outputs":[],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"isNotFinalized","outputs":[{"internalType":"bool","name":"notFinal","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"proxyAcceptGovernance","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"proxyCancelNomination","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"proxyIsGovernor","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newGovernor","type":"address"}],"name":"proxyNominateNewGovernor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"governorForRemoval","type":"address"}],"name":"proxyRemoveGovernor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"removedImplementation","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"},{"internalType":"bool","name":"finalize","type":"bool"}],"name":"removeImplementation","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newImplementation","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"},{"internalType":"bool","name":"finalize","type":"bool"}],"name":"upgradeTo","outputs":[],"stateMutability":"payable","type":"function"},{"stateMutability":"payable","type":"receive"}]