creation_sourcecode: {{
    "language": "Solidity",
    "sources": {
      "src/account-multicall/LlamaAccountMulticallFactory.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.23;\n\nimport {LlamaAccountMulticallExtension} from \"src/account-multicall/LlamaAccountMulticallExtension.sol\";\nimport {LlamaAccountMulticallGuard} from \"src/account-multicall/LlamaAccountMulticallGuard.sol\";\nimport {LlamaAccountMulticallStorage} from \"src/account-multicall/LlamaAccountMulticallStorage.sol\";\n\n/// @title LlamaAccountMulticallFactory\n/// @author Llama (devsdosomething@llama.xyz)\n/// @notice This contract enables Llama instances to deploy an account multicall module.\ncontract LlamaAccountMulticallFactory {\n  /// @dev Configuration of new Llama account multicall module.\n  struct LlamaAccountMulticallConfig {\n    address llamaExecutor; // The address of the Llama executor.\n    uint256 nonce; // The nonce of the new account multicall module.\n    LlamaAccountMulticallStorage.TargetSelectorAuthorization[] data; // The target-selectors to authorize.\n  }\n\n  /// @dev Emitted when a new Llama account multicall module is created.\n  event LlamaAccountMulticallModuleCreated(\n    address indexed deployer,\n    address indexed llamaExecutor,\n    uint256 nonce,\n    address accountMulticallGuard,\n    address accountMulticallExtension,\n    address accountMulticallStorage,\n    uint256 chainId\n  );\n\n  /// @notice Deploys a new Llama account multicall module.\n  /// @param accountMulticallConfig The configuration of the new Llama account multicall module.\n  /// @return accountMulticallGuard The deployed account multicall guard.\n  /// @return accountMulticallExtension The deployed account multicall extension.\n  /// @return accountMulticallStorage The deployed account multicall storage.\n  function deploy(LlamaAccountMulticallConfig memory accountMulticallConfig)\n    external\n    returns (\n      LlamaAccountMulticallGuard accountMulticallGuard,\n      LlamaAccountMulticallExtension accountMulticallExtension,\n      LlamaAccountMulticallStorage accountMulticallStorage\n    )\n  {\n    bytes32 salt =\n      keccak256(abi.encodePacked(msg.sender, accountMulticallConfig.llamaExecutor, accountMulticallConfig.nonce));\n\n    // Deploy and initialize account multicall storage.\n    accountMulticallStorage = new LlamaAccountMulticallStorage{salt: salt}(accountMulticallConfig.llamaExecutor);\n    accountMulticallStorage.initializeAuthorizedTargetSelectors(accountMulticallConfig.data);\n\n    // Deploy account multicall extension.\n    accountMulticallExtension = new LlamaAccountMulticallExtension{salt: salt}(accountMulticallStorage);\n\n    // Deploy account multicall guard.\n    accountMulticallGuard = new LlamaAccountMulticallGuard{salt: salt}(accountMulticallExtension);\n\n    emit LlamaAccountMulticallModuleCreated(\n      msg.sender,\n      accountMulticallConfig.llamaExecutor,\n      accountMulticallConfig.nonce,\n      address(accountMulticallGuard),\n      address(accountMulticallExtension),\n      address(accountMulticallStorage),\n      block.chainid\n    );\n  }\n}\n"
      },
      "src/account-multicall/LlamaAccountMulticallExtension.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.23;\n\nimport {LlamaAccountMulticallStorage} from \"src/account-multicall/LlamaAccountMulticallStorage.sol\";\nimport {LlamaBaseAccountExtension} from \"src/common/LlamaBaseAccountExtension.sol\";\nimport {LlamaUtils} from \"src/lib/LlamaUtils.sol\";\n\n/// @title Llama Account Multicall Extension\n/// @author Llama (devsdosomething@llama.xyz)\n/// @notice An account extension that can multicall on behalf of the Llama account.\n/// @dev This contract should be delegatecalled from a Llama account.\ncontract LlamaAccountMulticallExtension is LlamaBaseAccountExtension {\n  /// @dev Struct to hold target data.\n  struct TargetData {\n    address target; // The target contract.\n    uint256 value; // The target call value.\n    bytes data; // The target call data.\n  }\n\n  /// @dev The call did not succeed.\n  /// @param index Index of the target data being called.\n  /// @param revertData Data returned by the called function.\n  error CallReverted(uint256 index, bytes revertData);\n\n  /// @dev Thrown if the target-selector is not authorized.\n  error UnauthorizedTargetSelector(address target, bytes4 selector);\n\n  /// @notice The Llama account multicall storage contract.\n  LlamaAccountMulticallStorage public immutable ACCOUNT_MULTICALL_STORAGE;\n\n  /// @dev Initializes the Llama account multicall extenstion.\n  constructor(LlamaAccountMulticallStorage accountMulticallStorage) {\n    ACCOUNT_MULTICALL_STORAGE = accountMulticallStorage;\n  }\n\n  /// @notice Multicalls on behalf of the Llama account.\n  /// @param targetData The target data to multicall.\n  /// @return returnData The return data from the target calls.\n  function multicall(TargetData[] memory targetData) external onlyDelegateCall returns (bytes[] memory returnData) {\n    uint256 length = targetData.length;\n    returnData = new bytes[](length);\n    for (uint256 i = 0; i < length; i = LlamaUtils.uncheckedIncrement(i)) {\n      address target = targetData[i].target;\n      uint256 value = targetData[i].value;\n      bytes memory callData = targetData[i].data;\n      bytes4 selector = bytes4(callData);\n\n      // Check if the target-selector is authorized.\n      if (!ACCOUNT_MULTICALL_STORAGE.authorizedTargetSelectors(target, selector)) {\n        revert UnauthorizedTargetSelector(target, selector);\n      }\n\n      // Execute the call.\n      (bool success, bytes memory result) = target.call{value: value}(callData);\n      if (!success) revert CallReverted(i, result);\n      returnData[i] = result;\n    }\n  }\n}\n"
      },
      "src/account-multicall/LlamaAccountMulticallGuard.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.23;\n\nimport {LlamaAccountMulticallExtension} from \"src/account-multicall/LlamaAccountMulticallExtension.sol\";\nimport {ILlamaActionGuard} from \"src/interfaces/ILlamaActionGuard.sol\";\nimport {ActionInfo} from \"src/lib/Structs.sol\";\n\n/// @title Llama Account Multicall Guard\n/// @author Llama (devsdosomething@llama.xyz)\n/// @notice A guard that only allows the `LlamaAccountMulticallExtension.multicall` to be delegate-called\n/// @dev This guard should be used to protect the `execute` function in the `LlamaAccount` contract\ncontract LlamaAccountMulticallGuard is ILlamaActionGuard {\n  /// @dev Thrown if the call is not authorized.\n  error UnauthorizedCall(address target, bytes4 selector, bool withDelegatecall);\n\n  /// @notice The address of the Llama account multicall extension.\n  LlamaAccountMulticallExtension public immutable ACCOUNT_MULTICALL_EXTENSION;\n\n  /// @dev Initializes the Llama account multicall guard.\n  constructor(LlamaAccountMulticallExtension accountMulticallExtension) {\n    ACCOUNT_MULTICALL_EXTENSION = accountMulticallExtension;\n  }\n\n  /// @inheritdoc ILlamaActionGuard\n  function validateActionCreation(ActionInfo calldata actionInfo) external view {\n    // Decode the action calldata to get the LlamaAccount execute target, call type and call data.\n    (address target, bool withDelegatecall,, bytes memory data) =\n      abi.decode(actionInfo.data[4:], (address, bool, uint256, bytes));\n    bytes4 selector = bytes4(data);\n\n    // Check if the target is the Llama account multicall extension, selector is `multicall` and the call type is a\n    // delegatecall.\n    if (\n      target != address(ACCOUNT_MULTICALL_EXTENSION) || selector != LlamaAccountMulticallExtension.multicall.selector\n        || !withDelegatecall\n    ) revert UnauthorizedCall(target, selector, withDelegatecall);\n  }\n\n  /// @inheritdoc ILlamaActionGuard\n  function validatePreActionExecution(ActionInfo calldata actionInfo) external pure {}\n\n  /// @inheritdoc ILlamaActionGuard\n  function validatePostActionExecution(ActionInfo calldata actionInfo) external pure {}\n}\n"
      },
      "src/account-multicall/LlamaAccountMulticallStorage.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.23;\n\nimport {LlamaUtils} from \"src/lib/LlamaUtils.sol\";\n\n/// @title Llama Account Multicall Storage\n/// @author Llama (devsdosomething@llama.xyz)\n/// @notice The storage contract for the `LlamaAccountMulticallExtension` contract.\n/// @dev This is a separate storage contract to prevent storage collisions with the Llama account.\ncontract LlamaAccountMulticallStorage {\n  // =========================\n  // ======== Structs ========\n  // =========================\n\n  /// @dev Struct to hold authorized target-selectors.\n  struct TargetSelectorAuthorization {\n    address target; // The target contract.\n    bytes4 selector; // The selector of the function being called.\n    bool isAuthorized; // Is the target-selector authorized.\n  }\n\n  // ========================\n  // ======== Errors ========\n  // ========================\n\n  /// @dev Thrown if `initializeAuthorizedTargetSelectors` is called again.\n  error AlreadyInitialized();\n\n  /// @dev Only callable by a Llama instance's executor.\n  error OnlyLlama();\n\n  // ========================\n  // ======== Events ========\n  // ========================\n\n  /// @notice Emitted when a target-selector is authorized.\n  event TargetSelectorAuthorized(address indexed target, bytes4 indexed selector, bool isAuthorized);\n\n  // ===================================\n  // ======== Storage Variables ========\n  // ===================================\n\n  /// @notice The Llama instance's executor.\n  address public immutable LLAMA_EXECUTOR;\n\n  /// @dev Whether the contract is initialized.\n  bool internal initialized;\n\n  /// @notice Mapping of all authorized target-selectors.\n  mapping(address target => mapping(bytes4 selector => bool isAuthorized)) public authorizedTargetSelectors;\n\n  // ======================================================\n  // ======== Contract Creation and Initialization ========\n  // ======================================================\n\n  /// @dev Sets the Llama executor.\n  constructor(address llamaExecutor) {\n    LLAMA_EXECUTOR = llamaExecutor;\n  }\n\n  /// @notice Initializes the authorized target-selectors.\n  /// @dev This function can only be called once. It should be called as part of the contract deployment.\n  /// @param data The target-selectors to authorize.\n  function initializeAuthorizedTargetSelectors(TargetSelectorAuthorization[] memory data) external {\n    if (initialized) revert AlreadyInitialized();\n    initialized = true;\n    _setAuthorizedTargetSelectors(data);\n  }\n\n  // ================================\n  // ======== External Logic ========\n  // ================================\n\n  /// @notice Sets the authorized target-selectors.\n  /// @param data The target-selectors to authorize.\n  function setAuthorizedTargetSelectors(TargetSelectorAuthorization[] memory data) external {\n    if (msg.sender != LLAMA_EXECUTOR) revert OnlyLlama();\n    _setAuthorizedTargetSelectors(data);\n  }\n\n  // ================================\n  // ======== Internal Logic ========\n  // ================================\n\n  /// @dev Sets the authorized target-selectors.\n  function _setAuthorizedTargetSelectors(TargetSelectorAuthorization[] memory data) internal {\n    uint256 length = data.length;\n    for (uint256 i = 0; i < length; i = LlamaUtils.uncheckedIncrement(i)) {\n      authorizedTargetSelectors[data[i].target][data[i].selector] = data[i].isAuthorized;\n      emit TargetSelectorAuthorized(data[i].target, data[i].selector, data[i].isAuthorized);\n    }\n  }\n}\n"
      },
      "src/common/LlamaBaseAccountExtension.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.23;\n\n/// @dev This account extension is a template for creating new account extensions, and should not be used directly.\nabstract contract LlamaBaseAccountExtension {\n  /// @dev Thrown if you try to CALL a function that has the `onlyDelegatecall` modifier.\n  error OnlyDelegateCall();\n\n  /// @dev Add this to your account extension's methods to ensure the account extension can only be used via\n  /// delegatecall, and not a regular call.\n  modifier onlyDelegateCall() {\n    if (address(this) == SELF) revert OnlyDelegateCall();\n    _;\n  }\n\n  /// @dev Address of the account extension contract. We save it off because during a delegatecall `address(this)`\n  /// refers to the caller's address, not this account extension's address.\n  address internal immutable SELF;\n\n  constructor() {\n    SELF = address(this);\n  }\n}\n"
      },
      "src/lib/LlamaUtils.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.23;\n\nimport {PermissionData} from \"src/lib/Structs.sol\";\n\n/// @dev Shared helper methods for Llama's contracts.\nlibrary LlamaUtils {\n  /// @dev Thrown when a value cannot be safely casted to a smaller type.\n  error UnsafeCast(uint256 n);\n\n  /// @dev Reverts if `n` does not fit in a `uint16`.\n  function toUint16(uint256 n) internal pure returns (uint16) {\n    if (n > type(uint16).max) revert UnsafeCast(n);\n    return uint16(n);\n  }\n\n  /// @dev Reverts if `n` does not fit in a `uint48`.\n  function toUint48(uint256 n) internal pure returns (uint48) {\n    if (n > type(uint48).max) revert UnsafeCast(n);\n    return uint48(n);\n  }\n\n  /// @dev Reverts if `n` does not fit in a `uint64`.\n  function toUint64(uint256 n) internal pure returns (uint64) {\n    if (n > type(uint64).max) revert UnsafeCast(n);\n    return uint64(n);\n  }\n\n  /// @dev Reverts if `n` does not fit in a `uint96`.\n  function toUint96(uint256 n) internal pure returns (uint96) {\n    if (n > type(uint96).max) revert UnsafeCast(n);\n    return uint96(n);\n  }\n\n  /// @dev Reverts if `n` does not fit in a `uint128`.\n  function toUint128(uint256 n) internal pure returns (uint128) {\n    if (n > type(uint128).max) revert UnsafeCast(n);\n    return uint128(n);\n  }\n\n  /// @dev Increments a `uint256` without checking for overflow.\n  function uncheckedIncrement(uint256 i) internal pure returns (uint256) {\n    unchecked {\n      return i + 1;\n    }\n  }\n\n  /// @dev Hashes a permission to return the corresponding permission ID.\n  function computePermissionId(PermissionData memory permission) internal pure returns (bytes32) {\n    return keccak256(abi.encode(permission));\n  }\n}\n"
      },
      "src/interfaces/ILlamaActionGuard.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.23;\n\nimport {ActionInfo} from \"src/lib/Structs.sol\";\n\n/// @title Llama Action Guard Interface\n/// @author Llama (devsdosomething@llama.xyz)\n/// @notice Executes checks on action creation and execution to verify that the action is allowed.\n/// @dev Methods are not `view` because (1) an action guard may write to it's own storage, and (2)\n/// Having `view` methods that can revert isn't great UX. Allowing guards to write to their own\n/// storage is useful to persist state between calls to the various guard methods. For example, a\n/// guard may:\n///   - Store the USD price of a token during action creation in `validateActionCreation`.\n///   - Verify the price has not changed by more than a given amount during `validatePreActionExecution`\n///     and save off the current USD value of an account.\n///   - Verify the USD value of an account has not decreased by more than a certain amount during\n///     execution, i.e. between `validatePreActionExecution` and `validatePostActionExecution`.\ninterface ILlamaActionGuard {\n  /// @notice Reverts if action creation is not allowed.\n  /// @param actionInfo Data required to create an action.\n  function validateActionCreation(ActionInfo calldata actionInfo) external;\n\n  /// @notice Called immediately before action execution, and reverts if the action is not allowed\n  /// to be executed.\n  /// @param actionInfo Data required to create an action.\n  function validatePreActionExecution(ActionInfo calldata actionInfo) external;\n\n  /// @notice Called immediately after action execution, and reverts if the just-executed\n  /// action should not have been allowed to execute.\n  /// @param actionInfo Data required to create an action.\n  function validatePostActionExecution(ActionInfo calldata actionInfo) external;\n}\n"
      },
      "src/lib/Structs.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.23;\n\nimport {ILlamaAccount} from \"src/interfaces/ILlamaAccount.sol\";\nimport {ILlamaCore} from \"src/interfaces/ILlamaCore.sol\";\nimport {ILlamaActionGuard} from \"src/interfaces/ILlamaActionGuard.sol\";\nimport {ILlamaStrategy} from \"src/interfaces/ILlamaStrategy.sol\";\nimport {ILlamaTokenAdapter} from \"src/token-voting/interfaces/ILlamaTokenAdapter.sol\";\nimport {RoleDescription} from \"src/lib/UDVTs.sol\";\n\n/// @dev Data required to create an action.\nstruct ActionInfo {\n  uint256 id; // ID of the action.\n  address creator; // Address that created the action.\n  uint8 creatorRole; // The role that created the action.\n  ILlamaStrategy strategy; // Strategy used to govern the action.\n  address target; // Contract being called by an action.\n  uint256 value; // Value in wei to be sent when the action is executed.\n  bytes data; // Data to be called on the target when the action is executed.\n}\n\n/// @dev Data that represents an action.\nstruct Action {\n  // Instead of storing all data required to execute an action in storage, we only save the hash to\n  // make action creation cheaper. The hash is computed by taking the keccak256 hash of the concatenation of each\n  // field in the `ActionInfo` struct.\n  bytes32 infoHash;\n  bool executed; // Has action executed.\n  bool canceled; // Is action canceled.\n  bool isScript; // Is the action's target a script.\n  ILlamaActionGuard guard; // The action's guard. This is the address(0) if no guard is set on the action's target and\n    // selector pair.\n  uint64 creationTime; // The timestamp when action was created (used for policy snapshots).\n  uint64 minExecutionTime; // Only set when an action is queued. The timestamp when action execution can begin.\n  uint96 totalApprovals; // The total quantity of policyholder approvals.\n  uint96 totalDisapprovals; // The total quantity of policyholder disapprovals.\n}\n\n/// @dev Data that represents a permission.\nstruct PermissionData {\n  address target; // Contract being called by an action.\n  bytes4 selector; // Selector of the function being called by an action.\n  ILlamaStrategy strategy; // Strategy used to govern the action.\n}\n\n/// @dev Data required to assign/revoke a role to/from a policyholder.\nstruct RoleHolderData {\n  uint8 role; // ID of the role to set (uint8 ensures onchain enumerability when burning policies).\n  address policyholder; // Policyholder to assign the role to.\n  uint96 quantity; // Quantity of the role to assign to the policyholder, i.e. their (dis)approval quantity.\n  uint64 expiration; // When the role expires.\n}\n\n/// @dev Data required to assign/revoke a permission to/from a role.\nstruct RolePermissionData {\n  uint8 role; // ID of the role to set (uint8 ensures onchain enumerability when burning policies).\n  PermissionData permissionData; // The `(target, selector, strategy)` tuple that will be keccak256 hashed to\n    // generate the permission ID to assign or unassign to the role\n  bool hasPermission; // Whether to assign the permission or remove the permission.\n}\n\n/// @dev Configuration of a new Llama instance.\nstruct LlamaInstanceConfig {\n  string name; // The name of the Llama instance.\n  ILlamaStrategy strategyLogic; // The initial strategy implementation (logic) contract.\n  ILlamaAccount accountLogic; // The initial account implementation (logic) contract.\n  bytes[] initialStrategies; // Array of initial strategy configurations.\n  bytes[] initialAccounts; // Array of initial account configurations.\n  LlamaPolicyConfig policyConfig; // Configuration of the instance's policy.\n}\n\n/// @dev Configuration of a new Llama policy.\nstruct LlamaPolicyConfig {\n  RoleDescription[] roleDescriptions; // The initial role descriptions.\n  RoleHolderData[] roleHolders; // The `role`, `policyholder`, `quantity` and `expiration` of the initial role holders.\n  RolePermissionData[] rolePermissions; // The `role`, `permissionData`, and  the `hasPermission` boolean.\n  string color; // The primary color of the SVG representation of the instance's policy (e.g. #00FF00).\n  string logo; // The SVG string representing the logo for the deployed Llama instance's NFT.\n}\n\n/// @dev Configuration of a new Llama token voting module.\nstruct LlamaTokenVotingConfig {\n  ILlamaCore llamaCore; // The address of the Llama core.\n  ILlamaTokenAdapter tokenAdapterLogic; // The logic contract of the token adapter.\n  bytes adapterConfig; // The configuration of the token adapter.\n  uint256 nonce; // The nonce to be used in the salt of the deterministic deployment.\n  uint256 creationThreshold; // The number of tokens required to create an action.\n  CasterConfig casterConfig; // The quorum and period data for the `LlamaTokenGovernor`.\n}\n\n/// @dev Quorum and period data for token voting caster contracts.\nstruct CasterConfig {\n  uint16 voteQuorumPct; // The minimum % of total supply that must be casted as `For` votes.\n  uint16 vetoQuorumPct; // The minimum % of total supply that must be casted as `For` vetoes.\n  uint16 delayPeriodPct; // The % of the total approval or queuing period used as a delay.\n  uint16 castingPeriodPct; // The % of the total approval or queuing period used to cast votes or vetoes\n}\n"
      },
      "src/interfaces/ILlamaAccount.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.23;\n\n/// @title Llama Account Logic Interface\n/// @author Llama (devsdosomething@llama.xyz)\n/// @notice This is the interface for Llama accounts which can be used to hold assets for a Llama instance.\ninterface ILlamaAccount {\n  /// @dev External call failed.\n  /// @param result Data returned by the called function.\n  error FailedExecution(bytes result);\n\n  // -------- For Inspection --------\n\n  /// @notice Returns the address of the Llama instance's executor.\n  function llamaExecutor() external view returns (address);\n\n  // -------- At Account Creation --------\n\n  /// @notice Initializes a new clone of the account.\n  /// @dev This function is called by the `_deployAccounts` function in the `LlamaCore` contract. The `initializer`\n  /// modifier ensures that this function can be invoked at most once.\n  /// @param config The account configuration, encoded as bytes to support differing constructor arguments in\n  /// different account logic contracts.\n  /// @return This return statement must be hardcoded to `true` to ensure that initializing an EOA\n  /// (like the zero address) will revert.\n  function initialize(bytes memory config) external returns (bool);\n\n  // -------- Generic Execution --------\n\n  /// @notice Execute arbitrary calls from the Llama Account.\n  /// @dev Be careful and intentional while assigning permissions to a policyholder that can create an action to call\n  /// this function, especially while using the delegatecall functionality as it can lead to arbitrary code execution in\n  /// the context of this Llama account.\n  /// @param target The address of the contract to call.\n  /// @param withDelegatecall Whether to use delegatecall or call.\n  /// @param value The amount of ETH to send with the call, taken from the Llama Account.\n  /// @param callData The calldata to pass to the contract.\n  /// @return The result of the call.\n  function execute(address target, bool withDelegatecall, uint256 value, bytes calldata callData)\n    external\n    returns (bytes memory);\n}\n"
      },
      "src/interfaces/ILlamaCore.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// TODO This interface was generated from `cast interface`, so some types are not as strong as they\n// could be. For example, the existing `ILlamaStrategy` were all `address` until they were manually\n// changed. So there are probably other types that need to be updated also.\npragma solidity ^0.8.23;\n\nimport {ILlamaPolicy} from \"src/interfaces/ILlamaPolicy.sol\";\nimport {ILlamaStrategy} from \"src/interfaces/ILlamaStrategy.sol\";\nimport {ActionState} from \"src/lib/Enums.sol\";\nimport {\n  Action,\n  ActionInfo,\n  LlamaInstanceConfig,\n  LlamaPolicyConfig,\n  PermissionData,\n  RoleHolderData,\n  RolePermissionData\n} from \"src/lib/Structs.sol\";\n\n/// @title LlamaCore Interface\n/// @author Llama (devsdosomething@llama.xyz)\n/// @notice This is the interface for LlamaCore.\ninterface ILlamaCore {\n  error InvalidSignature();\n\n  error PolicyholderDoesNotHavePermission();\n\n  /// @dev The action is not in the expected state.\n  /// @param current The current state of the action.\n  error InvalidActionState(ActionState current);\n\n  /// @dev Action execution failed.\n  /// @param reason Data returned by the function called by the action.\n  error FailedActionExecution(bytes reason);\n\n  function actionGuard(address target, bytes4 selector) external view returns (address guard);\n\n  function actionsCount() external view returns (uint256);\n\n  function approvals(uint256 actionId, address policyholder) external view returns (bool hasApproved);\n\n  function authorizedAccountLogics(address accountLogic) external view returns (bool isAuthorized);\n\n  function authorizedScripts(address script) external view returns (bool isAuthorized);\n\n  function authorizedStrategyLogics(ILlamaStrategy strategyLogic) external view returns (bool isAuthorized);\n\n  function cancelAction(ActionInfo memory actionInfo) external;\n\n  function cancelActionBySig(address policyholder, ActionInfo memory actionInfo, uint8 v, bytes32 r, bytes32 s)\n    external;\n\n  function castApproval(uint8 role, ActionInfo memory actionInfo, string memory reason) external returns (uint96);\n\n  function castApprovalBySig(\n    address policyholder,\n    uint8 role,\n    ActionInfo memory actionInfo,\n    string memory reason,\n    uint8 v,\n    bytes32 r,\n    bytes32 s\n  ) external returns (uint96);\n\n  function castDisapproval(uint8 role, ActionInfo memory actionInfo, string memory reason) external returns (uint96);\n\n  function castDisapprovalBySig(\n    address policyholder,\n    uint8 role,\n    ActionInfo memory actionInfo,\n    string memory reason,\n    uint8 v,\n    bytes32 r,\n    bytes32 s\n  ) external returns (uint96);\n\n  function createAccounts(address llamaAccountLogic, bytes[] memory accountConfigs) external;\n\n  function createAction(\n    uint8 role,\n    ILlamaStrategy strategy,\n    address target,\n    uint256 value,\n    bytes memory data,\n    string memory description\n  ) external returns (uint256 actionId);\n\n  function createActionBySig(\n    address policyholder,\n    uint8 role,\n    ILlamaStrategy strategy,\n    address target,\n    uint256 value,\n    bytes memory data,\n    string memory description,\n    uint8 v,\n    bytes32 r,\n    bytes32 s\n  ) external returns (uint256 actionId);\n\n  function createStrategies(address llamaStrategyLogic, bytes[] memory strategyConfigs) external;\n\n  function disapprovals(uint256 actionId, address policyholder) external view returns (bool hasDisapproved);\n\n  function executeAction(ActionInfo memory actionInfo) external payable;\n\n  function executor() external view returns (address);\n\n  function getAction(uint256 actionId) external view returns (Action memory);\n\n  function getActionState(ActionInfo memory actionInfo) external view returns (uint8);\n\n  function incrementNonce(bytes4 selector) external;\n\n  function initialize(LlamaInstanceConfig memory config, address policyLogic, address policyMetadataLogic) external;\n\n  function name() external view returns (string memory);\n\n  function nonces(address policyholder, bytes4 selector) external view returns (uint256 currentNonce);\n\n  function policy() external view returns (ILlamaPolicy);\n\n  function queueAction(ActionInfo memory actionInfo) external;\n\n  function setAccountLogicAuthorization(address accountLogic, bool authorized) external;\n\n  function setGuard(address target, bytes4 selector, address guard) external;\n\n  function setScriptAuthorization(address script, bool authorized) external;\n\n  function setStrategyAuthorization(ILlamaStrategy strategy, bool authorized) external;\n\n  function setStrategyLogicAuthorization(ILlamaStrategy strategyLogic, bool authorized) external;\n\n  function strategies(ILlamaStrategy strategy) external view returns (bool deployed, bool authorized);\n}\n"
      },
      "src/interfaces/ILlamaStrategy.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.23;\n\nimport {ActionInfo} from \"src/lib/Structs.sol\";\nimport {ILlamaCore} from \"src/interfaces/ILlamaCore.sol\";\nimport {ILlamaPolicy} from \"src/interfaces/ILlamaPolicy.sol\";\n\n/// @title Llama Strategy Interface\n/// @author Llama (devsdosomething@llama.xyz)\n/// @notice This is the interface for Llama strategies which determine the rules of an action's process.\n/// @dev The interface is sorted by the stage of the action's lifecycle in which the method's are used.\ninterface ILlamaStrategy {\n  // -------- For Inspection --------\n  // These are not strictly required by the core, but are useful for inspecting a strategy contract.\n\n  /// @notice Returns the address of the Llama core that this strategy is registered to.\n  function llamaCore() external view returns (ILlamaCore);\n\n  /// @notice Returns the name of the Llama policy that this strategy is registered to.\n  function policy() external view returns (ILlamaPolicy);\n\n  // -------- Required for Strategies used with LlamaTokenGovernor --------\n\n  /// @notice Returns the approval period of the strategy in seconds.\n  function approvalPeriod() external view returns (uint64);\n\n  /// @notice Returns the queuing period of the strategy in seconds.\n  function queuingPeriod() external view returns (uint64);\n\n  /// @notice The role that can approve an action.\n  function approvalRole() external view returns (uint8);\n\n  /// @notice The role that can disapprove an action.\n  function disapprovalRole() external view returns (uint8);\n\n  /// @notice Returns true if an action can force an action to be approved and false otherwise.\n  function forceApprovalRole(uint8 role) external view returns (bool isForceApproval);\n\n  /// @notice Returns true if an action can force an action to be disapproved and false otherwise.\n  function forceDisapprovalRole(uint8 role) external view returns (bool isForceDisapproval);\n\n  // -------- At Strategy Creation --------\n\n  /// @notice Initializes a new clone of the strategy.\n  /// @dev This function is called by the `_deployStrategies` function in the `LlamaCore` contract. The `initializer`\n  /// modifier ensures that this function can be invoked at most once.\n  /// @param config The strategy configuration, encoded as bytes to support differing constructor arguments in\n  /// different strategies.\n  /// @return This return statement must be hardcoded to `true` to ensure that initializing an EOA\n  /// (like the zero address) will revert.\n  function initialize(bytes memory config) external returns (bool);\n\n  // -------- At Action Creation --------\n\n  /// @notice Reverts if action creation is not allowed.\n  /// @param actionInfo Data required to create an action.\n  function validateActionCreation(ActionInfo calldata actionInfo) external view;\n\n  // -------- When Casting Approval --------\n\n  /// @notice Reverts if approvals are not allowed with this strategy for the given policyholder when approving with\n  /// role.\n  /// @param actionInfo Data required to create an action.\n  /// @param policyholder Address of the policyholder.\n  /// @param role The role of the policyholder being used to cast approval.\n  function checkIfApprovalEnabled(ActionInfo calldata actionInfo, address policyholder, uint8 role) external view;\n\n  /// @notice Get the quantity of an approval of a policyholder at a specific timestamp.\n  /// @param policyholder Address of the policyholder.\n  /// @param role The role to check quantity for.\n  /// @param timestamp The timestamp at which to get the approval quantity.\n  /// @return The quantity of the policyholder's approval.\n  function getApprovalQuantityAt(address policyholder, uint8 role, uint256 timestamp) external view returns (uint96);\n\n  // -------- When Casting Disapproval --------\n\n  /// @notice Reverts if disapprovals are not allowed with this strategy for the given policyholder when disapproving\n  /// with role.\n  /// @param actionInfo Data required to create an action.\n  /// @param policyholder Address of the policyholder.\n  /// @param role The role of the policyholder being used to cast disapproval.\n  function checkIfDisapprovalEnabled(ActionInfo calldata actionInfo, address policyholder, uint8 role) external view;\n\n  /// @notice Get the quantity of a disapproval of a policyholder at a specific timestamp.\n  /// @param policyholder Address of the policyholder.\n  /// @param role The role to check quantity for.\n  /// @param timestamp The timestamp at which to get the disapproval quantity.\n  /// @return The quantity of the policyholder's disapproval.\n  function getDisapprovalQuantityAt(address policyholder, uint8 role, uint256 timestamp) external view returns (uint96);\n\n  // -------- When Queueing --------\n\n  /// @notice Returns the earliest timestamp, in seconds, at which an action can be executed.\n  /// @param actionInfo Data required to create an action.\n  /// @return The earliest timestamp at which an action can be executed.\n  function minExecutionTime(ActionInfo calldata actionInfo) external view returns (uint64);\n\n  // -------- When Canceling --------\n\n  /// @notice Reverts if the action cannot be canceled.\n  /// @param actionInfo Data required to create an action.\n  /// @param caller Policyholder initiating the cancelation.\n  function validateActionCancelation(ActionInfo calldata actionInfo, address caller) external view;\n\n  // -------- When Determining Action State --------\n  // These are used during casting of approvals and disapprovals, when queueing, and when executing.\n\n  /// @notice Get whether an action is currently active.\n  /// @param actionInfo Data required to create an action.\n  /// @return Boolean value that is `true` if the action is currently active, `false` otherwise.\n  function isActionActive(ActionInfo calldata actionInfo) external view returns (bool);\n\n  /// @notice Get whether an action has passed the approval process.\n  /// @param actionInfo Data required to create an action.\n  /// @return Boolean value that is `true` if the action has passed the approval process.\n  function isActionApproved(ActionInfo calldata actionInfo) external view returns (bool);\n\n  /// @notice Get whether an action has been vetoed during the disapproval process.\n  /// @param actionInfo Data required to create an action.\n  /// @return Boolean value that is `true` if the action has been vetoed during the disapproval process.\n  function isActionDisapproved(ActionInfo calldata actionInfo) external view returns (bool);\n\n  /// @notice Returns `true` if the action is expired, `false` otherwise.\n  /// @param actionInfo Data required to create an action.\n  /// @return Boolean value that is `true` if the action is expired.\n  function isActionExpired(ActionInfo calldata actionInfo) external view returns (bool);\n}\n"
      },
      "src/token-voting/interfaces/ILlamaTokenAdapter.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.23;\n\n/// @title ILlamaTokenAdapter\n/// @author Llama (devsdosomething@llama.xyz)\n/// @notice This contract provides an interface for voting token adapters.\ninterface ILlamaTokenAdapter {\n  /// @notice Initializes a new clone of the token adapter.\n  /// @dev This function is called by the `deploy` function in the `LlamaTokenVotingFactory` contract. The `initializer`\n  /// modifier ensures that this function can be invoked at most once.\n  /// @param config The token adapter configuration, encoded as bytes to support differing constructor arguments in\n  /// different token adapters.\n  /// @return This return statement must be hardcoded to `true` to ensure that initializing an EOA\n  /// (like the zero address) will revert.\n  function initialize(bytes memory config) external returns (bool);\n\n  /// @notice Returns the token voting module's voting token address.\n  /// @return token The voting token.\n  function token() external view returns (address token);\n\n  /// @notice Returns the current timepoint according to the token's clock.\n  /// @return timepoint the current timepoint\n  function clock() external view returns (uint48 timepoint);\n\n  /// @notice Reverts if the token's CLOCK_MODE changes from what's in the adapter or if the clock() function doesn't\n  function checkIfInconsistentClock() external view;\n\n  /// @notice Converts a timestamp to timepoint units.\n  /// @param timestamp The timestamp to convert.\n  /// @return timepoint the current timepoint\n  function timestampToTimepoint(uint256 timestamp) external view returns (uint48 timepoint);\n\n  /// @notice Get the voting balance of a token holder at a specified past timepoint.\n  /// @param account The token holder's address.\n  /// @param timepoint The timepoint at which to get the voting balance.\n  /// @return The number of votes the account had at timepoint.\n  function getPastVotes(address account, uint48 timepoint) external view returns (uint256);\n\n  /// @notice Get the total supply of a token at a specified past timepoint.\n  /// @param timepoint The timepoint at which to get the total supply.\n  /// @return The total supply of the token at timepoint.\n  function getPastTotalSupply(uint48 timepoint) external view returns (uint256);\n}\n"
      },
      "src/lib/UDVTs.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.23;\n\n// @dev We use this UDVT for stronger typing of the Role Description.\ntype RoleDescription is bytes32;\n"
      },
      "src/interfaces/ILlamaPolicy.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// TODO This interface was generated from `cast interface`, so some types are not as strong as they\n// could be.\npragma solidity ^0.8.23;\n\nimport {RoleDescription} from \"../lib/UDVTs.sol\";\n\n/// @title LlamaPolicy Interface\n/// @author Llama (devsdosomething@llama.xyz)\n/// @notice This is the interface for LlamaPolicy.\ninterface ILlamaPolicy {\n  event Approval(address indexed owner, address indexed spender, uint256 indexed id);\n  event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n  event ExpiredRoleRevoked(address indexed caller, address indexed policyholder, uint8 indexed role);\n  event Initialized(uint8 version);\n  event PolicyMetadataSet(address policyMetadata, address indexed policyMetadataLogic, bytes initializationData);\n  event RoleAssigned(address indexed policyholder, uint8 indexed role, uint64 expiration, uint96 quantity);\n  event RoleInitialized(uint8 indexed role, bytes32 description);\n  event RolePermissionAssigned(\n    uint8 indexed role, bytes32 indexed permissionId, PermissionData permissionData, bool hasPermission\n  );\n  event Transfer(address indexed from, address indexed to, uint256 indexed id);\n\n  struct LlamaPolicyConfig {\n    RoleDescription[] roleDescriptions;\n    RoleHolderData[] roleHolders;\n    RolePermissionData[] rolePermissions;\n    string color;\n    string logo;\n  }\n\n  struct PermissionData {\n    address target;\n    bytes4 selector;\n    address strategy;\n  }\n\n  struct Checkpoint {\n    uint64 timestamp;\n    uint64 expiration;\n    uint96 quantity;\n  }\n\n  struct History {\n    Checkpoint[] _checkpoints;\n  }\n\n  struct RoleHolderData {\n    uint8 role;\n    address policyholder;\n    uint96 quantity;\n    uint64 expiration;\n  }\n\n  struct RolePermissionData {\n    uint8 role;\n    PermissionData permissionData;\n    bool hasPermission;\n  }\n\n  function approve(address, uint256) external pure;\n  function balanceOf(address owner) external view returns (uint256);\n  function canCreateAction(uint8 role, bytes32 permissionId) external view returns (bool hasPermission);\n  function contractURI() external view returns (string memory);\n  function getApproved(uint256) external view returns (address);\n  function getPastQuantity(address policyholder, uint8 role, uint256 timestamp) external view returns (uint96);\n  function getPastRoleSupplyAsNumberOfHolders(uint8 role, uint256 timestamp)\n    external\n    view\n    returns (uint96 numberOfHolders);\n  function getPastRoleSupplyAsQuantitySum(uint8 role, uint256 timestamp) external view returns (uint96 totalQuantity);\n  function getQuantity(address policyholder, uint8 role) external view returns (uint96);\n  function getRoleSupplyAsNumberOfHolders(uint8 role) external view returns (uint96 numberOfHolders);\n  function getRoleSupplyAsQuantitySum(uint8 role) external view returns (uint96 totalQuantity);\n  function hasPermissionId(address policyholder, uint8 role, bytes32 permissionId) external view returns (bool);\n  function hasRole(address policyholder, uint8 role) external view returns (bool);\n  function hasRole(address policyholder, uint8 role, uint256 timestamp) external view returns (bool);\n  function initialize(\n    string memory _name,\n    LlamaPolicyConfig memory config,\n    address policyMetadataLogic,\n    address executor,\n    PermissionData memory bootstrapPermissionData\n  ) external;\n  function initializeRole(RoleDescription description) external;\n  function isApprovedForAll(address, address) external view returns (bool);\n  function isRoleExpired(address policyholder, uint8 role) external view returns (bool);\n  function llamaExecutor() external view returns (address);\n  function llamaPolicyMetadata() external view returns (address);\n  function name() external view returns (string memory);\n  function numRoles() external view returns (uint8);\n  function ownerOf(uint256 id) external view returns (address owner);\n  function revokeExpiredRole(uint8 role, address policyholder) external;\n  function revokePolicy(address policyholder) external;\n  function roleBalanceCheckpoints(address policyholder, uint8 role, uint256 start, uint256 end)\n    external\n    view\n    returns (History memory);\n  function roleBalanceCheckpoints(address policyholder, uint8 role) external view returns (History memory);\n  function roleBalanceCheckpointsLength(address policyholder, uint8 role) external view returns (uint256);\n  function roleExpiration(address policyholder, uint8 role) external view returns (uint64);\n  function roleSupplyCheckpoints(uint8 role, uint256 start, uint256 end) external view returns (History memory);\n  function roleSupplyCheckpoints(uint8 role) external view returns (History memory);\n  function roleSupplyCheckpointsLength(uint8 role) external view returns (uint256);\n  function safeTransferFrom(address, address, uint256) external pure;\n  function safeTransferFrom(address, address, uint256, bytes memory) external pure;\n  function setAndInitializePolicyMetadata(address llamaPolicyMetadataLogic, bytes memory config) external;\n  function setApprovalForAll(address, bool) external pure;\n  function setRoleHolder(uint8 role, address policyholder, uint96 quantity, uint64 expiration) external;\n  function setRolePermission(uint8 role, PermissionData memory permissionData, bool hasPermission) external;\n  function supportsInterface(bytes4 interfaceId) external view returns (bool);\n  function symbol() external view returns (string memory);\n  function tokenURI(uint256 tokenId) external view returns (string memory);\n  function totalSupply() external view returns (uint256);\n  function transferFrom(address, address, uint256) external pure;\n  function updateRoleDescription(uint8 role, RoleDescription description) external;\n}\n"
      },
      "src/lib/Enums.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.23;\n\n/// @dev Possible states of an action during its lifecycle.\nenum ActionState {\n  Active, // Action created and approval period begins.\n  Canceled, // Action canceled by creator.\n  Failed, // Action approval failed.\n  Approved, // Action approval succeeded and ready to be queued.\n  Queued, // Action queued for queueing duration and disapproval period begins.\n  Expired, // block.timestamp is greater than Action's executionTime + expirationDelay.\n  Executed // Action has executed successfully.\n\n}\n\n/// @dev Possible states of a user cast vote.\nenum VoteType {\n  Against,\n  For,\n  Abstain\n}\n"
      }
    },
    "settings": {
      "remappings": [
        "@openzeppelin/=lib/openzeppelin-contracts/contracts/",
        "@solmate/=lib/solmate/src/",
        "@solady/=lib/solady/src/",
        "@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/",
        "ds-test/=lib/forge-std/lib/ds-test/src/",
        "erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/",
        "forge-std/=lib/forge-std/src/",
        "openzeppelin-contracts/=lib/openzeppelin-contracts/",
        "solady/=lib/solady/",
        "solmate/=lib/solmate/src/"
      ],
      "optimizer": {
        "enabled": true,
        "runs": 19000
      },
      "metadata": {
        "useLiteralContent": false,
        "bytecodeHash": "none",
        "appendCBOR": true
      },
      "outputSelection": {
        "*": {
          "*": [
            "evm.bytecode",
            "evm.deployedBytecode",
            "devdoc",
            "userdoc",
            "metadata",
            "abi"
          ]
        }
      },
      "evmVersion": "paris",
      "viaIR": false,
      "libraries": {}
    }
  }}