feat: RecoveryManager role on GovernanceRouter (#353)

* RecoveryManager role

Fix inequality

* Require recovery activated to exit recovery

* Add RecoveryManager tests

* Move utils & pass lint

* Test transfer RecoveryManager role:

* Refactor RecoveryManager tests

* Change block.number -> timestamp

* ran prettier

* Add recovery manager to typescript

* Fix comment

* Re-arrange inRecovery check

Co-authored-by: Conner Swann <me@connerswann.me>
buddies-main-deployment
Anna Carroll 3 years ago committed by GitHub
parent 5b2e48a358
commit d20438434c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 143
      solidity/optics-core/contracts/governance/GovernanceRouter.sol
  2. 4
      solidity/optics-core/contracts/test/TestGovernanceRouter.sol
  3. 15
      solidity/optics-core/js/deployOpticsUtils.js
  4. 2
      solidity/optics-core/js/types.js
  5. 9
      solidity/optics-core/test/cross-chain/GovernanceRouter.test.js
  6. 467
      solidity/optics-core/test/cross-chain/RecoveryManager.test.js
  7. 11
      solidity/optics-core/test/cross-chain/SimpleMessage.test.js
  8. 16
      solidity/optics-core/test/cross-chain/crossChainTestUtils.js
  9. 4
      solidity/optics-core/test/cross-chain/generateTestChainConfigs.js
  10. 6
      typescript/src/chain.ts
  11. 4
      typescript/src/index.ts
  12. 215
      typescript/src/typechain/optics-core/GovernanceRouter.d.ts
  13. 215
      typescript/src/typechain/optics-core/TestGovernanceRouter.d.ts
  14. 153
      typescript/src/typechain/optics-core/factories/GovernanceRouter__factory.ts
  15. 153
      typescript/src/typechain/optics-core/factories/TestGovernanceRouter__factory.ts

@ -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

@ -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

@ -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,
);

@ -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,

@ -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);

@ -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,
);
});
});

@ -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 () => {

@ -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,
};

@ -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,

@ -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'),

