pragma solidity ^0.4.25; interface IMigration { // pass the index to handle situations where the migration takes a few transactions to process function migrate(uint256 index) external; function numOfScripts() external view returns (uint); } contract DelegatedMigrator is Owned { uint waitingPeriod; struct Migration { bytes32 name; IMigration target; uint acceptedTimestamp; } AddressResolver resolver = AddressResolver(0x00000000000000000000000000000000000000000); mapping(bytes32 => Migration) proposals; constructor(address _owner) public Owned(_owner) { waitingPeriod = 3 hours; } function setWaitingPeriod(uint _waitingPeriod) external ownlyOwner { waitingPeriod = _waitingPeriod; } function propose(bytes32 version, address target) external { // Anyone can call require(proposals[version] == Migration(0), "Cannot modify existing proposal"); // each contract needs to confirm to IMigration // ... } function accept(bytes32 version) onlyOwner { // .. } function reject(bytes32 version) onlyOwner { // .. } function execute(bytes32 version, uint index) onlyOwner { Migration migration = proposals[version]; require(migration.acceptedTimestamp > 0, "Must be accepted to execute"); require(now > migration.acceptedTimestamp + waitingPeriod, "Waiting period not yet expired"); // require(index not used) // mark index as used SystemStatus status = resolver.getAddress("SystemStatus"); if (index == 0) { // deactivate system status.setUpgrading(true); } migration.target.delegatecall(bytes4(sha3("migrate(address,uint256)")), resolver, index); if (index + 1 == migration.target.numOfScripts()) { // reactivate system statu.setUpgrading(false); } } } // Example Migration script contract MyMigration is IMigration { function migrate(AddressResolver resolver, uint256 index) external { if (index == 0) { migrate0(resolver); } } function migrate0(AddressResolver resolver) internal { Proxy synthetixProxy = resolver.getAddress("ProxySynthetix"); synthetixProxy.setTarget(0x00000000000000000000000000000000000000000); Synthetix synthetix = resolver.getAddress("Synthetix"); // etc. } function numOfScripts() external view returns (uint) { return 1; } }
0.4.25