Remove typechain package (#238)
parent
f04959a57b
commit
9527f362d4
@ -1,7 +1,8 @@ |
|||||||
node_modules/ |
node_modules/ |
||||||
cache/ |
cache/ |
||||||
artifacts/ |
artifacts/ |
||||||
typechain/ |
types/ |
||||||
|
dist/ |
||||||
coverage/ |
coverage/ |
||||||
coverage.json |
coverage.json |
||||||
.env |
.env |
||||||
|
@ -1,73 +1,16 @@ |
|||||||
{ |
{ |
||||||
"compilerOptions": { |
"compilerOptions": { |
||||||
/* Visit https://aka.ms/tsconfig.json to read more about this file */ |
"outDir": "./dist/", |
||||||
|
"rootDir": "./types/" |
||||||
/* Basic Options */ |
}, |
||||||
// "incremental": true, /* Enable incremental compilation */ |
"exclude": [ |
||||||
"target": "ES2017" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', 'ES2021', or 'ESNEXT'. */, |
"./node_modules/", |
||||||
"module": "commonjs" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */, |
"./dist/", |
||||||
// "lib": [], /* Specify library files to be included in the compilation. */ |
"./types/hardhat.d.ts" |
||||||
// "allowJs": true, /* Allow javascript files to be compiled. */ |
], |
||||||
// "checkJs": true, /* Report errors in .js files. */ |
"extends": "../../tsconfig.package.json", |
||||||
// "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', 'react', 'react-jsx' or 'react-jsxdev'. */ |
"include": [ |
||||||
// "declaration": true, /* Generates corresponding '.d.ts' file. */ |
"./types/*.ts", |
||||||
// "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */ |
"./types/factories/*.ts" |
||||||
// "sourceMap": true, /* Generates corresponding '.map' file. */ |
] |
||||||
// "outFile": "./", /* Concatenate and emit output to single file. */ |
|
||||||
// "outDir": "./", /* Redirect output structure to the directory. */ |
|
||||||
// "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ |
|
||||||
// "composite": true, /* Enable project compilation */ |
|
||||||
// "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */ |
|
||||||
// "removeComments": true, /* Do not emit comments to output. */ |
|
||||||
// "noEmit": true, /* Do not emit outputs. */ |
|
||||||
// "importHelpers": true, /* Import emit helpers from 'tslib'. */ |
|
||||||
// "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ |
|
||||||
// "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ |
|
||||||
"resolveJsonModule": true /* Allows for importing, extracting types from and generating . json files.*/, |
|
||||||
|
|
||||||
/* Strict Type-Checking Options */ |
|
||||||
"strict": true /* Enable all strict type-checking options. */, |
|
||||||
// "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ |
|
||||||
// "strictNullChecks": true, /* Enable strict null checks. */ |
|
||||||
// "strictFunctionTypes": true, /* Enable strict checking of function types. */ |
|
||||||
// "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */ |
|
||||||
// "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */ |
|
||||||
// "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ |
|
||||||
// "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ |
|
||||||
|
|
||||||
/* Additional Checks */ |
|
||||||
// "noUnusedLocals": true, /* Report errors on unused locals. */ |
|
||||||
// "noUnusedParameters": true, /* Report errors on unused parameters. */ |
|
||||||
// "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ |
|
||||||
// "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ |
|
||||||
// "noUncheckedIndexedAccess": true, /* Include 'undefined' in index signature results */ |
|
||||||
// "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an 'override' modifier. */ |
|
||||||
// "noPropertyAccessFromIndexSignature": true, /* Require undeclared properties from index signatures to use element accesses. */ |
|
||||||
|
|
||||||
/* Module Resolution Options */ |
|
||||||
// "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ |
|
||||||
// "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ |
|
||||||
// "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ |
|
||||||
// "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */ |
|
||||||
// "typeRoots": [], /* List of folders to include type definitions from. */ |
|
||||||
// "types": [], /* Type declaration files to be included in compilation. */ |
|
||||||
// "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ |
|
||||||
"esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */, |
|
||||||
// "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ |
|
||||||
// "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ |
|
||||||
|
|
||||||
/* Source Map Options */ |
|
||||||
// "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ |
|
||||||
// "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ |
|
||||||
// "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */ |
|
||||||
// "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */ |
|
||||||
|
|
||||||
/* Experimental Options */ |
|
||||||
// "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ |
|
||||||
// "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ |
|
||||||
|
|
||||||
/* Advanced Options */ |
|
||||||
"skipLibCheck": true /* Skip type checking of declaration files. */, |
|
||||||
"forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */ |
|
||||||
} |
|
||||||
} |
} |
||||||
|
@ -1,7 +1,8 @@ |
|||||||
node_modules/ |
node_modules/ |
||||||
cache/ |
cache/ |
||||||
artifacts/ |
artifacts/ |
||||||
typechain/ |
types/ |
||||||
|
dist/ |
||||||
coverage/ |
coverage/ |
||||||
coverage.json |
coverage.json |
||||||
.env |
.env |
||||||
|
@ -1,484 +0,0 @@ |
|||||||
import { ethers, abacus } from 'hardhat'; |
|
||||||
import { expect } from 'chai'; |
|
||||||
import * as types from 'ethers'; |
|
||||||
|
|
||||||
import { formatCall, sendFromSigner } from './utils'; |
|
||||||
import { increaseTimestampBy } from '../utils'; |
|
||||||
import { Validator } from '../lib/core'; |
|
||||||
import { Signer } from '../lib/types'; |
|
||||||
import { |
|
||||||
ValidatorManager, |
|
||||||
TestGovernanceRouter, |
|
||||||
TestOutbox, |
|
||||||
} from '../../typechain'; |
|
||||||
import { AbacusDeployment } from '../lib/AbacusDeployment'; |
|
||||||
import { GovernanceDeployment } from '../lib/GovernanceDeployment'; |
|
||||||
|
|
||||||
async function expectNotInRecovery( |
|
||||||
validatorManager: ValidatorManager, |
|
||||||
recoveryManager: types.Signer, |
|
||||||
randomSigner: Signer, |
|
||||||
governor: Signer, |
|
||||||
governanceRouter: TestGovernanceRouter, |
|
||||||
outbox: TestOutbox, |
|
||||||
) { |
|
||||||
expect(await governanceRouter.inRecovery()).to.be.false; |
|
||||||
|
|
||||||
// Format abacus call message
|
|
||||||
const call = await formatCall(validatorManager, 'setValidator', [ |
|
||||||
1000, |
|
||||||
randomSigner.address, |
|
||||||
]); |
|
||||||
|
|
||||||
// Expect that Governor *CAN* Call Local & Call Remote
|
|
||||||
// dispatch call on local governorRouter
|
|
||||||
await expect( |
|
||||||
sendFromSigner(governor, governanceRouter, 'callLocal', [[call]]), |
|
||||||
) |
|
||||||
.to.emit(validatorManager, 'NewValidator') |
|
||||||
.withArgs(1000, randomSigner.address); |
|
||||||
|
|
||||||
// dispatch call on local governorRouter
|
|
||||||
await expect( |
|
||||||
sendFromSigner(governor, governanceRouter, 'callRemote', [2000, [call]]), |
|
||||||
).to.emit(outbox, '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, |
|
||||||
abacus.ethersAddressToBytes32(randomSigner.address), |
|
||||||
]), |
|
||||||
) |
|
||||||
.to.emit(governanceRouter, 'SetRouter') |
|
||||||
.withArgs( |
|
||||||
otherDomain, |
|
||||||
previousRouter, |
|
||||||
abacus.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, |
|
||||||
abacus.ethersAddressToBytes32(randomSigner.address), |
|
||||||
]), |
|
||||||
).to.be.revertedWith('! called by governor'); |
|
||||||
} |
|
||||||
|
|
||||||
async function expectOnlyRecoveryManagerCanTransferRole( |
|
||||||
governor: Signer, |
|
||||||
governanceRouter: TestGovernanceRouter, |
|
||||||
randomSigner: Signer, |
|
||||||
recoveryManager: Signer, |
|
||||||
) { |
|
||||||
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: Signer, |
|
||||||
governanceRouter: TestGovernanceRouter, |
|
||||||
randomSigner: Signer, |
|
||||||
recoveryManager: Signer, |
|
||||||
) { |
|
||||||
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: Signer, |
|
||||||
governanceRouter: TestGovernanceRouter, |
|
||||||
randomSigner: Signer, |
|
||||||
recoveryManager: Signer, |
|
||||||
) { |
|
||||||
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); |
|
||||||
} |
|
||||||
|
|
||||||
const localDomain = 1000; |
|
||||||
const remoteDomain = 2000; |
|
||||||
const domains = [localDomain, remoteDomain]; |
|
||||||
|
|
||||||
/* |
|
||||||
* Deploy the full Abacus suite on two chains |
|
||||||
*/ |
|
||||||
describe('RecoveryManager', async () => { |
|
||||||
let abacusDeployment: AbacusDeployment; |
|
||||||
let governanceDeployment: GovernanceDeployment; |
|
||||||
let governor: Signer, |
|
||||||
recoveryManager: Signer, |
|
||||||
randomSigner: Signer, |
|
||||||
governanceRouter: TestGovernanceRouter, |
|
||||||
outbox: TestOutbox, |
|
||||||
validatorManager: ValidatorManager; |
|
||||||
|
|
||||||
before(async () => { |
|
||||||
[governor, recoveryManager, randomSigner] = await ethers.getSigners(); |
|
||||||
const validator = await Validator.fromSigner(randomSigner, localDomain); |
|
||||||
abacusDeployment = await AbacusDeployment.fromDomains( |
|
||||||
domains, |
|
||||||
randomSigner, |
|
||||||
); |
|
||||||
governanceDeployment = await GovernanceDeployment.fromAbacusDeployment( |
|
||||||
abacusDeployment, |
|
||||||
recoveryManager, |
|
||||||
); |
|
||||||
for (const domain of domains) { |
|
||||||
await abacusDeployment.transferOwnership( |
|
||||||
domain, |
|
||||||
governanceDeployment.router(domain).address, |
|
||||||
); |
|
||||||
} |
|
||||||
|
|
||||||
governanceRouter = governanceDeployment.router(localDomain); |
|
||||||
outbox = abacusDeployment.outbox(localDomain); |
|
||||||
validatorManager = abacusDeployment.validatorManager(localDomain); |
|
||||||
|
|
||||||
// set governor
|
|
||||||
await governanceRouter.transferGovernor(localDomain, governor.address); |
|
||||||
}); |
|
||||||
|
|
||||||
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( |
|
||||||
validatorManager, |
|
||||||
recoveryManager, |
|
||||||
randomSigner, |
|
||||||
governor, |
|
||||||
governanceRouter, |
|
||||||
outbox, |
|
||||||
); |
|
||||||
}); |
|
||||||
|
|
||||||
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( |
|
||||||
validatorManager, |
|
||||||
recoveryManager, |
|
||||||
randomSigner, |
|
||||||
governor, |
|
||||||
governanceRouter, |
|
||||||
outbox, |
|
||||||
); |
|
||||||
}); |
|
||||||
|
|
||||||
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 increaseTimestampBy(ethers.provider, timelock.toNumber()); |
|
||||||
expect(await governanceRouter.inRecovery()).to.be.true; |
|
||||||
}); |
|
||||||
|
|
||||||
it('Recovery Active: RecoveryManager CAN call local', async () => { |
|
||||||
// Format abacus call message
|
|
||||||
const call = await formatCall(validatorManager, 'setValidator', [ |
|
||||||
localDomain, |
|
||||||
randomSigner.address, |
|
||||||
]); |
|
||||||
|
|
||||||
// dispatch call on local governorRouter
|
|
||||||
await expect( |
|
||||||
sendFromSigner(recoveryManager, governanceRouter, 'callLocal', [[call]]), |
|
||||||
) |
|
||||||
.to.emit(validatorManager, 'NewValidator') |
|
||||||
.withArgs(localDomain, randomSigner.address); |
|
||||||
}); |
|
||||||
|
|
||||||
it('Recovery Active: RecoveryManager CANNOT call remote', async () => { |
|
||||||
// Format abacus call message
|
|
||||||
const call = await formatCall(validatorManager, 'setValidator', [ |
|
||||||
localDomain, |
|
||||||
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, |
|
||||||
abacus.ethersAddressToBytes32(randomSigner.address), |
|
||||||
]), |
|
||||||
) |
|
||||||
.to.emit(governanceRouter, 'SetRouter') |
|
||||||
.withArgs( |
|
||||||
otherDomain, |
|
||||||
previousRouter, |
|
||||||
abacus.ethersAddressToBytes32(randomSigner.address), |
|
||||||
); |
|
||||||
}); |
|
||||||
|
|
||||||
it('Recovery Active: Governor CANNOT call local OR remote', async () => { |
|
||||||
// Format abacus call message
|
|
||||||
const call = await formatCall(validatorManager, 'setValidator', [ |
|
||||||
localDomain, |
|
||||||
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, |
|
||||||
abacus.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( |
|
||||||
validatorManager, |
|
||||||
recoveryManager, |
|
||||||
randomSigner, |
|
||||||
governor, |
|
||||||
governanceRouter, |
|
||||||
outbox, |
|
||||||
); |
|
||||||
}); |
|
||||||
|
|
||||||
it('Exited Recovery: ONLY RecoveryManager can transfer RecoveryManager role', async () => { |
|
||||||
await expectOnlyRecoveryManagerCanTransferRole( |
|
||||||
governor, |
|
||||||
governanceRouter, |
|
||||||
randomSigner, |
|
||||||
recoveryManager, |
|
||||||
); |
|
||||||
}); |
|
||||||
}); |
|
@ -1,130 +0,0 @@ |
|||||||
import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers'; |
|
||||||
import { assert } from 'chai'; |
|
||||||
import * as ethers from 'ethers'; |
|
||||||
|
|
||||||
import { AbacusDeployment } from '@abacus-network/abacus-sol/test/lib/AbacusDeployment'; |
|
||||||
import { utils, types } from '@abacus-network/utils'; |
|
||||||
|
|
||||||
import { |
|
||||||
MockWeth__factory, |
|
||||||
MockWeth, |
|
||||||
BridgeToken, |
|
||||||
BridgeToken__factory, |
|
||||||
BridgeRouter, |
|
||||||
BridgeRouter__factory, |
|
||||||
ETHHelper, |
|
||||||
ETHHelper__factory, |
|
||||||
} from '../../../typechain'; |
|
||||||
import { |
|
||||||
UpgradeBeacon__factory, |
|
||||||
UpgradeBeacon, |
|
||||||
} from '@abacus-network/abacus-sol/typechain'; |
|
||||||
|
|
||||||
export interface BridgeInstance { |
|
||||||
domain: types.Domain; |
|
||||||
router: BridgeRouter; |
|
||||||
helper: ETHHelper; |
|
||||||
beacon: UpgradeBeacon; |
|
||||||
token: BridgeToken; |
|
||||||
weth: MockWeth; |
|
||||||
signer: ethers.Signer; |
|
||||||
} |
|
||||||
|
|
||||||
export class BridgeDeployment { |
|
||||||
constructor( |
|
||||||
public readonly domains: types.Domain[], |
|
||||||
public readonly instances: Record<number, BridgeInstance>, |
|
||||||
) {} |
|
||||||
|
|
||||||
static async fromAbacusDeployment( |
|
||||||
abacus: AbacusDeployment, |
|
||||||
signer: ethers.Signer, |
|
||||||
) { |
|
||||||
const instances: Record<number, BridgeInstance> = {}; |
|
||||||
for (const domain of abacus.domains) { |
|
||||||
const instance = await BridgeDeployment.deployInstance( |
|
||||||
domain, |
|
||||||
signer, |
|
||||||
abacus.instances[domain].connectionManager.address, |
|
||||||
); |
|
||||||
instances[domain] = instance; |
|
||||||
} |
|
||||||
|
|
||||||
for (const local of abacus.domains) { |
|
||||||
for (const remote of abacus.domains) { |
|
||||||
if (local !== remote) { |
|
||||||
await instances[local].router.enrollRemoteRouter( |
|
||||||
remote, |
|
||||||
utils.addressToBytes32(instances[remote].router.address), |
|
||||||
); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
return new BridgeDeployment(abacus.domains, instances); |
|
||||||
} |
|
||||||
|
|
||||||
static async deployInstance( |
|
||||||
domain: types.Domain, |
|
||||||
signer: ethers.Signer, |
|
||||||
connectionManagerAddress: types.Address, |
|
||||||
): Promise<BridgeInstance> { |
|
||||||
const wethFactory = new MockWeth__factory(signer); |
|
||||||
const weth = await wethFactory.deploy(); |
|
||||||
await weth.initialize(); |
|
||||||
|
|
||||||
const tokenFactory = new BridgeToken__factory(signer); |
|
||||||
const token = await tokenFactory.deploy(); |
|
||||||
await token.initialize(); |
|
||||||
|
|
||||||
const beaconFactory = new UpgradeBeacon__factory(signer); |
|
||||||
const beacon = await beaconFactory.deploy( |
|
||||||
token.address, |
|
||||||
await signer.getAddress(), |
|
||||||
); |
|
||||||
|
|
||||||
const routerFactory = new BridgeRouter__factory(signer); |
|
||||||
const router = await routerFactory.deploy(); |
|
||||||
await router.initialize(beacon.address, connectionManagerAddress); |
|
||||||
|
|
||||||
const helperFactory = new ETHHelper__factory(signer); |
|
||||||
const helper = await helperFactory.deploy(weth.address, router.address); |
|
||||||
return { |
|
||||||
domain, |
|
||||||
beacon, |
|
||||||
router, |
|
||||||
helper, |
|
||||||
token, |
|
||||||
weth, |
|
||||||
signer, |
|
||||||
}; |
|
||||||
} |
|
||||||
|
|
||||||
router(domain: types.Domain): BridgeRouter { |
|
||||||
return this.instances[domain].router; |
|
||||||
} |
|
||||||
|
|
||||||
signer(domain: types.Domain): ethers.Signer { |
|
||||||
return this.instances[domain].signer; |
|
||||||
} |
|
||||||
|
|
||||||
weth(domain: types.Domain): MockWeth { |
|
||||||
return this.instances[domain].weth; |
|
||||||
} |
|
||||||
|
|
||||||
helper(domain: types.Domain): ETHHelper { |
|
||||||
return this.instances[domain].helper; |
|
||||||
} |
|
||||||
|
|
||||||
async bridgeToken( |
|
||||||
local: types.Domain, |
|
||||||
remote: types.Domain, |
|
||||||
address: ethers.BytesLike, |
|
||||||
): Promise<BridgeToken> { |
|
||||||
const router = this.router(local); |
|
||||||
const reprAddr = await router['getLocalAddress(uint32,bytes32)']( |
|
||||||
remote, |
|
||||||
address, |
|
||||||
); |
|
||||||
return BridgeToken__factory.connect(reprAddr, this.signer(local)); |
|
||||||
} |
|
||||||
} |
|
@ -1,79 +0,0 @@ |
|||||||
import { ethers } from 'ethers'; |
|
||||||
import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers'; |
|
||||||
import { utils, types } from '@abacus-network/utils'; |
|
||||||
import { AbacusDeployment } from '@abacus-network/abacus-sol/test'; |
|
||||||
|
|
||||||
import { |
|
||||||
GovernanceRouter__factory, |
|
||||||
GovernanceRouter, |
|
||||||
} from '../../../typechain'; |
|
||||||
|
|
||||||
export interface GovernanceInstance { |
|
||||||
domain: types.Domain; |
|
||||||
router: GovernanceRouter; |
|
||||||
} |
|
||||||
|
|
||||||
const recoveryTimelock = 60 * 60 * 24 * 7; |
|
||||||
|
|
||||||
export class GovernanceDeployment { |
|
||||||
constructor( |
|
||||||
public readonly domains: types.Domain[], |
|
||||||
public readonly instances: Record<number, GovernanceInstance>, |
|
||||||
) {} |
|
||||||
|
|
||||||
static async fromAbacusDeployment( |
|
||||||
abacus: AbacusDeployment, |
|
||||||
governor: SignerWithAddress, |
|
||||||
recoveryManager: SignerWithAddress, |
|
||||||
) { |
|
||||||
// Deploy routers.
|
|
||||||
const instances: Record<number, GovernanceInstance> = {}; |
|
||||||
for (const domain of abacus.domains) { |
|
||||||
const instance = await GovernanceDeployment.deployInstance( |
|
||||||
domain, |
|
||||||
governor, |
|
||||||
recoveryManager, |
|
||||||
abacus.connectionManager(domain).address, |
|
||||||
); |
|
||||||
instances[domain] = instance; |
|
||||||
} |
|
||||||
|
|
||||||
// Make all routers aware of eachother.
|
|
||||||
for (const local of abacus.domains) { |
|
||||||
for (const remote of abacus.domains) { |
|
||||||
await instances[local].router.enrollRemoteRouter( |
|
||||||
remote, |
|
||||||
utils.addressToBytes32(instances[remote].router.address), |
|
||||||
); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
// Set the governor on one router, clear it on all other routers.
|
|
||||||
for (let i = 0; i < abacus.domains.length; i++) { |
|
||||||
const addr = i === 0 ? governor.address : ethers.constants.AddressZero; |
|
||||||
await instances[abacus.domains[i]].router.setGovernor(addr); |
|
||||||
} |
|
||||||
|
|
||||||
return new GovernanceDeployment(abacus.domains, instances); |
|
||||||
} |
|
||||||
|
|
||||||
static async deployInstance( |
|
||||||
domain: types.Domain, |
|
||||||
governor: SignerWithAddress, |
|
||||||
recoveryManager: SignerWithAddress, |
|
||||||
connectionManagerAddress: types.Address, |
|
||||||
): Promise<GovernanceInstance> { |
|
||||||
const routerFactory = new GovernanceRouter__factory(governor); |
|
||||||
const router = await routerFactory.deploy(recoveryTimelock); |
|
||||||
await router.initialize(connectionManagerAddress); |
|
||||||
await router.transferOwnership(recoveryManager.address); |
|
||||||
return { |
|
||||||
domain, |
|
||||||
router, |
|
||||||
}; |
|
||||||
} |
|
||||||
|
|
||||||
router(domain: types.Domain): GovernanceRouter { |
|
||||||
return this.instances[domain].router; |
|
||||||
} |
|
||||||
} |
|
@ -1,73 +1,16 @@ |
|||||||
{ |
{ |
||||||
"compilerOptions": { |
"compilerOptions": { |
||||||
/* Visit https://aka.ms/tsconfig.json to read more about this file */ |
"outDir": "./dist/", |
||||||
|
"rootDir": "./types/" |
||||||
/* Basic Options */ |
}, |
||||||
// "incremental": true, /* Enable incremental compilation */ |
"exclude": [ |
||||||
"target": "ES2017" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', 'ES2021', or 'ESNEXT'. */, |
"./node_modules/", |
||||||
"module": "commonjs" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */, |
"./dist/", |
||||||
// "lib": [], /* Specify library files to be included in the compilation. */ |
"./types/hardhat.d.ts" |
||||||
// "allowJs": true, /* Allow javascript files to be compiled. */ |
], |
||||||
// "checkJs": true, /* Report errors in .js files. */ |
"extends": "../../tsconfig.package.json", |
||||||
// "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', 'react', 'react-jsx' or 'react-jsxdev'. */ |
"include": [ |
||||||
// "declaration": true, /* Generates corresponding '.d.ts' file. */ |
"./types/*.ts", |
||||||
// "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */ |
"./types/factories/*.ts" |
||||||
// "sourceMap": true, /* Generates corresponding '.map' file. */ |
] |
||||||
// "outFile": "./", /* Concatenate and emit output to single file. */ |
|
||||||
// "outDir": "./", /* Redirect output structure to the directory. */ |
|
||||||
// "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ |
|
||||||
// "composite": true, /* Enable project compilation */ |
|
||||||
// "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */ |
|
||||||
// "removeComments": true, /* Do not emit comments to output. */ |
|
||||||
// "noEmit": true, /* Do not emit outputs. */ |
|
||||||
// "importHelpers": true, /* Import emit helpers from 'tslib'. */ |
|
||||||
// "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ |
|
||||||
// "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ |
|
||||||
"resolveJsonModule": true /* Allows for importing, extracting types from and generating . json files.*/, |
|
||||||
|
|
||||||
/* Strict Type-Checking Options */ |
|
||||||
"strict": true /* Enable all strict type-checking options. */, |
|
||||||
// "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ |
|
||||||
// "strictNullChecks": true, /* Enable strict null checks. */ |
|
||||||
// "strictFunctionTypes": true, /* Enable strict checking of function types. */ |
|
||||||
// "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */ |
|
||||||
// "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */ |
|
||||||
// "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ |
|
||||||
// "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ |
|
||||||
|
|
||||||
/* Additional Checks */ |
|
||||||
// "noUnusedLocals": true, /* Report errors on unused locals. */ |
|
||||||
// "noUnusedParameters": true, /* Report errors on unused parameters. */ |
|
||||||
// "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ |
|
||||||
// "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ |
|
||||||
// "noUncheckedIndexedAccess": true, /* Include 'undefined' in index signature results */ |
|
||||||
// "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an 'override' modifier. */ |
|
||||||
// "noPropertyAccessFromIndexSignature": true, /* Require undeclared properties from index signatures to use element accesses. */ |
|
||||||
|
|
||||||
/* Module Resolution Options */ |
|
||||||
// "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ |
|
||||||
// "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ |
|
||||||
// "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ |
|
||||||
// "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */ |
|
||||||
// "typeRoots": [], /* List of folders to include type definitions from. */ |
|
||||||
// "types": [], /* Type declaration files to be included in compilation. */ |
|
||||||
// "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ |
|
||||||
"esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */, |
|
||||||
// "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ |
|
||||||
// "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ |
|
||||||
|
|
||||||
/* Source Map Options */ |
|
||||||
// "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ |
|
||||||
// "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ |
|
||||||
// "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */ |
|
||||||
// "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */ |
|
||||||
|
|
||||||
/* Experimental Options */ |
|
||||||
// "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ |
|
||||||
// "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ |
|
||||||
|
|
||||||
/* Advanced Options */ |
|
||||||
"skipLibCheck": true /* Skip type checking of declaration files. */, |
|
||||||
"forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */ |
|
||||||
} |
|
||||||
} |
} |
||||||
|
@ -1,10 +1,10 @@ |
|||||||
{ |
{ |
||||||
"compilerOptions": { |
"compilerOptions": { |
||||||
"composite": true, |
|
||||||
"declaration": true, |
"declaration": true, |
||||||
"declarationMap": true, |
"declarationMap": true, |
||||||
"esModuleInterop": true, |
"esModuleInterop": true, |
||||||
"forceConsistentCasingInFileNames": true, |
"forceConsistentCasingInFileNames": true, |
||||||
|
"incremental": false, |
||||||
"lib": ["es2015", "es5", "dom"], |
"lib": ["es2015", "es5", "dom"], |
||||||
"module": "commonjs", |
"module": "commonjs", |
||||||
"moduleResolution": "node", |
"moduleResolution": "node", |
@ -1,4 +1,3 @@ |
|||||||
dist/ |
dist/ |
||||||
unprocessed/ |
unprocessed/ |
||||||
tsconfig.tsbuildinfo |
|
||||||
credentials.json |
credentials.json |
||||||
|
@ -1,4 +0,0 @@ |
|||||||
.env |
|
||||||
dist |
|
||||||
abacus-core/* |
|
||||||
abacus-xapps/* |
|
@ -1,2 +0,0 @@ |
|||||||
export * as core from "./abacus-core"; |
|
||||||
export * as xapps from "./abacus-xapps"; |
|
@ -1,23 +0,0 @@ |
|||||||
{ |
|
||||||
"scripts": { |
|
||||||
"build": "tsc && npm run copy-files", |
|
||||||
"check": "tsc --noEmit", |
|
||||||
"copy-files": "cp abacus-core/*.d.ts dist/abacus-core && cp abacus-xapps/*.d.ts dist/abacus-xapps" |
|
||||||
}, |
|
||||||
"devDependencies": { |
|
||||||
"ethers": "^5.5.3" |
|
||||||
}, |
|
||||||
"name": "@abacus-network/ts-interface", |
|
||||||
"version": "0.0.1", |
|
||||||
"description": "Abacus contract typechain gens", |
|
||||||
"main": "dist/index.js", |
|
||||||
"types": "dist/index.d.ts", |
|
||||||
"author": "Celo Labs Inc.", |
|
||||||
"license": "MIT OR Apache-2.0", |
|
||||||
"prepublish": "npm run build", |
|
||||||
"dependencies": { |
|
||||||
"@ethersproject/experimental": "^5.5.0", |
|
||||||
"@types/node": "^16.11.21", |
|
||||||
"typescript": "^4.5.5" |
|
||||||
} |
|
||||||
} |
|
@ -1,20 +0,0 @@ |
|||||||
{ |
|
||||||
"compilerOptions": { |
|
||||||
"outDir": "./dist/", |
|
||||||
"rootDir": "./" |
|
||||||
}, |
|
||||||
"exclude": [ |
|
||||||
"./node_modules/", |
|
||||||
"./dist/", |
|
||||||
"./abacus-core/hardhat.d.ts", |
|
||||||
"./abacus-xapps/hardhat.d.ts" |
|
||||||
], |
|
||||||
"extends": "../tsconfig.package.json", |
|
||||||
"include": [ |
|
||||||
"./index.ts", |
|
||||||
"./abacus-core/*.ts", |
|
||||||
"./abacus-xapps/*.ts", |
|
||||||
"./abacus-core/factories/*.ts", |
|
||||||
"./abacus-xapps/factories/*.ts" |
|
||||||
] |
|
||||||
} |
|
Loading…
Reference in new issue