### Deploy Custom Zodiac Module with Setup Source: https://context7.com/gnosisguild/zodiac/llms.txt Deploys a custom module that is not part of the known contracts list. This function allows for the deployment of any module compatible with a setUp function, taking the mastercopy address, ABI, setup arguments, provider, network, and a salt nonce as input. It returns the transaction details and the expected module address. ```typescript import { ethers } from "ethers"; import { deployAndSetUpCustomModule, SupportedNetworks, } from "@gnosis-guild/zodiac"; // Custom module ABI (must have setUp function) const customModuleAbi = [ "function setUp(bytes memory initializeParams) public", "function owner() view returns (address)", "function avatar() view returns (address)", "function target() view returns (address)", "function executeProposal(address to, uint256 value, bytes data) external returns (bool)", ]; async function deployCustomModule() { const provider = new ethers.JsonRpcProvider("https://eth-mainnet.alchemyapi.io/v2/YOUR_KEY"); const signer = new ethers.Wallet("YOUR_PRIVATE_KEY", provider); const mastercopyAddress = "0xYourCustomModuleMastercopy"; // Setup arguments matching your custom module's setUp function const setupArgs = { types: ["address", "address", "uint256"], values: [ "0xYourSafeAddress", // avatar "0xYourSafeAddress", // target 86400, // custom parameter (e.g., delay) ], }; const saltNonce = "12345"; const { transaction, expectedModuleAddress } = await deployAndSetUpCustomModule( mastercopyAddress, customModuleAbi, setupArgs, provider, SupportedNetworks.Mainnet, saltNonce ); console.log("Expected address:", expectedModuleAddress); // Execute deployment const tx = await signer.sendTransaction({ to: transaction.to, data: transaction.data, value: transaction.value, }); await tx.wait(); console.log("Custom module deployed at:", expectedModuleAddress); return expectedModuleAddress; } deployCustomModule().catch(console.error); ``` -------------------------------- ### Install Zodiac Dependencies Source: https://github.com/gnosisguild/zodiac/blob/master/README.md Installs the Zodiac library using the Yarn package manager to enable access to core contracts and interfaces. ```bash yarn add @gnosis-guild/zodiac ``` -------------------------------- ### Implement a Custom Zodiac Module Source: https://github.com/gnosisguild/zodiac/blob/master/README.md Demonstrates how to create a custom module by inheriting from the base Module contract provided by the Zodiac library. This is the starting point for building decision-making logic for an Avatar. ```solidity pragma solidity ^0.8.6; import "@gnosis-guild/zodiac/contracts/core/Module.sol"; contract MyModule is Module { /// insert your code here } ``` -------------------------------- ### Implement a Custom Zodiac Governance Module Source: https://context7.com/gnosisguild/zodiac/llms.txt This snippet demonstrates how to extend the base Module contract to create a custom governance module. It includes the setup process and methods for executing transactions through an Avatar. ```solidity // SPDX-License-Identifier: LGPL-3.0-only pragma solidity ^0.8.6; import "@gnosis-guild/zodiac/contracts/core/Module.sol"; contract MyGovernanceModule is Module { uint256 public proposalCount; mapping(uint256 => bool) public executed; constructor(address _avatar, address _target) { bytes memory initParams = abi.encode(_avatar, _target); setUp(initParams); } function setUp(bytes memory initializeParams) public override initializer { __Ownable_init(msg.sender); (address _avatar, address _target) = abi.decode( initializeParams, (address, address) ); avatar = _avatar; target = _target; } function executeProposal( uint256 proposalId, address to, uint256 value, bytes memory data ) external { require(!executed[proposalId], "Already executed"); executed[proposalId] = true; bool success = exec(to, value, data, Enum.Operation.Call); require(success, "Execution failed"); } function executeAndReturn( address to, uint256 value, bytes memory data ) external returns (bytes memory) { (bool success, bytes memory returnData) = execAndReturnData( to, value, data, Enum.Operation.Call ); require(success, "Execution failed"); return returnData; } } ``` -------------------------------- ### Get Module Instance Source: https://github.com/gnosisguild/zodiac/blob/master/sdk/factory/README.md Retrieves a contract instance for a specified Zodiac module at a given address, allowing interaction with the module's functions. ```APIDOC ## Get Module Instance ### Description Returns a contract instance for a specified Zodiac module, enabling direct interaction with its functions. This requires the module's name, its deployed address, and an Ethereum provider. ### Interface `getModuleInstance(moduleName, moduleAddress, provider)` ### Arguments #### Path Parameters - **moduleName** (string) - Required - The name of the module. Must be a key in the `CONTRACT_ADDRESSES` object. - **moduleAddress** (string) - Required - The deployed address of the module contract. - **provider** (object) - Required - An instance of `JsonRpcProvider` from `ethers`. ### Returns A contract instance of the specified module, ready for interaction. #### Success Response (200) - **contractInstance** (object) - An ethers.js contract instance for the module. ### Request Example ```json { "contractInstance": "[ethers.Contract instance]" } ``` ``` -------------------------------- ### GET getFactoryAndMasterCopy Source: https://github.com/gnosisguild/zodiac/blob/master/sdk/factory/README.md Retrieves the factory contract instance and the module master copy instance for a specified module. ```APIDOC ## GET getFactoryAndMasterCopy ### Description Returns an object containing the factory contract instance and the master copy instance for a given Zodiac module. ### Method GET ### Endpoint getFactoryAndMasterCopy(moduleName, provider, chainId) ### Parameters #### Path Parameters - **moduleName** (string) - Required - Name of the module to be deployed (must exist in CONTRACT_ADDRESSES). - **provider** (JsonRpcProvider) - Required - An instance of JsonRpcProvider from ethers. - **chainId** (number) - Required - The network ID to interact with. ### Request Example getFactoryAndMasterCopy('SafeModule', provider, 1) ### Response #### Success Response (200) - **moduleFactory** (Contract) - The factory contract instance. - **moduleMastercopy** (Contract) - The module master copy instance. #### Response Example { "moduleFactory": "[Contract Instance]", "moduleMastercopy": "[Contract Instance]" } ``` -------------------------------- ### Get Factory and Master Copy Instance (JavaScript) Source: https://github.com/gnosisguild/zodiac/blob/master/sdk/factory/README.md Retrieves instances of the module factory and master copy contract for a specified module. Requires module name, an ethers provider, and the chain ID. Returns an object containing both contract instances. Ensure the module name exists in `CONTRACT_ADDRESSES`. ```javascript import { ethers } from "ethers"; // Assuming CONTRACT_ADDRESSES and getModuleFactory are defined elsewhere async function getFactoryAndMasterCopy(moduleName, provider, chainId) { const factoryAddress = CONTRACT_ADDRESSES[moduleName][chainId]; const masterCopyAddress = CONTRACT_ADDRESSES[moduleName][chainId]; // Assuming master copy address is same as factory for simplicity in example const moduleFactory = await getModuleFactory(factoryAddress, provider); const moduleMastercopy = await getModuleFactory(masterCopyAddress, provider); // In reality, this might be a different contract instance or ABI return { moduleFactory: moduleFactory, moduleMastercopy: moduleMastercopy, }; } // Example Usage: // const provider = new ethers.providers.JsonRpcProvider("YOUR_RPC_URL"); // const moduleName = "someModule"; // const chainId = 1; // Ethereum Mainnet // getFactoryAndMasterCopy(moduleName, provider, chainId).then(contracts => { // console.log("Module Factory:", contracts.moduleFactory); // console.log("Module Mastercopy:", contracts.moduleMastercopy); // }).catch(error => { // console.error("Error getting contracts:", error); // }); ``` -------------------------------- ### Get Zodiac Module Factory and Mastercopy Source: https://context7.com/gnosisguild/zodiac/llms.txt Retrieves instances of both the ModuleProxyFactory and a module's mastercopy contract for a specified network. This is useful for custom deployment workflows or when needing direct access to these core contracts. It requires the known contract type, a provider, and the network. ```typescript import { ethers } from "ethers"; import { getModuleFactoryAndMasterCopy, KnownContracts, SupportedNetworks, } from "@gnosis-guild/zodiac"; async function getFactoryAndMastercopy() { const provider = new ethers.JsonRpcProvider("https://eth-mainnet.alchemyapi.io/v2/YOUR_KEY"); const { moduleFactory, moduleMastercopy } = getModuleFactoryAndMasterCopy( KnownContracts.ROLES_V2, provider, SupportedNetworks.Mainnet ); // Get factory address const factoryAddress = await moduleFactory.getAddress(); console.log("Factory address:", factoryAddress); // Get mastercopy address const mastercopyAddress = await moduleMastercopy.getAddress(); console.log("Roles V2 mastercopy:", mastercopyAddress); // You can now use these for custom deployment flows return { moduleFactory, moduleMastercopy }; } getFactoryAndMastercopy().catch(console.error); ``` -------------------------------- ### Get Typed Zodiac Module Instance Source: https://context7.com/gnosisguild/zodiac/llms.txt Retrieves a typed contract instance for interacting with a deployed Zodiac module. This function requires the module's address and the signer, and can utilize known contract types for easier interaction. It allows reading module state and executing transactions. ```typescript import { ethers } from "ethers"; import { getModuleInstance, KnownContracts, } from "@gnosis-guild/zodiac"; async function interactWithModule() { const provider = new ethers.JsonRpcProvider("https://eth-mainnet.alchemyapi.io/v2/YOUR_KEY"); const signer = new ethers.Wallet("YOUR_PRIVATE_KEY", provider); const moduleAddress = "0xYourDeployedModuleAddress"; // Get typed contract instance for Delay module const delayModule = getModuleInstance( KnownContracts.DELAY, moduleAddress, signer ); // Read module state const owner = await delayModule.owner(); const avatar = await delayModule.avatar(); const target = await delayModule.target(); const txCooldown = await delayModule.txCooldown(); const txExpiration = await delayModule.txExpiration(); console.log("Module configuration:"); console.log(" Owner:", owner); console.log(" Avatar:", avatar); console.log(" Target:", target); console.log(" Cooldown:", txCooldown.toString(), "seconds"); console.log(" Expiration:", txExpiration.toString(), "seconds"); // Queue a transaction (if authorized) const tx = await delayModule.execTransactionFromModule( "0xTargetContract", ethers.parseEther("1.0"), "0x", // empty data for ETH transfer 0 // Call operation ); await tx.wait(); console.log("Transaction queued"); return delayModule; } interactWithModule().catch(console.error); ``` -------------------------------- ### Deploy and Initialize Zodiac Module with SDK (TypeScript) Source: https://context7.com/gnosisguild/zodiac/llms.txt The SDK function `deployAndSetUpModule` simplifies the deployment and initialization of a Zodiac module. It generates a transaction that can be executed by a signer, handling the necessary parameters for deploying a module proxy and setting it up with provided arguments. ```typescript import { ethers } from "ethers"; import { deployAndSetUpModule, KnownContracts, SupportedNetworks, } from "@gnosis-guild/zodiac"; async function deployRealityModule() { const provider = new ethers.JsonRpcProvider("https://eth-mainnet.alchemyapi.io/v2/YOUR_KEY"); const signer = new ethers.Wallet("YOUR_PRIVATE_KEY", provider); // Setup arguments for Reality.eth module const setupArgs = { types: [ "address", // owner "address", // avatar (Safe address) "address", // target (Safe address) "address", // oracle (Reality.eth address) "uint32", // timeout "uint32", // cooldown "uint32", // expiration "uint256", // bond "uint256", // templateId ], values: [ "0xYourOwnerAddress", "0xYourSafeAddress", "0xYourSafeAddress", "0x5b7dD1E86623548AF054A4985F7fc8Ccbb554E2c", // Reality.eth mainnet 86400, // 24 hour timeout 86400, // 24 hour cooldown 604800, // 7 day expiration ethers.parseEther("0.1"), // 0.1 ETH bond 1, // template ID ], }; const saltNonce = Date.now().toString(); // Get deployment transaction and expected address const { transaction, expectedModuleAddress } = await deployAndSetUpModule( KnownContracts.REALITY_ETH, setupArgs, provider, SupportedNetworks.Mainnet, saltNonce ); console.log("Expected module address:", expectedModuleAddress); console.log("Deployment transaction:", transaction); // Execute the deployment const tx = await signer.sendTransaction({ to: transaction.to, data: transaction.data, value: transaction.value, }); const receipt = await tx.wait(); console.log("Module deployed at:", expectedModuleAddress); console.log("Transaction hash:", receipt.hash); return expectedModuleAddress; } deployRealityModule().catch(console.error); ``` -------------------------------- ### Deploy and Set Up Custom Module Source: https://github.com/gnosisguild/zodiac/blob/master/sdk/factory/README.md Deploys a custom Zodiac module using its mastercopy address and ABI, then sets it up on a Safe. This is for modules not included in the default list. ```APIDOC ## Deploy and Set Up Custom Module ### Description Deploys a custom module using its mastercopy address and ABI, and then sets it up for use with a Safe. This method is suitable for deploying modules that are not pre-listed in the `CONTRACT_ADDRESSES`. ### Interface `deployAndSetUpCustomModule(mastercopyAddress, abi, setupArgs, provider, chainId, saltNonce)` ### Arguments #### Path Parameters - **mastercopyAddress** (string) - Required - The address of the module's mastercopy contract. - **abi** (array) - Required - The ABI of the module to be deployed. - **setupArgs** (object) - Required - An object containing arguments for the module's `setUp` function. - **values** (array) - Required - An array of arguments for the `setUp` function. - **types** (array) - Required - An array of the types for each argument in `values`. - **provider** (object) - Required - An instance of `JsonRpcProvider` from `ethers`. - **chainId** (number) - Required - The network ID to interact with. - **saltNonce** (string) - Required - A salt to use for the deployment process. ### Returns An object containing the transaction details to be executed by the Safe and the expected address of the newly deployed module. #### Success Response (200) - **transaction** (object) - Details of the transaction to be executed. - **data** (string) - The transaction data. - **to** (string) - The recipient address of the transaction. - **value** (string) - The value to be sent with the transaction (as a BigNumber string, e.g., "0"). - **expectedModuleAddress** (string) - The predicted address of the deployed module. ### Request Example ```json { "transaction": { "data": "0x", "to": "0x...", "value": "0" }, "expectedModuleAddress": "0x..." } ``` ``` -------------------------------- ### Deploy and Set Up Known Module Source: https://github.com/gnosisguild/zodiac/blob/master/sdk/factory/README.md Deploys a known Zodiac module from the predefined list and sets it up on a Safe. This function is useful for deploying modules like social recovery or transaction guards. ```APIDOC ## Deploy and Set Up Known Module ### Description Deploys a contract from the list of known Zodiac modules and configures it for use with a Safe. This method is intended for modules listed in the `CONTRACT_ADDRESSES` constant. ### Interface `deployAndSetUpModule(moduleName, setupArgs, provider, chainId, saltNonce)` ### Arguments #### Path Parameters - **moduleName** (string) - Required - The name of the module to deploy. Must be a key in the `CONTRACT_ADDRESSES` object. - **setupArgs** (object) - Required - An object containing arguments for the module's `setUp` function. - **values** (array) - Required - An array of arguments for the `setUp` function. - **types** (array) - Required - An array of the types for each argument in `values`. - **provider** (object) - Required - An instance of `JsonRpcProvider` from `ethers`. - **chainId** (number) - Required - The network ID to interact with. - **saltNonce** (string) - Required - A salt for the Create2 opcode used in deployment. ### Returns An object containing the transaction details to be executed by the Safe and the expected address of the newly deployed module. #### Success Response (200) - **transaction** (object) - Details of the transaction to be executed. - **data** (string) - The transaction data. - **to** (string) - The recipient address of the transaction. - **value** (string) - The value to be sent with the transaction (as a BigNumber string, e.g., "0"). - **expectedModuleAddress** (string) - The predicted address of the deployed module. ### Request Example ```json { "transaction": { "data": "0x", "to": "0x...", "value": "0" }, "expectedModuleAddress": "0x..." } ``` ``` -------------------------------- ### IAvatar Interface Methods Source: https://context7.com/gnosisguild/zodiac/llms.txt Documentation for the core methods used to manage modules and execute transactions on an Avatar contract. ```APIDOC ## POST /IAvatar/execTransactionFromModule ### Description Allows an enabled module to execute a transaction through the Avatar contract. ### Method POST ### Parameters #### Request Body - **to** (address) - Required - Destination address of the transaction - **value** (uint256) - Required - Ether value to send - **data** (bytes) - Required - Transaction data payload - **operation** (Enum.Operation) - Required - 0 for call, 1 for delegate call ### Response #### Success Response (200) - **success** (bool) - Returns true if the transaction execution was successful. --- ## GET /IAvatar/isModuleEnabled ### Description Checks if a specific address is currently an enabled module on the Avatar. ### Method GET ### Parameters #### Query Parameters - **module** (address) - Required - The address of the module to check ### Response #### Success Response (200) - **enabled** (bool) - Returns true if the module is enabled. ``` -------------------------------- ### Deploy Zodiac Module Proxy with ModuleProxyFactory (Solidity) Source: https://context7.com/gnosisguild/zodiac/llms.txt The ModuleProxyFactory contract deploys minimal proxy (clone) contracts for Zodiac modules. This pattern reduces deployment gas costs and enables deterministic addresses across chains. It takes the master copy address, initializer data, and a salt nonce to deploy and initialize the module. ```solidity // SPDX-License-Identifier: LGPL-3.0-only pragma solidity >=0.8.0; contract ModuleProxyFactory { event ModuleProxyCreation(address indexed proxy, address indexed masterCopy); error ZeroAddress(address target); error TargetHasNoCode(address target); error TakenAddress(address address_); error FailedInitialization(); /// @notice Deploy a module proxy and initialize it /// @param masterCopy Address of the mastercopy contract to clone /// @param initializer Encoded setUp() call data /// @param saltNonce Nonce for deterministic address generation function deployModule( address masterCopy, bytes memory initializer, uint256 saltNonce ) public returns (address proxy) { if (address(masterCopy) == address(0)) revert ZeroAddress(masterCopy); if (address(masterCopy).code.length == 0) revert TargetHasNoCode(masterCopy); bytes32 salt = keccak256(abi.encodePacked(keccak256(initializer), saltNonce)); bytes memory deployment = abi.encodePacked( hex"602d8060093d393df3363d3d373d3d3d363d73", masterCopy, hex"5af43d82803e903d91602b57fd5bf3" ); assembly { proxy := create2(0, add(deployment, 0x20), mload(deployment), salt) } if (proxy == address(0)) revert TakenAddress(proxy); (bool success, ) = proxy.call(initializer); if (!success) revert FailedInitialization(); emit ModuleProxyCreation(proxy, masterCopy); } } ``` -------------------------------- ### Deploy Module Mastercopy Deterministically Source: https://context7.com/gnosisguild/zodiac/llms.txt Deploys a module mastercopy using the Singleton Factory to ensure consistent addresses across different EVM chains. It takes a signer, contract factory, constructor arguments, and a salt as inputs. ```typescript import { ethers } from "ethers"; import { deployMastercopy } from "@gnosis-guild/zodiac"; async function deployModuleMastercopy() { const provider = new ethers.JsonRpcProvider("https://eth-mainnet.alchemyapi.io/v2/YOUR_KEY"); const signer = await provider.getSigner(); const MyModule = await ethers.getContractFactory("MyCustomModule", signer); const constructorArgs = ["0x0000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000001"]; const salt = ethers.keccak256(ethers.toUtf8Bytes("MyModule_v1.0.0")); const mastercopyAddress = await deployMastercopy(signer, MyModule, constructorArgs, salt); if (mastercopyAddress === ethers.ZeroAddress) { console.log("Mastercopy already deployed"); } else { console.log("Mastercopy deployed at:", mastercopyAddress); } return mastercopyAddress; } deployModuleMastercopy().catch(console.error); ``` -------------------------------- ### Singleton Factory Deployment Script (TypeScript) Source: https://github.com/gnosisguild/zodiac/blob/master/sdk/factory/README.md A script to deploy the Module Proxy Factory using the EIP-2470 Singleton Factory. It first checks if the Singleton Factory is deployed at the correct address and deploys it if necessary. The script will fail if the Singleton Factory cannot be deployed. ```typescript import { ethers, Signer } from "ethers"; import { deploySingletonFactory } from "./singleton-deployment"; // Assuming this path async function deployModuleProxyFactory(signer: Signer, chainId: number): Promise { const singletonFactoryAddress = "0x1d1731265B947731473471987A72361835782360"; // Example address, check constants let factory = await deploySingletonFactory(signer, singletonFactoryAddress); // Further logic to deploy Module Proxy Factory using the deployed Singleton Factory // ... return factory; // Return the deployed Module Proxy Factory instance } // Example Usage: // const provider = new ethers.providers.Web3Provider(window.ethereum); // const signer = provider.getSigner(); // const chainId = await provider.getNetwork().then(net => net.chainId); // deployModuleProxyFactory(signer, chainId).then(factory => { // console.log("Module Proxy Factory deployed at:", factory.address); // }).catch(error => { // console.error("Error deploying Module Proxy Factory:", error); // }); ``` -------------------------------- ### Check Supported Networks Source: https://context7.com/gnosisguild/zodiac/llms.txt Provides a list of supported EVM networks and a utility function to verify if a specific chain ID is supported by the Zodiac SDK. ```typescript import { SupportedNetworks } from "@gnosis-guild/zodiac"; function isSupported(chainId: number): boolean { return chainId in SupportedNetworks; } ``` -------------------------------- ### Implement WhitelistGuard using BaseGuard Source: https://context7.com/gnosisguild/zodiac/llms.txt This snippet demonstrates how to create a custom guard that enforces address and function selector whitelisting. It overrides checkTransaction to validate targets and selectors before execution and checkAfterExecution to ensure transaction success. ```solidity // SPDX-License-Identifier: LGPL-3.0-only pragma solidity ^0.8.6; import "@gnosis-guild/zodiac/contracts/guard/BaseGuard.sol"; import "@gnosis-guild/zodiac/contracts/factory/FactoryFriendly.sol"; contract WhitelistGuard is FactoryFriendly, BaseGuard { mapping(address => bool) public allowedTargets; mapping(bytes4 => bool) public allowedSelectors; event TargetAllowed(address target); event SelectorAllowed(bytes4 selector); constructor(address[] memory _targets, bytes4[] memory _selectors) { bytes memory initParams = abi.encode(_targets, _selectors); setUp(initParams); } function setUp(bytes memory initializeParams) public override initializer { (address[] memory _targets, bytes4[] memory _selectors) = abi.decode( initializeParams, (address[], bytes4[]) ); for (uint i = 0; i < _targets.length; i++) { allowedTargets[_targets[i]] = true; emit TargetAllowed(_targets[i]); } for (uint i = 0; i < _selectors.length; i++) { allowedSelectors[_selectors[i]] = true; emit SelectorAllowed(_selectors[i]); } } function checkTransaction( address to, uint256 value, bytes memory data, Enum.Operation operation, uint256, uint256, uint256, address, address payable, bytes memory, address ) external view override { require(allowedTargets[to], "Target not allowed"); if (data.length >= 4) { bytes4 selector; assembly { selector := mload(add(data, 32)) } require(allowedSelectors[selector], "Function not allowed"); } require(operation == Enum.Operation.Call, "Delegate calls not allowed"); } function checkAfterExecution(bytes32, bool success) external view override { require(success, "Transaction must succeed"); } } ``` -------------------------------- ### Calculate New Module Address Source: https://github.com/gnosisguild/zodiac/blob/master/sdk/factory/README.md Calculates the future address of a module before deployment, based on the module factory, mastercopy, initialization data, and a salt. ```APIDOC ## Calculate New Module Address ### Description Calculates the predicted address of a module that will be deployed. This is useful for constructing batched transactions that include deployment and subsequent calls to the new module. ### Interface `calculateProxyAddress(moduleFactory, mastercopyAddress, initData, saltNonce)` ### Arguments #### Path Parameters - **moduleFactory** (object) - Required - The Module Proxy Factory contract object. - **mastercopyAddress** (string) - Required - The address of the module's mastercopy contract. - **initData** (string) - Required - The encoded initialization data for the module's `setUp` function. - **saltNonce** (string) - Required - A salt to use for the deployment process. ### Returns A string representing the expected address of the deployed module. #### Success Response (200) - **address** (string) - The calculated address of the module. ### Request Example ```json { "address": "0x..." } ``` ``` -------------------------------- ### Calculate Deterministic Module Proxy Address Source: https://context7.com/gnosisguild/zodiac/llms.txt Calculates the future deployment address of a module proxy without performing an actual transaction. It requires the module factory, mastercopy address, encoded initialization data, and a salt nonce. ```typescript import { ethers } from "ethers"; import { calculateProxyAddress, getModuleFactoryAndMasterCopy, KnownContracts, SupportedNetworks } from "@gnosis-guild/zodiac"; async function predictModuleAddress() { const provider = new ethers.JsonRpcProvider("https://eth-mainnet.alchemyapi.io/v2/YOUR_KEY"); const { moduleFactory, moduleMastercopy } = getModuleFactoryAndMasterCopy(KnownContracts.DELAY, provider, SupportedNetworks.Mainnet); const initParams = ethers.AbiCoder.defaultAbiCoder().encode(["address", "address", "address", "uint256", "uint256"], ["0xOwnerAddress", "0xSafeAddress", "0xSafeAddress", 86400, 604800]); const setupData = moduleMastercopy.interface.encodeFunctionData("setUp", [initParams]); const saltNonce = "42"; const expectedAddress = await calculateProxyAddress(moduleFactory, await moduleMastercopy.getAddress(), setupData, saltNonce); console.log("Module will be deployed at:", expectedAddress); return expectedAddress; } predictModuleAddress().catch(console.error); ``` -------------------------------- ### WhitelistGuard Contract Implementation Source: https://context7.com/gnosisguild/zodiac/llms.txt Defines a guard that enforces address whitelisting and function selector restrictions for transactions. ```APIDOC ## WhitelistGuard Contract ### Description The WhitelistGuard contract restricts transaction execution to specific target addresses and function selectors. It implements BaseGuard to perform pre-execution validation and post-execution success checks. ### Method N/A (Smart Contract Implementation) ### Endpoint N/A ### Parameters #### Constructor Parameters - **_targets** (address[]) - Required - List of allowed target addresses. - **_selectors** (bytes4[]) - Required - List of allowed function selectors. ### Request Example // Deploying with allowed targets and selectors new WhitelistGuard([0x123...], [0xabcdef01]); ### Response #### Success Response (N/A) - **TargetAllowed** (event) - Emitted when a target is added. - **SelectorAllowed** (event) - Emitted when a selector is added. ``` -------------------------------- ### IAvatar Interface Definition Source: https://context7.com/gnosisguild/zodiac/llms.txt Defines the IAvatar interface for programmable accounts. This interface manages module registration and provides methods for modules to execute transactions on the avatar. ```solidity // SPDX-License-Identifier: LGPL-3.0-only pragma solidity >=0.7.0 <0.9.0; import {Enum} from "@gnosis.pm/safe-contracts/contracts/common/Enum.sol"; interface IAvatar { event EnabledModule(address module); event DisabledModule(address module); event ExecutionFromModuleSuccess(address indexed module); event ExecutionFromModuleFailure(address indexed module); function enableModule(address module) external; function disableModule(address prevModule, address module) external; function execTransactionFromModule( address to, uint256 value, bytes memory data, Enum.Operation operation ) external returns (bool success); function execTransactionFromModuleReturnData( address to, uint256 value, bytes memory data, Enum.Operation operation ) external returns (bool success, bytes memory returnData); function isModuleEnabled(address module) external view returns (bool); function getModulesPaginated( address start, uint256 pageSize ) external view returns (address[] memory array, address next); } ``` -------------------------------- ### GuardableModule Contract Implementation Source: https://context7.com/gnosisguild/zodiac/llms.txt Extends the base Module contract to support automated transaction guarding via the GuardableModule interface. ```APIDOC ## GuardableModule Contract ### Description GuardableModule provides a framework for modules to execute transactions that are automatically validated by an attached Guard contract. It ensures that all module-initiated transactions undergo pre and post-execution checks. ### Method N/A (Smart Contract Implementation) ### Endpoint N/A ### Parameters #### Constructor Parameters - **_avatar** (address) - Required - The address of the avatar (e.g., Safe). - **_target** (address) - Required - The target contract address. - **_threshold** (uint256) - Required - The voting threshold required for execution. ### Request Example // Executing a transaction through a guarded module module.execute(to, value, data); ### Response #### Success Response (bool) - **success** (bool) - Returns true if the transaction execution and all guard checks passed. ``` -------------------------------- ### Access Zodiac Contract Metadata and ABIs Source: https://context7.com/gnosisguild/zodiac/llms.txt Retrieves pre-deployed contract addresses, version history, and ABIs for Zodiac modules. This utility simplifies integration by providing centralized access to contract constants. ```typescript import { ContractAddresses, ContractVersions, ContractAbis, ContractFactories, KnownContracts, SupportedNetworks } from "@gnosis-guild/zodiac"; const mainnetContracts = ContractAddresses[SupportedNetworks.Mainnet]; console.log("Mainnet Factory:", mainnetContracts[KnownContracts.FACTORY]); const mainnetVersions = ContractVersions[SupportedNetworks.Mainnet]; console.log("Delay versions:", mainnetVersions[KnownContracts.DELAY]); const delayAbi = ContractAbis[KnownContracts.DELAY]; console.log("Delay ABI functions:", delayAbi.length); const DelayFactory = ContractFactories[KnownContracts.DELAY]; ``` -------------------------------- ### Implement GuardedVotingModule using GuardableModule Source: https://context7.com/gnosisguild/zodiac/llms.txt This snippet shows how to extend GuardableModule to create a voting module that automatically triggers guard checks during transaction execution. It requires a threshold of votes before calling the internal exec function. ```solidity // SPDX-License-Identifier: LGPL-3.0-only pragma solidity ^0.8.6; import "@gnosis-guild/zodiac/contracts/core/GuardableModule.sol"; contract GuardedVotingModule is GuardableModule { mapping(bytes32 => uint256) public votes; uint256 public threshold; constructor(address _avatar, address _target, uint256 _threshold) { bytes memory initParams = abi.encode(_avatar, _target, _threshold); setUp(initParams); } function setUp(bytes memory initializeParams) public override initializer { __Ownable_init(msg.sender); (address _avatar, address _target, uint256 _threshold) = abi.decode( initializeParams, (address, address, uint256) ); avatar = _avatar; target = _target; threshold = _threshold; } function vote(bytes32 proposalHash) external { votes[proposalHash]++; } function execute( address to, uint256 value, bytes memory data ) external returns (bool) { bytes32 proposalHash = keccak256(abi.encode(to, value, data)); require(votes[proposalHash] >= threshold, "Threshold not met"); bool success = exec(to, value, data, Enum.Operation.Call); return success; } } ``` -------------------------------- ### Embed Zodiac Branding in Markdown Source: https://github.com/gnosisguild/zodiac/blob/master/README.md Use these markdown snippets to display official Zodiac banners or badges on your website or repository. Each snippet creates an image that functions as a hyperlink to the main Zodiac GitHub repository. ```markdown [![White on black banner](https://raw.githubusercontent.com/gnosisguild/zodiac/master/branding/zodiac-badge-black-white.svg)](https://github.com/gnosisguild/zodiac) ``` ```markdown [![Black on White Banner](https://raw.githubusercontent.com/gnosisguild/zodiac/master/branding/zodiac-banner-white-black.svg)](https://github.com/gnosisguild/zodiac) ``` -------------------------------- ### Implement a Zodiac Delay Modifier Source: https://context7.com/gnosisguild/zodiac/llms.txt This snippet shows how to extend the Modifier contract to enforce a time delay on transactions. It implements the IAvatar interface to queue transactions from modules and execute them after a specified period. ```solidity // SPDX-License-Identifier: LGPL-3.0-only pragma solidity ^0.8.6; import "@gnosis-guild/zodiac/contracts/core/Modifier.sol"; contract DelayModifier is Modifier { uint256 public delay; struct QueuedTx { address to; uint256 value; bytes data; Enum.Operation operation; uint256 executeAfter; } mapping(bytes32 => QueuedTx) public queue; constructor(address _avatar, address _target, uint256 _delay) { bytes memory initParams = abi.encode(_avatar, _target, _delay); setUp(initParams); } function setUp(bytes memory initializeParams) public override initializer { __Ownable_init(msg.sender); setupModules(); (address _avatar, address _target, uint256 _delay) = abi.decode( initializeParams, (address, address, uint256) ); avatar = _avatar; target = _target; delay = _delay; } function execTransactionFromModule( address to, uint256 value, bytes calldata data, Enum.Operation operation ) public override moduleOnly returns (bool success) { bytes32 txHash = keccak256(abi.encode(to, value, data, operation)); queue[txHash] = QueuedTx({ to: to, value: value, data: data, operation: operation, executeAfter: block.timestamp + delay }); return true; } function executeQueued(bytes32 txHash) external returns (bool) { QueuedTx memory queuedTx = queue[txHash]; require(queuedTx.executeAfter != 0, "Not queued"); require(block.timestamp >= queuedTx.executeAfter, "Delay not passed"); delete queue[txHash]; return exec(queuedTx.to, queuedTx.value, queuedTx.data, queuedTx.operation); } function execTransactionFromModuleReturnData( address to, uint256 value, bytes calldata data, Enum.Operation operation ) public override moduleOnly returns (bool success, bytes memory returnData) { return (execTransactionFromModule(to, value, data, operation), ""); } } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.