Skip to content
This repository has been archived by the owner on Oct 27, 2023. It is now read-only.

Commit

Permalink
Add tasks to interact with test registry (5afe#14)
Browse files Browse the repository at this point in the history
  • Loading branch information
rmeissner authored Jul 13, 2023
1 parent 77e091a commit c5b6394
Show file tree
Hide file tree
Showing 11 changed files with 62 additions and 27 deletions.
1 change: 1 addition & 0 deletions contracts/contracts/Imports.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ pragma solidity ^0.8.18;

// Import the contract so hardhat compiles it, and we have the ABI available
import {MockContract} from "@safe-global/mock-contract/contracts/MockContract.sol";
import {TestSafeProtocolRegistryUnrestricted} from "@safe-global/safe-core-protocol/contracts/test/TestSafeProtocolRegistryUnrestricted.sol";
2 changes: 2 additions & 0 deletions contracts/hardhat.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ const argv : any = yargs

const { NODE_URL, MNEMONIC, INFURA_KEY, ETHERSCAN_API_KEY} = process.env;

import "./src/tasks/test_registry"

const deterministicDeployment = (network: string): DeterministicDeploymentInfo => {
const info = getSingletonFactoryInfo(parseInt(network));
if (!info) {
Expand Down
27 changes: 27 additions & 0 deletions contracts/src/tasks/test_registry.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import "hardhat-deploy";
import "@nomicfoundation/hardhat-ethers";
import { task } from "hardhat/config";
import { getPlugin, getRegistry, getSamplePlugin } from "../utils/contracts";
import { IntegrationType } from "../utils/constants";
import { loadPluginMetaData } from "../utils/metadata";

task("register-plugin", "Registers the sample Plugin in the Safe{Core} test register")
.setAction(async (_, hre) => {
const registry = await getRegistry(hre)
const plugin = await getSamplePlugin(hre)
await registry.addIntegration(await plugin.getAddress(), IntegrationType.Plugin)
console.log("Registered Plugin registry")
});

task("list-plugins", "List available Plugins in the Safe{Core} test register")
.setAction(async (_, hre) => {
const registry = await getRegistry(hre)
const events = await registry.queryFilter(registry.filters.IntegrationAdded)
for (const event of events) {
const plugin = await getPlugin(hre, event.args.integration)
const metaData = await loadPluginMetaData(hre, plugin)
console.log(event.args.integration, metaData)
}
});

export { }
File renamed without changes.
File renamed without changes.
18 changes: 18 additions & 0 deletions contracts/src/utils/contracts.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { BaseContract } from "ethers";
import { BasePlugin, SamplePlugin, TestSafeProtocolRegistryUnrestricted } from "../../typechain-types";
import { HardhatRuntimeEnvironment } from "hardhat/types";
import { getProtocolRegistryAddress } from "./protocol";

export const getInstance = async <T extends BaseContract>(hre: HardhatRuntimeEnvironment, name: string, address: string): Promise<T> => {
// TODO: this typecasting should be refactored
return (await hre.ethers.getContractAt(name, address)) as unknown as T;
};

export const getSingleton = async <T extends BaseContract>(hre: HardhatRuntimeEnvironment, name: string): Promise<T> => {
const deployment = await hre.deployments.get(name);
return getInstance<T>(hre, name, deployment.address);
};

export const getPlugin = (hre: HardhatRuntimeEnvironment, address: string) => getInstance<BasePlugin>(hre, "BasePlugin", address);
export const getSamplePlugin = (hre: HardhatRuntimeEnvironment) => getSingleton<SamplePlugin>(hre, "SamplePlugin");
export const getRegistry = async (hre: HardhatRuntimeEnvironment) => getInstance<TestSafeProtocolRegistryUnrestricted>(hre, "TestSafeProtocolRegistryUnrestricted", await getProtocolRegistryAddress(hre));
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { AbiCoder, isHexString, keccak256 } from "ethers";
import { BasePlugin, MetaDataProvider } from "../../typechain-types";
import { getInstance } from "./contracts";
import { getInstance } from "../utils/contracts";
import { HardhatRuntimeEnvironment } from "hardhat/types";

interface PluginMetaData {
name: string;
Expand All @@ -17,24 +18,24 @@ const ProviderType_Contract = 2n;

const PluginMetaDataType: string[] = ["string name", "string version", "bool requiresRootAccess", "string iconUrl", "string appUrl"];

const loadPluginMetaDataFromContract = async (provider: string, metaDataHash: string): Promise<string> => {
const providerInstance = await getInstance<MetaDataProvider>("MetaDataProvider", provider);
const loadPluginMetaDataFromContract = async (hre: HardhatRuntimeEnvironment, provider: string, metaDataHash: string): Promise<string> => {
const providerInstance = await getInstance<MetaDataProvider>(hre, "MetaDataProvider", provider);
return await providerInstance.retrieveMetaData(metaDataHash);
};

const loadRawMetaData = async (plugin: BasePlugin, metaDataHash: string): Promise<string> => {
const loadRawMetaData = async (hre: HardhatRuntimeEnvironment, plugin: BasePlugin, metaDataHash: string): Promise<string> => {
const [type, source] = await plugin.metaProvider();
switch (type) {
case ProviderType_Contract:
return loadPluginMetaDataFromContract(AbiCoder.defaultAbiCoder().decode(["address"], source)[0], metaDataHash);
return loadPluginMetaDataFromContract(hre, AbiCoder.defaultAbiCoder().decode(["address"], source)[0], metaDataHash);
default:
throw Error("Unsupported MetaDataProviderType");
}
};

export const loadPluginMetaData = async (plugin: BasePlugin): Promise<PluginMetaData> => {
export const loadPluginMetaData = async (hre: HardhatRuntimeEnvironment, plugin: BasePlugin): Promise<PluginMetaData> => {
const metaDataHash = await plugin.metaDataHash();
const metaData = await loadRawMetaData(plugin, metaDataHash);
const metaData = await loadRawMetaData(hre, plugin, metaDataHash);
if (metaDataHash !== keccak256(metaData)) throw Error("Invalid meta data retrieved!");
return decodePluginMetaData(metaData);
};
Expand Down
3 changes: 2 additions & 1 deletion contracts/src/utils/protocol.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ export const getProtocolRegistryAddress = async(hre: HardhatRuntimeEnvironment):
if (chainId === "31337") return deployMock(hre, "RegistryMock")

if (!(chainId in protocolDeployments)) throw Error("Unsupported Chain")
const registry = (protocolDeployments as any)[chainId][0].contracts.SafeProtocolRegistry.address
// We use the unrestricted registry for the demo
const registry = (protocolDeployments as any)[chainId][0].contracts.TestSafeProtocolRegistryUnrestricted.address
if (typeof registry !== "string") throw Error("Unexpected Registry")
return registry
}
8 changes: 4 additions & 4 deletions contracts/test/SamplePlugin.spec.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import hre, { deployments } from "hardhat";
import { expect } from "chai";
import { SignerWithAddress } from "@nomicfoundation/hardhat-ethers/signers";
import { getSamplePlugin } from "./utils/contracts";
import { loadPluginMetaData } from "./utils/metadata";
import { getSamplePlugin } from "../src/utils/contracts";
import { loadPluginMetaData } from "../src/utils/metadata";

describe("SamplePlugin", async () => {
let user1: SignerWithAddress;
Expand All @@ -13,7 +13,7 @@ describe("SamplePlugin", async () => {

const setup = deployments.createFixture(async ({ deployments }) => {
await deployments.fixture();
const plugin = await getSamplePlugin();
const plugin = await getSamplePlugin(hre);
return {
plugin,
};
Expand All @@ -29,7 +29,7 @@ describe("SamplePlugin", async () => {

it("can retrieve meta data for module", async () => {
const { plugin } = await setup();
expect(await loadPluginMetaData(plugin)).to.be.deep.eq({
expect(await loadPluginMetaData(hre, plugin)).to.be.deep.eq({
name: "Sample Plugin",
version: "1.0.0",
requiresRootAccess: false,
Expand Down
15 changes: 0 additions & 15 deletions contracts/test/utils/contracts.ts

This file was deleted.

0 comments on commit c5b6394

Please sign in to comment.