Skip to content

Commit

Permalink
chore: sending all related governance payload to solana
Browse files Browse the repository at this point in the history
  • Loading branch information
kupermind committed Jun 13, 2024
1 parent 39ac89c commit fa17ac1
Show file tree
Hide file tree
Showing 15 changed files with 557 additions and 7 deletions.
1 change: 1 addition & 0 deletions abis/test/WormholeCore.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"previousAdmin","type":"address"},{"indexed":false,"internalType":"address","name":"newAdmin","type":"address"}],"name":"AdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"beacon","type":"address"}],"name":"BeaconUpgraded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"oldContract","type":"address"},{"indexed":true,"internalType":"address","name":"newContract","type":"address"}],"name":"ContractUpgraded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint32","name":"index","type":"uint32"}],"name":"GuardianSetAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint64","name":"sequence","type":"uint64"},{"indexed":false,"internalType":"uint32","name":"nonce","type":"uint32"},{"indexed":false,"internalType":"bytes","name":"payload","type":"bytes"},{"indexed":false,"internalType":"uint8","name":"consistencyLevel","type":"uint8"}],"name":"LogMessagePublished","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"implementation","type":"address"}],"name":"Upgraded","type":"event"},{"stateMutability":"payable","type":"fallback"},{"inputs":[],"name":"chainId","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"evmChainId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"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"},{"inputs":[],"name":"getGuardianSetExpiry","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"hash","type":"bytes32"}],"name":"governanceActionIsConsumed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"governanceChainId","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"governanceContract","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"isFork","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"impl","type":"address"}],"name":"isInitialized","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"messageFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"emitter","type":"address"}],"name":"nextSequence","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"encodedVM","type":"bytes"}],"name":"parseAndVerifyVM","outputs":[{"components":[{"internalType":"uint8","name":"version","type":"uint8"},{"internalType":"uint32","name":"timestamp","type":"uint32"},{"internalType":"uint32","name":"nonce","type":"uint32"},{"internalType":"uint16","name":"emitterChainId","type":"uint16"},{"internalType":"bytes32","name":"emitterAddress","type":"bytes32"},{"internalType":"uint64","name":"sequence","type":"uint64"},{"internalType":"uint8","name":"consistencyLevel","type":"uint8"},{"internalType":"bytes","name":"payload","type":"bytes"},{"internalType":"uint32","name":"guardianSetIndex","type":"uint32"},{"components":[{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"uint8","name":"guardianIndex","type":"uint8"}],"internalType":"struct Structs.Signature[]","name":"signatures","type":"tuple[]"},{"internalType":"bytes32","name":"hash","type":"bytes32"}],"internalType":"struct Structs.VM","name":"vm","type":"tuple"},{"internalType":"bool","name":"valid","type":"bool"},{"internalType":"string","name":"reason","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"encodedUpgrade","type":"bytes"}],"name":"parseContractUpgrade","outputs":[{"components":[{"internalType":"bytes32","name":"module","type":"bytes32"},{"internalType":"uint8","name":"action","type":"uint8"},{"internalType":"uint16","name":"chain","type":"uint16"},{"internalType":"address","name":"newContract","type":"address"}],"internalType":"struct GovernanceStructs.ContractUpgrade","name":"cu","type":"tuple"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes","name":"encodedUpgrade","type":"bytes"}],"name":"parseGuardianSetUpgrade","outputs":[{"components":[{"internalType":"bytes32","name":"module","type":"bytes32"},{"internalType":"uint8","name":"action","type":"uint8"},{"internalType":"uint16","name":"chain","type":"uint16"},{"components":[{"internalType":"address[]","name":"keys","type":"address[]"},{"internalType":"uint32","name":"expirationTime","type":"uint32"}],"internalType":"struct Structs.GuardianSet","name":"newGuardianSet","type":"tuple"},{"internalType":"uint32","name":"newGuardianSetIndex","type":"uint32"}],"internalType":"struct GovernanceStructs.GuardianSetUpgrade","name":"gsu","type":"tuple"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes","name":"encodedRecoverChainId","type":"bytes"}],"name":"parseRecoverChainId","outputs":[{"components":[{"internalType":"bytes32","name":"module","type":"bytes32"},{"internalType":"uint8","name":"action","type":"uint8"},{"internalType":"uint256","name":"evmChainId","type":"uint256"},{"internalType":"uint16","name":"newChainId","type":"uint16"}],"internalType":"struct GovernanceStructs.RecoverChainId","name":"rci","type":"tuple"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes","name":"encodedSetMessageFee","type":"bytes"}],"name":"parseSetMessageFee","outputs":[{"components":[{"internalType":"bytes32","name":"module","type":"bytes32"},{"internalType":"uint8","name":"action","type":"uint8"},{"internalType":"uint16","name":"chain","type":"uint16"},{"internalType":"uint256","name":"messageFee","type":"uint256"}],"internalType":"struct GovernanceStructs.SetMessageFee","name":"smf","type":"tuple"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes","name":"encodedTransferFees","type":"bytes"}],"name":"parseTransferFees","outputs":[{"components":[{"internalType":"bytes32","name":"module","type":"bytes32"},{"internalType":"uint8","name":"action","type":"uint8"},{"internalType":"uint16","name":"chain","type":"uint16"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes32","name":"recipient","type":"bytes32"}],"internalType":"struct GovernanceStructs.TransferFees","name":"tf","type":"tuple"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes","name":"encodedVM","type":"bytes"}],"name":"parseVM","outputs":[{"components":[{"internalType":"uint8","name":"version","type":"uint8"},{"internalType":"uint32","name":"timestamp","type":"uint32"},{"internalType":"uint32","name":"nonce","type":"uint32"},{"internalType":"uint16","name":"emitterChainId","type":"uint16"},{"internalType":"bytes32","name":"emitterAddress","type":"bytes32"},{"internalType":"uint64","name":"sequence","type":"uint64"},{"internalType":"uint8","name":"consistencyLevel","type":"uint8"},{"internalType":"bytes","name":"payload","type":"bytes"},{"internalType":"uint32","name":"guardianSetIndex","type":"uint32"},{"components":[{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"uint8","name":"guardianIndex","type":"uint8"}],"internalType":"struct Structs.Signature[]","name":"signatures","type":"tuple[]"},{"internalType":"bytes32","name":"hash","type":"bytes32"}],"internalType":"struct Structs.VM","name":"vm","type":"tuple"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint32","name":"nonce","type":"uint32"},{"internalType":"bytes","name":"payload","type":"bytes"},{"internalType":"uint8","name":"consistencyLevel","type":"uint8"}],"name":"publishMessage","outputs":[{"internalType":"uint64","name":"sequence","type":"uint64"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"numGuardians","type":"uint256"}],"name":"quorum","outputs":[{"internalType":"uint256","name":"numSignaturesRequiredForQuorum","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes","name":"_vm","type":"bytes"}],"name":"submitContractUpgrade","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"_vm","type":"bytes"}],"name":"submitNewGuardianSet","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"_vm","type":"bytes"}],"name":"submitRecoverChainId","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"_vm","type":"bytes"}],"name":"submitSetMessageFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"_vm","type":"bytes"}],"name":"submitTransferFees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"hash","type":"bytes32"},{"components":[{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"uint8","name":"guardianIndex","type":"uint8"}],"internalType":"struct Structs.Signature[]","name":"signatures","type":"tuple[]"},{"components":[{"internalType":"address[]","name":"keys","type":"address[]"},{"internalType":"uint32","name":"expirationTime","type":"uint32"}],"internalType":"struct Structs.GuardianSet","name":"guardianSet","type":"tuple"}],"name":"verifySignatures","outputs":[{"internalType":"bool","name":"valid","type":"bool"},{"internalType":"string","name":"reason","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[{"components":[{"internalType":"uint8","name":"version","type":"uint8"},{"internalType":"uint32","name":"timestamp","type":"uint32"},{"internalType":"uint32","name":"nonce","type":"uint32"},{"internalType":"uint16","name":"emitterChainId","type":"uint16"},{"internalType":"bytes32","name":"emitterAddress","type":"bytes32"},{"internalType":"uint64","name":"sequence","type":"uint64"},{"internalType":"uint8","name":"consistencyLevel","type":"uint8"},{"internalType":"bytes","name":"payload","type":"bytes"},{"internalType":"uint32","name":"guardianSetIndex","type":"uint32"},{"components":[{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"uint8","name":"guardianIndex","type":"uint8"}],"internalType":"struct Structs.Signature[]","name":"signatures","type":"tuple[]"},{"internalType":"bytes32","name":"hash","type":"bytes32"}],"internalType":"struct Structs.VM","name":"vm","type":"tuple"}],"name":"verifyVM","outputs":[{"internalType":"bool","name":"valid","type":"bool"},{"internalType":"string","name":"reason","type":"string"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]
14 changes: 7 additions & 7 deletions contracts/bridges/test/MockTimelock.sol
Original file line number Diff line number Diff line change
@@ -1,25 +1,25 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;
pragma solidity ^0.8.25;

error ExecFailed(address fxRoot, bytes payload);
error ExecFailed(address relayer, bytes payload);

/// @title MockTimelock - Mock of Timelock contract on the L1 side
/// @author Aleksandr Kuperman - <[email protected]>
/// @author AL
contract MockTimelock {
// Fx Root address on L1
address public immutable fxRoot;
address public immutable relayer;

constructor(address _fxRoot) {
fxRoot = _fxRoot;
constructor(address _relayer) {
relayer = _relayer;
}

/// @dev Executes the payload at the Fx Root address.
/// @param payload Bytes of payload.
function execute(bytes memory payload) external payable {
(bool success, ) = fxRoot.call{value: msg.value}(payload);
(bool success, ) = relayer.call{value: msg.value}(payload);
if (!success) {
revert ExecFailed(fxRoot, payload);
revert ExecFailed(relayer, payload);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/*global process*/

const { ethers } = require("hardhat");
const { LedgerSigner } = require("@anders-t/ethers-ledger");

Check warning on line 4 in scripts/deployment/bridges/solana/test/polygon/deploy_00_mock_timelock.js

View workflow job for this annotation

GitHub Actions / build

'LedgerSigner' is assigned a value but never used

async function main() {
const fs = require("fs");
const globalsFile = "globals.json";
const dataFromJSON = fs.readFileSync(globalsFile, "utf8");
let parsedData = JSON.parse(dataFromJSON);
const providerName = parsedData.providerName;

let networkURL = parsedData.networkURL;
if (providerName === "polygon") {
if (!process.env.ALCHEMY_API_KEY_MATIC) {
console.log("set ALCHEMY_API_KEY_MATIC env variable");
}
networkURL += process.env.ALCHEMY_API_KEY_MATIC;
} else if (providerName === "polygonAmoy") {
if (!process.env.ALCHEMY_API_KEY_AMOY) {
console.log("set ALCHEMY_API_KEY_AMOY env variable");
return;
}
networkURL += process.env.ALCHEMY_API_KEY_AMOY;
}

const provider = new ethers.providers.JsonRpcProvider(networkURL);

Check warning on line 27 in scripts/deployment/bridges/solana/test/polygon/deploy_00_mock_timelock.js

View workflow job for this annotation

GitHub Actions / build

'provider' is assigned a value but never used
const signers = await ethers.getSigners();

// EOA address
const EOA = signers[0];
const deployer = await EOA.getAddress();
console.log("EOA is:", deployer);

// Transaction signing and execution
console.log("1. EOA to deploy mock timelock contract");
const Timelock = await ethers.getContractFactory("MockTimelock");
console.log("You are signing the following transaction: Timelock.connect(EOA).deploy(WormholeAddress)");
const timelock = await Timelock.connect(EOA).deploy(parsedData.wormholeAddress);
const result = await timelock.deployed();

// Transaction details
console.log("Contract deployment: MockTimelock");
console.log("Contract address:", timelock.address);
console.log("Transaction:", result.deployTransaction.hash);

// Writing updated parameters back to the JSON file
parsedData.timelockAddress = timelock.address;
fs.writeFileSync(globalsFile, JSON.stringify(parsedData));

// Contract verification
if (parsedData.contractVerification) {
const execSync = require("child_process").execSync;
execSync("npx hardhat verify --constructor-args scripts/deployment/bridges/solana/test/polygon/verify_00_mock_timelock.js --network " + providerName + " " + timelock.address, { encoding: "utf-8" });
}
}

main()
.then(() => process.exit(0))
.catch((error) => {
console.error(error);
process.exit(1);
});
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"contractVerification":true,"providerName":"polygon","networkURL":"https://polygon-mainnet.g.alchemy.com/v2/","gasPriceInGwei":"40","wormholeAddress":"0x7A4B5a56256163F07b2C80A7cA55aBE66c4ec4d7","timelockAddress":""}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*global process*/

const { ethers } = require("ethers");

async function main() {
const ALCHEMY_API_KEY_MATIC = process.env.ALCHEMY_API_KEY_MATIC;
const polygonURL = "https://polygon-mainnet.g.alchemy.com/v2/" + ALCHEMY_API_KEY_MATIC;
const polygonProvider = new ethers.providers.JsonRpcProvider(polygonURL);
await polygonProvider.getBlockNumber().then((result) => {
console.log("Current block number polygon: " + result);
});

const fs = require("fs");
// Wormhole Core address on polygon
const wormholeAddress = "0x7A4B5a56256163F07b2C80A7cA55aBE66c4ec4d7";
const wormholeJSON = "abis/test/WormholeCore.json";
let contractFromJSON = fs.readFileSync(wormholeJSON, "utf8");
const wormholeABI = JSON.parse(contractFromJSON);
const wormhole = new ethers.Contract(wormholeAddress, wormholeABI, polygonProvider);

// Mock Timelock contract address on goerli (has Wormhole Core address in it already)
const mockTimelockAddress = "0x4cEB52802ef86edF8796632546d89e55c87a0901";
const mockTimelockJSON = "artifacts/contracts/bridges/test/MockTimelock.sol/MockTimelock.json";
contractFromJSON = fs.readFileSync(mockTimelockJSON, "utf8");
parsedFile = JSON.parse(contractFromJSON);

Check failure on line 25 in scripts/deployment/bridges/solana/test/polygon/timelock_send_message.js

View workflow job for this annotation

GitHub Actions / build

'parsedFile' is not defined
const mockTimelockABI = parsedFile["abi"];

Check failure on line 26 in scripts/deployment/bridges/solana/test/polygon/timelock_send_message.js

View workflow job for this annotation

GitHub Actions / build

'parsedFile' is not defined
const mockTimelock = new ethers.Contract(mockTimelockAddress, mockTimelockABI, polygonProvider);

// Get the EOA
const account = ethers.utils.HDNode.fromMnemonic(process.env.TESTNET_MNEMONIC).derivePath("m/44'/60'/0'/0/0");
const EOApolygon = new ethers.Wallet(account, polygonProvider);
console.log(EOApolygon.address);

// Wrap the data to send over the bridge
// hello world == 68656c6c6f20776f726c64
const data = "0x68656c6c6f20776f726c64";

const wormholeFinality = 0; // 0 = confirmed, 1 = finalized
const payload = wormhole.interface.encodeFunctionData("publishMessage", [0, data, wormholeFinality]);
console.log(payload);
const gasPrice = ethers.utils.parseUnits("40", "gwei");
const tx = await mockTimelock.connect(EOApolygon).execute(payload, { gasPrice });
console.log("Timelock data execution hash", tx.hash);
await tx.wait();

// https://wormholescan.io/#/tx/0x7b0145014a4e8f0d8621fbc0e366460dda3ba307732eff539f7c1e8e6589718a?view=advanced
}

main()
.then(() => process.exit(0))
.catch((error) => {
console.error(error);
process.exit(1);
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
const fs = require("fs");
const globalsFile = "globals.json";
const dataFromJSON = fs.readFileSync(globalsFile, "utf8");
const parsedData = JSON.parse(dataFromJSON);

module.exports = [
parsedData.wormholeAddress
];
Loading

0 comments on commit fa17ac1

Please sign in to comment.