[contract-manager] Evm contract manager verification (#981)
* Add eos network to contract manager * Wormhole contract inspection tooling * Helper function to hash contract code
This commit is contained in:
parent
7cd9ec7e03
commit
69182f29c2
|
@ -7,6 +7,19 @@ import { DataSource } from "xc_admin_common";
|
|||
// Just to make sure tx gas limit is enough
|
||||
const GAS_ESTIMATE_MULTIPLIER = 2;
|
||||
const EXTENDED_PYTH_ABI = [
|
||||
{
|
||||
inputs: [],
|
||||
name: "wormhole",
|
||||
outputs: [
|
||||
{
|
||||
internalType: "contract IWormhole",
|
||||
name: "",
|
||||
type: "address",
|
||||
},
|
||||
],
|
||||
stateMutability: "view",
|
||||
type: "function",
|
||||
},
|
||||
{
|
||||
inputs: [],
|
||||
name: "governanceDataSource",
|
||||
|
@ -126,6 +139,74 @@ const EXTENDED_PYTH_ABI = [
|
|||
...PythInterfaceAbi,
|
||||
] as any;
|
||||
|
||||
const WORMHOLE_ABI = [
|
||||
{
|
||||
inputs: [],
|
||||
name: "getCurrentGuardianSetIndex",
|
||||
outputs: [
|
||||
{
|
||||
internalType: "uint32",
|
||||
name: "",
|
||||
type: "uint32",
|
||||
},
|
||||
],
|
||||
stateMutability: "view",
|
||||
type: "function",
|
||||
},
|
||||
{
|
||||
inputs: [
|
||||
{
|
||||
internalType: "uint32",
|
||||
name: "index",
|
||||
type: "uint32",
|
||||
},
|
||||
],
|
||||
name: "getGuardianSet",
|
||||
outputs: [
|
||||
{
|
||||
components: [
|
||||
{
|
||||
internalType: "address[]",
|
||||
name: "keys",
|
||||
type: "address[]",
|
||||
},
|
||||
{
|
||||
internalType: "uint32",
|
||||
name: "expirationTime",
|
||||
type: "uint32",
|
||||
},
|
||||
],
|
||||
internalType: "struct Structs.GuardianSet",
|
||||
name: "",
|
||||
type: "tuple",
|
||||
},
|
||||
],
|
||||
stateMutability: "view",
|
||||
type: "function",
|
||||
},
|
||||
] as any;
|
||||
export class WormholeEvmContract {
|
||||
constructor(public chain: EvmChain, public address: string) {}
|
||||
getContract() {
|
||||
const web3 = new Web3(this.chain.getRpcUrl());
|
||||
return new web3.eth.Contract(WORMHOLE_ABI, this.address);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of guardian addresses used for VAA verification in this contract
|
||||
*/
|
||||
async getGuardianSet(): Promise<string[]> {
|
||||
const wormholeContract = this.getContract();
|
||||
const currentIndex = await wormholeContract.methods
|
||||
.getCurrentGuardianSetIndex()
|
||||
.call();
|
||||
const [currentSet] = await wormholeContract.methods
|
||||
.getGuardianSet(currentIndex)
|
||||
.call();
|
||||
return currentSet;
|
||||
}
|
||||
}
|
||||
|
||||
export class EvmContract extends Contract {
|
||||
static type = "EvmContract";
|
||||
|
||||
|
@ -197,10 +278,24 @@ export class EvmContract extends Contract {
|
|||
* Returns the bytecode of the contract in hex format
|
||||
*/
|
||||
async getCode(): Promise<string> {
|
||||
// TODO: handle proxy contracts
|
||||
const web3 = new Web3(this.chain.getRpcUrl());
|
||||
return web3.eth.getCode(this.address);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the keccak256 digest of the contract bytecode after replacing any occurences of the contract addr in the bytecode with 0
|
||||
* This is used to verify that the contract code is the same on all chains
|
||||
*/
|
||||
async getCodeDigestWithoutAddress(): Promise<string> {
|
||||
const code = await this.getCode();
|
||||
const strippedCode = code.replaceAll(
|
||||
this.address.toLowerCase().replace("0x", ""),
|
||||
"0000000000000000000000000000000000000000"
|
||||
);
|
||||
return Web3.utils.keccak256(strippedCode);
|
||||
}
|
||||
|
||||
async getLastExecutedGovernanceSequence() {
|
||||
const pythContract = await this.getContract();
|
||||
return Number(
|
||||
|
@ -238,6 +333,15 @@ export class EvmContract extends Contract {
|
|||
return Number(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the wormhole contract which is being used for VAA verification
|
||||
*/
|
||||
async getWormholeContract(): Promise<WormholeEvmContract> {
|
||||
const pythContract = this.getContract();
|
||||
const address = await pythContract.methods.wormhole().call();
|
||||
return new WormholeEvmContract(this.chain, address);
|
||||
}
|
||||
|
||||
async getBaseUpdateFee() {
|
||||
const pythContract = this.getContract();
|
||||
const result = await pythContract.methods.singleUpdateFeeInWei().call();
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
id: eos
|
||||
wormholeChainName: eos
|
||||
mainnet: true
|
||||
rpcUrl: https://api.evm.eosnetwork.com
|
||||
networkId: 17777
|
||||
type: EvmChain
|
|
@ -0,0 +1,6 @@
|
|||
id: eos_testnet
|
||||
wormholeChainName: eos
|
||||
mainnet: false
|
||||
rpcUrl: https://api.testnet.evm.eosnetwork.com
|
||||
networkId: 15557
|
||||
type: EvmChain
|
|
@ -0,0 +1,3 @@
|
|||
chain: eos
|
||||
address: "0xA2aa501b19aff244D90cc15a4Cf739D2725B5729"
|
||||
type: EvmContract
|
|
@ -0,0 +1,3 @@
|
|||
chain: eos_testnet
|
||||
address: "0xA2aa501b19aff244D90cc15a4Cf739D2725B5729"
|
||||
type: EvmContract
|
Loading…
Reference in New Issue