Skip to content

Commit

Permalink
feat: allow configuration of Gnosis contractAddresses
Browse files Browse the repository at this point in the history
Provide our own types as gnosis does not define adequate types.

Signed-off-by: Ryan Goulding <[email protected]>
  • Loading branch information
ryandgoulding committed Nov 28, 2023
1 parent cf3d897 commit baf0e15
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 7 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@layerzerolabs/ua-utils",
"version": "0.0.17",
"version": "0.0.21",
"repository": "https://github.com/LayerZero-Labs/ua-utils.git",
"license": "MIT",
"main": "dist/index.js",
Expand Down
13 changes: 7 additions & 6 deletions src/utils/crossChainHelper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ import Safe from "@gnosis.pm/safe-core-sdk";
import { LZ_APP_ABI } from "../constants/abi";
import { LZ_ENDPOINTS } from "../constants/endpoints";
import { MainnetEndpointId, TestnetEndpointId, SandboxEndpointId } from "@layerzerolabs/lz-definitions";
import { promptToProceed, arrayToCsv, getConfig } from "./helpers";
import { toContractNetworksString, getSafeConfigs, SafeConfigs } from './gnosis'
import { promptToProceed, arrayToCsv } from "./helpers";
const path = require("path");
const fs = require("fs");
import { writeFile } from "fs/promises";
Expand Down Expand Up @@ -174,7 +175,7 @@ export async function executeTransactions(hre: any, taskArgs: any, transactionBy

if (taskArgs.n) {
await promptToProceed("Would you like to Submit to gnosis?", taskArgs.noPrompt);
const gnosisConfig = getConfig(taskArgs.gnosisConfigPath);
const gnosisConfig = getSafeConfigs(taskArgs.gnosisConfigPath);
await Promise.all(
transactionBynetwork.map(async ({ network, transactions }) => {
const transactionToCommit = transactions.filter((transaction: any) => transaction.needChange);
Expand Down Expand Up @@ -239,22 +240,22 @@ export async function executeTransactions(hre: any, taskArgs: any, transactionBy
}


export const executeGnosisTransactions = async (hre: any, network: string, gnosisConfig: any, transactions: Transaction[]) => {
export const executeGnosisTransactions = async (hre: any, network: string, gnosisConfig: SafeConfigs, transactions: Transaction[]) => {
const signer = await getConnectedWallet(hre, network, 0);
if (!gnosisConfig[network]) {
throw Error(`Gnosis for ${network} not found or not supported`);
}

const { safeAddress, url } = gnosisConfig[network];
console.log(`safeAddress[${safeAddress}] url[${url}]`);
const { safeAddress, url, contractNetworks } = gnosisConfig[network];
console.log(`safeAddress[${safeAddress}] url[${url}] ${toContractNetworksString(contractNetworks)}`);

const safeService = new SafeServiceClient(url);
const ethAdapter = new EthersAdapter({
ethers: hre.ethers,
signerOrProvider: signer,
});

const safeSdk: Safe = await Safe.create({ ethAdapter, safeAddress });
const safeSdk: Safe = await Safe.create({ ethAdapter, safeAddress, ...(!!contractNetworks && contractNetworks)});
const gnosisTransactions = transactions.map((tx) => ({ to: tx.contractAddress, data: tx.calldata!, value: "0" }));
const nonce = await safeService.getNextNonce(safeAddress);
const safeTransaction = await safeSdk.createTransaction(gnosisTransactions, { nonce });
Expand Down
51 changes: 51 additions & 0 deletions src/utils/gnosis.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { readFileSync } from 'fs'

const GNOSIS_SAFE_FILE_ENCODING = 'utf-8'

/**
* Gnosis Safe configuration for a specific network.
*/
type SafeConfig = {
safeAddress: string
url: string
contractNetworks?: ContractNetworks
}

/**
* Contract addresses for each network.
*/
type ContractNetworks = {
[chainListId: number]: {
multiSendAddress: string
safeMasterCopyAddress: string
safeProxyFactoryAddress: string
}
}

/**
* Converts a ContractNetworks object to a string.
* @param {ContractNetworks} contractNetworks The ContractNetworks object to convert.
*/
export const toContractNetworksString = (contractNetworks?: ContractNetworks): string => {
if (contractNetworks === undefined) {
return ''
}
return Object.entries(contractNetworks).reduce((accumulator, [chainListId, config]) => {
return accumulator + `contractNetworks[chainListId=${chainListId}, multiSendAddress=${config.multiSendAddress}, safeMasterCopyAddress=${config.safeMasterCopyAddress}, safeProxyFactoryAddress=${config.safeProxyFactoryAddress}]`;
}, '');
}

/**
* Gnosis Safe configuration per network.
*/
export interface SafeConfigs {
[chainName: string]: SafeConfig
}

/**
* Reads the safe config file and returns the parsed SafeConfigs.
* @param {string} fileName The name of the safe config file.
*/
export const getSafeConfigs = (fileName: string): SafeConfigs => {
return JSON.parse(readFileSync(fileName, GNOSIS_SAFE_FILE_ENCODING)) as SafeConfigs
}

0 comments on commit baf0e15

Please sign in to comment.