diff --git a/solidity/optics-core/contracts/governance/GovernanceRouter.sol b/solidity/optics-core/contracts/governance/GovernanceRouter.sol index c5c0dafeb..64dbe4894 100644 --- a/solidity/optics-core/contracts/governance/GovernanceRouter.sol +++ b/solidity/optics-core/contracts/governance/GovernanceRouter.sol @@ -3,6 +3,7 @@ pragma solidity >=0.6.11; pragma experimental ABIEncoderV2; import {Initializable} from "@openzeppelin/contracts/proxy/Initializable.sol"; +import {SafeMath} from "@openzeppelin/contracts/math/SafeMath.sol"; import {TypedMemView} from "@summa-tx/memview-sol/contracts/TypedMemView.sol"; import {Home} from "../Home.sol"; @@ -11,41 +12,62 @@ import {IMessageRecipient} from "../../interfaces/IMessageRecipient.sol"; import {GovernanceMessage} from "./GovernanceMessage.sol"; contract GovernanceRouter is Initializable, IMessageRecipient { + using SafeMath for uint256; using TypedMemView for bytes; using TypedMemView for bytes29; using GovernanceMessage for bytes29; - XAppConnectionManager public xAppConnectionManager; - uint32 public immutable localDomain; - uint32 public governorDomain; // domain of Governor chain -- for accepting incoming messages from Governor + uint256 public immutable recoveryTimelock; // number of seconds before recovery can be activated + + uint256 public recoveryActiveAt; // timestamp when recovery timelock expires; 0 if timelock has not been initiated + address public recoveryManager; // the address of the recovery manager multisig + address public governor; // the local entity empowered to call governance functions, set to 0x0 on non-Governor chains + uint32 public governorDomain; // domain of Governor chain -- for accepting incoming messages from Governor + + XAppConnectionManager public xAppConnectionManager; mapping(uint32 => bytes32) public routers; // registry of domain -> remote GovernanceRouter contract address uint32[] public domains; // array of all domains registered + event SetRouter( + uint32 indexed domain, + bytes32 previousRouter, + bytes32 newRouter + ); + event TransferGovernor( uint32 previousGovernorDomain, uint32 newGovernorDomain, address indexed previousGovernor, address indexed newGovernor ); - event SetRouter( - uint32 indexed domain, - bytes32 previousRouter, - bytes32 newRouter + + event TransferRecoveryManager( + address indexed previousRecoveryManager, + address indexed newRecoveryManager ); - constructor(uint32 _localDomain) { + event InitiateRecovery(address indexed recoveryManager, uint256 endBlock); + event ExitRecovery(address recoveryManager); + + constructor(uint32 _localDomain, uint256 _recoveryTimelock) { localDomain = _localDomain; + recoveryTimelock = _recoveryTimelock; } - function initialize(address _xAppConnectionManager) public initializer { + function initialize( + address _xAppConnectionManager, + address _recoveryManager + ) public initializer { // initialize governor address _governorAddr = msg.sender; bool _isLocalGovernor = true; _transferGovernor(localDomain, _governorAddr, _isLocalGovernor); + recoveryManager = _recoveryManager; + // initialize XAppConnectionManager setXAppConnectionManager(_xAppConnectionManager); @@ -55,23 +77,50 @@ contract GovernanceRouter is Initializable, IMessageRecipient { ); } + modifier typeAssert(bytes29 _view, GovernanceMessage.Types _type) { + _view.assertType(uint40(_type)); + _; + } + modifier onlyReplica() { require(xAppConnectionManager.isReplica(msg.sender), "!replica"); _; } - modifier typeAssert(bytes29 _view, GovernanceMessage.Types _type) { - _view.assertType(uint40(_type)); + modifier onlyGovernorRouter(uint32 _domain, bytes32 _address) { + require(_isGovernorRouter(_domain, _address), "!governorRouter"); _; } modifier onlyGovernor() { - require(msg.sender == governor, "Caller is not the governor"); + require(msg.sender == governor, "! called by governor"); _; } - modifier onlyGovernorRouter(uint32 _domain, bytes32 _address) { - require(_isGovernorRouter(_domain, _address), "!governorRouter"); + modifier onlyRecoveryManager() { + require(msg.sender == recoveryManager, "! called by recovery manager"); + _; + } + + modifier onlyInRecovery() { + require(inRecovery(), "! in recovery"); + _; + } + + modifier onlyNotInRecovery() { + require(!inRecovery(), "in recovery"); + _; + } + + modifier onlyGovernorOrRecoveryManager() { + if (!inRecovery()) { + require(msg.sender == governor, "! called by governor"); + } else { + require( + msg.sender == recoveryManager, + "! called by recovery manager" + ); + } _; } @@ -111,7 +160,7 @@ contract GovernanceRouter is Initializable, IMessageRecipient { */ function callLocal(GovernanceMessage.Call[] calldata _calls) external - onlyGovernor + onlyGovernorOrRecoveryManager { for (uint256 i = 0; i < _calls.length; i++) { _dispatchCall(_calls[i]); @@ -126,7 +175,7 @@ contract GovernanceRouter is Initializable, IMessageRecipient { function callRemote( uint32 _destination, GovernanceMessage.Call[] calldata _calls - ) external onlyGovernor { + ) external onlyGovernor onlyNotInRecovery { bytes32 _router = _mustHaveRouter(_destination); bytes memory _msg = GovernanceMessage.formatCalls(_calls); @@ -141,6 +190,7 @@ contract GovernanceRouter is Initializable, IMessageRecipient { function transferGovernor(uint32 _newDomain, address _newGovernor) external onlyGovernor + onlyNotInRecovery { bool _isLocalGovernor = _isLocalDomain(_newDomain); @@ -161,13 +211,31 @@ contract GovernanceRouter is Initializable, IMessageRecipient { _sendToAllRemoteRouters(_transferGovernorMessage); } + /** + * @notice Transfer recovery manager role + * @dev callable by the recoveryManager at any time to transfer the role + * @param _newRecoveryManager The address of the new recovery manager + */ + function transferRecoveryManager(address _newRecoveryManager) + external + onlyRecoveryManager + { + emit TransferRecoveryManager(recoveryManager, _newRecoveryManager); + + recoveryManager = _newRecoveryManager; + } + /** * @notice Set the router address for a given domain and * dispatch the change to all remote routers * @param _domain The domain * @param _router The address of the new router */ - function setRouter(uint32 _domain, bytes32 _router) external onlyGovernor { + function setRouter(uint32 _domain, bytes32 _router) + external + onlyGovernor + onlyNotInRecovery + { _setRouter(_domain, _router); // set the router locally bytes memory _setRouterMessage = @@ -184,9 +252,9 @@ contract GovernanceRouter is Initializable, IMessageRecipient { * @param _domain The domain * @param _router The new router */ - function setRouterDuringSetup(uint32 _domain, bytes32 _router) + function setRouterLocal(uint32 _domain, bytes32 _router) external - onlyGovernor + onlyGovernorOrRecoveryManager { _setRouter(_domain, _router); // set the router locally } @@ -198,11 +266,46 @@ contract GovernanceRouter is Initializable, IMessageRecipient { */ function setXAppConnectionManager(address _xAppConnectionManager) public - onlyGovernor + onlyGovernorOrRecoveryManager { xAppConnectionManager = XAppConnectionManager(_xAppConnectionManager); } + /** + * @notice Initiate the recovery timelock + * @dev callable by the recovery manager + */ + function initiateRecoveryTimelock() + external + onlyNotInRecovery + onlyRecoveryManager + { + require(recoveryActiveAt == 0, "recovery already initiated"); + + recoveryActiveAt = block.timestamp.add(recoveryTimelock); + + emit InitiateRecovery(recoveryManager, recoveryActiveAt); + } + + /** + * @notice Exit recovery mode + * @dev callable by the recovery manager to end recovery mode + */ + function exitRecovery() external onlyRecoveryManager { + require(recoveryActiveAt != 0, "recovery not initiated"); + + delete recoveryActiveAt; + + emit ExitRecovery(recoveryManager); + } + + function inRecovery() public view returns (bool) { + uint256 _recoveryActiveAt = recoveryActiveAt; + bool _recoveryInitiated = _recoveryActiveAt != 0; + bool _recoveryActive = _recoveryActiveAt <= block.timestamp; + return _recoveryInitiated && _recoveryActive; + } + /** * @notice Handle message dispatching calls locally * @param _msg The message diff --git a/solidity/optics-core/contracts/test/TestGovernanceRouter.sol b/solidity/optics-core/contracts/test/TestGovernanceRouter.sol index 6da066cdc..4df74cb6f 100644 --- a/solidity/optics-core/contracts/test/TestGovernanceRouter.sol +++ b/solidity/optics-core/contracts/test/TestGovernanceRouter.sol @@ -10,7 +10,9 @@ contract TestGovernanceRouter is GovernanceRouter { using TypedMemView for bytes29; using GovernanceMessage for bytes29; - constructor(uint32 _localDomain) GovernanceRouter(_localDomain) {} // solhint-disable-line no-empty-blocks + constructor(uint32 _localDomain, uint256 _recoveryTimelock) + GovernanceRouter(_localDomain, 50) + {} // solhint-disable-line no-empty-blocks function testSetRouter(uint32 _domain, bytes32 _router) external { _setRouter(_domain, _router); // set the router locally diff --git a/solidity/optics-core/js/deployOpticsUtils.js b/solidity/optics-core/js/deployOpticsUtils.js index eaaac92f8..12a619fdd 100644 --- a/solidity/optics-core/js/deployOpticsUtils.js +++ b/solidity/optics-core/js/deployOpticsUtils.js @@ -11,8 +11,10 @@ */ async function devDeployGovernanceRouter( localDomain, + recoveryTimelock, controller, xAppConnectionManagerAddress, + recoveryManagerAddress, isTestDeploy, ) { const contractStr = isTestDeploy @@ -20,8 +22,8 @@ async function devDeployGovernanceRouter( : 'GovernanceRouter'; const { contracts } = await optics.deployUpgradeSetupAndProxy( contractStr, - [localDomain], - [xAppConnectionManagerAddress], + [localDomain, recoveryTimelock], + [xAppConnectionManagerAddress, recoveryManagerAddress], controller, ); @@ -167,7 +169,12 @@ async function devDeployReplicaProxy( * @return contracts - OpticsContracts type for the suite of Optics contract on this chain */ async function devDeployOptics(local, remotes, isTestDeploy) { - const { domain, updater: localUpdaterAddress } = local; + const { + domain, + recoveryTimelock, + recoveryManagerAddress, + updater: localUpdaterAddress, + } = local; // Deploy UpgradeBeaconController // Note: initial owner will be the signer that's deploying @@ -194,8 +201,10 @@ async function devDeployOptics(local, remotes, isTestDeploy) { // Note: initial governor will be the signer that's deploying const governanceRouter = await devDeployGovernanceRouter( domain, + recoveryTimelock, upgradeBeaconController, xAppConnectionManager.address, + recoveryManagerAddress, isTestDeploy, ); diff --git a/solidity/optics-core/js/types.js b/solidity/optics-core/js/types.js index b778ec17d..da7581f47 100644 --- a/solidity/optics-core/js/types.js +++ b/solidity/optics-core/js/types.js @@ -2,6 +2,8 @@ * ChainConfig { * domain: int, * updater: address, + * recoveryTimelock: int, + * recoveryManager: address, // NOTE: this may change if we add a multisig to the deploy setup * currentRoot: bytes32, * nextToProcessIndex: int, * optimisticSeconds: int, diff --git a/solidity/optics-core/test/cross-chain/GovernanceRouter.test.js b/solidity/optics-core/test/cross-chain/GovernanceRouter.test.js index 3cacfc549..0ad6a8c97 100644 --- a/solidity/optics-core/test/cross-chain/GovernanceRouter.test.js +++ b/solidity/optics-core/test/cross-chain/GovernanceRouter.test.js @@ -26,7 +26,9 @@ describe('GovernanceRouter', async () => { const governorDomain = 1000; const nonGovernorDomain = 2000; const thirdDomain = 3000; - const [thirdRouter] = provider.getWallets(); + const walletProvider = new testUtils.WalletProvider(provider); + const [thirdRouter, recoveryManager] = walletProvider.getWalletsPersistent(2); + let governorRouter, governorHome, governorReplicaOnNonGovernorChain, @@ -51,7 +53,10 @@ describe('GovernanceRouter', async () => { beforeEach(async () => { // generate TestChainConfigs for the given domains - const configs = await domainsToTestConfigs(domains); + const configs = await domainsToTestConfigs( + domains, + recoveryManager.address, + ); // deploy the entire Optics suite on each chain chainDetails = await deployMultipleChains(configs); diff --git a/solidity/optics-core/test/cross-chain/RecoveryManager.test.js b/solidity/optics-core/test/cross-chain/RecoveryManager.test.js new file mode 100644 index 000000000..b8c27a141 --- /dev/null +++ b/solidity/optics-core/test/cross-chain/RecoveryManager.test.js @@ -0,0 +1,467 @@ +const { provider } = waffle; +const { expect } = require('chai'); +const testUtils = require('../utils'); +const { domainsToTestConfigs } = require('./generateTestChainConfigs'); +const { formatCall, sendFromSigner } = require('./crossChainTestUtils'); +const { + deployMultipleChains, + getHome, + getGovernanceRouter, + getUpdaterManager, +} = require('./deployCrossChainTest'); + +async function expectNotInRecovery( + updaterManager, + recoveryManager, + randomSigner, + governor, + governanceRouter, + home, +) { + expect(await governanceRouter.inRecovery()).to.be.false; + + // Format optics call message + const call = await formatCall(updaterManager, 'setUpdater', [ + randomSigner.address, + ]); + + // Expect that Governor *CAN* Call Local & Call Remote + // dispatch call on local governorRouter + await expect( + sendFromSigner(governor, governanceRouter, 'callLocal', [[call]]), + ) + .to.emit(home, 'NewUpdater') + .withArgs(randomSigner.address); + + // dispatch call on local governorRouter + await expect( + sendFromSigner(governor, governanceRouter, 'callRemote', [2000, [call]]), + ).to.emit(home, 'Dispatch'); + + // set xApp Connection Manager + const xAppConnectionManager = await governanceRouter.xAppConnectionManager(); + await expect( + sendFromSigner(governor, governanceRouter, 'setXAppConnectionManager', [ + randomSigner.address, + ]), + ).to.not.be.reverted; + // reset xApp Connection Manager to actual contract + await sendFromSigner(governor, governanceRouter, 'setXAppConnectionManager', [ + xAppConnectionManager, + ]); + + // set Router Locally + const otherDomain = 2000; + const previousRouter = await governanceRouter.routers(otherDomain); + await expect( + sendFromSigner(governor, governanceRouter, 'setRouterLocal', [ + 2000, + optics.ethersAddressToBytes32(randomSigner.address), + ]), + ) + .to.emit(governanceRouter, 'SetRouter') + .withArgs( + otherDomain, + previousRouter, + optics.ethersAddressToBytes32(randomSigner.address), + ); + + // Expect that Recovery Manager CANNOT Call Local OR Call Remote + // cannot dispatch call on local governorRouter + await expect( + sendFromSigner(recoveryManager, governanceRouter, 'callLocal', [[call]]), + ).to.be.revertedWith('! called by governor'); + + // cannot dispatch call to remote governorRouter + await expect( + sendFromSigner(recoveryManager, governanceRouter, 'callRemote', [ + 2000, + [call], + ]), + ).to.be.revertedWith('! called by governor'); + + // cannot set xAppConnectionManager + await expect( + sendFromSigner( + recoveryManager, + governanceRouter, + 'setXAppConnectionManager', + [randomSigner.address], + ), + ).to.be.revertedWith('! called by governor'); + + // cannot set Router + await expect( + sendFromSigner(recoveryManager, governanceRouter, 'setRouterLocal', [ + 2000, + optics.ethersAddressToBytes32(randomSigner.address), + ]), + ).to.be.revertedWith('! called by governor'); +} + +async function expectOnlyRecoveryManagerCanTransferRole( + governor, + governanceRouter, + randomSigner, + recoveryManager, +) { + await expect( + sendFromSigner(governor, governanceRouter, 'transferRecoveryManager', [ + randomSigner.address, + ]), + ).to.be.revertedWith('! called by recovery manager'); + + await expect( + sendFromSigner(randomSigner, governanceRouter, 'transferRecoveryManager', [ + randomSigner.address, + ]), + ).to.be.revertedWith('! called by recovery manager'); + + await expect( + sendFromSigner( + recoveryManager, + governanceRouter, + 'transferRecoveryManager', + [randomSigner.address], + ), + ) + .to.emit(governanceRouter, 'TransferRecoveryManager') + .withArgs(recoveryManager.address, randomSigner.address); + + await expect( + sendFromSigner(randomSigner, governanceRouter, 'transferRecoveryManager', [ + recoveryManager.address, + ]), + ) + .to.emit(governanceRouter, 'TransferRecoveryManager') + .withArgs(randomSigner.address, recoveryManager.address); +} + +async function expectOnlyRecoveryManagerCanExitRecovery( + governor, + governanceRouter, + randomSigner, + recoveryManager, +) { + await expect( + sendFromSigner(governor, governanceRouter, 'exitRecovery', []), + ).to.be.revertedWith('! called by recovery manager'); + + await expect( + sendFromSigner(randomSigner, governanceRouter, 'exitRecovery', []), + ).to.be.revertedWith('! called by recovery manager'); + + await expect( + sendFromSigner(recoveryManager, governanceRouter, 'exitRecovery', []), + ) + .to.emit(governanceRouter, 'ExitRecovery') + .withArgs(recoveryManager.address); +} + +async function expectOnlyRecoveryManagerCanInitiateRecovery( + governor, + governanceRouter, + randomSigner, + recoveryManager, +) { + await expect( + sendFromSigner(governor, governanceRouter, 'initiateRecoveryTimelock', []), + ).to.be.revertedWith('! called by recovery manager'); + + await expect( + sendFromSigner( + randomSigner, + governanceRouter, + 'initiateRecoveryTimelock', + [], + ), + ).to.be.revertedWith('! called by recovery manager'); + + expect(await governanceRouter.recoveryActiveAt()).to.equal(0); + + await expect( + sendFromSigner( + recoveryManager, + governanceRouter, + 'initiateRecoveryTimelock', + [], + ), + ).to.emit(governanceRouter, 'InitiateRecovery'); + + expect(await governanceRouter.recoveryActiveAt()).to.not.equal(0); +} + +/* + * Deploy the full Optics suite on two chains + */ +describe('RecoveryManager', async () => { + const domains = [1000, 2000]; + const domain = 1000; + const walletProvider = new testUtils.WalletProvider(provider); + const [ + governor, + recoveryManager, + randomSigner, + ] = walletProvider.getWalletsPersistent(5); + + let governanceRouter, home, updaterManager, chainDetails; + + before(async () => { + // generate TestChainConfigs for the given domains + const configs = await domainsToTestConfigs( + domains, + recoveryManager.address, + ); + + // deploy the entire Optics suite on each chain + chainDetails = await deployMultipleChains(configs); + + // get the governance router + governanceRouter = getGovernanceRouter(chainDetails, domain); + // transfer governorship to the governor signer + await governanceRouter.transferGovernor(domain, governor.address); + + home = getHome(chainDetails, domain); + + updaterManager = getUpdaterManager(chainDetails, domain); + }); + + it('Before Recovery Initiated: Timelock has not been set', async () => { + expect(await governanceRouter.recoveryActiveAt()).to.equal(0); + }); + + it('Before Recovery Initiated: Cannot Exit Recovery yet', async () => { + await expect( + sendFromSigner(recoveryManager, governanceRouter, 'exitRecovery', []), + ).to.be.revertedWith('recovery not initiated'); + }); + + it('Before Recovery Initiated: Not in Recovery (Governor CAN Call Local & Remote; Recovery Manager CANNOT Call either)', async () => { + await expectNotInRecovery( + updaterManager, + recoveryManager, + randomSigner, + governor, + governanceRouter, + home, + ); + }); + + it('Before Recovery Initiated: ONLY RecoveryManager can transfer RecoveryManager role', async () => { + await expectOnlyRecoveryManagerCanTransferRole( + governor, + governanceRouter, + randomSigner, + recoveryManager, + ); + }); + + it('Before Recovery Initiated: ONLY RecoveryManager can Initiate Recovery', async () => { + await expectOnlyRecoveryManagerCanInitiateRecovery( + governor, + governanceRouter, + randomSigner, + recoveryManager, + ); + }); + + it('Before Recovery Active: CANNOT Initiate Recovery Twice', async () => { + await expect( + sendFromSigner( + recoveryManager, + governanceRouter, + 'initiateRecoveryTimelock', + [], + ), + ).to.be.revertedWith('recovery already initiated'); + }); + + it('Before Recovery Active: Not in Recovery (Governor CAN Call Local & Remote; Recovery Manager CANNOT Call either)', async () => { + await expectNotInRecovery( + updaterManager, + recoveryManager, + randomSigner, + governor, + governanceRouter, + home, + ); + }); + + it('Before Recovery Active: ONLY RecoveryManager can transfer RecoveryManager role', async () => { + await expectOnlyRecoveryManagerCanTransferRole( + governor, + governanceRouter, + randomSigner, + recoveryManager, + ); + }); + + it('Before Recovery Active: ONLY RecoveryManager can Exit Recovery', async () => { + await expectOnlyRecoveryManagerCanExitRecovery( + governor, + governanceRouter, + randomSigner, + recoveryManager, + ); + }); + + it('Before Recovery Active: ONLY RecoveryManager can Initiate Recovery (CAN initiate a second time)', async () => { + await expectOnlyRecoveryManagerCanInitiateRecovery( + governor, + governanceRouter, + randomSigner, + recoveryManager, + ); + }); + + it('Recovery Active: inRecovery becomes true when timelock expires', async () => { + // increase timestamp on-chain + const timelock = await governanceRouter.recoveryTimelock(); + await testUtils.increaseTimestampBy(provider, timelock.toNumber()); + expect(await governanceRouter.inRecovery()).to.be.true; + }); + + it('Recovery Active: RecoveryManager CAN call local', async () => { + // Format optics call message + const call = await formatCall(updaterManager, 'setUpdater', [ + randomSigner.address, + ]); + + // dispatch call on local governorRouter + await expect( + sendFromSigner(recoveryManager, governanceRouter, 'callLocal', [[call]]), + ) + .to.emit(home, 'NewUpdater') + .withArgs(randomSigner.address); + }); + + it('Recovery Active: RecoveryManager CANNOT call remote', async () => { + // Format optics call message + const call = await formatCall(updaterManager, 'setUpdater', [ + randomSigner.address, + ]); + + // dispatch call on local governorRouter + await expect( + sendFromSigner(recoveryManager, governanceRouter, 'callRemote', [ + 2000, + [call], + ]), + ).to.be.revertedWith('! called by governor'); + }); + + it('Recovery Active: RecoveryManager CAN set xAppConnectionManager', async () => { + // set xApp Connection Manager + const xAppConnectionManager = await governanceRouter.xAppConnectionManager(); + await expect( + sendFromSigner( + recoveryManager, + governanceRouter, + 'setXAppConnectionManager', + [randomSigner.address], + ), + ).to.not.be.reverted; + // reset xApp Connection Manager to actual contract + await sendFromSigner( + recoveryManager, + governanceRouter, + 'setXAppConnectionManager', + [xAppConnectionManager], + ); + }); + + it('Recovery Active: RecoveryManager CAN set Router locally', async () => { + const otherDomain = 2000; + const previousRouter = await governanceRouter.routers(otherDomain); + await expect( + sendFromSigner(recoveryManager, governanceRouter, 'setRouterLocal', [ + 2000, + optics.ethersAddressToBytes32(randomSigner.address), + ]), + ) + .to.emit(governanceRouter, 'SetRouter') + .withArgs( + otherDomain, + previousRouter, + optics.ethersAddressToBytes32(randomSigner.address), + ); + }); + + it('Recovery Active: Governor CANNOT call local OR remote', async () => { + // Format optics call message + const call = await formatCall(updaterManager, 'setUpdater', [ + randomSigner.address, + ]); + + // dispatch call on local governorRouter + await expect( + sendFromSigner(governor, governanceRouter, 'callLocal', [[call]]), + ).to.be.revertedWith('! called by recovery manager'); + + // dispatch call on local governorRouter + await expect( + sendFromSigner(governor, governanceRouter, 'callRemote', [2000, [call]]), + ).to.be.revertedWith('in recovery'); + }); + + it('Recovery Active: Governor CANNOT set xAppConnectionManager', async () => { + // cannot set xAppConnectionManager + await expect( + sendFromSigner(governor, governanceRouter, 'setXAppConnectionManager', [ + randomSigner.address, + ]), + ).to.be.revertedWith('! called by recovery manager'); + }); + + it('Recovery Active: Governor CANNOT set Router locally', async () => { + // cannot set Router + await expect( + sendFromSigner(governor, governanceRouter, 'setRouterLocal', [ + 2000, + optics.ethersAddressToBytes32(randomSigner.address), + ]), + ).to.be.revertedWith('! called by recovery manager'); + }); + + it('Recovery Active: ONLY RecoveryManager can transfer RecoveryManager role', async () => { + await expectOnlyRecoveryManagerCanTransferRole( + governor, + governanceRouter, + randomSigner, + recoveryManager, + ); + }); + + it('Recovery Active: ONLY RecoveryManager can Exit Recovery', async () => { + await expectOnlyRecoveryManagerCanExitRecovery( + governor, + governanceRouter, + randomSigner, + recoveryManager, + ); + }); + + it('Exited Recovery: Timelock is deleted', async () => { + expect(await governanceRouter.recoveryActiveAt()).to.equal(0); + }); + + it('Exited Recovery: Not in Recovery (Governor CAN Call Local & Remote; Recovery Manager CANNOT Call either)', async () => { + await expectNotInRecovery( + updaterManager, + recoveryManager, + randomSigner, + governor, + governanceRouter, + home, + ); + }); + + it('Exited Recovery: ONLY RecoveryManager can transfer RecoveryManager role', async () => { + await expectOnlyRecoveryManagerCanTransferRole( + governor, + governanceRouter, + randomSigner, + recoveryManager, + ); + }); +}); diff --git a/solidity/optics-core/test/cross-chain/SimpleMessage.test.js b/solidity/optics-core/test/cross-chain/SimpleMessage.test.js index ebaffec1c..7f8d4179b 100644 --- a/solidity/optics-core/test/cross-chain/SimpleMessage.test.js +++ b/solidity/optics-core/test/cross-chain/SimpleMessage.test.js @@ -33,18 +33,21 @@ describe('SimpleCrossChainMessage', async () => { const replicaDomain = domains[1]; const walletProvider = new testUtils.WalletProvider(provider); - let randomSigner, chainDetails, firstRootEnqueuedToReplica; + let randomSigner, recoveryManager, chainDetails, firstRootEnqueuedToReplica; let latestRoot = {}, latestUpdate = {}; before(async () => { + [randomSigner, recoveryManager] = walletProvider.getWalletsPersistent(2); + // generate TestChainConfigs for the given domains - const configs = await domainsToTestConfigs(domains); + const configs = await domainsToTestConfigs( + domains, + recoveryManager.address, + ); // deploy the entire Optics suite on each chain chainDetails = await deployMultipleChains(configs); - - [randomSigner] = walletProvider.getWalletsPersistent(1); }); it('All Homes have correct initial state', async () => { diff --git a/solidity/optics-core/test/cross-chain/crossChainTestUtils.js b/solidity/optics-core/test/cross-chain/crossChainTestUtils.js index 876aef35b..c23577256 100644 --- a/solidity/optics-core/test/cross-chain/crossChainTestUtils.js +++ b/solidity/optics-core/test/cross-chain/crossChainTestUtils.js @@ -194,10 +194,26 @@ async function formatCall(destinationContract, functionStr, functionArgs) { }; } +function encodeData(contract, functionName, args) { + const func = contract.interface.getFunction(functionName); + return contract.interface.encodeFunctionData(func, args); +} + +// Send a transaction from the specified signer +async function sendFromSigner(signer, contract, functionName, args) { + const data = encodeData(contract, functionName, args); + + return signer.sendTransaction({ + to: contract.address, + data, + }); +} + module.exports = { enqueueUpdateToReplica, enqueueMessagesAndUpdateHome, formatMessage, formatCall, formatOpticsMessage, + sendFromSigner, }; diff --git a/solidity/optics-core/test/cross-chain/generateTestChainConfigs.js b/solidity/optics-core/test/cross-chain/generateTestChainConfigs.js index a70ca426b..dda154274 100644 --- a/solidity/optics-core/test/cross-chain/generateTestChainConfigs.js +++ b/solidity/optics-core/test/cross-chain/generateTestChainConfigs.js @@ -11,10 +11,12 @@ const { provider } = waffle; * * @return configs - TestChainConfig[] */ -async function domainsToTestConfigs(domains) { +async function domainsToTestConfigs(domains, recoveryManagerAddress) { let configs = domains.map((domain) => { return { domain, + recoveryTimelock: 1200, + recoveryManagerAddress, currentRoot: '0x0000000000000000000000000000000000000000000000000000000000000000', nextToProcessIndex: 0, diff --git a/typescript/src/chain.ts b/typescript/src/chain.ts index 602172ca9..a5139a649 100644 --- a/typescript/src/chain.ts +++ b/typescript/src/chain.ts @@ -61,6 +61,8 @@ export interface ChainConfig { deployerKey: string; domain: number; updater: Address; + recoveryTimelock: number; + recoveryManager: Address; optimisticSeconds: number; watchers?: Address[]; gasPrice?: ethers.BigNumberish; @@ -74,6 +76,8 @@ export type Chain = { deployer: ethers.Signer; domain: number; updater: Address; + recoveryTimelock: number; + recoveryManager: Address; optimisticSeconds: number; watchers: Address[]; gasPrice: ethers.BigNumber; @@ -101,6 +105,8 @@ export function toChain(config: ChainConfig): Chain { deployer, domain: config.domain, updater: config.updater, + recoveryTimelock: config.recoveryTimelock, + recoveryManager: config.recoveryManager, optimisticSeconds: config.optimisticSeconds, watchers: config.watchers ?? [], gasPrice: BigNumber.from(config.gasPrice ?? '20000000000'), diff --git a/typescript/src/index.ts b/typescript/src/index.ts index a0a322008..3e9444498 100644 --- a/typescript/src/index.ts +++ b/typescript/src/index.ts @@ -85,11 +85,12 @@ async function deployHome(deploy: Deploy) { * @param deploy - The deploy instance */ async function deployGovernanceRouter(deploy: Deploy) { + let { recoveryManager, recoveryTimelock } = deploy.chain; let { xappConnectionManager } = deploy.contracts; let initData = contracts.GovernanceRouter__factory.createInterface().encodeFunctionData( 'initialize', - [xappConnectionManager!.address], + [xappConnectionManager!.address, recoveryManager], ); const governance = await proxyUtils.deployProxy( @@ -97,6 +98,7 @@ async function deployGovernanceRouter(deploy: Deploy) { new contracts.GovernanceRouter__factory(deploy.chain.deployer), initData, deploy.chain.domain, + recoveryTimelock, ); deploy.contracts.governance = governance; diff --git a/typescript/src/typechain/optics-core/GovernanceRouter.d.ts b/typescript/src/typechain/optics-core/GovernanceRouter.d.ts index fb6fb7681..c0d25690e 100644 --- a/typescript/src/typechain/optics-core/GovernanceRouter.d.ts +++ b/typescript/src/typechain/optics-core/GovernanceRouter.d.ts @@ -24,16 +24,23 @@ interface GovernanceRouterInterface extends ethers.utils.Interface { "callLocal(tuple[])": FunctionFragment; "callRemote(uint32,tuple[])": FunctionFragment; "domains(uint256)": FunctionFragment; + "exitRecovery()": FunctionFragment; "governor()": FunctionFragment; "governorDomain()": FunctionFragment; "handle(uint32,bytes32,bytes)": FunctionFragment; - "initialize(address)": FunctionFragment; + "inRecovery()": FunctionFragment; + "initialize(address,address)": FunctionFragment; + "initiateRecoveryTimelock()": FunctionFragment; "localDomain()": FunctionFragment; + "recoveryActiveAt()": FunctionFragment; + "recoveryManager()": FunctionFragment; + "recoveryTimelock()": FunctionFragment; "routers(uint32)": FunctionFragment; "setRouter(uint32,bytes32)": FunctionFragment; - "setRouterDuringSetup(uint32,bytes32)": FunctionFragment; + "setRouterLocal(uint32,bytes32)": FunctionFragment; "setXAppConnectionManager(address)": FunctionFragment; "transferGovernor(uint32,address)": FunctionFragment; + "transferRecoveryManager(address)": FunctionFragment; "xAppConnectionManager()": FunctionFragment; }; @@ -49,6 +56,10 @@ interface GovernanceRouterInterface extends ethers.utils.Interface { functionFragment: "domains", values: [BigNumberish] ): string; + encodeFunctionData( + functionFragment: "exitRecovery", + values?: undefined + ): string; encodeFunctionData(functionFragment: "governor", values?: undefined): string; encodeFunctionData( functionFragment: "governorDomain", @@ -58,11 +69,34 @@ interface GovernanceRouterInterface extends ethers.utils.Interface { functionFragment: "handle", values: [BigNumberish, BytesLike, BytesLike] ): string; - encodeFunctionData(functionFragment: "initialize", values: [string]): string; + encodeFunctionData( + functionFragment: "inRecovery", + values?: undefined + ): string; + encodeFunctionData( + functionFragment: "initialize", + values: [string, string] + ): string; + encodeFunctionData( + functionFragment: "initiateRecoveryTimelock", + values?: undefined + ): string; encodeFunctionData( functionFragment: "localDomain", values?: undefined ): string; + encodeFunctionData( + functionFragment: "recoveryActiveAt", + values?: undefined + ): string; + encodeFunctionData( + functionFragment: "recoveryManager", + values?: undefined + ): string; + encodeFunctionData( + functionFragment: "recoveryTimelock", + values?: undefined + ): string; encodeFunctionData( functionFragment: "routers", values: [BigNumberish] @@ -72,7 +106,7 @@ interface GovernanceRouterInterface extends ethers.utils.Interface { values: [BigNumberish, BytesLike] ): string; encodeFunctionData( - functionFragment: "setRouterDuringSetup", + functionFragment: "setRouterLocal", values: [BigNumberish, BytesLike] ): string; encodeFunctionData( @@ -83,6 +117,10 @@ interface GovernanceRouterInterface extends ethers.utils.Interface { functionFragment: "transferGovernor", values: [BigNumberish, string] ): string; + encodeFunctionData( + functionFragment: "transferRecoveryManager", + values: [string] + ): string; encodeFunctionData( functionFragment: "xAppConnectionManager", values?: undefined @@ -91,21 +129,42 @@ interface GovernanceRouterInterface extends ethers.utils.Interface { decodeFunctionResult(functionFragment: "callLocal", data: BytesLike): Result; decodeFunctionResult(functionFragment: "callRemote", data: BytesLike): Result; decodeFunctionResult(functionFragment: "domains", data: BytesLike): Result; + decodeFunctionResult( + functionFragment: "exitRecovery", + data: BytesLike + ): Result; decodeFunctionResult(functionFragment: "governor", data: BytesLike): Result; decodeFunctionResult( functionFragment: "governorDomain", data: BytesLike ): Result; decodeFunctionResult(functionFragment: "handle", data: BytesLike): Result; + decodeFunctionResult(functionFragment: "inRecovery", data: BytesLike): Result; decodeFunctionResult(functionFragment: "initialize", data: BytesLike): Result; + decodeFunctionResult( + functionFragment: "initiateRecoveryTimelock", + data: BytesLike + ): Result; decodeFunctionResult( functionFragment: "localDomain", data: BytesLike ): Result; + decodeFunctionResult( + functionFragment: "recoveryActiveAt", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "recoveryManager", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "recoveryTimelock", + data: BytesLike + ): Result; decodeFunctionResult(functionFragment: "routers", data: BytesLike): Result; decodeFunctionResult(functionFragment: "setRouter", data: BytesLike): Result; decodeFunctionResult( - functionFragment: "setRouterDuringSetup", + functionFragment: "setRouterLocal", data: BytesLike ): Result; decodeFunctionResult( @@ -116,18 +175,28 @@ interface GovernanceRouterInterface extends ethers.utils.Interface { functionFragment: "transferGovernor", data: BytesLike ): Result; + decodeFunctionResult( + functionFragment: "transferRecoveryManager", + data: BytesLike + ): Result; decodeFunctionResult( functionFragment: "xAppConnectionManager", data: BytesLike ): Result; events: { + "ExitRecovery(address)": EventFragment; + "InitiateRecovery(address,uint256)": EventFragment; "SetRouter(uint32,bytes32,bytes32)": EventFragment; "TransferGovernor(uint32,uint32,address,address)": EventFragment; + "TransferRecoveryManager(address,address)": EventFragment; }; + getEvent(nameOrSignatureOrTopic: "ExitRecovery"): EventFragment; + getEvent(nameOrSignatureOrTopic: "InitiateRecovery"): EventFragment; getEvent(nameOrSignatureOrTopic: "SetRouter"): EventFragment; getEvent(nameOrSignatureOrTopic: "TransferGovernor"): EventFragment; + getEvent(nameOrSignatureOrTopic: "TransferRecoveryManager"): EventFragment; } export class GovernanceRouter extends BaseContract { @@ -187,6 +256,10 @@ export class GovernanceRouter extends BaseContract { domains(arg0: BigNumberish, overrides?: CallOverrides): Promise<[number]>; + exitRecovery( + overrides?: Overrides & { from?: string | Promise } + ): Promise; + governor(overrides?: CallOverrides): Promise<[string]>; governorDomain(overrides?: CallOverrides): Promise<[number]>; @@ -198,13 +271,26 @@ export class GovernanceRouter extends BaseContract { overrides?: Overrides & { from?: string | Promise } ): Promise; + inRecovery(overrides?: CallOverrides): Promise<[boolean]>; + initialize( _xAppConnectionManager: string, + _recoveryManager: string, + overrides?: Overrides & { from?: string | Promise } + ): Promise; + + initiateRecoveryTimelock( overrides?: Overrides & { from?: string | Promise } ): Promise; localDomain(overrides?: CallOverrides): Promise<[number]>; + recoveryActiveAt(overrides?: CallOverrides): Promise<[BigNumber]>; + + recoveryManager(overrides?: CallOverrides): Promise<[string]>; + + recoveryTimelock(overrides?: CallOverrides): Promise<[BigNumber]>; + routers(arg0: BigNumberish, overrides?: CallOverrides): Promise<[string]>; setRouter( @@ -213,7 +299,7 @@ export class GovernanceRouter extends BaseContract { overrides?: Overrides & { from?: string | Promise } ): Promise; - setRouterDuringSetup( + setRouterLocal( _domain: BigNumberish, _router: BytesLike, overrides?: Overrides & { from?: string | Promise } @@ -230,6 +316,11 @@ export class GovernanceRouter extends BaseContract { overrides?: Overrides & { from?: string | Promise } ): Promise; + transferRecoveryManager( + _newRecoveryManager: string, + overrides?: Overrides & { from?: string | Promise } + ): Promise; + xAppConnectionManager(overrides?: CallOverrides): Promise<[string]>; }; @@ -246,6 +337,10 @@ export class GovernanceRouter extends BaseContract { domains(arg0: BigNumberish, overrides?: CallOverrides): Promise; + exitRecovery( + overrides?: Overrides & { from?: string | Promise } + ): Promise; + governor(overrides?: CallOverrides): Promise; governorDomain(overrides?: CallOverrides): Promise; @@ -257,13 +352,26 @@ export class GovernanceRouter extends BaseContract { overrides?: Overrides & { from?: string | Promise } ): Promise; + inRecovery(overrides?: CallOverrides): Promise; + initialize( _xAppConnectionManager: string, + _recoveryManager: string, + overrides?: Overrides & { from?: string | Promise } + ): Promise; + + initiateRecoveryTimelock( overrides?: Overrides & { from?: string | Promise } ): Promise; localDomain(overrides?: CallOverrides): Promise; + recoveryActiveAt(overrides?: CallOverrides): Promise; + + recoveryManager(overrides?: CallOverrides): Promise; + + recoveryTimelock(overrides?: CallOverrides): Promise; + routers(arg0: BigNumberish, overrides?: CallOverrides): Promise; setRouter( @@ -272,7 +380,7 @@ export class GovernanceRouter extends BaseContract { overrides?: Overrides & { from?: string | Promise } ): Promise; - setRouterDuringSetup( + setRouterLocal( _domain: BigNumberish, _router: BytesLike, overrides?: Overrides & { from?: string | Promise } @@ -289,6 +397,11 @@ export class GovernanceRouter extends BaseContract { overrides?: Overrides & { from?: string | Promise } ): Promise; + transferRecoveryManager( + _newRecoveryManager: string, + overrides?: Overrides & { from?: string | Promise } + ): Promise; + xAppConnectionManager(overrides?: CallOverrides): Promise; callStatic: { @@ -305,6 +418,8 @@ export class GovernanceRouter extends BaseContract { domains(arg0: BigNumberish, overrides?: CallOverrides): Promise; + exitRecovery(overrides?: CallOverrides): Promise; + governor(overrides?: CallOverrides): Promise; governorDomain(overrides?: CallOverrides): Promise; @@ -316,13 +431,24 @@ export class GovernanceRouter extends BaseContract { overrides?: CallOverrides ): Promise; + inRecovery(overrides?: CallOverrides): Promise; + initialize( _xAppConnectionManager: string, + _recoveryManager: string, overrides?: CallOverrides ): Promise; + initiateRecoveryTimelock(overrides?: CallOverrides): Promise; + localDomain(overrides?: CallOverrides): Promise; + recoveryActiveAt(overrides?: CallOverrides): Promise; + + recoveryManager(overrides?: CallOverrides): Promise; + + recoveryTimelock(overrides?: CallOverrides): Promise; + routers(arg0: BigNumberish, overrides?: CallOverrides): Promise; setRouter( @@ -331,7 +457,7 @@ export class GovernanceRouter extends BaseContract { overrides?: CallOverrides ): Promise; - setRouterDuringSetup( + setRouterLocal( _domain: BigNumberish, _router: BytesLike, overrides?: CallOverrides @@ -348,10 +474,27 @@ export class GovernanceRouter extends BaseContract { overrides?: CallOverrides ): Promise; + transferRecoveryManager( + _newRecoveryManager: string, + overrides?: CallOverrides + ): Promise; + xAppConnectionManager(overrides?: CallOverrides): Promise; }; filters: { + ExitRecovery( + recoveryManager?: null + ): TypedEventFilter<[string], { recoveryManager: string }>; + + InitiateRecovery( + recoveryManager?: string | null, + endBlock?: null + ): TypedEventFilter< + [string, BigNumber], + { recoveryManager: string; endBlock: BigNumber } + >; + SetRouter( domain?: BigNumberish | null, previousRouter?: null, @@ -375,6 +518,14 @@ export class GovernanceRouter extends BaseContract { newGovernor: string; } >; + + TransferRecoveryManager( + previousRecoveryManager?: string | null, + newRecoveryManager?: string | null + ): TypedEventFilter< + [string, string], + { previousRecoveryManager: string; newRecoveryManager: string } + >; }; estimateGas: { @@ -391,6 +542,10 @@ export class GovernanceRouter extends BaseContract { domains(arg0: BigNumberish, overrides?: CallOverrides): Promise; + exitRecovery( + overrides?: Overrides & { from?: string | Promise } + ): Promise; + governor(overrides?: CallOverrides): Promise; governorDomain(overrides?: CallOverrides): Promise; @@ -402,13 +557,26 @@ export class GovernanceRouter extends BaseContract { overrides?: Overrides & { from?: string | Promise } ): Promise; + inRecovery(overrides?: CallOverrides): Promise; + initialize( _xAppConnectionManager: string, + _recoveryManager: string, + overrides?: Overrides & { from?: string | Promise } + ): Promise; + + initiateRecoveryTimelock( overrides?: Overrides & { from?: string | Promise } ): Promise; localDomain(overrides?: CallOverrides): Promise; + recoveryActiveAt(overrides?: CallOverrides): Promise; + + recoveryManager(overrides?: CallOverrides): Promise; + + recoveryTimelock(overrides?: CallOverrides): Promise; + routers(arg0: BigNumberish, overrides?: CallOverrides): Promise; setRouter( @@ -417,7 +585,7 @@ export class GovernanceRouter extends BaseContract { overrides?: Overrides & { from?: string | Promise } ): Promise; - setRouterDuringSetup( + setRouterLocal( _domain: BigNumberish, _router: BytesLike, overrides?: Overrides & { from?: string | Promise } @@ -434,6 +602,11 @@ export class GovernanceRouter extends BaseContract { overrides?: Overrides & { from?: string | Promise } ): Promise; + transferRecoveryManager( + _newRecoveryManager: string, + overrides?: Overrides & { from?: string | Promise } + ): Promise; + xAppConnectionManager(overrides?: CallOverrides): Promise; }; @@ -454,6 +627,10 @@ export class GovernanceRouter extends BaseContract { overrides?: CallOverrides ): Promise; + exitRecovery( + overrides?: Overrides & { from?: string | Promise } + ): Promise; + governor(overrides?: CallOverrides): Promise; governorDomain(overrides?: CallOverrides): Promise; @@ -465,13 +642,26 @@ export class GovernanceRouter extends BaseContract { overrides?: Overrides & { from?: string | Promise } ): Promise; + inRecovery(overrides?: CallOverrides): Promise; + initialize( _xAppConnectionManager: string, + _recoveryManager: string, + overrides?: Overrides & { from?: string | Promise } + ): Promise; + + initiateRecoveryTimelock( overrides?: Overrides & { from?: string | Promise } ): Promise; localDomain(overrides?: CallOverrides): Promise; + recoveryActiveAt(overrides?: CallOverrides): Promise; + + recoveryManager(overrides?: CallOverrides): Promise; + + recoveryTimelock(overrides?: CallOverrides): Promise; + routers( arg0: BigNumberish, overrides?: CallOverrides @@ -483,7 +673,7 @@ export class GovernanceRouter extends BaseContract { overrides?: Overrides & { from?: string | Promise } ): Promise; - setRouterDuringSetup( + setRouterLocal( _domain: BigNumberish, _router: BytesLike, overrides?: Overrides & { from?: string | Promise } @@ -500,6 +690,11 @@ export class GovernanceRouter extends BaseContract { overrides?: Overrides & { from?: string | Promise } ): Promise; + transferRecoveryManager( + _newRecoveryManager: string, + overrides?: Overrides & { from?: string | Promise } + ): Promise; + xAppConnectionManager( overrides?: CallOverrides ): Promise; diff --git a/typescript/src/typechain/optics-core/TestGovernanceRouter.d.ts b/typescript/src/typechain/optics-core/TestGovernanceRouter.d.ts index 895609bf0..d42016800 100644 --- a/typescript/src/typechain/optics-core/TestGovernanceRouter.d.ts +++ b/typescript/src/typechain/optics-core/TestGovernanceRouter.d.ts @@ -25,18 +25,25 @@ interface TestGovernanceRouterInterface extends ethers.utils.Interface { "callRemote(uint32,tuple[])": FunctionFragment; "containsDomain(uint32)": FunctionFragment; "domains(uint256)": FunctionFragment; + "exitRecovery()": FunctionFragment; "governor()": FunctionFragment; "governorDomain()": FunctionFragment; "handle(uint32,bytes32,bytes)": FunctionFragment; - "initialize(address)": FunctionFragment; + "inRecovery()": FunctionFragment; + "initialize(address,address)": FunctionFragment; + "initiateRecoveryTimelock()": FunctionFragment; "localDomain()": FunctionFragment; + "recoveryActiveAt()": FunctionFragment; + "recoveryManager()": FunctionFragment; + "recoveryTimelock()": FunctionFragment; "routers(uint32)": FunctionFragment; "setRouter(uint32,bytes32)": FunctionFragment; "setRouterAddress(uint32,address)": FunctionFragment; - "setRouterDuringSetup(uint32,bytes32)": FunctionFragment; + "setRouterLocal(uint32,bytes32)": FunctionFragment; "setXAppConnectionManager(address)": FunctionFragment; "testSetRouter(uint32,bytes32)": FunctionFragment; "transferGovernor(uint32,address)": FunctionFragment; + "transferRecoveryManager(address)": FunctionFragment; "xAppConnectionManager()": FunctionFragment; }; @@ -56,6 +63,10 @@ interface TestGovernanceRouterInterface extends ethers.utils.Interface { functionFragment: "domains", values: [BigNumberish] ): string; + encodeFunctionData( + functionFragment: "exitRecovery", + values?: undefined + ): string; encodeFunctionData(functionFragment: "governor", values?: undefined): string; encodeFunctionData( functionFragment: "governorDomain", @@ -65,11 +76,34 @@ interface TestGovernanceRouterInterface extends ethers.utils.Interface { functionFragment: "handle", values: [BigNumberish, BytesLike, BytesLike] ): string; - encodeFunctionData(functionFragment: "initialize", values: [string]): string; + encodeFunctionData( + functionFragment: "inRecovery", + values?: undefined + ): string; + encodeFunctionData( + functionFragment: "initialize", + values: [string, string] + ): string; + encodeFunctionData( + functionFragment: "initiateRecoveryTimelock", + values?: undefined + ): string; encodeFunctionData( functionFragment: "localDomain", values?: undefined ): string; + encodeFunctionData( + functionFragment: "recoveryActiveAt", + values?: undefined + ): string; + encodeFunctionData( + functionFragment: "recoveryManager", + values?: undefined + ): string; + encodeFunctionData( + functionFragment: "recoveryTimelock", + values?: undefined + ): string; encodeFunctionData( functionFragment: "routers", values: [BigNumberish] @@ -83,7 +117,7 @@ interface TestGovernanceRouterInterface extends ethers.utils.Interface { values: [BigNumberish, string] ): string; encodeFunctionData( - functionFragment: "setRouterDuringSetup", + functionFragment: "setRouterLocal", values: [BigNumberish, BytesLike] ): string; encodeFunctionData( @@ -98,6 +132,10 @@ interface TestGovernanceRouterInterface extends ethers.utils.Interface { functionFragment: "transferGovernor", values: [BigNumberish, string] ): string; + encodeFunctionData( + functionFragment: "transferRecoveryManager", + values: [string] + ): string; encodeFunctionData( functionFragment: "xAppConnectionManager", values?: undefined @@ -110,17 +148,38 @@ interface TestGovernanceRouterInterface extends ethers.utils.Interface { data: BytesLike ): Result; decodeFunctionResult(functionFragment: "domains", data: BytesLike): Result; + decodeFunctionResult( + functionFragment: "exitRecovery", + data: BytesLike + ): Result; decodeFunctionResult(functionFragment: "governor", data: BytesLike): Result; decodeFunctionResult( functionFragment: "governorDomain", data: BytesLike ): Result; decodeFunctionResult(functionFragment: "handle", data: BytesLike): Result; + decodeFunctionResult(functionFragment: "inRecovery", data: BytesLike): Result; decodeFunctionResult(functionFragment: "initialize", data: BytesLike): Result; + decodeFunctionResult( + functionFragment: "initiateRecoveryTimelock", + data: BytesLike + ): Result; decodeFunctionResult( functionFragment: "localDomain", data: BytesLike ): Result; + decodeFunctionResult( + functionFragment: "recoveryActiveAt", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "recoveryManager", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "recoveryTimelock", + data: BytesLike + ): Result; decodeFunctionResult(functionFragment: "routers", data: BytesLike): Result; decodeFunctionResult(functionFragment: "setRouter", data: BytesLike): Result; decodeFunctionResult( @@ -128,7 +187,7 @@ interface TestGovernanceRouterInterface extends ethers.utils.Interface { data: BytesLike ): Result; decodeFunctionResult( - functionFragment: "setRouterDuringSetup", + functionFragment: "setRouterLocal", data: BytesLike ): Result; decodeFunctionResult( @@ -143,18 +202,28 @@ interface TestGovernanceRouterInterface extends ethers.utils.Interface { functionFragment: "transferGovernor", data: BytesLike ): Result; + decodeFunctionResult( + functionFragment: "transferRecoveryManager", + data: BytesLike + ): Result; decodeFunctionResult( functionFragment: "xAppConnectionManager", data: BytesLike ): Result; events: { + "ExitRecovery(address)": EventFragment; + "InitiateRecovery(address,uint256)": EventFragment; "SetRouter(uint32,bytes32,bytes32)": EventFragment; "TransferGovernor(uint32,uint32,address,address)": EventFragment; + "TransferRecoveryManager(address,address)": EventFragment; }; + getEvent(nameOrSignatureOrTopic: "ExitRecovery"): EventFragment; + getEvent(nameOrSignatureOrTopic: "InitiateRecovery"): EventFragment; getEvent(nameOrSignatureOrTopic: "SetRouter"): EventFragment; getEvent(nameOrSignatureOrTopic: "TransferGovernor"): EventFragment; + getEvent(nameOrSignatureOrTopic: "TransferRecoveryManager"): EventFragment; } export class TestGovernanceRouter extends BaseContract { @@ -219,6 +288,10 @@ export class TestGovernanceRouter extends BaseContract { domains(arg0: BigNumberish, overrides?: CallOverrides): Promise<[number]>; + exitRecovery( + overrides?: Overrides & { from?: string | Promise } + ): Promise; + governor(overrides?: CallOverrides): Promise<[string]>; governorDomain(overrides?: CallOverrides): Promise<[number]>; @@ -230,13 +303,26 @@ export class TestGovernanceRouter extends BaseContract { overrides?: Overrides & { from?: string | Promise } ): Promise; + inRecovery(overrides?: CallOverrides): Promise<[boolean]>; + initialize( _xAppConnectionManager: string, + _recoveryManager: string, + overrides?: Overrides & { from?: string | Promise } + ): Promise; + + initiateRecoveryTimelock( overrides?: Overrides & { from?: string | Promise } ): Promise; localDomain(overrides?: CallOverrides): Promise<[number]>; + recoveryActiveAt(overrides?: CallOverrides): Promise<[BigNumber]>; + + recoveryManager(overrides?: CallOverrides): Promise<[string]>; + + recoveryTimelock(overrides?: CallOverrides): Promise<[BigNumber]>; + routers(arg0: BigNumberish, overrides?: CallOverrides): Promise<[string]>; setRouter( @@ -251,7 +337,7 @@ export class TestGovernanceRouter extends BaseContract { overrides?: Overrides & { from?: string | Promise } ): Promise; - setRouterDuringSetup( + setRouterLocal( _domain: BigNumberish, _router: BytesLike, overrides?: Overrides & { from?: string | Promise } @@ -274,6 +360,11 @@ export class TestGovernanceRouter extends BaseContract { overrides?: Overrides & { from?: string | Promise } ): Promise; + transferRecoveryManager( + _newRecoveryManager: string, + overrides?: Overrides & { from?: string | Promise } + ): Promise; + xAppConnectionManager(overrides?: CallOverrides): Promise<[string]>; }; @@ -295,6 +386,10 @@ export class TestGovernanceRouter extends BaseContract { domains(arg0: BigNumberish, overrides?: CallOverrides): Promise; + exitRecovery( + overrides?: Overrides & { from?: string | Promise } + ): Promise; + governor(overrides?: CallOverrides): Promise; governorDomain(overrides?: CallOverrides): Promise; @@ -306,13 +401,26 @@ export class TestGovernanceRouter extends BaseContract { overrides?: Overrides & { from?: string | Promise } ): Promise; + inRecovery(overrides?: CallOverrides): Promise; + initialize( _xAppConnectionManager: string, + _recoveryManager: string, + overrides?: Overrides & { from?: string | Promise } + ): Promise; + + initiateRecoveryTimelock( overrides?: Overrides & { from?: string | Promise } ): Promise; localDomain(overrides?: CallOverrides): Promise; + recoveryActiveAt(overrides?: CallOverrides): Promise; + + recoveryManager(overrides?: CallOverrides): Promise; + + recoveryTimelock(overrides?: CallOverrides): Promise; + routers(arg0: BigNumberish, overrides?: CallOverrides): Promise; setRouter( @@ -327,7 +435,7 @@ export class TestGovernanceRouter extends BaseContract { overrides?: Overrides & { from?: string | Promise } ): Promise; - setRouterDuringSetup( + setRouterLocal( _domain: BigNumberish, _router: BytesLike, overrides?: Overrides & { from?: string | Promise } @@ -350,6 +458,11 @@ export class TestGovernanceRouter extends BaseContract { overrides?: Overrides & { from?: string | Promise } ): Promise; + transferRecoveryManager( + _newRecoveryManager: string, + overrides?: Overrides & { from?: string | Promise } + ): Promise; + xAppConnectionManager(overrides?: CallOverrides): Promise; callStatic: { @@ -371,6 +484,8 @@ export class TestGovernanceRouter extends BaseContract { domains(arg0: BigNumberish, overrides?: CallOverrides): Promise; + exitRecovery(overrides?: CallOverrides): Promise; + governor(overrides?: CallOverrides): Promise; governorDomain(overrides?: CallOverrides): Promise; @@ -382,13 +497,24 @@ export class TestGovernanceRouter extends BaseContract { overrides?: CallOverrides ): Promise; + inRecovery(overrides?: CallOverrides): Promise; + initialize( _xAppConnectionManager: string, + _recoveryManager: string, overrides?: CallOverrides ): Promise; + initiateRecoveryTimelock(overrides?: CallOverrides): Promise; + localDomain(overrides?: CallOverrides): Promise; + recoveryActiveAt(overrides?: CallOverrides): Promise; + + recoveryManager(overrides?: CallOverrides): Promise; + + recoveryTimelock(overrides?: CallOverrides): Promise; + routers(arg0: BigNumberish, overrides?: CallOverrides): Promise; setRouter( @@ -403,7 +529,7 @@ export class TestGovernanceRouter extends BaseContract { overrides?: CallOverrides ): Promise; - setRouterDuringSetup( + setRouterLocal( _domain: BigNumberish, _router: BytesLike, overrides?: CallOverrides @@ -426,10 +552,27 @@ export class TestGovernanceRouter extends BaseContract { overrides?: CallOverrides ): Promise; + transferRecoveryManager( + _newRecoveryManager: string, + overrides?: CallOverrides + ): Promise; + xAppConnectionManager(overrides?: CallOverrides): Promise; }; filters: { + ExitRecovery( + recoveryManager?: null + ): TypedEventFilter<[string], { recoveryManager: string }>; + + InitiateRecovery( + recoveryManager?: string | null, + endBlock?: null + ): TypedEventFilter< + [string, BigNumber], + { recoveryManager: string; endBlock: BigNumber } + >; + SetRouter( domain?: BigNumberish | null, previousRouter?: null, @@ -453,6 +596,14 @@ export class TestGovernanceRouter extends BaseContract { newGovernor: string; } >; + + TransferRecoveryManager( + previousRecoveryManager?: string | null, + newRecoveryManager?: string | null + ): TypedEventFilter< + [string, string], + { previousRecoveryManager: string; newRecoveryManager: string } + >; }; estimateGas: { @@ -474,6 +625,10 @@ export class TestGovernanceRouter extends BaseContract { domains(arg0: BigNumberish, overrides?: CallOverrides): Promise; + exitRecovery( + overrides?: Overrides & { from?: string | Promise } + ): Promise; + governor(overrides?: CallOverrides): Promise; governorDomain(overrides?: CallOverrides): Promise; @@ -485,13 +640,26 @@ export class TestGovernanceRouter extends BaseContract { overrides?: Overrides & { from?: string | Promise } ): Promise; + inRecovery(overrides?: CallOverrides): Promise; + initialize( _xAppConnectionManager: string, + _recoveryManager: string, + overrides?: Overrides & { from?: string | Promise } + ): Promise; + + initiateRecoveryTimelock( overrides?: Overrides & { from?: string | Promise } ): Promise; localDomain(overrides?: CallOverrides): Promise; + recoveryActiveAt(overrides?: CallOverrides): Promise; + + recoveryManager(overrides?: CallOverrides): Promise; + + recoveryTimelock(overrides?: CallOverrides): Promise; + routers(arg0: BigNumberish, overrides?: CallOverrides): Promise; setRouter( @@ -506,7 +674,7 @@ export class TestGovernanceRouter extends BaseContract { overrides?: Overrides & { from?: string | Promise } ): Promise; - setRouterDuringSetup( + setRouterLocal( _domain: BigNumberish, _router: BytesLike, overrides?: Overrides & { from?: string | Promise } @@ -529,6 +697,11 @@ export class TestGovernanceRouter extends BaseContract { overrides?: Overrides & { from?: string | Promise } ): Promise; + transferRecoveryManager( + _newRecoveryManager: string, + overrides?: Overrides & { from?: string | Promise } + ): Promise; + xAppConnectionManager(overrides?: CallOverrides): Promise; }; @@ -554,6 +727,10 @@ export class TestGovernanceRouter extends BaseContract { overrides?: CallOverrides ): Promise; + exitRecovery( + overrides?: Overrides & { from?: string | Promise } + ): Promise; + governor(overrides?: CallOverrides): Promise; governorDomain(overrides?: CallOverrides): Promise; @@ -565,13 +742,26 @@ export class TestGovernanceRouter extends BaseContract { overrides?: Overrides & { from?: string | Promise } ): Promise; + inRecovery(overrides?: CallOverrides): Promise; + initialize( _xAppConnectionManager: string, + _recoveryManager: string, + overrides?: Overrides & { from?: string | Promise } + ): Promise; + + initiateRecoveryTimelock( overrides?: Overrides & { from?: string | Promise } ): Promise; localDomain(overrides?: CallOverrides): Promise; + recoveryActiveAt(overrides?: CallOverrides): Promise; + + recoveryManager(overrides?: CallOverrides): Promise; + + recoveryTimelock(overrides?: CallOverrides): Promise; + routers( arg0: BigNumberish, overrides?: CallOverrides @@ -589,7 +779,7 @@ export class TestGovernanceRouter extends BaseContract { overrides?: Overrides & { from?: string | Promise } ): Promise; - setRouterDuringSetup( + setRouterLocal( _domain: BigNumberish, _router: BytesLike, overrides?: Overrides & { from?: string | Promise } @@ -612,6 +802,11 @@ export class TestGovernanceRouter extends BaseContract { overrides?: Overrides & { from?: string | Promise } ): Promise; + transferRecoveryManager( + _newRecoveryManager: string, + overrides?: Overrides & { from?: string | Promise } + ): Promise; + xAppConnectionManager( overrides?: CallOverrides ): Promise; diff --git a/typescript/src/typechain/optics-core/factories/GovernanceRouter__factory.ts b/typescript/src/typechain/optics-core/factories/GovernanceRouter__factory.ts index 12765b0d1..0d6385779 100644 --- a/typescript/src/typechain/optics-core/factories/GovernanceRouter__factory.ts +++ b/typescript/src/typechain/optics-core/factories/GovernanceRouter__factory.ts @@ -24,10 +24,47 @@ const _abi = [ name: "_localDomain", type: "uint32", }, + { + internalType: "uint256", + name: "_recoveryTimelock", + type: "uint256", + }, ], stateMutability: "nonpayable", type: "constructor", }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: "address", + name: "recoveryManager", + type: "address", + }, + ], + name: "ExitRecovery", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "address", + name: "recoveryManager", + type: "address", + }, + { + indexed: false, + internalType: "uint256", + name: "endBlock", + type: "uint256", + }, + ], + name: "InitiateRecovery", + type: "event", + }, { anonymous: false, inputs: [ @@ -84,6 +121,25 @@ const _abi = [ name: "TransferGovernor", type: "event", }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "address", + name: "previousRecoveryManager", + type: "address", + }, + { + indexed: true, + internalType: "address", + name: "newRecoveryManager", + type: "address", + }, + ], + name: "TransferRecoveryManager", + type: "event", + }, { inputs: [ { @@ -158,6 +214,13 @@ const _abi = [ stateMutability: "view", type: "function", }, + { + inputs: [], + name: "exitRecovery", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, { inputs: [], name: "governor", @@ -207,6 +270,19 @@ const _abi = [ stateMutability: "nonpayable", type: "function", }, + { + inputs: [], + name: "inRecovery", + outputs: [ + { + internalType: "bool", + name: "", + type: "bool", + }, + ], + stateMutability: "view", + type: "function", + }, { inputs: [ { @@ -214,12 +290,24 @@ const _abi = [ name: "_xAppConnectionManager", type: "address", }, + { + internalType: "address", + name: "_recoveryManager", + type: "address", + }, ], name: "initialize", outputs: [], stateMutability: "nonpayable", type: "function", }, + { + inputs: [], + name: "initiateRecoveryTimelock", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, { inputs: [], name: "localDomain", @@ -233,6 +321,45 @@ const _abi = [ stateMutability: "view", type: "function", }, + { + inputs: [], + name: "recoveryActiveAt", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "recoveryManager", + outputs: [ + { + internalType: "address", + name: "", + type: "address", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "recoveryTimelock", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + stateMutability: "view", + type: "function", + }, { inputs: [ { @@ -283,7 +410,7 @@ const _abi = [ type: "bytes32", }, ], - name: "setRouterDuringSetup", + name: "setRouterLocal", outputs: [], stateMutability: "nonpayable", type: "function", @@ -319,6 +446,19 @@ const _abi = [ stateMutability: "nonpayable", type: "function", }, + { + inputs: [ + { + internalType: "address", + name: "_newRecoveryManager", + type: "address", + }, + ], + name: "transferRecoveryManager", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, { inputs: [], name: "xAppConnectionManager", @@ -335,7 +475,7 @@ const _abi = [ ]; const _bytecode = - "0x60a06040523480156200001157600080fd5b50604051620031593803806200315983398101604081905262000034916200004a565b60e01b6001600160e01b03191660805262000077565b6000602082840312156200005c578081fd5b815163ffffffff8116811462000070578182fd5b9392505050565b60805160e01c6130b5620000a460003980610872528061097e52806109af52806113ce52506130b56000f3fe608060405234801561001057600080fd5b50600436106100ea5760003560e01c806356d5d4751161008c5780638d3638f4116100665780638d3638f4146101be578063c4d66de8146101c6578063db2021ae146101d9578063e8c6f83a146101ec576100ea565b806356d5d4751461018557806366cf8fab146101985780637d8dfc33146101ab576100ea565b806341bdc8b5116100c857806341bdc8b5146101355780634626abee1461014a5780634fedbbb51461015d5780635585416c14610170576100ea565b80630c340a24146100ef5780632ead72f61461010d5780633339df961461012d575b600080fd5b6100f76101ff565b6040516101049190612c07565b60405180910390f35b61012061011b3660046129dc565b61021b565b6040516101049190612c28565b6100f761022d565b61014861014336600461292c565b61024f565b005b610148610158366004612948565b6102f6565b61014861016b366004612a4c565b61038f565b610178610518565b6040516101049190612dbe565b610148610193366004612aca565b61053e565b6101786101a63660046129c4565b6107d7565b6101486101b9366004612a9f565b610811565b610178610870565b6101486101d436600461292c565b610894565b6101486101e7366004612a14565b610ae5565b6101486101fa366004612a9f565b610b7f565b60015473ffffffffffffffffffffffffffffffffffffffff1681565b60026020526000908152604090205481565b60005462010000900473ffffffffffffffffffffffffffffffffffffffff1681565b60015473ffffffffffffffffffffffffffffffffffffffff1633146102a9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016102a090612d87565b60405180910390fd5b6000805473ffffffffffffffffffffffffffffffffffffffff90921662010000027fffffffffffffffffffff0000000000000000000000000000000000000000ffff909216919091179055565b60015473ffffffffffffffffffffffffffffffffffffffff163314610347576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016102a090612d87565b60005b8181101561038a5761038183838381811061036157fe5b90506020028101906103739190612e4b565b61037c90612f02565b610bf1565b5060010161034a565b505050565b60015473ffffffffffffffffffffffffffffffffffffffff1633146103e0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016102a090612d87565b60006103eb84610cb4565b905060006104016103fc8486612ea2565b610d06565b9050600060029054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16639fa92f9d6040518163ffffffff1660e01b815260040160206040518083038186803b15801561046b57600080fd5b505afa15801561047f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104a391906129a8565b73ffffffffffffffffffffffffffffffffffffffff1663d34686398684846040518463ffffffff1660e01b81526004016104df93929190612dcf565b600060405180830381600087803b1580156104f957600080fd5b505af115801561050d573d6000803e3d6000fd5b505050505050505050565b600054760100000000000000000000000000000000000000000000900463ffffffff1681565b6000546040517f5190bc530000000000000000000000000000000000000000000000000000000081526201000090910473ffffffffffffffffffffffffffffffffffffffff1690635190bc5390610599903390600401612c07565b60206040518083038186803b1580156105b157600080fd5b505afa1580156105c5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105e99190612988565b61061f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016102a090612cab565b828261062b8282610edb565b610661576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016102a090612c3f565b600061066d8482610f2d565b905061069a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000008216610f51565b156106d7576106d26106cd7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000008316610fac565b610ffa565b6107cf565b6107027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000008216611093565b1561073a576106d26107357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000083166110f1565b61110b565b6107657fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000008216611196565b1561079d576106d26107987fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000831661119f565b6111b9565b6040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016102a090612d50565b505050505050565b600381815481106107e757600080fd5b9060005260206000209060089182820401919006600402915054906101000a900463ffffffff1681565b60015473ffffffffffffffffffffffffffffffffffffffff163314610862576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016102a090612d87565b61086c828261122a565b5050565b7f000000000000000000000000000000000000000000000000000000000000000081565b600054610100900460ff16806108ad57506108ad6112bb565b806108bb575060005460ff16155b610910576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602e815260200180612f90602e913960400191505060405180910390fd5b600054610100900460ff1615801561097657600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff909116610100171660011790555b3360016109a47f000000000000000000000000000000000000000000000000000000000000000083836112cc565b6109ad8461024f565b7f000000000000000000000000000000000000000000000000000000000000000063ffffffff16600060029054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16638d3638f46040518163ffffffff1660e01b815260040160206040518083038186803b158015610a3c57600080fd5b505afa158015610a50573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a7491906129f8565b63ffffffff1614610ab1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016102a090612c76565b5050801561086c57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1690555050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610b36576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016102a090612d87565b6000610b41836113cc565b9050610b4e8383836112cc565b8015610b5a575061086c565b6000610b6e84610b69856113fb565b611414565b9050610b7981611441565b50505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610bd0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016102a090612d87565b610bda828261122a565b6000610be68383611638565b905061038a81611441565b60606000610c028360000151611660565b905060008173ffffffffffffffffffffffffffffffffffffffff168460200151604051610c2f9190612b5f565b6000604051808303816000865af19150503d8060008114610c6c576040519150601f19603f3d011682016040523d82523d6000602084013e610c71565b606091505b509350905080610cad576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016102a090612ce2565b5050919050565b63ffffffff811660009081526002602052604090205480610d01576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016102a090612d19565b919050565b805160609060006002820167ffffffffffffffff81118015610d2757600080fd5b50604051908082528060200260200182016040528015610d51578160200160208202803683370190505b509050610d9f60006001604051602001610d6b9190612b7b565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905290610f2d565b81600081518110610dac57fe5b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000909216602092830291909101820152604051610df291600091610d6b91869101612bd7565b81600181518110610dff57fe5b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000009092166020928302919091019091015260005b82811015610ec9576000858281518110610e4957fe5b602002602001015190506000610e7c600083600001518460200151518560200151604051602001610d6b93929190612b32565b905080846002850181518110610e8e57fe5b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000909216602092830291909101909101525050600101610e33565b50610ed381611663565b949350505050565b6000805463ffffffff84811676010000000000000000000000000000000000000000000090920416148015610f24575063ffffffff831660009081526002602052604090205482145b90505b92915050565b815160009060208401610f4864ffffffffff851682846116b3565b95945050505050565b60006001610f5e83611714565b60ff16148015610f2757506040610f967fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000008416611744565b6bffffffffffffffffffffffff16101592915050565b6000610fb782610f51565b15610ff257610feb60015b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000841690611758565b9050610d01565b610f2761177e565b80600161102b815b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000008416906117a2565b5060006110597fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000008516611922565b905060005b815181101561108c5761108382828151811061107657fe5b6020026020010151610bf1565b5060010161105e565b5050505050565b600060025b60ff166110a483611714565b60ff16148015610f27575060256110dc7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000008416611744565b6bffffffffffffffffffffffff161492915050565b60006110fc82611093565b15610ff257610feb6002610fc2565b80600261111781611002565b5060006111457fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000008516611ac5565b9050600061117c6111777fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000008716611af6565b611660565b90506000611189836113cc565b90506107cf8383836112cc565b60006003611098565b60006111aa82611196565b15610ff257610feb6003610fc2565b8060036111c581611002565b5060006111f37fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000008516611ac5565b905060006112227fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000008616611af6565b905061108c82825b63ffffffff8216600081815260026020526040908190205490519091907fe1cc453e5e6d48a5e3dd7dc6c72117211d2bea20fbb91fd980ebc3e7f73fe546906112769084908690612c31565b60405180910390a2816112925761128c83611b27565b5061086c565b806112a0576112a083611bce565b5063ffffffff91909116600090815260026020526040902055565b60006112c630611c2e565b15905090565b806112dc576112da83610cb4565b505b6000816112ea5760006112ec565b825b600080547fffffffffffff00000000ffffffffffffffffffffffffffffffffffffffffffff1676010000000000000000000000000000000000000000000063ffffffff88811682029290921792839055600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8681169182179283905560405196975090959116937f4daaa39e87dee84708195369c30e97baa0665dc8562ac10535a0f3a9329943aa936113be9390910416908990612e34565b60405180910390a350505050565b7f000000000000000000000000000000000000000000000000000000000000000063ffffffff90811691161490565b73ffffffffffffffffffffffffffffffffffffffff1690565b6060610f2461143c611437600060028787604051602001610d6b93929190612b90565b611c34565b611c69565b60008060029054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16639fa92f9d6040518163ffffffff1660e01b815260040160206040518083038186803b1580156114aa57600080fd5b505afa1580156114be573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114e291906129a8565b905060005b60035481101561038a57600063ffffffff166003828154811061150657fe5b6000918252602090912060088204015460079091166004026101000a900463ffffffff1614611630578173ffffffffffffffffffffffffffffffffffffffff1663d34686396003838154811061155857fe5b90600052602060002090600891828204019190066004029054906101000a900463ffffffff16600260006003868154811061158f57fe5b6000918252602080832060088304015463ffffffff6004600790941684026101000a909104168452830193909352604091820190205490517fffffffff0000000000000000000000000000000000000000000000000000000060e086901b1681526115fd9392899101612dcf565b600060405180830381600087803b15801561161757600080fd5b505af115801561162b573d6000803e3d6000fd5b505050505b6001016114e7565b6060610f2461143c61165b600060038787604051602001610d6b93929190612b90565b611cad565b90565b60405160609060006116788460208401611cbb565b9050600061168582611744565b6bffffffffffffffffffffffff16905060006116a083611d33565b9184525082016020016040525092915050565b6000806116c08484611d47565b90506040518111156116d0575060005b806116fe577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000091505061170d565b611709858585611db9565b9150505b9392505050565b6000610f277fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000008316826001611dcc565b60181c6bffffffffffffffffffffffff1690565b60d81b7affffffffffffffffffffffffffffffffffffffffffffffffffffff9091161790565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000090565b60006117ae8383611ded565b61191b5760006117cc6117c085611e0f565b64ffffffffff16611e15565b91505060006117e18464ffffffffff16611e15565b604080517f5479706520617373657274696f6e206661696c65642e20476f742030780000006020808301919091527fffffffffffffffffffff0000000000000000000000000000000000000000000060b088811b8216603d8501527f2e20457870656374656420307800000000000000000000000000000000000000604785015285901b1660548301528251603e818403018152605e8301938490527f08c379a000000000000000000000000000000000000000000000000000000000909352606282018181528351608284015283519496509294508493839260a2019185019080838360005b838110156118e05781810151838201526020016118c8565b50505050905090810190601f16801561190d5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5090919050565b606060006119547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000008416600180611dcc565b905060006119c56002806119897fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000008816611744565b6bffffffffffffffffffffffff160360017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000008816929190611ee9565b905060008260ff1667ffffffffffffffff811180156119e357600080fd5b50604051908082528060200260200182016040528015611a1d57816020015b611a0a6127e0565b815260200190600190039081611a025790505b50905060005b6000611a507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000008516611744565b6bffffffffffffffffffffffff161115611abc57611a6d83611f79565b828281518110611a7957fe5b602090810291909101015152611a8e83611fa9565b828281518110611a9a57fe5b602002602001015160200181905250611ab283611fe8565b9250600101611a23565b50949350505050565b6000610f277fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000831660016004611dcc565b6000610f277fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000831660056020612073565b63ffffffff811660009081526002602052604081208190555b60035481101561086c578163ffffffff1660038281548110611b5e57fe5b6000918252602090912060088204015460079091166004026101000a900463ffffffff161415611bc35760038181548110611b9557fe5b90600052602060002090600891828204019190066004026101000a81549063ffffffff021916905550611bcb565b600101611b40565b50565b600380546001810182556000919091527fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b6008820401805460079092166004026101000a63ffffffff818102199093169390921691909102919091179055565b3b151590565b6000610f27611c42836110f1565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000166121e1565b6060600080611c7784611744565b6bffffffffffffffffffffffff1690506040519150819250611c9c848360200161225b565b508181016020016040529052919050565b6000610f27611c428361119f565b600060405182811115611cce5760206060fd5b506000805b8451811015611d26576000858281518110611cea57fe5b60200260200101519050611d008184870161225b565b50611d0a81611744565b6bffffffffffffffffffffffff16929092019150600101611cd3565b50610ed360008483611db9565b6000611d3e82612387565b60200292915050565b81810182811015610f2757604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f4f766572666c6f7720647572696e67206164646974696f6e2e00000000000000604482015290519081900360640190fd5b606092831b9190911790911b1760181b90565b60008160200360080260ff16611de3858585612073565b901c949350505050565b60008164ffffffffff16611e0084611e0f565b64ffffffffff16149392505050565b60d81c90565b600080601f5b600f8160ff161115611e7d5760ff600882021684901c611e3a816123bb565b61ffff16841793508160ff16601014611e5557601084901b93505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01611e1b565b50600f5b60ff8160ff161015611ee35760ff600882021684901c611ea0816123bb565b61ffff16831792508160ff16600014611ebb57601083901b92505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01611e81565b50915091565b600080611ef5866123eb565b6bffffffffffffffffffffffff169050611f0e866123ff565b611f2285611f1c8489611d47565b90611d47565b1115611f51577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000915050610ed3565b611f5b8186611d47565b9050611f6f8364ffffffffff1682866116b3565b9695505050505050565b6000610f277fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000008316826020612073565b6060610f2761143c6040611fbc85612429565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000861691906004611ee9565b6000816001611ff681611002565b50600061200285612429565b6040019050610f4881806120377fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000008916611744565b6bffffffffffffffffffffffff160360017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000008916929190611ee9565b600060ff82166120855750600061170d565b61208e84611744565b6bffffffffffffffffffffffff166120a98460ff8516611d47565b111561214b576120ea6120bb856123eb565b6bffffffffffffffffffffffff166120d286611744565b6bffffffffffffffffffffffff16858560ff16612459565b6040517f08c379a00000000000000000000000000000000000000000000000000000000081526020600482018181528351602484015283519092839260449091019190850190808383600083156118e05781810151838201526020016118c8565b60208260ff1611156121a8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603a815260200180612fbe603a913960400191505060405180910390fd5b6008820260006121b7866123eb565b6bffffffffffffffffffffffff16905060006121d2836125b4565b91909501511695945050505050565b60006121ec826125fd565b61225757604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f56616c696469747920617373657274696f6e206661696c656400000000000000604482015290519081900360640190fd5b5090565b60006122668361263a565b6122bb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526028815260200180612ff86028913960400191505060405180910390fd5b6122c4836125fd565b612319576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602b815260200180613020602b913960400191505060405180910390fd5b600061232484611744565b6bffffffffffffffffffffffff169050600061233f856123eb565b6bffffffffffffffffffffffff16905060006040519050848111156123645760206060fd5b8285848460045afa50611f6f61237987611e0f565b64ffffffffff168685611db9565b600060206123ad602061239985611744565b6bffffffffffffffffffffffff1690611d47565b816123b457fe5b0492915050565b60006123cd60048360ff16901c61264c565b60ff161760081b62ffff00166123e28261264c565b60ff1617919050565b60781c6bffffffffffffffffffffffff1690565b600061240a82611744565b612413836123eb565b016bffffffffffffffffffffffff169050919050565b6000610f277fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000008316602080612073565b6060600061246686611e15565b915050600061247486611e15565b915050600061248286611e15565b915050600061249086611e15565b91505083838383604051602001808061304b603591397fffffffffffff000000000000000000000000000000000000000000000000000060d087811b821660358401527f2077697468206c656e6774682030780000000000000000000000000000000000603b84015286901b16604a8201526050016021612f6f82397fffffffffffff000000000000000000000000000000000000000000000000000060d094851b811660218301527f2077697468206c656e677468203078000000000000000000000000000000000060278301529290931b9091166036830152507f2e00000000000000000000000000000000000000000000000000000000000000603c82015260408051601d818403018152603d90920190529b9a5050505050505050505050565b7f80000000000000000000000000000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9091011d90565b600061260882611e0f565b64ffffffffff1664ffffffffff141561262357506000610d01565b600061262e836123ff565b60405110199392505050565b6000612645826127b8565b1592915050565b600060f08083179060ff82161415612668576030915050610d01565b8060ff1660f1141561267e576031915050610d01565b8060ff1660f21415612694576032915050610d01565b8060ff1660f314156126aa576033915050610d01565b8060ff1660f414156126c0576034915050610d01565b8060ff1660f514156126d6576035915050610d01565b8060ff1660f614156126ec576036915050610d01565b8060ff1660f71415612702576037915050610d01565b8060ff1660f81415612718576038915050610d01565b8060ff1660f9141561272e576039915050610d01565b8060ff1660fa1415612744576061915050610d01565b8060ff1660fb141561275a576062915050610d01565b8060ff1660fc1415612770576063915050610d01565b8060ff1660fd1415612786576064915050610d01565b8060ff1660fe141561279c576065915050610d01565b8060ff1660ff14156127b2576066915050610d01565b50919050565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000009081161490565b60408051808201909152600081526060602082015290565b60008083601f840112612809578182fd5b50813567ffffffffffffffff811115612820578182fd5b602083019150836020808302850101111561283a57600080fd5b9250929050565b600082601f830112612851578081fd5b813567ffffffffffffffff81111561286557fe5b61289660207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601612e7e565b8181528460208386010111156128aa578283fd5b816020850160208301379081016020019190915292915050565b6000604082840312156128d5578081fd5b6040516040810167ffffffffffffffff82821081831117156128f357fe5b8160405282935084358352602085013591508082111561291257600080fd5b5061291f85828601612841565b6020830152505092915050565b60006020828403121561293d578081fd5b813561170d81612f3a565b6000806020838503121561295a578081fd5b823567ffffffffffffffff811115612970578182fd5b61297c858286016127f8565b90969095509350505050565b600060208284031215612999578081fd5b8151801515811461170d578182fd5b6000602082840312156129b9578081fd5b815161170d81612f3a565b6000602082840312156129d5578081fd5b5035919050565b6000602082840312156129ed578081fd5b813561170d81612f5c565b600060208284031215612a09578081fd5b815161170d81612f5c565b60008060408385031215612a26578182fd5b8235612a3181612f5c565b91506020830135612a4181612f3a565b809150509250929050565b600080600060408486031215612a60578081fd5b8335612a6b81612f5c565b9250602084013567ffffffffffffffff811115612a86578182fd5b612a92868287016127f8565b9497909650939450505050565b60008060408385031215612ab1578182fd5b8235612abc81612f5c565b946020939093013593505050565b600080600060608486031215612ade578283fd5b8335612ae981612f5c565b925060208401359150604084013567ffffffffffffffff811115612b0b578182fd5b612b1786828701612841565b9150509250925092565b60058110612b2b57fe5b60f81b9052565b60008482528360208301528251612b50816040850160208701612f0e565b91909101604001949350505050565b60008251612b71818460208701612f0e565b9190910192915050565b6000612b878284612b21565b50600101919050565b6000612b9c8286612b21565b5060e09290921b7fffffffff000000000000000000000000000000000000000000000000000000001660018301526005820152602501919050565b60f89190911b7fff0000000000000000000000000000000000000000000000000000000000000016815260010190565b73ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b90815260200190565b918252602082015260400190565b6020808252600f908201527f21676f7665726e6f72526f757465720000000000000000000000000000000000604082015260600190565b6020808252818101527f58417070436f6e6e656374696f6e4d616e616765722062616420646f6d61696e604082015260600190565b60208082526008908201527f217265706c696361000000000000000000000000000000000000000000000000604082015260600190565b6020808252600b908201527f63616c6c206661696c6564000000000000000000000000000000000000000000604082015260600190565b60208082526007908201527f21726f7574657200000000000000000000000000000000000000000000000000604082015260600190565b60208082526013908201527f2176616c6964206d657373616765207479706500000000000000000000000000604082015260600190565b6020808252601a908201527f43616c6c6572206973206e6f742074686520676f7665726e6f72000000000000604082015260600190565b63ffffffff91909116815260200190565b600063ffffffff85168252836020830152606060408301528251806060840152612e00816080850160208701612f0e565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01691909101608001949350505050565b63ffffffff92831681529116602082015260400190565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc1833603018112612b71578182fd5b60405181810167ffffffffffffffff81118282101715612e9a57fe5b604052919050565b600067ffffffffffffffff831115612eb657fe5b6020612ec58182860201612e7e565b8481528181019084845b87811015612ef657612ee436833589016128c4565b84529284019290840190600101612ecf565b50909695505050505050565b6000610f2736836128c4565b60005b83811015612f29578181015183820152602001612f11565b83811115610b795750506000910152565b73ffffffffffffffffffffffffffffffffffffffff81168114611bcb57600080fd5b63ffffffff81168114611bcb57600080fdfe2e20417474656d7074656420746f20696e646578206174206f6666736574203078496e697469616c697a61626c653a20636f6e747261637420697320616c726561647920696e697469616c697a656454797065644d656d566965772f696e646578202d20417474656d7074656420746f20696e646578206d6f7265207468616e20333220627974657354797065644d656d566965772f636f7079546f202d204e756c6c20706f696e74657220646572656654797065644d656d566965772f636f7079546f202d20496e76616c696420706f696e74657220646572656654797065644d656d566965772f696e646578202d204f76657272616e2074686520766965772e20536c696365206973206174203078a264697066735822122043414c0dee20343b11a46cc7ed8869c6ae7914bcf55001a2f577bbdb5fcdd27f64736f6c63430007060033"; + "0x60c06040523480156200001157600080fd5b506040516200395338038062003953833981016040819052620000349162000050565b60e09190911b6001600160e01b03191660805260a05262000087565b6000806040838503121562000063578182fd5b825163ffffffff8116811462000077578283fd5b6020939093015192949293505050565b60805160e01c60a051613891620000c2600039806104a45280610f6352508061081d528061088e5280610f875280611aa552506138916000f3fe608060405234801561001057600080fd5b50600436106101775760003560e01c806356d5d475116100d8578063db2021ae1161008c578063e6b3d94911610066578063e6b3d949146102a1578063e8c6f83a146102b4578063f05151df146102c757610177565b8063db2021ae1461027e578063de314b1914610291578063e54292981461029957610177565b806366cf8fab116100bd57806366cf8fab1461025b578063670a43c41461026e5780638d3638f41461027657610177565b806356d5d4751461024057806363706be31461025357610177565b806341bdc8b51161012f578063485cc95511610114578063485cc955146102055780634fedbbb5146102185780635585416c1461022b57610177565b806341bdc8b5146101df5780634626abee146101f257610177565b80632ead72f6116101605780632ead72f6146101af578063316c92b6146101cf5780633339df96146101d757610177565b80630c340a241461017c5780630ce219951461019a575b600080fd5b6101846102dc565b60405161019191906132fc565b60405180910390f35b6101ad6101a8366004613194565b6102f8565b005b6101c26101bd3660046130ec565b6103c2565b6040516101919190613328565b6101ad6103d4565b610184610522565b6101ad6101ed366004613004565b61053e565b6101ad610200366004613058565b610638565b6101ad610213366004613020565b610733565b6101ad610226366004613141565b6109c5565b610233610b8d565b604051610191919061359a565b6101ad61024e3660046131bf565b610bb1565b6101ad610e44565b6102336102693660046130d4565b610f27565b6101c2610f61565b610233610f85565b6101ad61028c366004613124565b610fa9565b610184611082565b6101c261109e565b6101ad6102af366004613004565b6110a4565b6101ad6102c2366004613194565b611183565b6102cf611234565b604051610191919061331d565b60035473ffffffffffffffffffffffffffffffffffffffff1681565b610300611234565b6103635760035473ffffffffffffffffffffffffffffffffffffffff16331461035e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161035590613376565b60405180910390fd5b6103b4565b60025473ffffffffffffffffffffffffffffffffffffffff1633146103b4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610355906134f5565b6103be8282611255565b5050565b60056020526000908152604090205481565b6103dc611234565b15610413576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161035590613450565b60025473ffffffffffffffffffffffffffffffffffffffff163314610464576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610355906134f5565b6001541561049e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161035590613487565b6104c8427f00000000000000000000000000000000000000000000000000000000000000006112e6565b600181905560025460405173ffffffffffffffffffffffffffffffffffffffff909116917f4c75781638d2c3a22c08e1295107f831b97683d017a1145733b743479a2ae225916105189190613328565b60405180910390a2565b60045473ffffffffffffffffffffffffffffffffffffffff1681565b610546611234565b6105a05760035473ffffffffffffffffffffffffffffffffffffffff16331461059b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161035590613376565b6105f1565b60025473ffffffffffffffffffffffffffffffffffffffff1633146105f1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610355906134f5565b600480547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b610640611234565b61069a5760035473ffffffffffffffffffffffffffffffffffffffff163314610695576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161035590613376565b6106eb565b60025473ffffffffffffffffffffffffffffffffffffffff1633146106eb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610355906134f5565b60005b8181101561072e5761072583838381811061070557fe5b90506020028101906107179190613627565b610720906136de565b611363565b506001016106ee565b505050565b600054610100900460ff168061074c575061074c611426565b8061075a575060005460ff16155b6107af576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602e81526020018061376c602e913960400191505060405180910390fd5b600054610100900460ff1615801561081557600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff909116610100171660011790555b3360016108437f00000000000000000000000000000000000000000000000000000000000000008383611437565b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff861617905561088c8561053e565b7f000000000000000000000000000000000000000000000000000000000000000063ffffffff16600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16638d3638f46040518163ffffffff1660e01b815260040160206040518083038186803b15801561091b57600080fd5b505afa15801561092f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109539190613108565b63ffffffff1614610990576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610355906133e4565b5050801561072e57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055505050565b60035473ffffffffffffffffffffffffffffffffffffffff163314610a16576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161035590613376565b610a1e611234565b15610a55576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161035590613450565b6000610a608461152e565b90506000610a76610a71848661367e565b611580565b9050600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16639fa92f9d6040518163ffffffff1660e01b815260040160206040518083038186803b158015610ae057600080fd5b505afa158015610af4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b1891906130b8565b73ffffffffffffffffffffffffffffffffffffffff1663d34686398684846040518463ffffffff1660e01b8152600401610b54939291906135ab565b600060405180830381600087803b158015610b6e57600080fd5b505af1158015610b82573d6000803e3d6000fd5b505050505050505050565b60035474010000000000000000000000000000000000000000900463ffffffff1681565b600480546040517f5190bc5300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911691635190bc5391610c06913391016132fc565b60206040518083038186803b158015610c1e57600080fd5b505afa158015610c32573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c569190613098565b610c8c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161035590613419565b8282610c988282611755565b610cce576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610355906133ad565b6000610cda84826117a2565b9050610d077fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000082166117c6565b15610d4457610d3f610d3a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000008316611821565b61186f565b610e3c565b610d6f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000008216611908565b15610da757610d3f610da27fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000008316611966565b611980565b610dd27fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000008216611a0b565b15610e0a57610d3f610e057fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000008316611a14565b611a2e565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161035590613563565b505050505050565b60025473ffffffffffffffffffffffffffffffffffffffff163314610e95576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610355906134f5565b600154610ece576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103559061333f565b60006001556002546040517f5397c02652a688dd1cac8544f233b3daaf96d7a9f974af80b70ab1538359e26191610f1d9173ffffffffffffffffffffffffffffffffffffffff909116906132fc565b60405180910390a1565b60068181548110610f3757600080fd5b9060005260206000209060089182820401919006600402915054906101000a900463ffffffff1681565b7f000000000000000000000000000000000000000000000000000000000000000081565b7f000000000000000000000000000000000000000000000000000000000000000081565b60035473ffffffffffffffffffffffffffffffffffffffff163314610ffa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161035590613376565b611002611234565b15611039576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161035590613450565b600061104483611aa3565b9050611051838383611437565b801561105d57506103be565b60006110718461106c85611ad2565b611aeb565b905061107c81611b18565b50505050565b60025473ffffffffffffffffffffffffffffffffffffffff1681565b60015481565b60025473ffffffffffffffffffffffffffffffffffffffff1633146110f5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610355906134f5565b60025460405173ffffffffffffffffffffffffffffffffffffffff8084169216907f3b3f758030fa296b85e15008f79cd22af8ffd2a7dd360d8963dcaf8e9fa2b5ff90600090a3600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60035473ffffffffffffffffffffffffffffffffffffffff1633146111d4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161035590613376565b6111dc611234565b15611213576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161035590613450565b61121d8282611255565b60006112298383611d10565b905061072e81611b18565b60015460009080158015904283111590829061124d5750805b935050505090565b63ffffffff8216600081815260056020526040908190205490519091907fe1cc453e5e6d48a5e3dd7dc6c72117211d2bea20fbb91fd980ebc3e7f73fe546906112a19084908690613331565b60405180910390a2816112bd576112b783611d38565b506103be565b806112cb576112cb83611ddf565b5063ffffffff91909116600090815260056020526040902055565b60008282018381101561135a57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b90505b92915050565b606060006113748360000151611e3f565b905060008173ffffffffffffffffffffffffffffffffffffffff1684602001516040516113a19190613254565b6000604051808303816000865af19150503d80600081146113de576040519150601f19603f3d011682016040523d82523d6000602084013e6113e3565b606091505b50935090508061141f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610355906134be565b5050919050565b600061143130611e42565b15905090565b80611447576114458361152e565b505b600081611455576000611457565b825b600380547fffffffffffffffff00000000ffffffffffffffffffffffffffffffffffffffff167401000000000000000000000000000000000000000063ffffffff8881168202929092177fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff858116918217948590556040519596509094908416937f4daaa39e87dee84708195369c30e97baa0665dc8562ac10535a0f3a9329943aa936115209390910416908990613610565b60405180910390a350505050565b63ffffffff81166000908152600560205260409020548061157b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103559061352c565b919050565b805160609060006002820167ffffffffffffffff811180156115a157600080fd5b506040519080825280602002602001820160405280156115cb578160200160208202803683370190505b509050611619600060016040516020016115e59190613270565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152919052906117a2565b8160008151811061162657fe5b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000090921660209283029190910182015260405161166c916000916115e5918691016132cc565b8160018151811061167957fe5b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000009092166020928302919091019091015260005b828110156117435760008582815181106116c357fe5b6020026020010151905060006116f66000836000015184602001515185602001516040516020016115e593929190613227565b90508084600285018151811061170857fe5b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000009092166020928302919091019091015250506001016116ad565b5061174d81611e48565b949350505050565b60035460009063ffffffff848116740100000000000000000000000000000000000000009092041614801561135a57505063ffffffff919091166000908152600560205260409020541490565b8151600090602084016117bd64ffffffffff85168284611e98565b95945050505050565b600060016117d383611ef9565b60ff1614801561135d5750604061180b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000008416611f29565b6bffffffffffffffffffffffff16101592915050565b600061182c826117c6565b156118675761186060015b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000841690611f3d565b905061157b565b61135d611f63565b8060016118a0815b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000841690611f87565b5060006118ce7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000008516612107565b905060005b8151811015611901576118f88282815181106118eb57fe5b6020026020010151611363565b506001016118d3565b5050505050565b600060025b60ff1661191983611ef9565b60ff1614801561135d575060256119517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000008416611f29565b6bffffffffffffffffffffffff161492915050565b600061197182611908565b15611867576118606002611837565b80600261198c81611877565b5060006119ba7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000085166122aa565b905060006119f16119ec7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000087166122db565b611e3f565b905060006119fe83611aa3565b9050610e3c838383611437565b6000600361190d565b6000611a1f82611a0b565b15611867576118606003611837565b806003611a3a81611877565b506000611a687fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000085166122aa565b90506000611a977fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000086166122db565b90506119018282611255565b7f000000000000000000000000000000000000000000000000000000000000000063ffffffff90811691161490565b73ffffffffffffffffffffffffffffffffffffffff1690565b606061135a611b13611b0e6000600287876040516020016115e593929190613285565b61230c565b612341565b6000600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16639fa92f9d6040518163ffffffff1660e01b815260040160206040518083038186803b158015611b8257600080fd5b505afa158015611b96573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bba91906130b8565b905060005b60065481101561072e57600063ffffffff1660068281548110611bde57fe5b6000918252602090912060088204015460079091166004026101000a900463ffffffff1614611d08578173ffffffffffffffffffffffffffffffffffffffff1663d346863960068381548110611c3057fe5b90600052602060002090600891828204019190066004029054906101000a900463ffffffff166005600060068681548110611c6757fe5b6000918252602080832060088304015463ffffffff6004600790941684026101000a909104168452830193909352604091820190205490517fffffffff0000000000000000000000000000000000000000000000000000000060e086901b168152611cd593928991016135ab565b600060405180830381600087803b158015611cef57600080fd5b505af1158015611d03573d6000803e3d6000fd5b505050505b600101611bbf565b606061135a611b13611d336000600387876040516020016115e593929190613285565b612385565b63ffffffff811660009081526005602052604081208190555b6006548110156103be578163ffffffff1660068281548110611d6f57fe5b6000918252602090912060088204015460079091166004026101000a900463ffffffff161415611dd45760068181548110611da657fe5b90600052602060002090600891828204019190066004026101000a81549063ffffffff021916905550611ddc565b600101611d51565b50565b600680546001810182556000919091527ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f6008820401805460079092166004026101000a63ffffffff818102199093169390921691909102919091179055565b90565b3b151590565b6040516060906000611e5d8460208401612393565b90506000611e6a82611f29565b6bffffffffffffffffffffffff1690506000611e858361240b565b9184525082016020016040525092915050565b600080611ea5848461241f565b9050604051811115611eb5575060005b80611ee3577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000915050611ef2565b611eee858585612491565b9150505b9392505050565b600061135d7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000083168260016124a4565b60181c6bffffffffffffffffffffffff1690565b60d81b7affffffffffffffffffffffffffffffffffffffffffffffffffffff9091161790565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000090565b6000611f9383836124c5565b612100576000611fb1611fa5856124e7565b64ffffffffff166124ed565b9150506000611fc68464ffffffffff166124ed565b604080517f5479706520617373657274696f6e206661696c65642e20476f742030780000006020808301919091527fffffffffffffffffffff0000000000000000000000000000000000000000000060b088811b8216603d8501527f2e20457870656374656420307800000000000000000000000000000000000000604785015285901b1660548301528251603e818403018152605e8301938490527f08c379a000000000000000000000000000000000000000000000000000000000909352606282018181528351608284015283519496509294508493839260a2019185019080838360005b838110156120c55781810151838201526020016120ad565b50505050905090810190601f1680156120f25780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5090919050565b606060006121397fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000084166001806124a4565b905060006121aa60028061216e7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000008816611f29565b6bffffffffffffffffffffffff160360017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000088169291906125c1565b905060008260ff1667ffffffffffffffff811180156121c857600080fd5b5060405190808252806020026020018201604052801561220257816020015b6121ef612eb8565b8152602001906001900390816121e75790505b50905060005b60006122357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000008516611f29565b6bffffffffffffffffffffffff1611156122a15761225283612651565b82828151811061225e57fe5b60209081029190910101515261227383612681565b82828151811061227f57fe5b602002602001015160200181905250612297836126c0565b9250600101612208565b50949350505050565b600061135d7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000008316600160046124a4565b600061135d7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000083166005602061274b565b600061135d61231a83611966565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000166128b9565b606060008061234f84611f29565b6bffffffffffffffffffffffff16905060405191508192506123748483602001612933565b508181016020016040529052919050565b600061135d61231a83611a14565b6000604051828111156123a65760206060fd5b506000805b84518110156123fe5760008582815181106123c257fe5b602002602001015190506123d881848701612933565b506123e281611f29565b6bffffffffffffffffffffffff169290920191506001016123ab565b5061174d60008483612491565b600061241682612a5f565b60200292915050565b8181018281101561135d57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f4f766572666c6f7720647572696e67206164646974696f6e2e00000000000000604482015290519081900360640190fd5b606092831b9190911790911b1760181b90565b60008160200360080260ff166124bb85858561274b565b901c949350505050565b60008164ffffffffff166124d8846124e7565b64ffffffffff16149392505050565b60d81c90565b600080601f5b600f8160ff1611156125555760ff600882021684901c61251281612a93565b61ffff16841793508160ff1660101461252d57601084901b93505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff016124f3565b50600f5b60ff8160ff1610156125bb5760ff600882021684901c61257881612a93565b61ffff16831792508160ff1660001461259357601083901b92505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01612559565b50915091565b6000806125cd86612ac3565b6bffffffffffffffffffffffff1690506125e686612ad7565b6125fa856125f4848961241f565b9061241f565b1115612629577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000091505061174d565b612633818661241f565b90506126478364ffffffffff168286611e98565b9695505050505050565b600061135d7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000831682602061274b565b606061135d611b13604061269485612b01565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000008616919060046125c1565b60008160016126ce81611877565b5060006126da85612b01565b60400190506117bd818061270f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000008916611f29565b6bffffffffffffffffffffffff160360017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000089169291906125c1565b600060ff821661275d57506000611ef2565b61276684611f29565b6bffffffffffffffffffffffff166127818460ff851661241f565b1115612823576127c261279385612ac3565b6bffffffffffffffffffffffff166127aa86611f29565b6bffffffffffffffffffffffff16858560ff16612b31565b6040517f08c379a00000000000000000000000000000000000000000000000000000000081526020600482018181528351602484015283519092839260449091019190850190808383600083156120c55781810151838201526020016120ad565b60208260ff161115612880576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603a81526020018061379a603a913960400191505060405180910390fd5b60088202600061288f86612ac3565b6bffffffffffffffffffffffff16905060006128aa83612c8c565b91909501511695945050505050565b60006128c482612cd5565b61292f57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f56616c696469747920617373657274696f6e206661696c656400000000000000604482015290519081900360640190fd5b5090565b600061293e83612d12565b612993576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260288152602001806137d46028913960400191505060405180910390fd5b61299c83612cd5565b6129f1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602b8152602001806137fc602b913960400191505060405180910390fd5b60006129fc84611f29565b6bffffffffffffffffffffffff1690506000612a1785612ac3565b6bffffffffffffffffffffffff1690506000604051905084811115612a3c5760206060fd5b8285848460045afa50612647612a51876124e7565b64ffffffffff168685612491565b60006020612a856020612a7185611f29565b6bffffffffffffffffffffffff169061241f565b81612a8c57fe5b0492915050565b6000612aa560048360ff16901c612d24565b60ff161760081b62ffff0016612aba82612d24565b60ff1617919050565b60781c6bffffffffffffffffffffffff1690565b6000612ae282611f29565b612aeb83612ac3565b016bffffffffffffffffffffffff169050919050565b600061135d7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000831660208061274b565b60606000612b3e866124ed565b9150506000612b4c866124ed565b9150506000612b5a866124ed565b9150506000612b68866124ed565b915050838383836040516020018080613827603591397fffffffffffff000000000000000000000000000000000000000000000000000060d087811b821660358401527f2077697468206c656e6774682030780000000000000000000000000000000000603b84015286901b16604a820152605001602161374b82397fffffffffffff000000000000000000000000000000000000000000000000000060d094851b811660218301527f2077697468206c656e677468203078000000000000000000000000000000000060278301529290931b9091166036830152507f2e00000000000000000000000000000000000000000000000000000000000000603c82015260408051601d818403018152603d90920190529b9a5050505050505050505050565b7f80000000000000000000000000000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9091011d90565b6000612ce0826124e7565b64ffffffffff1664ffffffffff1415612cfb5750600061157b565b6000612d0683612ad7565b60405110199392505050565b6000612d1d82612e90565b1592915050565b600060f08083179060ff82161415612d4057603091505061157b565b8060ff1660f11415612d5657603191505061157b565b8060ff1660f21415612d6c57603291505061157b565b8060ff1660f31415612d8257603391505061157b565b8060ff1660f41415612d9857603491505061157b565b8060ff1660f51415612dae57603591505061157b565b8060ff1660f61415612dc457603691505061157b565b8060ff1660f71415612dda57603791505061157b565b8060ff1660f81415612df057603891505061157b565b8060ff1660f91415612e0657603991505061157b565b8060ff1660fa1415612e1c57606191505061157b565b8060ff1660fb1415612e3257606291505061157b565b8060ff1660fc1415612e4857606391505061157b565b8060ff1660fd1415612e5e57606491505061157b565b8060ff1660fe1415612e7457606591505061157b565b8060ff1660ff1415612e8a57606691505061157b565b50919050565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000009081161490565b60408051808201909152600081526060602082015290565b60008083601f840112612ee1578182fd5b50813567ffffffffffffffff811115612ef8578182fd5b6020830191508360208083028501011115612f1257600080fd5b9250929050565b600082601f830112612f29578081fd5b813567ffffffffffffffff811115612f3d57fe5b612f6e60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8401160161365a565b818152846020838601011115612f82578283fd5b816020850160208301379081016020019190915292915050565b600060408284031215612fad578081fd5b6040516040810167ffffffffffffffff8282108183111715612fcb57fe5b81604052829350843583526020850135915080821115612fea57600080fd5b50612ff785828601612f19565b6020830152505092915050565b600060208284031215613015578081fd5b813561135a81613716565b60008060408385031215613032578081fd5b823561303d81613716565b9150602083013561304d81613716565b809150509250929050565b6000806020838503121561306a578182fd5b823567ffffffffffffffff811115613080578283fd5b61308c85828601612ed0565b90969095509350505050565b6000602082840312156130a9578081fd5b8151801515811461135a578182fd5b6000602082840312156130c9578081fd5b815161135a81613716565b6000602082840312156130e5578081fd5b5035919050565b6000602082840312156130fd578081fd5b813561135a81613738565b600060208284031215613119578081fd5b815161135a81613738565b60008060408385031215613136578182fd5b823561303d81613738565b600080600060408486031215613155578081fd5b833561316081613738565b9250602084013567ffffffffffffffff81111561317b578182fd5b61318786828701612ed0565b9497909650939450505050565b600080604083850312156131a6578182fd5b82356131b181613738565b946020939093013593505050565b6000806000606084860312156131d3578283fd5b83356131de81613738565b925060208401359150604084013567ffffffffffffffff811115613200578182fd5b61320c86828701612f19565b9150509250925092565b6005811061322057fe5b60f81b9052565b600084825283602083015282516132458160408501602087016136ea565b91909101604001949350505050565b600082516132668184602087016136ea565b9190910192915050565b600061327c8284613216565b50600101919050565b60006132918286613216565b5060e09290921b7fffffffff000000000000000000000000000000000000000000000000000000001660018301526005820152602501919050565b60f89190911b7fff0000000000000000000000000000000000000000000000000000000000000016815260010190565b73ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b901515815260200190565b90815260200190565b918252602082015260400190565b60208082526016908201527f7265636f76657279206e6f7420696e6974696174656400000000000000000000604082015260600190565b60208082526014908201527f212063616c6c656420627920676f7665726e6f72000000000000000000000000604082015260600190565b6020808252600f908201527f21676f7665726e6f72526f757465720000000000000000000000000000000000604082015260600190565b6020808252818101527f58417070436f6e6e656374696f6e4d616e616765722062616420646f6d61696e604082015260600190565b60208082526008908201527f217265706c696361000000000000000000000000000000000000000000000000604082015260600190565b6020808252600b908201527f696e207265636f76657279000000000000000000000000000000000000000000604082015260600190565b6020808252601a908201527f7265636f7665727920616c726561647920696e69746961746564000000000000604082015260600190565b6020808252600b908201527f63616c6c206661696c6564000000000000000000000000000000000000000000604082015260600190565b6020808252601c908201527f212063616c6c6564206279207265636f76657279206d616e6167657200000000604082015260600190565b60208082526007908201527f21726f7574657200000000000000000000000000000000000000000000000000604082015260600190565b60208082526013908201527f2176616c6964206d657373616765207479706500000000000000000000000000604082015260600190565b63ffffffff91909116815260200190565b600063ffffffff851682528360208301526060604083015282518060608401526135dc8160808501602087016136ea565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01691909101608001949350505050565b63ffffffff92831681529116602082015260400190565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc1833603018112613266578182fd5b60405181810167ffffffffffffffff8111828210171561367657fe5b604052919050565b600067ffffffffffffffff83111561369257fe5b60206136a1818286020161365a565b8481528181019084845b878110156136d2576136c03683358901612f9c565b845292840192908401906001016136ab565b50909695505050505050565b600061135d3683612f9c565b60005b838110156137055781810151838201526020016136ed565b8381111561107c5750506000910152565b73ffffffffffffffffffffffffffffffffffffffff81168114611ddc57600080fd5b63ffffffff81168114611ddc57600080fdfe2e20417474656d7074656420746f20696e646578206174206f6666736574203078496e697469616c697a61626c653a20636f6e747261637420697320616c726561647920696e697469616c697a656454797065644d656d566965772f696e646578202d20417474656d7074656420746f20696e646578206d6f7265207468616e20333220627974657354797065644d656d566965772f636f7079546f202d204e756c6c20706f696e74657220646572656654797065644d656d566965772f636f7079546f202d20496e76616c696420706f696e74657220646572656654797065644d656d566965772f696e646578202d204f76657272616e2074686520766965772e20536c696365206973206174203078a26469706673582212203a4e5acfc922bad6890cf88c4e929cd9e9a4e47d0e6333b09c5968cab76a318064736f6c63430007060033"; export class GovernanceRouter__factory extends ContractFactory { constructor(signer?: Signer) { @@ -344,18 +484,25 @@ export class GovernanceRouter__factory extends ContractFactory { deploy( _localDomain: BigNumberish, + _recoveryTimelock: BigNumberish, overrides?: Overrides & { from?: string | Promise } ): Promise { return super.deploy( _localDomain, + _recoveryTimelock, overrides || {} ) as Promise; } getDeployTransaction( _localDomain: BigNumberish, + _recoveryTimelock: BigNumberish, overrides?: Overrides & { from?: string | Promise } ): TransactionRequest { - return super.getDeployTransaction(_localDomain, overrides || {}); + return super.getDeployTransaction( + _localDomain, + _recoveryTimelock, + overrides || {} + ); } attach(address: string): GovernanceRouter { return super.attach(address) as GovernanceRouter; diff --git a/typescript/src/typechain/optics-core/factories/TestGovernanceRouter__factory.ts b/typescript/src/typechain/optics-core/factories/TestGovernanceRouter__factory.ts index 6f0d8defe..a893b2f8d 100644 --- a/typescript/src/typechain/optics-core/factories/TestGovernanceRouter__factory.ts +++ b/typescript/src/typechain/optics-core/factories/TestGovernanceRouter__factory.ts @@ -24,10 +24,47 @@ const _abi = [ name: "_localDomain", type: "uint32", }, + { + internalType: "uint256", + name: "_recoveryTimelock", + type: "uint256", + }, ], stateMutability: "nonpayable", type: "constructor", }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: "address", + name: "recoveryManager", + type: "address", + }, + ], + name: "ExitRecovery", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "address", + name: "recoveryManager", + type: "address", + }, + { + indexed: false, + internalType: "uint256", + name: "endBlock", + type: "uint256", + }, + ], + name: "InitiateRecovery", + type: "event", + }, { anonymous: false, inputs: [ @@ -84,6 +121,25 @@ const _abi = [ name: "TransferGovernor", type: "event", }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "address", + name: "previousRecoveryManager", + type: "address", + }, + { + indexed: true, + internalType: "address", + name: "newRecoveryManager", + type: "address", + }, + ], + name: "TransferRecoveryManager", + type: "event", + }, { inputs: [ { @@ -177,6 +233,13 @@ const _abi = [ stateMutability: "view", type: "function", }, + { + inputs: [], + name: "exitRecovery", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, { inputs: [], name: "governor", @@ -226,6 +289,19 @@ const _abi = [ stateMutability: "nonpayable", type: "function", }, + { + inputs: [], + name: "inRecovery", + outputs: [ + { + internalType: "bool", + name: "", + type: "bool", + }, + ], + stateMutability: "view", + type: "function", + }, { inputs: [ { @@ -233,12 +309,24 @@ const _abi = [ name: "_xAppConnectionManager", type: "address", }, + { + internalType: "address", + name: "_recoveryManager", + type: "address", + }, ], name: "initialize", outputs: [], stateMutability: "nonpayable", type: "function", }, + { + inputs: [], + name: "initiateRecoveryTimelock", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, { inputs: [], name: "localDomain", @@ -252,6 +340,45 @@ const _abi = [ stateMutability: "view", type: "function", }, + { + inputs: [], + name: "recoveryActiveAt", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "recoveryManager", + outputs: [ + { + internalType: "address", + name: "", + type: "address", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "recoveryTimelock", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + stateMutability: "view", + type: "function", + }, { inputs: [ { @@ -320,7 +447,7 @@ const _abi = [ type: "bytes32", }, ], - name: "setRouterDuringSetup", + name: "setRouterLocal", outputs: [], stateMutability: "nonpayable", type: "function", @@ -374,6 +501,19 @@ const _abi = [ stateMutability: "nonpayable", type: "function", }, + { + inputs: [ + { + internalType: "address", + name: "_newRecoveryManager", + type: "address", + }, + ], + name: "transferRecoveryManager", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, { inputs: [], name: "xAppConnectionManager", @@ -390,7 +530,7 @@ const _abi = [ ]; const _bytecode = - "0x60a06040523480156200001157600080fd5b50604051620032513803806200325183398101604081905262000034916200004a565b60e01b6001600160e01b03191660805262000077565b6000602082840312156200005c578081fd5b815163ffffffff8116811462000070578182fd5b9392505050565b60805160e01c6131ad620000a4600039806109735280610a915280610ac252806116f852506131ad6000f3fe608060405234801561001057600080fd5b506004361061011b5760003560e01c806356f7e298116100b25780638d3638f411610081578063c4d66de811610066578063c4d66de81461023d578063db2021ae14610250578063e8c6f83a146102635761011b565b80638d3638f414610222578063c3ef21341461022a5761011b565b806356f7e298146101c957806366cf8fab146101e957806368b967dc146101fc5780637d8dfc331461020f5761011b565b80634626abee116100ee5780634626abee1461017b5780634fedbbb51461018e5780635585416c146101a157806356d5d475146101b65761011b565b80630c340a24146101205780632ead72f61461013e5780633339df961461015e57806341bdc8b514610166575b600080fd5b610128610276565b6040516101359190612cf4565b60405180910390f35b61015161014c366004612ac9565b610292565b6040516101359190612d20565b6101286102a4565b610179610174366004612a19565b6102c6565b005b610179610189366004612a35565b61036d565b61017961019c366004612b39565b610406565b6101a961058f565b6040516101359190612eb6565b6101796101c4366004612bb7565b6105b5565b6101dc6101d7366004612ac9565b61084e565b6040516101359190612d15565b6101a96101f7366004612ab1565b6108b7565b61017961020a366004612b8c565b6108f1565b61017961021d366004612b8c565b610912565b6101a9610971565b610179610238366004612b01565b610995565b61017961024b366004612a19565b6109a7565b61017961025e366004612b01565b610bf8565b610179610271366004612b8c565b610c92565b60015473ffffffffffffffffffffffffffffffffffffffff1681565b60026020526000908152604090205481565b60005462010000900473ffffffffffffffffffffffffffffffffffffffff1681565b60015473ffffffffffffffffffffffffffffffffffffffff163314610320576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161031790612e7f565b60405180910390fd5b6000805473ffffffffffffffffffffffffffffffffffffffff90921662010000027fffffffffffffffffffff0000000000000000000000000000000000000000ffff909216919091179055565b60015473ffffffffffffffffffffffffffffffffffffffff1633146103be576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161031790612e7f565b60005b81811015610401576103f88383838181106103d857fe5b90506020028101906103ea9190612f43565b6103f390612ffa565b610ce3565b506001016103c1565b505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610457576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161031790612e7f565b600061046284610da6565b905060006104786104738486612f9a565b610df3565b9050600060029054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16639fa92f9d6040518163ffffffff1660e01b815260040160206040518083038186803b1580156104e257600080fd5b505afa1580156104f6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061051a9190612a95565b73ffffffffffffffffffffffffffffffffffffffff1663d34686398684846040518463ffffffff1660e01b815260040161055693929190612ec7565b600060405180830381600087803b15801561057057600080fd5b505af1158015610584573d6000803e3d6000fd5b505050505050505050565b600054760100000000000000000000000000000000000000000000900463ffffffff1681565b6000546040517f5190bc530000000000000000000000000000000000000000000000000000000081526201000090910473ffffffffffffffffffffffffffffffffffffffff1690635190bc5390610610903390600401612cf4565b60206040518083038186803b15801561062857600080fd5b505afa15801561063c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106609190612a75565b610696576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161031790612da3565b82826106a28282610fc8565b6106d8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161031790612d37565b60006106e4848261101a565b90506107117fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000821661103e565b1561074e576107496107447fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000008316611099565b6110e7565b610846565b6107797fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000008216611180565b156107b1576107496107ac7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000083166111de565b6111f8565b6107dc7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000008216611283565b156108145761074961080f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000831661128c565b6112a6565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161031790612e48565b505050505050565b6000805b6003548110156108ac578263ffffffff166003828154811061087057fe5b6000918252602090912060088204015460079091166004026101000a900463ffffffff1614156108a45760019150506108b2565b600101610852565b50600090505b919050565b600381815481106108c757600080fd5b9060005260206000209060089182820401919006600402915054906101000a900463ffffffff1681565b6108fb8282611317565b600061090783836113a8565b9050610401816113d5565b60015473ffffffffffffffffffffffffffffffffffffffff163314610963576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161031790612e7f565b61096d8282611317565b5050565b7f000000000000000000000000000000000000000000000000000000000000000081565b61096d826109a2836115cc565b611317565b600054610100900460ff16806109c057506109c06115e5565b806109ce575060005460ff16155b610a23576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602e815260200180613088602e913960400191505060405180910390fd5b600054610100900460ff16158015610a8957600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff909116610100171660011790555b336001610ab77f000000000000000000000000000000000000000000000000000000000000000083836115f6565b610ac0846102c6565b7f000000000000000000000000000000000000000000000000000000000000000063ffffffff16600060029054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16638d3638f46040518163ffffffff1660e01b815260040160206040518083038186803b158015610b4f57600080fd5b505afa158015610b63573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b879190612ae5565b63ffffffff1614610bc4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161031790612d6e565b5050801561096d57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1690555050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610c49576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161031790612e7f565b6000610c54836116f6565b9050610c618383836115f6565b8015610c6d575061096d565b6000610c8184610c7c856115cc565b611725565b9050610c8c816113d5565b50505050565b60015473ffffffffffffffffffffffffffffffffffffffff1633146108f1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161031790612e7f565b60606000610cf4836000015161174d565b905060008173ffffffffffffffffffffffffffffffffffffffff168460200151604051610d219190612c4c565b6000604051808303816000865af19150503d8060008114610d5e576040519150601f19603f3d011682016040523d82523d6000602084013e610d63565b606091505b509350905080610d9f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161031790612dda565b5050919050565b63ffffffff8116600090815260026020526040902054806108b2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161031790612e11565b805160609060006002820167ffffffffffffffff81118015610e1457600080fd5b50604051908082528060200260200182016040528015610e3e578160200160208202803683370190505b509050610e8c60006001604051602001610e589190612c68565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190529061101a565b81600081518110610e9957fe5b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000909216602092830291909101820152604051610edf91600091610e5891869101612cc4565b81600181518110610eec57fe5b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000009092166020928302919091019091015260005b82811015610fb6576000858281518110610f3657fe5b602002602001015190506000610f69600083600001518460200151518560200151604051602001610e5893929190612c1f565b905080846002850181518110610f7b57fe5b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000909216602092830291909101909101525050600101610f20565b50610fc081611750565b949350505050565b6000805463ffffffff84811676010000000000000000000000000000000000000000000090920416148015611011575063ffffffff831660009081526002602052604090205482145b90505b92915050565b81516000906020840161103564ffffffffff851682846117a0565b95945050505050565b6000600161104b83611801565b60ff16148015611014575060406110837fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000008416611831565b6bffffffffffffffffffffffff16101592915050565b60006110a48261103e565b156110df576110d860015b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000841690611845565b90506108b2565b61101461186b565b806001611118815b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000084169061188f565b5060006111467fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000008516611a0f565b905060005b81518110156111795761117082828151811061116357fe5b6020026020010151610ce3565b5060010161114b565b5050505050565b600060025b60ff1661119183611801565b60ff16148015611014575060256111c97fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000008416611831565b6bffffffffffffffffffffffff161492915050565b60006111e982611180565b156110df576110d860026110af565b806002611204816110ef565b5060006112327fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000008516611bb2565b905060006112696112647fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000008716611be3565b61174d565b90506000611276836116f6565b90506108468383836115f6565b60006003611185565b600061129782611283565b156110df576110d860036110af565b8060036112b2816110ef565b5060006112e07fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000008516611bb2565b9050600061130f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000008616611be3565b905061117982825b63ffffffff8216600081815260026020526040908190205490519091907fe1cc453e5e6d48a5e3dd7dc6c72117211d2bea20fbb91fd980ebc3e7f73fe546906113639084908690612d29565b60405180910390a28161137f5761137983611c14565b5061096d565b8061138d5761138d83611cbb565b5063ffffffff91909116600090815260026020526040902055565b60606110116113d06113cb600060038787604051602001610e5893929190612c7d565b611d1b565b611d50565b60008060029054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16639fa92f9d6040518163ffffffff1660e01b815260040160206040518083038186803b15801561143e57600080fd5b505afa158015611452573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114769190612a95565b905060005b60035481101561040157600063ffffffff166003828154811061149a57fe5b6000918252602090912060088204015460079091166004026101000a900463ffffffff16146115c4578173ffffffffffffffffffffffffffffffffffffffff1663d3468639600383815481106114ec57fe5b90600052602060002090600891828204019190066004029054906101000a900463ffffffff16600260006003868154811061152357fe5b6000918252602080832060088304015463ffffffff6004600790941684026101000a909104168452830193909352604091820190205490517fffffffff0000000000000000000000000000000000000000000000000000000060e086901b1681526115919392899101612ec7565b600060405180830381600087803b1580156115ab57600080fd5b505af11580156115bf573d6000803e3d6000fd5b505050505b60010161147b565b73ffffffffffffffffffffffffffffffffffffffff1690565b60006115f030611d94565b15905090565b806116065761160483610da6565b505b600081611614576000611616565b825b600080547fffffffffffff00000000ffffffffffffffffffffffffffffffffffffffffffff1676010000000000000000000000000000000000000000000063ffffffff88811682029290921792839055600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8681169182179283905560405196975090959116937f4daaa39e87dee84708195369c30e97baa0665dc8562ac10535a0f3a9329943aa936116e89390910416908990612f2c565b60405180910390a350505050565b7f000000000000000000000000000000000000000000000000000000000000000063ffffffff90811691161490565b60606110116113d0611748600060028787604051602001610e5893929190612c7d565b611d9a565b90565b60405160609060006117658460208401611da8565b9050600061177282611831565b6bffffffffffffffffffffffff169050600061178d83611e20565b9184525082016020016040525092915050565b6000806117ad8484611e34565b90506040518111156117bd575060005b806117eb577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000009150506117fa565b6117f6858585611ea6565b9150505b9392505050565b60006110147fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000008316826001611eb9565b60181c6bffffffffffffffffffffffff1690565b60d81b7affffffffffffffffffffffffffffffffffffffffffffffffffffff9091161790565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000090565b600061189b8383611eda565b611a085760006118b96118ad85611efc565b64ffffffffff16611f02565b91505060006118ce8464ffffffffff16611f02565b604080517f5479706520617373657274696f6e206661696c65642e20476f742030780000006020808301919091527fffffffffffffffffffff0000000000000000000000000000000000000000000060b088811b8216603d8501527f2e20457870656374656420307800000000000000000000000000000000000000604785015285901b1660548301528251603e818403018152605e8301938490527f08c379a000000000000000000000000000000000000000000000000000000000909352606282018181528351608284015283519496509294508493839260a2019185019080838360005b838110156119cd5781810151838201526020016119b5565b50505050905090810190601f1680156119fa5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5090919050565b60606000611a417fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000008416600180611eb9565b90506000611ab2600280611a767fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000008816611831565b6bffffffffffffffffffffffff160360017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000008816929190611fd6565b905060008260ff1667ffffffffffffffff81118015611ad057600080fd5b50604051908082528060200260200182016040528015611b0a57816020015b611af76128cd565b815260200190600190039081611aef5790505b50905060005b6000611b3d7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000008516611831565b6bffffffffffffffffffffffff161115611ba957611b5a83612066565b828281518110611b6657fe5b602090810291909101015152611b7b83612096565b828281518110611b8757fe5b602002602001015160200181905250611b9f836120d5565b9250600101611b10565b50949350505050565b60006110147fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000831660016004611eb9565b60006110147fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000831660056020612160565b63ffffffff811660009081526002602052604081208190555b60035481101561096d578163ffffffff1660038281548110611c4b57fe5b6000918252602090912060088204015460079091166004026101000a900463ffffffff161415611cb05760038181548110611c8257fe5b90600052602060002090600891828204019190066004026101000a81549063ffffffff021916905550611cb8565b600101611c2d565b50565b600380546001810182556000919091527fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b6008820401805460079092166004026101000a63ffffffff818102199093169390921691909102919091179055565b6000611014611d298361128c565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000166122ce565b6060600080611d5e84611831565b6bffffffffffffffffffffffff1690506040519150819250611d838483602001612348565b508181016020016040529052919050565b3b151590565b6000611014611d29836111de565b600060405182811115611dbb5760206060fd5b506000805b8451811015611e13576000858281518110611dd757fe5b60200260200101519050611ded81848701612348565b50611df781611831565b6bffffffffffffffffffffffff16929092019150600101611dc0565b50610fc060008483611ea6565b6000611e2b82612474565b60200292915050565b8181018281101561101457604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f4f766572666c6f7720647572696e67206164646974696f6e2e00000000000000604482015290519081900360640190fd5b606092831b9190911790911b1760181b90565b60008160200360080260ff16611ed0858585612160565b901c949350505050565b60008164ffffffffff16611eed84611efc565b64ffffffffff16149392505050565b60d81c90565b600080601f5b600f8160ff161115611f6a5760ff600882021684901c611f27816124a8565b61ffff16841793508160ff16601014611f4257601084901b93505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01611f08565b50600f5b60ff8160ff161015611fd05760ff600882021684901c611f8d816124a8565b61ffff16831792508160ff16600014611fa857601083901b92505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01611f6e565b50915091565b600080611fe2866124d8565b6bffffffffffffffffffffffff169050611ffb866124ec565b61200f856120098489611e34565b90611e34565b111561203e577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000915050610fc0565b6120488186611e34565b905061205c8364ffffffffff1682866117a0565b9695505050505050565b60006110147fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000008316826020612160565b60606110146113d060406120a985612516565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000861691906004611fd6565b60008160016120e3816110ef565b5060006120ef85612516565b604001905061103581806121247fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000008916611831565b6bffffffffffffffffffffffff160360017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000008916929190611fd6565b600060ff8216612172575060006117fa565b61217b84611831565b6bffffffffffffffffffffffff166121968460ff8516611e34565b1115612238576121d76121a8856124d8565b6bffffffffffffffffffffffff166121bf86611831565b6bffffffffffffffffffffffff16858560ff16612546565b6040517f08c379a00000000000000000000000000000000000000000000000000000000081526020600482018181528351602484015283519092839260449091019190850190808383600083156119cd5781810151838201526020016119b5565b60208260ff161115612295576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603a8152602001806130b6603a913960400191505060405180910390fd5b6008820260006122a4866124d8565b6bffffffffffffffffffffffff16905060006122bf836126a1565b91909501511695945050505050565b60006122d9826126ea565b61234457604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f56616c696469747920617373657274696f6e206661696c656400000000000000604482015290519081900360640190fd5b5090565b600061235383612727565b6123a8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260288152602001806130f06028913960400191505060405180910390fd5b6123b1836126ea565b612406576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602b815260200180613118602b913960400191505060405180910390fd5b600061241184611831565b6bffffffffffffffffffffffff169050600061242c856124d8565b6bffffffffffffffffffffffff16905060006040519050848111156124515760206060fd5b8285848460045afa5061205c61246687611efc565b64ffffffffff168685611ea6565b6000602061249a602061248685611831565b6bffffffffffffffffffffffff1690611e34565b816124a157fe5b0492915050565b60006124ba60048360ff16901c612739565b60ff161760081b62ffff00166124cf82612739565b60ff1617919050565b60781c6bffffffffffffffffffffffff1690565b60006124f782611831565b612500836124d8565b016bffffffffffffffffffffffff169050919050565b60006110147fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000008316602080612160565b6060600061255386611f02565b915050600061256186611f02565b915050600061256f86611f02565b915050600061257d86611f02565b915050838383836040516020018080613143603591397fffffffffffff000000000000000000000000000000000000000000000000000060d087811b821660358401527f2077697468206c656e6774682030780000000000000000000000000000000000603b84015286901b16604a820152605001602161306782397fffffffffffff000000000000000000000000000000000000000000000000000060d094851b811660218301527f2077697468206c656e677468203078000000000000000000000000000000000060278301529290931b9091166036830152507f2e00000000000000000000000000000000000000000000000000000000000000603c82015260408051601d818403018152603d90920190529b9a5050505050505050505050565b7f80000000000000000000000000000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9091011d90565b60006126f582611efc565b64ffffffffff1664ffffffffff1415612710575060006108b2565b600061271b836124ec565b60405110199392505050565b6000612732826128a5565b1592915050565b600060f08083179060ff821614156127555760309150506108b2565b8060ff1660f1141561276b5760319150506108b2565b8060ff1660f214156127815760329150506108b2565b8060ff1660f314156127975760339150506108b2565b8060ff1660f414156127ad5760349150506108b2565b8060ff1660f514156127c35760359150506108b2565b8060ff1660f614156127d95760369150506108b2565b8060ff1660f714156127ef5760379150506108b2565b8060ff1660f814156128055760389150506108b2565b8060ff1660f9141561281b5760399150506108b2565b8060ff1660fa14156128315760619150506108b2565b8060ff1660fb14156128475760629150506108b2565b8060ff1660fc141561285d5760639150506108b2565b8060ff1660fd14156128735760649150506108b2565b8060ff1660fe14156128895760659150506108b2565b8060ff1660ff141561289f5760669150506108b2565b50919050565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000009081161490565b60408051808201909152600081526060602082015290565b60008083601f8401126128f6578182fd5b50813567ffffffffffffffff81111561290d578182fd5b602083019150836020808302850101111561292757600080fd5b9250929050565b600082601f83011261293e578081fd5b813567ffffffffffffffff81111561295257fe5b61298360207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601612f76565b818152846020838601011115612997578283fd5b816020850160208301379081016020019190915292915050565b6000604082840312156129c2578081fd5b6040516040810167ffffffffffffffff82821081831117156129e057fe5b816040528293508435835260208501359150808211156129ff57600080fd5b50612a0c8582860161292e565b6020830152505092915050565b600060208284031215612a2a578081fd5b81356117fa81613032565b60008060208385031215612a47578081fd5b823567ffffffffffffffff811115612a5d578182fd5b612a69858286016128e5565b90969095509350505050565b600060208284031215612a86578081fd5b815180151581146117fa578182fd5b600060208284031215612aa6578081fd5b81516117fa81613032565b600060208284031215612ac2578081fd5b5035919050565b600060208284031215612ada578081fd5b81356117fa81613054565b600060208284031215612af6578081fd5b81516117fa81613054565b60008060408385031215612b13578182fd5b8235612b1e81613054565b91506020830135612b2e81613032565b809150509250929050565b600080600060408486031215612b4d578081fd5b8335612b5881613054565b9250602084013567ffffffffffffffff811115612b73578182fd5b612b7f868287016128e5565b9497909650939450505050565b60008060408385031215612b9e578182fd5b8235612ba981613054565b946020939093013593505050565b600080600060608486031215612bcb578283fd5b8335612bd681613054565b925060208401359150604084013567ffffffffffffffff811115612bf8578182fd5b612c048682870161292e565b9150509250925092565b60058110612c1857fe5b60f81b9052565b60008482528360208301528251612c3d816040850160208701613006565b91909101604001949350505050565b60008251612c5e818460208701613006565b9190910192915050565b6000612c748284612c0e565b50600101919050565b6000612c898286612c0e565b5060e09290921b7fffffffff000000000000000000000000000000000000000000000000000000001660018301526005820152602501919050565b60f89190911b7fff0000000000000000000000000000000000000000000000000000000000000016815260010190565b73ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b901515815260200190565b90815260200190565b918252602082015260400190565b6020808252600f908201527f21676f7665726e6f72526f757465720000000000000000000000000000000000604082015260600190565b6020808252818101527f58417070436f6e6e656374696f6e4d616e616765722062616420646f6d61696e604082015260600190565b60208082526008908201527f217265706c696361000000000000000000000000000000000000000000000000604082015260600190565b6020808252600b908201527f63616c6c206661696c6564000000000000000000000000000000000000000000604082015260600190565b60208082526007908201527f21726f7574657200000000000000000000000000000000000000000000000000604082015260600190565b60208082526013908201527f2176616c6964206d657373616765207479706500000000000000000000000000604082015260600190565b6020808252601a908201527f43616c6c6572206973206e6f742074686520676f7665726e6f72000000000000604082015260600190565b63ffffffff91909116815260200190565b600063ffffffff85168252836020830152606060408301528251806060840152612ef8816080850160208701613006565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01691909101608001949350505050565b63ffffffff92831681529116602082015260400190565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc1833603018112612c5e578182fd5b60405181810167ffffffffffffffff81118282101715612f9257fe5b604052919050565b600067ffffffffffffffff831115612fae57fe5b6020612fbd8182860201612f76565b8481528181019084845b87811015612fee57612fdc36833589016129b1565b84529284019290840190600101612fc7565b50909695505050505050565b600061101436836129b1565b60005b83811015613021578181015183820152602001613009565b83811115610c8c5750506000910152565b73ffffffffffffffffffffffffffffffffffffffff81168114611cb857600080fd5b63ffffffff81168114611cb857600080fdfe2e20417474656d7074656420746f20696e646578206174206f6666736574203078496e697469616c697a61626c653a20636f6e747261637420697320616c726561647920696e697469616c697a656454797065644d656d566965772f696e646578202d20417474656d7074656420746f20696e646578206d6f7265207468616e20333220627974657354797065644d656d566965772f636f7079546f202d204e756c6c20706f696e74657220646572656654797065644d656d566965772f636f7079546f202d20496e76616c696420706f696e74657220646572656654797065644d656d566965772f696e646578202d204f76657272616e2074686520766965772e20536c696365206973206174203078a2646970667358221220f1c5e8b04831ce1615d5c841de3bfb0e991c1655f3c3ad937c6150a5e5dfe7ef64736f6c63430007060033"; + "0x60c06040523480156200001157600080fd5b5060405162003a2338038062003a23833981016040819052620000349162000050565b5060e01b6001600160e01b031916608052603260a05262000087565b6000806040838503121562000063578182fd5b825163ffffffff8116811462000077578283fd5b6020939093015192949293505050565b60805160e01c60a051613961620000c2600039806104fe528061102652508061087752806108e8528061106b5280611db352506139616000f3fe608060405234801561001057600080fd5b50600436106101985760003560e01c806363706be3116100e3578063db2021ae1161008c578063e6b3d94911610066578063e6b3d94914610308578063e8c6f83a1461031b578063f05151df1461032e57610198565b8063db2021ae146102e5578063de314b19146102f8578063e54292981461030057610198565b806368b967dc116100bd57806368b967dc146102b75780638d3638f4146102ca578063c3ef2134146102d257610198565b806363706be31461029457806366cf8fab1461029c578063670a43c4146102af57610198565b80634626abee116101455780635585416c1161011f5780635585416c1461024c57806356d5d4751461026157806356f7e2981461027457610198565b80634626abee14610213578063485cc955146102265780634fedbbb51461023957610198565b8063316c92b611610176578063316c92b6146101f05780633339df96146101f857806341bdc8b51461020057610198565b80630c340a241461019d5780630ce21995146101bb5780632ead72f6146101d0575b600080fd5b6101a5610336565b6040516101b291906133cc565b60405180910390f35b6101ce6101c9366004613264565b610352565b005b6101e36101de3660046131bc565b61041c565b6040516101b291906133f8565b6101ce61042e565b6101a561057c565b6101ce61020e3660046130d4565b610598565b6101ce610221366004613128565b610692565b6101ce6102343660046130f0565b61078d565b6101ce610247366004613211565b610a1f565b610254610be7565b6040516101b2919061366a565b6101ce61026f36600461328f565b610c0b565b6102876102823660046131bc565b610e9e565b6040516101b291906133ed565b6101ce610f07565b6102546102aa3660046131a4565b610fea565b6101e3611024565b6101ce6102c5366004613264565b611048565b610254611069565b6101ce6102e03660046131f4565b61108d565b6101ce6102f33660046131f4565b61109f565b6101a5611178565b6101e3611194565b6101ce6103163660046130d4565b61119a565b6101ce610329366004613264565b611279565b610287611309565b60035473ffffffffffffffffffffffffffffffffffffffff1681565b61035a611309565b6103bd5760035473ffffffffffffffffffffffffffffffffffffffff1633146103b8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103af90613446565b60405180910390fd5b61040e565b60025473ffffffffffffffffffffffffffffffffffffffff16331461040e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103af906135c5565b610418828261132a565b5050565b60056020526000908152604090205481565b610436611309565b1561046d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103af90613520565b60025473ffffffffffffffffffffffffffffffffffffffff1633146104be576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103af906135c5565b600154156104f8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103af90613557565b610522427f00000000000000000000000000000000000000000000000000000000000000006113bb565b600181905560025460405173ffffffffffffffffffffffffffffffffffffffff909116917f4c75781638d2c3a22c08e1295107f831b97683d017a1145733b743479a2ae2259161057291906133f8565b60405180910390a2565b60045473ffffffffffffffffffffffffffffffffffffffff1681565b6105a0611309565b6105fa5760035473ffffffffffffffffffffffffffffffffffffffff1633146105f5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103af90613446565b61064b565b60025473ffffffffffffffffffffffffffffffffffffffff16331461064b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103af906135c5565b600480547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b61069a611309565b6106f45760035473ffffffffffffffffffffffffffffffffffffffff1633146106ef576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103af90613446565b610745565b60025473ffffffffffffffffffffffffffffffffffffffff163314610745576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103af906135c5565b60005b818110156107885761077f83838381811061075f57fe5b905060200281019061077191906136f7565b61077a906137ae565b611438565b50600101610748565b505050565b600054610100900460ff16806107a657506107a66114fb565b806107b4575060005460ff16155b610809576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602e81526020018061383c602e913960400191505060405180910390fd5b600054610100900460ff1615801561086f57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff909116610100171660011790555b33600161089d7f0000000000000000000000000000000000000000000000000000000000000000838361150c565b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff86161790556108e685610598565b7f000000000000000000000000000000000000000000000000000000000000000063ffffffff16600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16638d3638f46040518163ffffffff1660e01b815260040160206040518083038186803b15801561097557600080fd5b505afa158015610989573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109ad91906131d8565b63ffffffff16146109ea576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103af906134b4565b5050801561078857600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055505050565b60035473ffffffffffffffffffffffffffffffffffffffff163314610a70576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103af90613446565b610a78611309565b15610aaf576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103af90613520565b6000610aba84611603565b90506000610ad0610acb848661374e565b611650565b9050600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16639fa92f9d6040518163ffffffff1660e01b815260040160206040518083038186803b158015610b3a57600080fd5b505afa158015610b4e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b729190613188565b73ffffffffffffffffffffffffffffffffffffffff1663d34686398684846040518463ffffffff1660e01b8152600401610bae9392919061367b565b600060405180830381600087803b158015610bc857600080fd5b505af1158015610bdc573d6000803e3d6000fd5b505050505050505050565b60035474010000000000000000000000000000000000000000900463ffffffff1681565b600480546040517f5190bc5300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911691635190bc5391610c60913391016133cc565b60206040518083038186803b158015610c7857600080fd5b505afa158015610c8c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cb09190613168565b610ce6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103af906134e9565b8282610cf28282611825565b610d28576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103af9061347d565b6000610d348482611872565b9050610d617fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000008216611896565b15610d9e57610d99610d947fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000083166118f1565b61193f565b610e96565b610dc97fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000082166119d8565b15610e0157610d99610dfc7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000008316611a36565b611a50565b610e2c7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000008216611adb565b15610e6457610d99610e5f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000008316611ae4565b611afe565b6040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103af90613633565b505050505050565b6000805b600654811015610efc578263ffffffff1660068281548110610ec057fe5b6000918252602090912060088204015460079091166004026101000a900463ffffffff161415610ef4576001915050610f02565b600101610ea2565b50600090505b919050565b60025473ffffffffffffffffffffffffffffffffffffffff163314610f58576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103af906135c5565b600154610f91576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103af9061340f565b60006001556002546040517f5397c02652a688dd1cac8544f233b3daaf96d7a9f974af80b70ab1538359e26191610fe09173ffffffffffffffffffffffffffffffffffffffff909116906133cc565b60405180910390a1565b60068181548110610ffa57600080fd5b9060005260206000209060089182820401919006600402915054906101000a900463ffffffff1681565b7f000000000000000000000000000000000000000000000000000000000000000081565b611052828261132a565b600061105e8383611b73565b905061078881611ba0565b7f000000000000000000000000000000000000000000000000000000000000000081565b6104188261109a83611d98565b61132a565b60035473ffffffffffffffffffffffffffffffffffffffff1633146110f0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103af90613446565b6110f8611309565b1561112f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103af90613520565b600061113a83611db1565b905061114783838361150c565b80156111535750610418565b60006111678461116285611d98565b611de0565b905061117281611ba0565b50505050565b60025473ffffffffffffffffffffffffffffffffffffffff1681565b60015481565b60025473ffffffffffffffffffffffffffffffffffffffff1633146111eb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103af906135c5565b60025460405173ffffffffffffffffffffffffffffffffffffffff8084169216907f3b3f758030fa296b85e15008f79cd22af8ffd2a7dd360d8963dcaf8e9fa2b5ff90600090a3600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60035473ffffffffffffffffffffffffffffffffffffffff1633146112ca576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103af90613446565b6112d2611309565b15611048576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103af90613520565b6001546000908015801590428311159082906113225750805b935050505090565b63ffffffff8216600081815260056020526040908190205490519091907fe1cc453e5e6d48a5e3dd7dc6c72117211d2bea20fbb91fd980ebc3e7f73fe546906113769084908690613401565b60405180910390a2816113925761138c83611e08565b50610418565b806113a0576113a083611eaf565b5063ffffffff91909116600090815260056020526040902055565b60008282018381101561142f57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b90505b92915050565b606060006114498360000151611f0f565b905060008173ffffffffffffffffffffffffffffffffffffffff1684602001516040516114769190613324565b6000604051808303816000865af19150503d80600081146114b3576040519150601f19603f3d011682016040523d82523d6000602084013e6114b8565b606091505b5093509050806114f4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103af9061358e565b5050919050565b600061150630611f12565b15905090565b8061151c5761151a83611603565b505b60008161152a57600061152c565b825b600380547fffffffffffffffff00000000ffffffffffffffffffffffffffffffffffffffff167401000000000000000000000000000000000000000063ffffffff8881168202929092177fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff858116918217948590556040519596509094908416937f4daaa39e87dee84708195369c30e97baa0665dc8562ac10535a0f3a9329943aa936115f593909104169089906136e0565b60405180910390a350505050565b63ffffffff811660009081526005602052604090205480610f02576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103af906135fc565b805160609060006002820167ffffffffffffffff8111801561167157600080fd5b5060405190808252806020026020018201604052801561169b578160200160208202803683370190505b5090506116e9600060016040516020016116b59190613340565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905290611872565b816000815181106116f657fe5b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000090921660209283029190910182015260405161173c916000916116b59186910161339c565b8160018151811061174957fe5b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000009092166020928302919091019091015260005b8281101561181357600085828151811061179357fe5b6020026020010151905060006117c66000836000015184602001515185602001516040516020016116b5939291906132f7565b9050808460028501815181106117d857fe5b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000090921660209283029190910190910152505060010161177d565b5061181d81611f18565b949350505050565b60035460009063ffffffff848116740100000000000000000000000000000000000000009092041614801561142f57505063ffffffff919091166000908152600560205260409020541490565b81516000906020840161188d64ffffffffff85168284611f68565b95945050505050565b600060016118a383611fc9565b60ff16148015611432575060406118db7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000008416611ff9565b6bffffffffffffffffffffffff16101592915050565b60006118fc82611896565b156119375761193060015b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000084169061200d565b9050610f02565b611432612033565b806001611970815b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000841690612057565b50600061199e7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000085166121d7565b905060005b81518110156119d1576119c88282815181106119bb57fe5b6020026020010151611438565b506001016119a3565b5050505050565b600060025b60ff166119e983611fc9565b60ff1614801561143257506025611a217fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000008416611ff9565b6bffffffffffffffffffffffff161492915050565b6000611a41826119d8565b15611937576119306002611907565b806002611a5c81611947565b506000611a8a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000851661237a565b90506000611ac1611abc7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000087166123ab565b611f0f565b90506000611ace83611db1565b9050610e9683838361150c565b600060036119dd565b6000611aef82611adb565b15611937576119306003611907565b806003611b0a81611947565b506000611b387fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000851661237a565b90506000611b677fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000086166123ab565b90506119d1828261132a565b606061142f611b9b611b966000600387876040516020016116b593929190613355565b6123dc565b612411565b6000600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16639fa92f9d6040518163ffffffff1660e01b815260040160206040518083038186803b158015611c0a57600080fd5b505afa158015611c1e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c429190613188565b905060005b60065481101561078857600063ffffffff1660068281548110611c6657fe5b6000918252602090912060088204015460079091166004026101000a900463ffffffff1614611d90578173ffffffffffffffffffffffffffffffffffffffff1663d346863960068381548110611cb857fe5b90600052602060002090600891828204019190066004029054906101000a900463ffffffff166005600060068681548110611cef57fe5b6000918252602080832060088304015463ffffffff6004600790941684026101000a909104168452830193909352604091820190205490517fffffffff0000000000000000000000000000000000000000000000000000000060e086901b168152611d5d939289910161367b565b600060405180830381600087803b158015611d7757600080fd5b505af1158015611d8b573d6000803e3d6000fd5b505050505b600101611c47565b73ffffffffffffffffffffffffffffffffffffffff1690565b7f000000000000000000000000000000000000000000000000000000000000000063ffffffff90811691161490565b606061142f611b9b611e036000600287876040516020016116b593929190613355565b612455565b63ffffffff811660009081526005602052604081208190555b600654811015610418578163ffffffff1660068281548110611e3f57fe5b6000918252602090912060088204015460079091166004026101000a900463ffffffff161415611ea45760068181548110611e7657fe5b90600052602060002090600891828204019190066004026101000a81549063ffffffff021916905550611eac565b600101611e21565b50565b600680546001810182556000919091527ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f6008820401805460079092166004026101000a63ffffffff818102199093169390921691909102919091179055565b90565b3b151590565b6040516060906000611f2d8460208401612463565b90506000611f3a82611ff9565b6bffffffffffffffffffffffff1690506000611f55836124db565b9184525082016020016040525092915050565b600080611f7584846124ef565b9050604051811115611f85575060005b80611fb3577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000915050611fc2565b611fbe858585612561565b9150505b9392505050565b60006114327fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000008316826001612574565b60181c6bffffffffffffffffffffffff1690565b60d81b7affffffffffffffffffffffffffffffffffffffffffffffffffffff9091161790565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000090565b60006120638383612595565b6121d0576000612081612075856125b7565b64ffffffffff166125bd565b91505060006120968464ffffffffff166125bd565b604080517f5479706520617373657274696f6e206661696c65642e20476f742030780000006020808301919091527fffffffffffffffffffff0000000000000000000000000000000000000000000060b088811b8216603d8501527f2e20457870656374656420307800000000000000000000000000000000000000604785015285901b1660548301528251603e818403018152605e8301938490527f08c379a000000000000000000000000000000000000000000000000000000000909352606282018181528351608284015283519496509294508493839260a2019185019080838360005b8381101561219557818101518382015260200161217d565b50505050905090810190601f1680156121c25780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5090919050565b606060006122097fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000008416600180612574565b9050600061227a60028061223e7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000008816611ff9565b6bffffffffffffffffffffffff160360017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000008816929190612691565b905060008260ff1667ffffffffffffffff8111801561229857600080fd5b506040519080825280602002602001820160405280156122d257816020015b6122bf612f88565b8152602001906001900390816122b75790505b50905060005b60006123057fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000008516611ff9565b6bffffffffffffffffffffffff1611156123715761232283612721565b82828151811061232e57fe5b60209081029190910101515261234383612751565b82828151811061234f57fe5b60200260200101516020018190525061236783612790565b92506001016122d8565b50949350505050565b60006114327fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000831660016004612574565b60006114327fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000083166005602061281b565b60006114326123ea83611ae4565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000016612989565b606060008061241f84611ff9565b6bffffffffffffffffffffffff16905060405191508192506124448483602001612a03565b508181016020016040529052919050565b60006114326123ea83611a36565b6000604051828111156124765760206060fd5b506000805b84518110156124ce57600085828151811061249257fe5b602002602001015190506124a881848701612a03565b506124b281611ff9565b6bffffffffffffffffffffffff1692909201915060010161247b565b5061181d60008483612561565b60006124e682612b2f565b60200292915050565b8181018281101561143257604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f4f766572666c6f7720647572696e67206164646974696f6e2e00000000000000604482015290519081900360640190fd5b606092831b9190911790911b1760181b90565b60008160200360080260ff1661258b85858561281b565b901c949350505050565b60008164ffffffffff166125a8846125b7565b64ffffffffff16149392505050565b60d81c90565b600080601f5b600f8160ff1611156126255760ff600882021684901c6125e281612b63565b61ffff16841793508160ff166010146125fd57601084901b93505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff016125c3565b50600f5b60ff8160ff16101561268b5760ff600882021684901c61264881612b63565b61ffff16831792508160ff1660001461266357601083901b92505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01612629565b50915091565b60008061269d86612b93565b6bffffffffffffffffffffffff1690506126b686612ba7565b6126ca856126c484896124ef565b906124ef565b11156126f9577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000091505061181d565b61270381866124ef565b90506127178364ffffffffff168286611f68565b9695505050505050565b60006114327fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000831682602061281b565b6060611432611b9b604061276485612bd1565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000861691906004612691565b600081600161279e81611947565b5060006127aa85612bd1565b604001905061188d81806127df7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000008916611ff9565b6bffffffffffffffffffffffff160360017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000008916929190612691565b600060ff821661282d57506000611fc2565b61283684611ff9565b6bffffffffffffffffffffffff166128518460ff85166124ef565b11156128f35761289261286385612b93565b6bffffffffffffffffffffffff1661287a86611ff9565b6bffffffffffffffffffffffff16858560ff16612c01565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181815283516024840152835190928392604490910191908501908083836000831561219557818101518382015260200161217d565b60208260ff161115612950576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603a81526020018061386a603a913960400191505060405180910390fd5b60088202600061295f86612b93565b6bffffffffffffffffffffffff169050600061297a83612d5c565b91909501511695945050505050565b600061299482612da5565b6129ff57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f56616c696469747920617373657274696f6e206661696c656400000000000000604482015290519081900360640190fd5b5090565b6000612a0e83612de2565b612a63576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260288152602001806138a46028913960400191505060405180910390fd5b612a6c83612da5565b612ac1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602b8152602001806138cc602b913960400191505060405180910390fd5b6000612acc84611ff9565b6bffffffffffffffffffffffff1690506000612ae785612b93565b6bffffffffffffffffffffffff1690506000604051905084811115612b0c5760206060fd5b8285848460045afa50612717612b21876125b7565b64ffffffffff168685612561565b60006020612b556020612b4185611ff9565b6bffffffffffffffffffffffff16906124ef565b81612b5c57fe5b0492915050565b6000612b7560048360ff16901c612df4565b60ff161760081b62ffff0016612b8a82612df4565b60ff1617919050565b60781c6bffffffffffffffffffffffff1690565b6000612bb282611ff9565b612bbb83612b93565b016bffffffffffffffffffffffff169050919050565b60006114327fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000831660208061281b565b60606000612c0e866125bd565b9150506000612c1c866125bd565b9150506000612c2a866125bd565b9150506000612c38866125bd565b9150508383838360405160200180806138f7603591397fffffffffffff000000000000000000000000000000000000000000000000000060d087811b821660358401527f2077697468206c656e6774682030780000000000000000000000000000000000603b84015286901b16604a820152605001602161381b82397fffffffffffff000000000000000000000000000000000000000000000000000060d094851b811660218301527f2077697468206c656e677468203078000000000000000000000000000000000060278301529290931b9091166036830152507f2e00000000000000000000000000000000000000000000000000000000000000603c82015260408051601d818403018152603d90920190529b9a5050505050505050505050565b7f80000000000000000000000000000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9091011d90565b6000612db0826125b7565b64ffffffffff1664ffffffffff1415612dcb57506000610f02565b6000612dd683612ba7565b60405110199392505050565b6000612ded82612f60565b1592915050565b600060f08083179060ff82161415612e10576030915050610f02565b8060ff1660f11415612e26576031915050610f02565b8060ff1660f21415612e3c576032915050610f02565b8060ff1660f31415612e52576033915050610f02565b8060ff1660f41415612e68576034915050610f02565b8060ff1660f51415612e7e576035915050610f02565b8060ff1660f61415612e94576036915050610f02565b8060ff1660f71415612eaa576037915050610f02565b8060ff1660f81415612ec0576038915050610f02565b8060ff1660f91415612ed6576039915050610f02565b8060ff1660fa1415612eec576061915050610f02565b8060ff1660fb1415612f02576062915050610f02565b8060ff1660fc1415612f18576063915050610f02565b8060ff1660fd1415612f2e576064915050610f02565b8060ff1660fe1415612f44576065915050610f02565b8060ff1660ff1415612f5a576066915050610f02565b50919050565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000009081161490565b60408051808201909152600081526060602082015290565b60008083601f840112612fb1578182fd5b50813567ffffffffffffffff811115612fc8578182fd5b6020830191508360208083028501011115612fe257600080fd5b9250929050565b600082601f830112612ff9578081fd5b813567ffffffffffffffff81111561300d57fe5b61303e60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8401160161372a565b818152846020838601011115613052578283fd5b816020850160208301379081016020019190915292915050565b60006040828403121561307d578081fd5b6040516040810167ffffffffffffffff828210818311171561309b57fe5b816040528293508435835260208501359150808211156130ba57600080fd5b506130c785828601612fe9565b6020830152505092915050565b6000602082840312156130e5578081fd5b813561142f816137e6565b60008060408385031215613102578081fd5b823561310d816137e6565b9150602083013561311d816137e6565b809150509250929050565b6000806020838503121561313a578182fd5b823567ffffffffffffffff811115613150578283fd5b61315c85828601612fa0565b90969095509350505050565b600060208284031215613179578081fd5b8151801515811461142f578182fd5b600060208284031215613199578081fd5b815161142f816137e6565b6000602082840312156131b5578081fd5b5035919050565b6000602082840312156131cd578081fd5b813561142f81613808565b6000602082840312156131e9578081fd5b815161142f81613808565b60008060408385031215613206578182fd5b823561310d81613808565b600080600060408486031215613225578081fd5b833561323081613808565b9250602084013567ffffffffffffffff81111561324b578182fd5b61325786828701612fa0565b9497909650939450505050565b60008060408385031215613276578182fd5b823561328181613808565b946020939093013593505050565b6000806000606084860312156132a3578283fd5b83356132ae81613808565b925060208401359150604084013567ffffffffffffffff8111156132d0578182fd5b6132dc86828701612fe9565b9150509250925092565b600581106132f057fe5b60f81b9052565b600084825283602083015282516133158160408501602087016137ba565b91909101604001949350505050565b600082516133368184602087016137ba565b9190910192915050565b600061334c82846132e6565b50600101919050565b600061336182866132e6565b5060e09290921b7fffffffff000000000000000000000000000000000000000000000000000000001660018301526005820152602501919050565b60f89190911b7fff0000000000000000000000000000000000000000000000000000000000000016815260010190565b73ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b901515815260200190565b90815260200190565b918252602082015260400190565b60208082526016908201527f7265636f76657279206e6f7420696e6974696174656400000000000000000000604082015260600190565b60208082526014908201527f212063616c6c656420627920676f7665726e6f72000000000000000000000000604082015260600190565b6020808252600f908201527f21676f7665726e6f72526f757465720000000000000000000000000000000000604082015260600190565b6020808252818101527f58417070436f6e6e656374696f6e4d616e616765722062616420646f6d61696e604082015260600190565b60208082526008908201527f217265706c696361000000000000000000000000000000000000000000000000604082015260600190565b6020808252600b908201527f696e207265636f76657279000000000000000000000000000000000000000000604082015260600190565b6020808252601a908201527f7265636f7665727920616c726561647920696e69746961746564000000000000604082015260600190565b6020808252600b908201527f63616c6c206661696c6564000000000000000000000000000000000000000000604082015260600190565b6020808252601c908201527f212063616c6c6564206279207265636f76657279206d616e6167657200000000604082015260600190565b60208082526007908201527f21726f7574657200000000000000000000000000000000000000000000000000604082015260600190565b60208082526013908201527f2176616c6964206d657373616765207479706500000000000000000000000000604082015260600190565b63ffffffff91909116815260200190565b600063ffffffff851682528360208301526060604083015282518060608401526136ac8160808501602087016137ba565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01691909101608001949350505050565b63ffffffff92831681529116602082015260400190565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc1833603018112613336578182fd5b60405181810167ffffffffffffffff8111828210171561374657fe5b604052919050565b600067ffffffffffffffff83111561376257fe5b6020613771818286020161372a565b8481528181019084845b878110156137a257613790368335890161306c565b8452928401929084019060010161377b565b50909695505050505050565b6000611432368361306c565b60005b838110156137d55781810151838201526020016137bd565b838111156111725750506000910152565b73ffffffffffffffffffffffffffffffffffffffff81168114611eac57600080fd5b63ffffffff81168114611eac57600080fdfe2e20417474656d7074656420746f20696e646578206174206f6666736574203078496e697469616c697a61626c653a20636f6e747261637420697320616c726561647920696e697469616c697a656454797065644d656d566965772f696e646578202d20417474656d7074656420746f20696e646578206d6f7265207468616e20333220627974657354797065644d656d566965772f636f7079546f202d204e756c6c20706f696e74657220646572656654797065644d656d566965772f636f7079546f202d20496e76616c696420706f696e74657220646572656654797065644d656d566965772f696e646578202d204f76657272616e2074686520766965772e20536c696365206973206174203078a26469706673582212205d26e53f22407279bd67a69c2185a7432a5e19531b68a15dd242c767800ba63e64736f6c63430007060033"; export class TestGovernanceRouter__factory extends ContractFactory { constructor(signer?: Signer) { @@ -399,18 +539,25 @@ export class TestGovernanceRouter__factory extends ContractFactory { deploy( _localDomain: BigNumberish, + _recoveryTimelock: BigNumberish, overrides?: Overrides & { from?: string | Promise } ): Promise { return super.deploy( _localDomain, + _recoveryTimelock, overrides || {} ) as Promise; } getDeployTransaction( _localDomain: BigNumberish, + _recoveryTimelock: BigNumberish, overrides?: Overrides & { from?: string | Promise } ): TransactionRequest { - return super.getDeployTransaction(_localDomain, overrides || {}); + return super.getDeployTransaction( + _localDomain, + _recoveryTimelock, + overrides || {} + ); } attach(address: string): TestGovernanceRouter { return super.attach(address) as TestGovernanceRouter;