@ -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<contracts.GovernanceRouter>(
@ -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;

@ -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<string> }
): Promise<ContractTransaction>;
governor(overrides?: CallOverrides): Promise<[string]>;
governorDomain(overrides?: CallOverrides): Promise<[number]>;
@ -198,13 +271,26 @@ export class GovernanceRouter extends BaseContract {
overrides?: Overrides & { from?: string | Promise<string> }
): Promise<ContractTransaction>;
inRecovery(overrides?: CallOverrides): Promise<[boolean]>;
initialize(
_xAppConnectionManager: string,
_recoveryManager: string,
overrides?: Overrides & { from?: string | Promise<string> }
): Promise<ContractTransaction>;
initiateRecoveryTimelock(
overrides?: Overrides & { from?: string | Promise<string> }
): Promise<ContractTransaction>;
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<string> }
): Promise<ContractTransaction>;
setRouterDuringSetup(
setRouterLocal(
_domain: BigNumberish,
_router: BytesLike,
overrides?: Overrides & { from?: string | Promise<string> }
@ -230,6 +316,11 @@ export class GovernanceRouter extends BaseContract {
overrides?: Overrides & { from?: string | Promise<string> }
): Promise<ContractTransaction>;
transferRecoveryManager(
_newRecoveryManager: string,
overrides?: Overrides & { from?: string | Promise<string> }
): Promise<ContractTransaction>;
xAppConnectionManager(overrides?: CallOverrides): Promise<[string]>;
};
@ -246,6 +337,10 @@ export class GovernanceRouter extends BaseContract {
domains(arg0: BigNumberish, overrides?: CallOverrides): Promise<number>;
exitRecovery(
overrides?: Overrides & { from?: string | Promise<string> }
): Promise<ContractTransaction>;
governor(overrides?: CallOverrides): Promise<string>;
governorDomain(overrides?: CallOverrides): Promise<number>;
@ -257,13 +352,26 @@ export class GovernanceRouter extends BaseContract {
overrides?: Overrides & { from?: string | Promise<string> }
): Promise<ContractTransaction>;
inRecovery(overrides?: CallOverrides): Promise<boolean>;
initialize(
_xAppConnectionManager: string,
_recoveryManager: string,
overrides?: Overrides & { from?: string | Promise<string> }
): Promise<ContractTransaction>;
initiateRecoveryTimelock(
overrides?: Overrides & { from?: string | Promise<string> }
): Promise<ContractTransaction>;
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(
@ -272,7 +380,7 @@ export class GovernanceRouter extends BaseContract {
overrides?: Overrides & { from?: string | Promise<string> }
): Promise<ContractTransaction>;
setRouterDuringSetup(
setRouterLocal(
_domain: BigNumberish,
_router: BytesLike,
overrides?: Overrides & { from?: string | Promise<string> }
@ -289,6 +397,11 @@ export class GovernanceRouter extends BaseContract {
overrides?: Overrides & { from?: string | Promise<string> }
): Promise<ContractTransaction>;
transferRecoveryManager(
_newRecoveryManager: string,
overrides?: Overrides & { from?: string | Promise<string> }
): Promise<ContractTransaction>;
xAppConnectionManager(overrides?: CallOverrides): Promise<string>;
callStatic: {
@ -305,6 +418,8 @@ export class GovernanceRouter extends BaseContract {
domains(arg0: BigNumberish, overrides?: CallOverrides): Promise<number>;
exitRecovery(overrides?: CallOverrides): Promise<void>;
governor(overrides?: CallOverrides): Promise<string>;
governorDomain(overrides?: CallOverrides): Promise<number>;
@ -316,13 +431,24 @@ export class GovernanceRouter extends BaseContract {
overrides?: CallOverrides
): Promise<void>;
inRecovery(overrides?: CallOverrides): Promise<boolean>;
initialize(
_xAppConnectionManager: string,
_recoveryManager: string,
overrides?: CallOverrides
): Promise<void>;
initiateRecoveryTimelock(overrides?: CallOverrides): Promise<void>;
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(
@ -331,7 +457,7 @@ export class GovernanceRouter extends BaseContract {
overrides?: CallOverrides
): Promise<void>;
setRouterDuringSetup(
setRouterLocal(
_domain: BigNumberish,
_router: BytesLike,
overrides?: CallOverrides
@ -348,10 +474,27 @@ export class GovernanceRouter extends BaseContract {
overrides?: CallOverrides
): Promise<void>;
transferRecoveryManager(
_newRecoveryManager: string,
overrides?: CallOverrides
): Promise<void>;
xAppConnectionManager(overrides?: CallOverrides): Promise<string>;
};
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<BigNumber>;
exitRecovery(
overrides?: Overrides & { from?: string | Promise<string> }
): Promise<BigNumber>;
governor(overrides?: CallOverrides): Promise<BigNumber>;
governorDomain(overrides?: CallOverrides): Promise<BigNumber>;
@ -402,13 +557,26 @@ export class GovernanceRouter extends BaseContract {
overrides?: Overrides & { from?: string | Promise<string> }
): Promise<BigNumber>;
inRecovery(overrides?: CallOverrides): Promise<BigNumber>;
initialize(
_xAppConnectionManager: string,
_recoveryManager: string,
overrides?: Overrides & { from?: string | Promise<string> }
): Promise<BigNumber>;
initiateRecoveryTimelock(
overrides?: Overrides & { from?: string | Promise<string> }
): Promise<BigNumber>;
localDomain(overrides?: CallOverrides): Promise<BigNumber>;
recoveryActiveAt(overrides?: CallOverrides): Promise<BigNumber>;
recoveryManager(overrides?: CallOverrides): Promise<BigNumber>;
recoveryTimelock(overrides?: CallOverrides): Promise<BigNumber>;
routers(arg0: BigNumberish, overrides?: CallOverrides): Promise<BigNumber>;
setRouter(
@ -417,7 +585,7 @@ export class GovernanceRouter extends BaseContract {
overrides?: Overrides & { from?: string | Promise<string> }
): Promise<BigNumber>;
setRouterDuringSetup(
setRouterLocal(
_domain: BigNumberish,
_router: BytesLike,
overrides?: Overrides & { from?: string | Promise<string> }
@ -434,6 +602,11 @@ export class GovernanceRouter extends BaseContract {
overrides?: Overrides & { from?: string | Promise<string> }
): Promise<BigNumber>;
transferRecoveryManager(
_newRecoveryManager: string,
overrides?: Overrides & { from?: string | Promise<string> }
): Promise<BigNumber>;
xAppConnectionManager(overrides?: CallOverrides): Promise<BigNumber>;
};
@ -454,6 +627,10 @@ export class GovernanceRouter extends BaseContract {
overrides?: CallOverrides
): Promise<PopulatedTransaction>;
exitRecovery(
overrides?: Overrides & { from?: string | Promise<string> }
): Promise<PopulatedTransaction>;
governor(overrides?: CallOverrides): Promise<PopulatedTransaction>;
governorDomain(overrides?: CallOverrides): Promise<PopulatedTransaction>;
@ -465,13 +642,26 @@ export class GovernanceRouter extends BaseContract {
overrides?: Overrides & { from?: string | Promise<string> }
): Promise<PopulatedTransaction>;
inRecovery(overrides?: CallOverrides): Promise<PopulatedTransaction>;
initialize(
_xAppConnectionManager: string,
_recoveryManager: string,
overrides?: Overrides & { from?: string | Promise<string> }
): Promise<PopulatedTransaction>;
initiateRecoveryTimelock(
overrides?: Overrides & { from?: string | Promise<string> }
): Promise<PopulatedTransaction>;
localDomain(overrides?: CallOverrides): Promise<PopulatedTransaction>;
recoveryActiveAt(overrides?: CallOverrides): Promise<PopulatedTransaction>;
recoveryManager(overrides?: CallOverrides): Promise<PopulatedTransaction>;
recoveryTimelock(overrides?: CallOverrides): Promise<PopulatedTransaction>;
routers(
arg0: BigNumberish,
overrides?: CallOverrides
@ -483,7 +673,7 @@ export class GovernanceRouter extends BaseContract {
overrides?: Overrides & { from?: string | Promise<string> }
): Promise<PopulatedTransaction>;
setRouterDuringSetup(
setRouterLocal(
_domain: BigNumberish,
_router: BytesLike,
overrides?: Overrides & { from?: string | Promise<string> }
@ -500,6 +690,11 @@ export class GovernanceRouter extends BaseContract {
overrides?: Overrides & { from?: string | Promise<string> }
): Promise<PopulatedTransaction>;
transferRecoveryManager(
_newRecoveryManager: string,
overrides?: Overrides & { from?: string | Promise<string> }
): Promise<PopulatedTransaction>;
xAppConnectionManager(
overrides?: CallOverrides
): Promise<PopulatedTransaction>;

@ -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<string> }
): Promise<ContractTransaction>;
governor(overrides?: CallOverrides): Promise<[string]>;
governorDomain(overrides?: CallOverrides): Promise<[number]>;
@ -230,13 +303,26 @@ export class TestGovernanceRouter extends BaseContract {
overrides?: Overrides & { from?: string | Promise<string> }
): Promise<ContractTransaction>;
inRecovery(overrides?: CallOverrides): Promise<[boolean]>;
initialize(
_xAppConnectionManager: string,
_recoveryManager: string,
overrides?: Overrides & { from?: string | Promise<string> }
): Promise<ContractTransaction>;
initiateRecoveryTimelock(
overrides?: Overrides & { from?: string | Promise<string> }
): Promise<ContractTransaction>;
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<string> }
): Promise<ContractTransaction>;
setRouterDuringSetup(
setRouterLocal(
_domain: BigNumberish,
_router: BytesLike,
overrides?: Overrides & { from?: string | Promise<string> }
@ -274,6 +360,11 @@ export class TestGovernanceRouter extends BaseContract {
overrides?: Overrides & { from?: string | Promise<string> }
): Promise<ContractTransaction>;
transferRecoveryManager(
_newRecoveryManager: string,
overrides?: Overrides & { from?: string | Promise<string> }
): Promise<ContractTransaction>;
xAppConnectionManager(overrides?: CallOverrides): Promise<[string]>;
};
@ -295,6 +386,10 @@ export class TestGovernanceRouter extends BaseContract {
domains(arg0: BigNumberish, overrides?: CallOverrides): Promise<number>;
exitRecovery(
overrides?: Overrides & { from?: string | Promise<string> }
): Promise<ContractTransaction>;
governor(overrides?: CallOverrides): Promise<string>;
governorDomain(overrides?: CallOverrides): Promise<number>;
@ -306,13 +401,26 @@ export class TestGovernanceRouter extends BaseContract {
overrides?: Overrides & { from?: string | Promise<string> }
): Promise<ContractTransaction>;
inRecovery(overrides?: CallOverrides): Promise<boolean>;
initialize(
_xAppConnectionManager: string,
_recoveryManager: string,
overrides?: Overrides & { from?: string | Promise<string> }
): Promise<ContractTransaction>;
initiateRecoveryTimelock(
overrides?: Overrides & { from?: string | Promise<string> }
): Promise<ContractTransaction>;
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(
@ -327,7 +435,7 @@ export class TestGovernanceRouter extends BaseContract {
overrides?: Overrides & { from?: string | Promise<string> }
): Promise<ContractTransaction>;
setRouterDuringSetup(
setRouterLocal(
_domain: BigNumberish,
_router: BytesLike,
overrides?: Overrides & { from?: string | Promise<string> }
@ -350,6 +458,11 @@ export class TestGovernanceRouter extends BaseContract {
overrides?: Overrides & { from?: string | Promise<string> }
): Promise<ContractTransaction>;
transferRecoveryManager(
_newRecoveryManager: string,
overrides?: Overrides & { from?: string | Promise<string> }
): Promise<ContractTransaction>;
xAppConnectionManager(overrides?: CallOverrides): Promise<string>;
callStatic: {
@ -371,6 +484,8 @@ export class TestGovernanceRouter extends BaseContract {
domains(arg0: BigNumberish, overrides?: CallOverrides): Promise<number>;
exitRecovery(overrides?: CallOverrides): Promise<void>;
governor(overrides?: CallOverrides): Promise<string>;
governorDomain(overrides?: CallOverrides): Promise<number>;
@ -382,13 +497,24 @@ export class TestGovernanceRouter extends BaseContract {
overrides?: CallOverrides
): Promise<void>;
inRecovery(overrides?: CallOverrides): Promise<boolean>;
initialize(
_xAppConnectionManager: string,
_recoveryManager: string,
overrides?: CallOverrides
): Promise<void>;
initiateRecoveryTimelock(overrides?: CallOverrides): Promise<void>;
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(
@ -403,7 +529,7 @@ export class TestGovernanceRouter extends BaseContract {
overrides?: CallOverrides
): Promise<void>;
setRouterDuringSetup(
setRouterLocal(
_domain: BigNumberish,
_router: BytesLike,
overrides?: CallOverrides
@ -426,10 +552,27 @@ export class TestGovernanceRouter extends BaseContract {
overrides?: CallOverrides
): Promise<void>;
transferRecoveryManager(
_newRecoveryManager: string,
overrides?: CallOverrides
): Promise<void>;
xAppConnectionManager(overrides?: CallOverrides): Promise<string>;
};
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<BigNumber>;
exitRecovery(
overrides?: Overrides & { from?: string | Promise<string> }
): Promise<BigNumber>;
governor(overrides?: CallOverrides): Promise<BigNumber>;
governorDomain(overrides?: CallOverrides): Promise<BigNumber>;
@ -485,13 +640,26 @@ export class TestGovernanceRouter extends BaseContract {
overrides?: Overrides & { from?: string | Promise<string> }
): Promise<BigNumber>;
inRecovery(overrides?: CallOverrides): Promise<BigNumber>;
initialize(
_xAppConnectionManager: string,
_recoveryManager: string,
overrides?: Overrides & { from?: string | Promise<string> }
): Promise<BigNumber>;
initiateRecoveryTimelock(
overrides?: Overrides & { from?: string | Promise<string> }
): Promise<BigNumber>;
localDomain(overrides?: CallOverrides): Promise<BigNumber>;
recoveryActiveAt(overrides?: CallOverrides): Promise<BigNumber>;
recoveryManager(overrides?: CallOverrides): Promise<BigNumber>;
recoveryTimelock(overrides?: CallOverrides): Promise<BigNumber>;
routers(arg0: BigNumberish, overrides?: CallOverrides): Promise<BigNumber>;
setRouter(
@ -506,7 +674,7 @@ export class TestGovernanceRouter extends BaseContract {
overrides?: Overrides & { from?: string | Promise<string> }
): Promise<BigNumber>;
setRouterDuringSetup(
setRouterLocal(
_domain: BigNumberish,
_router: BytesLike,
overrides?: Overrides & { from?: string | Promise<string> }
@ -529,6 +697,11 @@ export class TestGovernanceRouter extends BaseContract {
overrides?: Overrides & { from?: string | Promise<string> }
): Promise<BigNumber>;
transferRecoveryManager(
_newRecoveryManager: string,
overrides?: Overrides & { from?: string | Promise<string> }
): Promise<BigNumber>;
xAppConnectionManager(overrides?: CallOverrides): Promise<BigNumber>;
};
@ -554,6 +727,10 @@ export class TestGovernanceRouter extends BaseContract {
overrides?: CallOverrides
): Promise<PopulatedTransaction>;
exitRecovery(
overrides?: Overrides & { from?: string | Promise<string> }
): Promise<PopulatedTransaction>;
governor(overrides?: CallOverrides): Promise<PopulatedTransaction>;
governorDomain(overrides?: CallOverrides): Promise<PopulatedTransaction>;
@ -565,13 +742,26 @@ export class TestGovernanceRouter extends BaseContract {
overrides?: Overrides & { from?: string | Promise<string> }
): Promise<PopulatedTransaction>;
inRecovery(overrides?: CallOverrides): Promise<PopulatedTransaction>;
initialize(
_xAppConnectionManager: string,
_recoveryManager: string,
overrides?: Overrides & { from?: string | Promise<string> }
): Promise<PopulatedTransaction>;
initiateRecoveryTimelock(
overrides?: Overrides & { from?: string | Promise<string> }
): Promise<PopulatedTransaction>;
localDomain(overrides?: CallOverrides): Promise<PopulatedTransaction>;
recoveryActiveAt(overrides?: CallOverrides): Promise<PopulatedTransaction>;
recoveryManager(overrides?: CallOverrides): Promise<PopulatedTransaction>;
recoveryTimelock(overrides?: CallOverrides): Promise<PopulatedTransaction>;
routers(
arg0: BigNumberish,
overrides?: CallOverrides
@ -589,7 +779,7 @@ export class TestGovernanceRouter extends BaseContract {
overrides?: Overrides & { from?: string | Promise<string> }
): Promise<PopulatedTransaction>;
setRouterDuringSetup(
setRouterLocal(
_domain: BigNumberish,
_router: BytesLike,
overrides?: Overrides & { from?: string | Promise<string> }
@ -612,6 +802,11 @@ export class TestGovernanceRouter extends BaseContract {
overrides?: Overrides & { from?: string | Promise<string> }
): Promise<PopulatedTransaction>;
transferRecoveryManager(
_newRecoveryManager: string,
overrides?: Overrides & { from?: string | Promise<string> }
): Promise<PopulatedTransaction>;
xAppConnectionManager(
overrides?: CallOverrides
): Promise<PopulatedTransaction>;

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long
Loading…
Cancel
Save