From a525188a87d5a75d9891b40d4a38737cfd66232d Mon Sep 17 00:00:00 2001 From: Solimander Date: Wed, 10 Dec 2025 15:26:51 -0700 Subject: [PATCH 01/31] app operations + trust model implementation --- .gitignore | 3 - docs/APP_OPERATIONS_TRUST_MODEL.md | 189 +++++ docs/future/APP_OWNERSHIP_TRANSFER.md | 140 ++++ script/Parser.s.sol | 6 +- script/releases/Env.sol | 1 - .../v1.0.4-init/1-deployContracts.s.sol | 5 - .../2-acceptAdminAndSetLimits.s.sol | 2 +- src/App.sol | 5 +- src/AppController.sol | 337 +++++--- src/factories/SafeTimelockFactory.sol | 139 ++++ src/interfaces/IAppController.sol | 167 ++-- src/interfaces/ISafe.sol | 16 + src/interfaces/ISafeProxyFactory.sol | 11 + src/interfaces/ISafeTimelockFactory.sol | 136 ++++ src/storage/SafeTimelockFactoryStorage.sol | 50 ++ test/AppController.t.sol | 769 ++++++++++++------ 16 files changed, 1578 insertions(+), 398 deletions(-) create mode 100644 docs/APP_OPERATIONS_TRUST_MODEL.md create mode 100644 docs/future/APP_OWNERSHIP_TRANSFER.md create mode 100644 src/factories/SafeTimelockFactory.sol create mode 100644 src/interfaces/ISafe.sol create mode 100644 src/interfaces/ISafeProxyFactory.sol create mode 100644 src/interfaces/ISafeTimelockFactory.sol create mode 100644 src/storage/SafeTimelockFactoryStorage.sol diff --git a/.gitignore b/.gitignore index d5d2bc6..7afc709 100644 --- a/.gitignore +++ b/.gitignore @@ -4,9 +4,6 @@ out/ /broadcast/ -# Docs -docs/ - # Dotenv file .env .idea diff --git a/docs/APP_OPERATIONS_TRUST_MODEL.md b/docs/APP_OPERATIONS_TRUST_MODEL.md new file mode 100644 index 0000000..ceaa2c7 --- /dev/null +++ b/docs/APP_OPERATIONS_TRUST_MODEL.md @@ -0,0 +1,189 @@ +# App Operations & Trust Model + +> **Note:** This branch includes a POC implementation of the changes described in this spec. + +## Overview + +This spec describes a new operational model for Eigen Compute apps, focusing on team operations and trust guarantees. The goals are: + +1. Make the operational structure legible for teams building on Eigen Compute +2. Enable teams to make verifiable commitments to their users (e.g., upgrade delays that can't be bypassed) + +## Design Principles + +1. **Role-based, not function-based** - Simpler to reason about than per-function permissions +2. **Team-scoped** - Roles are granted per-team (owner address), not per-app +3. **Legibility** - Trust configurations must be displayable on all interfaces +4. **Factory-deployed primitives** - Timelocks and multisigs deployed via factories can be verified as legitimate + +## Team Model + +An app owner's address IS the team identity. This is similar to GitHub or Vercel teams, but the team is built around the owner address rather than a separate entity. This keeps things simple - no team entity to create, straightforward billing tied to the owner, and works naturally for the common case of a single EOA or multisig. Ownership can be transferred to a new address if the team structure changes (see Future Additions). + +Any role (including the team owner) can be: +- An EOA (solo dev or operator) +- A multisig (shared control) +- A multisig behind a timelock (for enforced delays on sensitive operations) + +This also enables a cleaner UX: manage your team once, and all apps under that team inherit the same permissions - similar to how Vercel or GitHub organization access works. App-level permissions would require managing access separately for each app, and wouldn't align with billing which is at the owner level. + +## Roles + +Roles are scoped to the team via `keccak256(abi.encode(teamAddress, TeamRole))`. + +| Role | Capabilities | +|------|-------------| +| `ADMIN` | Full access: create apps, upgrade, start, stop, terminate, manage roles | +| `PAUSER` | Stop apps (emergency response) | +| `DEVELOPER` | Update metadata, view logs, submit builds | + +Admins implicitly have all other roles. The last admin cannot be revoked or renounced (prevents accidental lockout). + +## SafeTimelockFactory + +Factory for deploying verified Gnosis Safes and OZ TimelockControllers. Deployed contracts can be verified via `isSafe()` and `isTimelock()`. + +### Why a factory? + +- Factory deployment guarantees unmodified OZ TimelockController (no bypasses) +- Enables UIs to display accurate delay information with confidence +- Supports atomic Safe + Timelock setup via EIP-7702: predict Safe address, deploy both, and configure Safe as proposer in a single transaction + +### Safe Deployment + +```solidity +struct SafeConfig { + address[] owners; + uint256 threshold; +} + +deploySafe(config, salt) → deterministic address +``` + +### Timelock Deployment + +```solidity +struct TimelockConfig { + uint256 minDelay; + address[] proposers; + address[] executors; +} + +deployTimelock(config, salt) → deterministic address +``` + +## Typical Configurations + +| Setup | Admin Entity | Delay | +|-------|-------------|-------| +| Dev/testing | EOA | 0 | +| Production | Multisig behind timelock | >0 | + +For emergency response, grant `PAUSER` to a lower-threshold multisig or EOA that can stop apps without going through the timelock. + +## CLI Integration + +### Identity (`ecloud auth`) + +**Login to existing identity:** + +``` +ecloud auth login + +> Select identity type: + 1. EOA (private key) + 2. Gnosis Safe (enter address) +``` + +**Create new identity:** + +``` +ecloud auth new + +> What would you like to create? + 1. EOA (new private key) + 2. Gnosis Safe + +# For Safe: +> Enter owner addresses: 0x1111..., 0x2222..., 0x3333... +> Enter threshold (e.g., 2 of 3): 2 + +> Add timelock delay? (y/N) y +> Enter minimum delay (e.g., "24h", "7d"): 24h + +> Deploying Safe + Timelock via factory... +``` + +When a timelock is configured, the CLI deploys via SafeTimelockFactory with your identity as both proposer and executor. + +**App actions with Safe:** + +When logged in as a Safe, app actions propose a transaction and link to the Safe UI: + +``` +ecloud compute app upgrade + +> Transaction proposed to Safe. +> View and sign at: https://app.safe.global/transactions/queue?safe=eth:0x1234... +``` + +**Viewing trust configuration:** + +``` +ecloud compute app info + +> App: my-app +> Owner: 0x1234... (3/5 Safe behind 24h timelock) +> Status: STARTED +> +> Team Roles: +> ADMIN: 0x1234... (3/5 Safe behind 24h timelock) +> 0xabcd... (EOA) +> PAUSER: 0x5678... (2/3 Safe, no delay) +> DEVELOPER: 0x9999... (EOA) +``` + +### Team Management (`ecloud compute team`) + +Manage roles for your team: + +``` +ecloud compute team grant
[role] +ecloud compute team revoke
[role] +ecloud compute team list +``` + +**Grant (interactive):** + +``` +ecloud compute team grant 0x1234... + +> Select role to grant: + 1. ADMIN - Full access: create apps, upgrade, start, stop, terminate, manage roles + 2. PAUSER - Stop apps (emergency response) + 3. DEVELOPER - Update metadata, view logs, submit builds + +> Role granted successfully. +``` + +**Revoke (interactive):** + +``` +ecloud compute team revoke 0x1234... + +> 0x1234... has: PAUSER, DEVELOPER +> Select role to revoke: + 1. PAUSER + 2. DEVELOPER + +> Role revoked successfully. +``` + +## Migration + +`migrateAdmins(apps[])` is a one-time state migration performed by Eigen admins to bridge existing PermissionController admins to AccessControl. + +## Future Additions + +- **Timelock Operations CLI** (`ecloud compute tx list`, `ecloud compute tx execute`) - View pending operations and execute when ready. Requires Safe Transaction Service integration and event indexing. +- **[App Ownership Transfer](future/APP_OWNERSHIP_TRANSFER.md)** - Two-step transfer pattern to move apps between teams (useful for acquisitions, team restructuring) diff --git a/docs/future/APP_OWNERSHIP_TRANSFER.md b/docs/future/APP_OWNERSHIP_TRANSFER.md new file mode 100644 index 0000000..30ff404 --- /dev/null +++ b/docs/future/APP_OWNERSHIP_TRANSFER.md @@ -0,0 +1,140 @@ +# App Ownership Transfer (Future) + +Technical specification for two-step app ownership transfer. + +## Overview + +Transfer app ownership between teams. Useful for acquisitions, team restructuring, or handing off projects. + +## Interface + +### Errors + +```solidity +error NoPendingTransfer(); +``` + +### Events + +```solidity +event AppTransferInitiated(IApp indexed app, address indexed currentOwner, address indexed pendingOwner); +event AppTransferCancelled(IApp indexed app); +event AppTransferred(IApp indexed app, address indexed oldOwner, address indexed newOwner); +``` + +### Storage + +Add to `AppConfig`: + +```solidity +struct AppConfig { + address owner; + uint32 operatorSetId; + uint32 latestReleaseBlockNumber; + AppStatus status; + address pendingOwner; // <-- add this +} +``` + +### Functions + +```solidity +/// @notice Initiates an app transfer to a new owner +/// @param app The app to transfer +/// @param newOwner The address of the new owner +/// @dev Only team admins can initiate transfers +/// @dev App must be active (STARTED or STOPPED) +/// @dev Can be called again to change the pending owner +function initiateAppTransfer(IApp app, address newOwner) external; + +/// @notice Accepts a pending app transfer +/// @param app The app to accept transfer for +/// @dev Only the pending owner can accept +/// @dev The new owner must have available quota at time of acceptance +function acceptAppTransfer(IApp app) external; + +/// @notice Cancels a pending app transfer +/// @param app The app to cancel transfer for +/// @dev Only team admins can cancel transfers +function cancelAppTransfer(IApp app) external; + +/// @notice Gets the pending owner for an app transfer +/// @param app The app to check +/// @return The pending owner address, or address(0) if no pending transfer +function getPendingAppOwner(IApp app) external view returns (address); +``` + +## Implementation + +### initiateAppTransfer + +```solidity +function initiateAppTransfer(IApp app, address newOwner) external appIsActive(app) onlyAdmin(app) { + address currentOwner = _appConfigs[app].owner; + _appConfigs[app].pendingOwner = newOwner; + emit AppTransferInitiated(app, currentOwner, newOwner); +} +``` + +### acceptAppTransfer + +```solidity +function acceptAppTransfer(IApp app) external { + AppConfig storage config = _appConfigs[app]; + address pendingOwner = config.pendingOwner; + + require(pendingOwner != address(0), NoPendingTransfer()); + require(msg.sender == pendingOwner, InvalidPermissions()); + + // Check new owner has available quota + UserConfig storage newOwnerConfig = _userConfigs[pendingOwner]; + require(newOwnerConfig.activeAppCount < newOwnerConfig.maxActiveApps, MaxActiveAppsExceeded()); + + address oldOwner = config.owner; + + // Update app ownership + config.owner = pendingOwner; + config.pendingOwner = address(0); + + // Transfer quota: decrement old owner, increment new owner + _userConfigs[oldOwner].activeAppCount--; + newOwnerConfig.activeAppCount++; + + // Grant ADMIN_ROLE to new owner so they can manage the app + _grantRole(_teamRole(pendingOwner, ADMIN_ROLE), pendingOwner); + + emit AppTransferred(app, oldOwner, pendingOwner); +} +``` + +### cancelAppTransfer + +```solidity +function cancelAppTransfer(IApp app) external onlyAdmin(app) { + require(_appConfigs[app].pendingOwner != address(0), NoPendingTransfer()); + _appConfigs[app].pendingOwner = address(0); + emit AppTransferCancelled(app); +} +``` + +## Quota Behavior + +- Quota is checked at **accept time**, not initiate time +- Old owner's `activeAppCount` decrements on accept +- New owner's `activeAppCount` increments on accept +- If new owner's quota fills between initiate and accept, accept reverts + +## Access Control + +- `initiateAppTransfer`: Requires `ADMIN_ROLE` on the app's owner team +- `acceptAppTransfer`: Only callable by the pending owner +- `cancelAppTransfer`: Requires `ADMIN_ROLE` on the app's owner team +- Old owner retains full control until transfer is accepted +- New owner automatically receives `ADMIN_ROLE` on their own team upon acceptance + +## Edge Cases + +- Calling `initiateAppTransfer` again overwrites the pending owner +- Old owner can still manage app (stop, upgrade, etc.) while transfer is pending +- Pending owner has no access until they accept +- Terminated apps cannot be transferred (`appIsActive` modifier) diff --git a/script/Parser.s.sol b/script/Parser.s.sol index 982a879..ab590ba 100644 --- a/script/Parser.s.sol +++ b/script/Parser.s.sol @@ -3,16 +3,12 @@ pragma solidity ^0.8.27; import {Script, console} from "forge-std/Script.sol"; import {ProxyAdmin} from "@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol"; -import { - TransparentUpgradeableProxy, - ITransparentUpgradeableProxy -} from "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol"; +import {TransparentUpgradeableProxy} from "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol"; import {IDelegationManager} from "@eigenlayer-contracts/src/contracts/interfaces/IDelegationManager.sol"; import {IAllocationManager} from "@eigenlayer-contracts/src/contracts/interfaces/IAllocationManager.sol"; import {IKeyRegistrar} from "@eigenlayer-contracts/src/contracts/interfaces/IKeyRegistrar.sol"; import {IPermissionController} from "@eigenlayer-contracts/src/contracts/interfaces/IPermissionController.sol"; import {IReleaseManager} from "@eigenlayer-contracts/src/contracts/interfaces/IReleaseManager.sol"; -import {EmptyContract} from "@eigenlayer-contracts/src/test/mocks/EmptyContract.sol"; import {UpgradeableBeacon} from "@openzeppelin/contracts/proxy/beacon/UpgradeableBeacon.sol"; import {App} from "../src/App.sol"; import {IAppController} from "../src/interfaces/IAppController.sol"; diff --git a/script/releases/Env.sol b/script/releases/Env.sol index 1607e51..639b398 100644 --- a/script/releases/Env.sol +++ b/script/releases/Env.sol @@ -9,7 +9,6 @@ import "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.so import "@openzeppelin/contracts/proxy/beacon/IBeacon.sol"; import "@openzeppelin/contracts/proxy/beacon/UpgradeableBeacon.sol"; -import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import {DelegationManager} from "@eigenlayer-contracts/src/contracts/core/DelegationManager.sol"; import {AllocationManager} from "@eigenlayer-contracts/src/contracts/core/AllocationManager.sol"; import {PermissionController} from "@eigenlayer-contracts/src/contracts/permissions/PermissionController.sol"; diff --git a/script/releases/v1.0.4-init/1-deployContracts.s.sol b/script/releases/v1.0.4-init/1-deployContracts.s.sol index 88ac49e..13be774 100644 --- a/script/releases/v1.0.4-init/1-deployContracts.s.sol +++ b/script/releases/v1.0.4-init/1-deployContracts.s.sol @@ -8,11 +8,6 @@ import "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.so import "@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol"; import "@openzeppelin/contracts/proxy/beacon/UpgradeableBeacon.sol"; -import {IDelegationManager} from "@eigenlayer-contracts/src/contracts/interfaces/IDelegationManager.sol"; -import {IAllocationManager} from "@eigenlayer-contracts/src/contracts/interfaces/IAllocationManager.sol"; -import {IKeyRegistrar} from "@eigenlayer-contracts/src/contracts/interfaces/IKeyRegistrar.sol"; -import {IPermissionController} from "@eigenlayer-contracts/src/contracts/interfaces/IPermissionController.sol"; -import {IReleaseManager} from "@eigenlayer-contracts/src/contracts/interfaces/IReleaseManager.sol"; import {EmptyContract} from "@eigenlayer-contracts/src/test/mocks/EmptyContract.sol"; import {App} from "../../../src/App.sol"; diff --git a/script/releases/v1.0.4-init/2-acceptAdminAndSetLimits.s.sol b/script/releases/v1.0.4-init/2-acceptAdminAndSetLimits.s.sol index 9869c8a..dd0a794 100644 --- a/script/releases/v1.0.4-init/2-acceptAdminAndSetLimits.s.sol +++ b/script/releases/v1.0.4-init/2-acceptAdminAndSetLimits.s.sol @@ -5,7 +5,7 @@ import {Deploy} from "./1-deployContracts.s.sol"; import "../Env.sol"; import {MultisigBuilder} from "zeus-templates/templates/MultisigBuilder.sol"; -import {Encode, MultisigCall} from "zeus-templates/utils/Encode.sol"; +import {Encode} from "zeus-templates/utils/Encode.sol"; /** * Purpose: diff --git a/src/App.sol b/src/App.sol index 722c86c..ef7226e 100644 --- a/src/App.sol +++ b/src/App.sol @@ -16,8 +16,5 @@ contract App is Initializable, SemVerMixin, AppStorage { } /// @inheritdoc IApp - function initialize(address admin) external initializer { - // Grant admin permissions to the owner - permissionController.addPendingAdmin(address(this), admin); - } + function initialize(address) external initializer {} } diff --git a/src/AppController.sol b/src/AppController.sol index 1791d4b..5dc3036 100644 --- a/src/AppController.sol +++ b/src/AppController.sol @@ -4,6 +4,9 @@ pragma solidity ^0.8.27; import {Create2} from "@openzeppelin/contracts/utils/Create2.sol"; import {OwnableUpgradeable} from "@openzeppelin-upgrades/contracts/access/OwnableUpgradeable.sol"; import {Initializable} from "@openzeppelin-upgrades/contracts/proxy/utils/Initializable.sol"; +import { + AccessControlEnumerableUpgradeable +} from "@openzeppelin-upgrades/contracts/access/AccessControlEnumerableUpgradeable.sol"; import {EnumerableSet} from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol"; import {SignatureUtilsMixin} from "@eigenlayer-contracts/src/contracts/mixins/SignatureUtilsMixin.sol"; import {IPermissionController} from "@eigenlayer-contracts/src/contracts/interfaces/IPermissionController.sol"; @@ -21,7 +24,13 @@ import {BeaconProxy} from "@openzeppelin/contracts/proxy/beacon/BeaconProxy.sol" import {IBeacon} from "@openzeppelin/contracts/proxy/beacon/IBeacon.sol"; import {IApp} from "./interfaces/IApp.sol"; -contract AppController is Initializable, SignatureUtilsMixin, PermissionControllerMixin, AppControllerStorage { +contract AppController is + Initializable, + SignatureUtilsMixin, + PermissionControllerMixin, + AppControllerStorage, + AccessControlEnumerableUpgradeable +{ using EnumerableSet for EnumerableSet.AddressSet; /// MODIFIERS @@ -38,6 +47,18 @@ contract AppController is Initializable, SignatureUtilsMixin, PermissionControll _; } + /// @notice Modifier to check if caller has the required role (or is admin) for an app + modifier onlyAdminOrRole(IApp app, TeamRole role) { + _checkAdminOrRole(app, role); + _; + } + + /// @notice Modifier to check if caller is an admin for an app + modifier onlyAdmin(IApp app) { + _checkIsAdmin(app); + _; + } + /** * @param _version The version string to use for this contract's domain separator * @param _permissionController The PermissionController contract address @@ -62,6 +83,9 @@ contract AppController is Initializable, SignatureUtilsMixin, PermissionControll /// @inheritdoc IAppController function initialize(address admin) external initializer { + // Initialize AccessControl + __AccessControl_init(); + // Accept the ComputeAVSRegistrar as an admin permissionController.acceptAdmin(address(computeAVSRegistrar)); @@ -98,45 +122,81 @@ contract AppController is Initializable, SignatureUtilsMixin, PermissionControll emit GlobalMaxActiveAppsSet(limit); } + /// @inheritdoc IAppController + /// @dev This function will be removed in a later upgrade once initial migrations are completed + function migrateAdmins(IApp[] calldata apps) external checkCanCall(address(this)) { + for (uint256 i = 0; i < apps.length; i++) { + IApp app = apps[i]; + require(_exists(_appConfigs[app].status), AppDoesNotExist()); + + address owner = _appConfigs[app].owner; + address[] memory admins = permissionController.getAdmins(address(app)); + + for (uint256 j = 0; j < admins.length; j++) { + _grantRole(_teamRole(owner, TeamRole.ADMIN), admins[j]); + } + } + } + /// @inheritdoc IAppController function createApp(bytes32 salt, Release calldata release) external returns (IApp app) { - _checkAndIncrementActiveApps(msg.sender); - app = _deployApp(salt, release, BillingType.DEFAULT); + return createAppForTeam(msg.sender, salt, release); } /// @inheritdoc IAppController - function createAppWithIsolatedBilling(bytes32 salt, Release calldata release) external returns (IApp app) { - _checkAndIncrementActiveApps(address(calculateAppId(msg.sender, salt))); - app = _deployApp(salt, release, BillingType.ISOLATED); + function createAppForTeam(address team, bytes32 salt, Release calldata release) public returns (IApp app) { + // Check caller is admin on the team (or is the team themselves for first app creation) + require(team == msg.sender || hasRole(_teamRole(team, TeamRole.ADMIN), msg.sender), InvalidPermissions()); + + _checkAndIncrementActiveApps(team); + + // Assign an operator set ID to the app + uint32 operatorSetId = computeAVSRegistrar.assignOperatorSetId(); + + // Publish the initial release metadata URI + releaseManager.publishMetadataURI( + OperatorSet({avs: address(computeAVSRegistrar), id: operatorSetId}), "https://eigencloud.xyz" + ); + + // Create app using BeaconProxy (salt is mixed with team for deterministic address) + app = IApp(Create2.deploy(0, _calculateAppMixedSalt(team, salt), _calculateAppInitCode(team))); + _appConfigs[app].operatorSetId = operatorSetId; + _appConfigs[app].latestReleaseBlockNumber = 0; + _appConfigs[app].owner = team; + _allApps.add(address(app)); + + emit AppCreated(team, app, operatorSetId); + + // Grant ADMIN role to the team if not already granted + _grantRole(_teamRole(team, TeamRole.ADMIN), team); + + // Upgrade the app with the initial release + _upgradeApp(app, release); + _startApp(app); } /// @inheritdoc IAppController - function upgradeApp(IApp app, Release calldata release) - external - checkCanCall(address(app)) - appIsActive(app) - returns (uint256) - { + function upgradeApp(IApp app, Release calldata release) external appIsActive(app) onlyAdmin(app) returns (uint256) { return _upgradeApp(app, release); } /// @inheritdoc IAppController function updateAppMetadataURI(IApp app, string calldata metadataURI) external - checkCanCall(address(app)) appExists(app) + onlyAdminOrRole(app, TeamRole.DEVELOPER) { emit AppMetadataURIUpdated(app, metadataURI); } /// @inheritdoc IAppController - function startApp(IApp app) external checkCanCall(address(app)) appExists(app) { + function startApp(IApp app) external appExists(app) onlyAdmin(app) { _startApp(app); } /// @inheritdoc IAppController - function stopApp(IApp app) external checkCanCall(address(app)) { - AppConfigStorage storage config = _appConfigs[app]; + function stopApp(IApp app) external onlyAdminOrRole(app, TeamRole.PAUSER) { + AppConfig storage config = _appConfigs[app]; require(config.status == AppStatus.STARTED, InvalidAppStatus()); config.status = AppStatus.STOPPED; @@ -144,7 +204,7 @@ contract AppController is Initializable, SignatureUtilsMixin, PermissionControll } /// @inheritdoc IAppController - function terminateApp(IApp app) external checkCanCall(address(app)) appIsActive(app) { + function terminateApp(IApp app) external appIsActive(app) onlyAdmin(app) { _terminateApp(app); } @@ -162,11 +222,10 @@ contract AppController is Initializable, SignatureUtilsMixin, PermissionControll // Suspend all provided apps, skipping apps that are already SUSPENDED, TERMINATED, or NONE for (uint256 i = 0; i < apps.length; i++) { IApp app = apps[i]; - AppConfigStorage memory config = _appConfigs[app]; + AppConfig memory config = _appConfigs[app]; - // Validate that the app is billed to this account - address billingAccount = config.billingType == BillingType.ISOLATED ? address(app) : config.creator; - require(billingAccount == account, InvalidAppStatus()); + // Validate ownership + require(config.owner == account, InvalidAppStatus()); // Only suspend if app is active (STARTED or STOPPED) if (_isActive(config.status)) { @@ -181,32 +240,100 @@ contract AppController is Initializable, SignatureUtilsMixin, PermissionControll _setMaxActiveAppsPerUser(account, 0); } + /// TEAM ROLE MANAGEMENT + + /// @inheritdoc IAppController + function grantTeamRole(address team, TeamRole role, address account) external { + require(hasRole(_teamRole(team, TeamRole.ADMIN), msg.sender), InvalidPermissions()); + _grantRole(_teamRole(team, role), account); + } + + /// @inheritdoc IAppController + function revokeTeamRole(address team, TeamRole role, address account) external { + require(hasRole(_teamRole(team, TeamRole.ADMIN), msg.sender), InvalidPermissions()); + bytes32 teamRole = _teamRole(team, role); + require(role != TeamRole.ADMIN || getRoleMemberCount(teamRole) > 1, CannotRevokeLastAdmin()); + + _revokeRole(teamRole, account); + } + + /// @inheritdoc IAppController + function renounceTeamRole(address team, TeamRole role) external { + bytes32 teamRole = _teamRole(team, role); + require(role != TeamRole.ADMIN || getRoleMemberCount(teamRole) > 1, CannotRevokeLastAdmin()); + + _revokeRole(teamRole, msg.sender); + } + + /// @inheritdoc IAppController + function hasTeamRole(address team, TeamRole role, address account) external view returns (bool) { + return _hasTeamRole(team, account, role); + } + + /// @inheritdoc IAppController + function getTeamRoleMemberCount(address team, TeamRole role) external view returns (uint256) { + return getRoleMemberCount(_teamRole(team, role)); + } + + /// @inheritdoc IAppController + function getTeamRoleMember(address team, TeamRole role, uint256 index) external view returns (address) { + return getRoleMember(_teamRole(team, role), index); + } + + /// @inheritdoc IAppController + function getTeamRoleMembers(address team, TeamRole role) external view returns (address[] memory) { + bytes32 teamRole = _teamRole(team, role); + uint256 count = getRoleMemberCount(teamRole); + address[] memory members = new address[](count); + for (uint256 i = 0; i < count; i++) { + members[i] = getRoleMember(teamRole, i); + } + return members; + } + /// INTERNAL FUNCTIONS /** - * @notice Deploys an app, configures it, publishes the initial release, and starts it - * @param salt The salt for deterministic deployment - * @param release The initial release to upgrade to - * @param _billingType The billing type for the app (DEFAULT or ISOLATED) - * @return app The deployed app instance + * @notice Computes a team-scoped role identifier by combining team address with role enum + * @param team The team address + * @param role The team role (ADMIN, PAUSER, or DEVELOPER) + * @return The team-scoped role identifier for use with AccessControl */ - function _deployApp(bytes32 salt, Release calldata release, BillingType _billingType) internal returns (IApp app) { - uint32 operatorSetId = computeAVSRegistrar.assignOperatorSetId(); - releaseManager.publishMetadataURI( - OperatorSet({avs: address(computeAVSRegistrar), id: operatorSetId}), "https://eigencloud.xyz" - ); + function _teamRole(address team, TeamRole role) internal pure returns (bytes32) { + return keccak256(abi.encode(team, role)); + } - app = IApp(Create2.deploy(0, _calculateAppMixedSalt(msg.sender, salt), _calculateAppInitCode(msg.sender))); - _appConfigs[app].operatorSetId = operatorSetId; - _appConfigs[app].latestReleaseBlockNumber = 0; - _appConfigs[app].creator = msg.sender; - _appConfigs[app].billingType = _billingType; - _allApps.add(address(app)); + /** + * @notice Checks if an account has the required role (admins always have access) + * @param team The team address + * @param account The account to check + * @param role The required role + * @return True if account has the required role or is an admin + */ + function _hasTeamRole(address team, address account, TeamRole role) internal view returns (bool) { + if (hasRole(_teamRole(team, TeamRole.ADMIN), account)) return true; + return hasRole(_teamRole(team, role), account); + } - emit AppCreated(msg.sender, app, operatorSetId); + /** + * @notice Checks if the caller has the required role (or is admin) for an app + * @param app The app to check access for + * @param role The required role + * @dev Reverts with InvalidPermissions if caller lacks the required role + */ + function _checkAdminOrRole(IApp app, TeamRole role) internal view { + address owner = _appConfigs[app].owner; + require(_hasTeamRole(owner, msg.sender, role), InvalidPermissions()); + } - _upgradeApp(app, release); - _startApp(app); + /** + * @notice Checks if the caller is an admin for the app's owner + * @param app The app to check access for + * @dev Reverts with InvalidPermissions if caller is not an admin + */ + function _checkIsAdmin(IApp app) internal view { + address owner = _appConfigs[app].owner; + require(hasRole(_teamRole(owner, TeamRole.ADMIN), msg.sender), InvalidPermissions()); } /** @@ -245,15 +372,16 @@ contract AppController is Initializable, SignatureUtilsMixin, PermissionControll } /** - * @notice Decrements global and billing account active app counters + * @notice Decrements global and owner active app counters * @param app The app instance to decrement counters for */ function _decrementActiveApps(IApp app) internal { // Decrement active app counts to free up capacity globalActiveAppCount--; - // Decrement the billing account's active app count - _userConfigs[getBillingAccount(app)].activeAppCount--; + // Decrement the owner's active app count + address appOwner = _appConfigs[app].owner; + _userConfigs[appOwner].activeAppCount--; } /** @@ -288,12 +416,12 @@ contract AppController is Initializable, SignatureUtilsMixin, PermissionControll * @param app The app instance to start */ function _startApp(IApp app) internal { - AppConfigStorage storage config = _appConfigs[app]; + AppConfig storage config = _appConfigs[app]; require(config.status != AppStatus.TERMINATED, InvalidAppStatus()); // If resuming from suspended, re-check limits and increment active app counters if (config.status == AppStatus.SUSPENDED) { - _checkAndIncrementActiveApps(getBillingAccount(app)); + _checkAndIncrementActiveApps(config.owner); } config.status = AppStatus.STARTED; emit AppStarted(app); @@ -340,18 +468,6 @@ contract AppController is Initializable, SignatureUtilsMixin, PermissionControll ); } - /** - * @notice Converts an AppConfigStorage to a public AppConfig - */ - function _toAppConfig(AppConfigStorage storage s) private view returns (AppConfig memory) { - return AppConfig({ - creator: s.creator, - operatorSetId: s.operatorSetId, - latestReleaseBlockNumber: s.latestReleaseBlockNumber, - status: s.status - }); - } - /** * @notice Gets filtered apps based on a predicate function * @param predicate The predicate function to apply to each app @@ -383,7 +499,7 @@ contract AppController is Initializable, SignatureUtilsMixin, PermissionControll } apps[found] = app; - appConfigsMem[found] = _toAppConfig(_appConfigs[app]); + appConfigsMem[found] = _appConfigs[app]; found++; } } @@ -396,33 +512,24 @@ contract AppController is Initializable, SignatureUtilsMixin, PermissionControll } /** - * @notice Check if address is developer of app + * @notice Check if address is developer of app (has ADMIN role on the app's owner team) * @param app The app to check * @param developer The developer to check - * @return True if the developer is the developer of the app + * @return True if the developer has admin access to the app */ function _isDeveloper(IApp app, address developer) private view returns (bool) { - return permissionController.isAdmin(address(app), developer); + address owner = _appConfigs[app].owner; + return _hasTeamRole(owner, developer, TeamRole.ADMIN); } /** - * @notice Check if address is creator of app + * @notice Check if address is owner of app * @param app The app to check - * @param creator The creator to check - * @return True if the creator is the creator of the app + * @param owner The owner to check + * @return True if the owner owns the app */ - function _isCreator(IApp app, address creator) private view returns (bool) { - return _appConfigs[app].creator == creator; - } - - /** - * @notice Check if an app is billed to the given account - * @param app The app to check - * @param account The billing account to match against - * @return True if the app is billed to the account - */ - function _isBilledTo(IApp app, address account) private view returns (bool) { - return getBillingAccount(app) == account; + function _isOwner(IApp app, address owner) private view returns (bool) { + return _appConfigs[app].owner == owner; } /// VIEW FUNCTIONS @@ -438,7 +545,7 @@ contract AppController is Initializable, SignatureUtilsMixin, PermissionControll } /// @inheritdoc IAppController - function calculateAppId(address deployer, bytes32 salt) public view returns (IApp) { + function calculateAppId(address deployer, bytes32 salt) external view returns (IApp) { return IApp( Create2.computeAddress( _calculateAppMixedSalt(deployer, salt), @@ -453,23 +560,8 @@ contract AppController is Initializable, SignatureUtilsMixin, PermissionControll } /// @inheritdoc IAppController - function getAppCreator(IApp app) external view returns (address) { - return _appConfigs[app].creator; - } - - /** - * @notice Resolves the billing account for an app - * @param app The app instance to resolve billing for - * @return The billing account address (app address if ISOLATED, creator if DEFAULT) - */ - function getBillingAccount(IApp app) public view returns (address) { - AppConfigStorage storage config = _appConfigs[app]; - return config.billingType == BillingType.ISOLATED ? address(app) : config.creator; - } - - /// @inheritdoc IAppController - function getBillingType(IApp app) external view returns (BillingType) { - return _appConfigs[app].billingType; + function getAppOwner(IApp app) external view returns (address) { + return _appConfigs[app].owner; } /// @inheritdoc IAppController @@ -498,7 +590,7 @@ contract AppController is Initializable, SignatureUtilsMixin, PermissionControll appConfigsMem = new AppConfig[](rangeSize); for (uint256 i = 0; i < rangeSize; i++) { apps[i] = IApp(_allApps.at(offset + i)); - appConfigsMem[i] = _toAppConfig(_appConfigs[apps[i]]); + appConfigsMem[i] = _appConfigs[apps[i]]; } } @@ -517,20 +609,67 @@ contract AppController is Initializable, SignatureUtilsMixin, PermissionControll view returns (IApp[] memory apps, AppConfig[] memory appConfigsMem) { - return _getFilteredApps(_isCreator, creator, offset, limit); + return _getFilteredApps(_isOwner, creator, offset, limit); } /// @inheritdoc IAppController - function getAppsByBillingAccount(address account, uint256 offset, uint256 limit) + function getAppsForAccount(address account, uint256 offset, uint256 limit) external view - returns (IApp[] memory apps, AppConfig[] memory appConfigsMem) + returns (AppRoles[] memory appRoles) { - return _getFilteredApps(_isBilledTo, account, offset, limit); + // Reuse _getFilteredApps with _accountHasAnyRole predicate for pagination + (IApp[] memory apps,) = _getFilteredApps(_accountHasAnyRole, account, offset, limit); + + // Build AppRoles array from filtered results + appRoles = new AppRoles[](apps.length); + for (uint256 i = 0; i < apps.length; i++) { + appRoles[i] = _buildAppRoles(apps[i], account); + } + } + + /** + * @notice Builds AppRoles struct for a single app + * @param app The app to build roles for + * @param account The account to check roles for + * @return The AppRoles struct with app, isOwner, and roles array + */ + function _buildAppRoles(IApp app, address account) private view returns (AppRoles memory) { + address owner = _appConfigs[app].owner; + + // Check roles + bool hasAdmin = hasRole(_teamRole(owner, TeamRole.ADMIN), account); + bool hasPauser = hasRole(_teamRole(owner, TeamRole.PAUSER), account); + bool hasDeveloper = hasRole(_teamRole(owner, TeamRole.DEVELOPER), account); + + // Count and build roles array + uint256 roleCount = (hasAdmin ? 1 : 0) + (hasPauser ? 1 : 0) + (hasDeveloper ? 1 : 0); + TeamRole[] memory roles = new TeamRole[](roleCount); + uint256 idx = 0; + if (hasAdmin) roles[idx++] = TeamRole.ADMIN; + if (hasPauser) roles[idx++] = TeamRole.PAUSER; + if (hasDeveloper) roles[idx++] = TeamRole.DEVELOPER; + + return AppRoles({app: app, isOwner: owner == account, roles: roles}); } /// @inheritdoc IAppController function calculateApiPermissionDigestHash(bytes4 permission, uint256 expiry) external view returns (bytes32) { return _calculateSignableDigest(keccak256(abi.encode(API_PERMISSION_TYPEHASH, permission, expiry))); } + + /** + * @notice Checks if an account has any role (owner, admin, pauser, or developer) on an app + * @param app The app to check + * @param account The account to check + * @return True if the account has any role on the app + */ + function _accountHasAnyRole(IApp app, address account) private view returns (bool) { + address owner = _appConfigs[app].owner; + if (owner == account) return true; + if (hasRole(_teamRole(owner, TeamRole.ADMIN), account)) return true; + if (hasRole(_teamRole(owner, TeamRole.PAUSER), account)) return true; + if (hasRole(_teamRole(owner, TeamRole.DEVELOPER), account)) return true; + return false; + } } diff --git a/src/factories/SafeTimelockFactory.sol b/src/factories/SafeTimelockFactory.sol new file mode 100644 index 0000000..1624fd0 --- /dev/null +++ b/src/factories/SafeTimelockFactory.sol @@ -0,0 +1,139 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity ^0.8.27; + +import {Create2} from "@openzeppelin/contracts/utils/Create2.sol"; +import {Initializable} from "@openzeppelin-upgrades/contracts/proxy/utils/Initializable.sol"; +import {EnumerableSet} from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol"; +import {TimelockController} from "@openzeppelin/contracts/governance/TimelockController.sol"; +import {SafeTimelockFactoryStorage} from "../storage/SafeTimelockFactoryStorage.sol"; +import {ISafeTimelockFactory} from "../interfaces/ISafeTimelockFactory.sol"; +import {ISafe} from "../interfaces/ISafe.sol"; +import {ISafeProxyFactory} from "../interfaces/ISafeProxyFactory.sol"; + +/** + * @title SafeTimelockFactory + * @notice Factory for deploying verified Gnosis Safes and TimelockControllers + * @dev Deployed entities can be verified as "official" via isSafe() and isTimelock() + */ +contract SafeTimelockFactory is Initializable, SafeTimelockFactoryStorage { + using EnumerableSet for EnumerableSet.AddressSet; + + constructor(address _safeSingleton, address _safeProxyFactory, address _defaultFallbackHandler) + SafeTimelockFactoryStorage(_safeSingleton, _safeProxyFactory, _defaultFallbackHandler) + { + _disableInitializers(); + } + + function initialize() external initializer {} + + /// EXTERNAL FUNCTIONS + + /// @inheritdoc ISafeTimelockFactory + function deploySafe(SafeConfig calldata config, bytes32 salt) external returns (address safe) { + _validateSafeConfig(config); + safe = _deploySafe(config, salt); + _safes.add(safe); + emit SafeDeployed(msg.sender, safe, config.owners, config.threshold, salt); + } + + /// @inheritdoc ISafeTimelockFactory + function deployTimelock(TimelockConfig calldata config, bytes32 salt) external returns (address timelock) { + _validateTimelockConfig(config); + timelock = _deployTimelock(config, salt); + _timelocks.add(timelock); + emit TimelockDeployed(msg.sender, timelock, config.minDelay, config.proposers, config.executors, salt); + } + + /// VIEW FUNCTIONS + + /// @inheritdoc ISafeTimelockFactory + function isSafe(address safe) external view returns (bool) { + return _safes.contains(safe); + } + + /// @inheritdoc ISafeTimelockFactory + function isTimelock(address timelock) external view returns (bool) { + return _timelocks.contains(timelock); + } + + /// @inheritdoc ISafeTimelockFactory + function calculateSafeAddress(address deployer, SafeConfig calldata config, bytes32 salt) + external + view + returns (address) + { + bytes memory initializer = _encodeSafeInitializer(config); + uint256 saltNonce = uint256(keccak256(abi.encodePacked(deployer, salt))); + bytes32 creationSalt = keccak256(abi.encodePacked(keccak256(initializer), saltNonce)); + bytes memory deploymentData = + abi.encodePacked(ISafeProxyFactory(safeProxyFactory).proxyCreationCode(), uint256(uint160(safeSingleton))); + return Create2.computeAddress(creationSalt, keccak256(deploymentData), safeProxyFactory); + } + + /// @inheritdoc ISafeTimelockFactory + function calculateTimelockAddress(address deployer, TimelockConfig calldata config, bytes32 salt) + external + view + returns (address) + { + bytes32 mixedSalt = keccak256(abi.encodePacked(deployer, salt)); + bytes memory initCode = abi.encodePacked( + type(TimelockController).creationCode, + abi.encode(config.minDelay, config.proposers, config.executors, address(0)) + ); + return Create2.computeAddress(mixedSalt, keccak256(initCode)); + } + + /// INTERNAL FUNCTIONS + + function _validateSafeConfig(SafeConfig calldata config) internal pure { + require(config.owners.length > 0, NoOwners()); + require(config.threshold > 0 && config.threshold <= config.owners.length, InvalidThreshold()); + for (uint256 i = 0; i < config.owners.length; i++) { + require(config.owners[i] != address(0), ZeroAddressOwner()); + for (uint256 j = i + 1; j < config.owners.length; j++) { + require(config.owners[i] != config.owners[j], DuplicateOwner()); + } + } + } + + function _validateTimelockConfig(TimelockConfig calldata config) internal pure { + require(config.proposers.length > 0, NoProposers()); + require(config.executors.length > 0, NoExecutors()); + for (uint256 i = 0; i < config.proposers.length; i++) { + require(config.proposers[i] != address(0), ZeroAddressProposer()); + } + for (uint256 i = 0; i < config.executors.length; i++) { + require(config.executors[i] != address(0), ZeroAddressExecutor()); + } + } + + function _deploySafe(SafeConfig calldata config, bytes32 salt) internal returns (address safe) { + bytes memory initializer = _encodeSafeInitializer(config); + uint256 saltNonce = uint256(keccak256(abi.encodePacked(msg.sender, salt))); + safe = ISafeProxyFactory(safeProxyFactory).createProxyWithNonce(safeSingleton, initializer, saltNonce); + } + + function _encodeSafeInitializer(SafeConfig calldata config) internal view returns (bytes memory) { + return abi.encodeWithSelector( + ISafe.setup.selector, + config.owners, + config.threshold, + address(0), + "", + defaultFallbackHandler, + address(0), + 0, + payable(address(0)) + ); + } + + function _deployTimelock(TimelockConfig calldata config, bytes32 salt) internal returns (address timelock) { + bytes32 mixedSalt = keccak256(abi.encodePacked(msg.sender, salt)); + bytes memory initCode = abi.encodePacked( + type(TimelockController).creationCode, + abi.encode(config.minDelay, config.proposers, config.executors, address(0)) + ); + timelock = Create2.deploy(0, mixedSalt, initCode); + } +} diff --git a/src/interfaces/IAppController.sol b/src/interfaces/IAppController.sol index 24a4177..5a9f015 100644 --- a/src/interfaces/IAppController.sol +++ b/src/interfaces/IAppController.sol @@ -29,8 +29,11 @@ interface IAppController { /// @notice Thrown when trying to suspend an account that still has active apps error AccountHasActiveApps(); + /// @notice Thrown when trying to revoke or renounce the last admin + error CannotRevokeLastAdmin(); + /// @notice Emitted when a new app is successfully created - event AppCreated(address indexed creator, IApp indexed app, uint32 operatorSetId); + event AppCreated(address indexed owner, IApp indexed app, uint32 operatorSetId); /// @notice Emitted when an app is upgraded event AppUpgraded(IApp indexed app, uint256 rmsReleaseId, Release release); @@ -59,7 +62,9 @@ interface IAppController { /// @notice Emitted when an app's metadata URI is updated event AppMetadataURIUpdated(IApp indexed app, string metadataURI); - /// @notice Enum for app status + /** + * @notice Enum for app status + */ enum AppStatus { NONE, // App has not been created yet STARTED, // App has been started @@ -68,10 +73,22 @@ interface IAppController { SUSPENDED // App is suspended and can be started again, but does not have reserved capacity } - /// @notice Billing type for an app - enum BillingType { - DEFAULT, // Billed to the creator's account - ISOLATED // Billed to the app's own address + /** + * @notice Enum for team roles + */ + enum TeamRole { + ADMIN, // Full access: upgrade, start, stop, terminate, manage roles + PAUSER, // Stop apps (emergency response) + DEVELOPER // Update metadata, view logs, submit builds + } + + /** + * @notice App with associated roles for an account + */ + struct AppRoles { + IApp app; + bool isOwner; + TeamRole[] roles; } /** @@ -86,23 +103,14 @@ interface IAppController { bytes encryptedEnv; } - /// @notice The controller's config for an app (public-facing, ABI-stable) + /// @notice The controller's config for an app struct AppConfig { - address creator; + address owner; uint32 operatorSetId; uint32 latestReleaseBlockNumber; AppStatus status; } - /// @notice Internal storage config for an app, extends AppConfig with additional fields - struct AppConfigStorage { - address creator; - uint32 operatorSetId; - uint32 latestReleaseBlockNumber; - AppStatus status; - BillingType billingType; - } - /// @notice User configuration and state struct UserConfig { uint32 maxActiveApps; @@ -130,6 +138,14 @@ interface IAppController { */ function setMaxGlobalActiveApps(uint32 limit) external; + /** + * @notice Migrates admins from PermissionController to AccessControl for specified apps + * @param apps The apps to migrate admins for + * @dev Caller must be UAM permissioned for the AppController + * @dev For each app, grants ADMIN_ROLE to all addresses that are admins via PermissionController + */ + function migrateAdmins(IApp[] calldata apps) external; + /** * @notice Creates a new app instance * @param salt The salt to use for the app @@ -139,13 +155,14 @@ interface IAppController { function createApp(bytes32 salt, Release calldata release) external returns (IApp app); /** - * @notice Creates a new app with isolated billing, where costs are billed to the app's own address + * @notice Creates a new app instance for a team + * @param team The team address (owner) to create the app for * @param salt The salt to use for the app * @param release The release to upgrade to * @return app The address of the newly created app - * @dev The app address is pre-computed and must have quota set via setMaxActiveAppsPerUser before calling + * @dev Caller must be the team address itself or have ADMIN role on the team */ - function createAppWithIsolatedBilling(bytes32 salt, Release calldata release) external returns (IApp app); + function createAppForTeam(address team, bytes32 salt, Release calldata release) external returns (IApp app); /** * @notice Upgrades an app with a new release to the ReleaseManager @@ -254,25 +271,11 @@ interface IAppController { function getAppStatus(IApp app) external view returns (AppStatus); /** - * @notice Gets the creator of an app - * @param app The app to check - * @return The address of the app creator - */ - function getAppCreator(IApp app) external view returns (address); - - /** - * @notice Gets the billing account for an app - * @param app The app to check - * @return The billing account address (app address if ISOLATED, creator if DEFAULT) - */ - function getBillingAccount(IApp app) external view returns (address); - - /** - * @notice Gets the billing type for an app + * @notice Gets the owner of an app * @param app The app to check - * @return The billing type (DEFAULT or ISOLATED) + * @return The address of the owner */ - function getBillingType(IApp app) external view returns (BillingType); + function getAppOwner(IApp app) external view returns (address); /** * @notice Gets the operator set ID for a given app @@ -304,6 +307,7 @@ interface IAppController { * @param limit The maximum number of apps to return in this page * @return apps An array of app contract instances * @return configs An array of corresponding app configurations + * @dev Deprecated: Use getAppsForAccount for comprehensive role information */ function getAppsByDeveloper(address developer, uint256 offset, uint256 limit) external @@ -311,31 +315,19 @@ interface IAppController { returns (IApp[] memory, AppConfig[] memory); /** - * @notice Retrieves a paginated list of apps created by the specified address and their configurations + * @notice Retrieves a paginated list of apps created by the specified creator and their configurations * @param creator The address of the creator * @param offset The starting index for pagination (0-based) * @param limit The maximum number of apps to return in this page * @return apps An array of app contract instances * @return configs An array of corresponding app configurations + * @dev Deprecated: Use getAppsForAccount for comprehensive role information */ function getAppsByCreator(address creator, uint256 offset, uint256 limit) external view returns (IApp[] memory, AppConfig[] memory); - /** - * @notice Retrieves a paginated list of apps billed to the specified account and their configurations - * @param account The billing account address (creator for regular apps, app address for isolated billing apps) - * @param offset The starting index for pagination (0-based) - * @param limit The maximum number of apps to return in this page - * @return apps An array of app contract instances - * @return configs An array of corresponding app configurations - */ - function getAppsByBillingAccount(address account, uint256 offset, uint256 limit) - external - view - returns (IApp[] memory, AppConfig[] memory); - /** * @notice Calculates the digest hash for a given api permission * @param permission The permission to calculate the digest hash for @@ -343,4 +335,77 @@ interface IAppController { * @return The digest hash */ function calculateApiPermissionDigestHash(bytes4 permission, uint256 expiry) external view returns (bytes32); + + /// ROLE-BASED ACCESS CONTROL + + /** + * @notice Grants a role to an account on a team + * @param team The team address + * @param role The role to grant (ADMIN, PAUSER, or DEVELOPER) + * @param account The account to grant the role to + * @dev Only team admins can grant roles + */ + function grantTeamRole(address team, TeamRole role, address account) external; + + /** + * @notice Revokes a role from an account on a team + * @param team The team address + * @param role The role to revoke + * @param account The account to revoke the role from + * @dev Only team admins can revoke roles + */ + function revokeTeamRole(address team, TeamRole role, address account) external; + + /** + * @notice Allows an account to renounce their own role on a team + * @param team The team address + * @param role The role to renounce + */ + function renounceTeamRole(address team, TeamRole role) external; + + /** + * @notice Checks if an account has a specific role on a team (admins always return true) + * @param team The team address + * @param role The role to check + * @param account The account to check + * @return True if the account has the role or is an admin + */ + function hasTeamRole(address team, TeamRole role, address account) external view returns (bool); + + /** + * @notice Gets the number of accounts with a specific role on a team + * @param team The team address + * @param role The role to check + * @return The number of accounts with the role + */ + function getTeamRoleMemberCount(address team, TeamRole role) external view returns (uint256); + + /** + * @notice Gets the account at index for a specific role on a team + * @param team The team address + * @param role The role to check + * @param index The index of the account + * @return The account address + */ + function getTeamRoleMember(address team, TeamRole role, uint256 index) external view returns (address); + + /** + * @notice Gets all accounts with a specific role on a team + * @param team The team address + * @param role The role to check + * @return Array of account addresses with the role + */ + function getTeamRoleMembers(address team, TeamRole role) external view returns (address[] memory); + + /** + * @notice Retrieves apps and the account's roles for each app + * @param account The account to check + * @param offset The starting index for pagination (0-based) + * @param limit The maximum number of apps to return in this page + * @return appRoles An array of AppRoles structs containing app and role information + */ + function getAppsForAccount(address account, uint256 offset, uint256 limit) + external + view + returns (AppRoles[] memory appRoles); } diff --git a/src/interfaces/ISafe.sol b/src/interfaces/ISafe.sol new file mode 100644 index 0000000..0c98a5a --- /dev/null +++ b/src/interfaces/ISafe.sol @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.27; + +/// @dev Interface for Gnosis Safe setup function +interface ISafe { + function setup( + address[] calldata _owners, + uint256 _threshold, + address to, + bytes calldata data, + address fallbackHandler, + address paymentToken, + uint256 payment, + address payable paymentReceiver + ) external; +} diff --git a/src/interfaces/ISafeProxyFactory.sol b/src/interfaces/ISafeProxyFactory.sol new file mode 100644 index 0000000..7fe3e8a --- /dev/null +++ b/src/interfaces/ISafeProxyFactory.sol @@ -0,0 +1,11 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.27; + +/// @dev Interface for Gnosis SafeProxyFactory +interface ISafeProxyFactory { + function createProxyWithNonce(address _singleton, bytes memory initializer, uint256 saltNonce) + external + returns (address proxy); + + function proxyCreationCode() external pure returns (bytes memory); +} diff --git a/src/interfaces/ISafeTimelockFactory.sol b/src/interfaces/ISafeTimelockFactory.sol new file mode 100644 index 0000000..e248ca0 --- /dev/null +++ b/src/interfaces/ISafeTimelockFactory.sol @@ -0,0 +1,136 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.27; + +/** + * @title ISafeTimelockFactory + * @notice Factory for deploying verified Gnosis Safes and TimelockControllers + * @dev Deployed entities can be verified as "official" via isSafe() and isTimelock() + */ +interface ISafeTimelockFactory { + /// STRUCTS + /// @notice Configuration for deploying a Gnosis Safe + struct SafeConfig { + address[] owners; // Addresses that can sign transactions + uint256 threshold; // Number of required signatures + } + + /// @notice Configuration for deploying a TimelockController + struct TimelockConfig { + uint256 minDelay; // Minimum delay in seconds before execution + address[] proposers; // Addresses that can propose and cancel operations + address[] executors; // Addresses that can execute ready operations + } + + /// EVENTS + + /// @notice Emitted when a Gnosis Safe is deployed + event SafeDeployed( + address indexed deployer, address indexed safe, address[] owners, uint256 threshold, bytes32 salt + ); + + /// @notice Emitted when a TimelockController is deployed + event TimelockDeployed( + address indexed deployer, + address indexed timelock, + uint256 minDelay, + address[] proposers, + address[] executors, + bytes32 salt + ); + + /// ERRORS + + /// @notice Thrown when threshold is zero or exceeds owner count + error InvalidThreshold(); + + /// @notice Thrown when owners array is empty + error NoOwners(); + + /// @notice Thrown when proposers array is empty + error NoProposers(); + + /// @notice Thrown when executors array is empty + error NoExecutors(); + + /// @notice Thrown when an owner address is zero + error ZeroAddressOwner(); + + /// @notice Thrown when a proposer address is zero + error ZeroAddressProposer(); + + /// @notice Thrown when an executor address is zero + error ZeroAddressExecutor(); + + /// @notice Thrown when duplicate owners are provided + error DuplicateOwner(); + + /// EXTERNAL FUNCTIONS + + /** + * @notice Deploys a new Gnosis Safe with deterministic address + * @param config Safe configuration (owners, threshold) + * @param salt User-provided salt for deterministic deployment + * @return safe The deployed Safe address + */ + function deploySafe(SafeConfig calldata config, bytes32 salt) external returns (address safe); + + /** + * @notice Deploys a new TimelockController with deterministic address + * @param config Timelock configuration (minDelay, proposers, executors) + * @param salt User-provided salt for deterministic deployment + * @return timelock The deployed TimelockController address + */ + function deployTimelock(TimelockConfig calldata config, bytes32 salt) external returns (address timelock); + + /// VIEW FUNCTIONS + + /** + * @notice Checks if an address is a Safe deployed by this factory + * @param safe The address to check + * @return True if the address is a factory-deployed Safe + */ + function isSafe(address safe) external view returns (bool); + + /** + * @notice Checks if an address is a Timelock deployed by this factory + * @param timelock The address to check + * @return True if the address is a factory-deployed Timelock + */ + function isTimelock(address timelock) external view returns (bool); + + /** + * @notice Pre-computes the address of a Safe deployment + * @param deployer The address that will deploy + * @param config Safe configuration + * @param salt User-provided salt + * @return The computed Safe address + */ + function calculateSafeAddress(address deployer, SafeConfig calldata config, bytes32 salt) + external + view + returns (address); + + /** + * @notice Pre-computes the address of a Timelock deployment + * @param deployer The address that will deploy + * @param config Timelock configuration + * @param salt User-provided salt + * @return The computed TimelockController address + */ + function calculateTimelockAddress(address deployer, TimelockConfig calldata config, bytes32 salt) + external + view + returns (address); + + /** + * @notice Returns the official Gnosis Safe singleton address + * @return The Safe singleton (master copy) address + */ + function safeSingleton() external view returns (address); + + /** + * @notice Returns the official Gnosis Safe proxy factory address + * @return The SafeProxyFactory address + */ + function safeProxyFactory() external view returns (address); +} diff --git a/src/storage/SafeTimelockFactoryStorage.sol b/src/storage/SafeTimelockFactoryStorage.sol new file mode 100644 index 0000000..e1d308f --- /dev/null +++ b/src/storage/SafeTimelockFactoryStorage.sol @@ -0,0 +1,50 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity ^0.8.27; + +import {ISafeTimelockFactory} from "../interfaces/ISafeTimelockFactory.sol"; +import {EnumerableSet} from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol"; + +/** + * @title SafeTimelockFactoryStorage + * @notice Storage contract for SafeTimelockFactory + */ +abstract contract SafeTimelockFactoryStorage is ISafeTimelockFactory { + using EnumerableSet for EnumerableSet.AddressSet; + + /// IMMUTABLES + + /// @notice The official Gnosis Safe singleton (master copy) address + address public immutable safeSingleton; + + /// @notice The official Gnosis Safe proxy factory address + address public immutable safeProxyFactory; + + /// @notice The default fallback handler for Safes + address public immutable defaultFallbackHandler; + + /// STATE VARIABLES + + /// @notice Set of all Safes deployed by this factory + EnumerableSet.AddressSet internal _safes; + + /// @notice Set of all Timelocks deployed by this factory + EnumerableSet.AddressSet internal _timelocks; + + /// STORAGE GAP + + /// @notice Storage gap for future upgrades + uint256[46] private __gap; + + /// CONSTRUCTOR + + /** + * @param _safeSingleton The official Gnosis Safe singleton address + * @param _safeProxyFactory The official Gnosis Safe proxy factory address + * @param _defaultFallbackHandler The default fallback handler for Safes + */ + constructor(address _safeSingleton, address _safeProxyFactory, address _defaultFallbackHandler) { + safeSingleton = _safeSingleton; + safeProxyFactory = _safeProxyFactory; + defaultFallbackHandler = _defaultFallbackHandler; + } +} diff --git a/test/AppController.t.sol b/test/AppController.t.sol index 94a36b2..82a05ec 100644 --- a/test/AppController.t.sol +++ b/test/AppController.t.sol @@ -11,7 +11,7 @@ contract AppControllerTest is ComputeDeployer { bytes32 public constant SALT = keccak256("test_salt"); // Event definitions for testing - event AppCreated(address indexed creator, IApp indexed app, uint32 operatorSetId); + event AppCreated(address indexed owner, IApp indexed app, uint32 operatorSetId); event AppTerminatedByAdmin(IApp indexed app); event AppSuspended(IApp indexed app); event AppSuspendedByAdmin(IApp indexed app); @@ -67,9 +67,6 @@ contract AppControllerTest is ComputeDeployer { // Verify the app was created at the predicted address assertEq(address(app), address(appController.calculateAppId(developer, SALT))); - // Default billing account should be the creator - assertEq(appController.getBillingAccount(app), developer); - vm.stopPrank(); } @@ -203,6 +200,120 @@ contract AppControllerTest is ComputeDeployer { appController.createApp(keccak256("test2"), _assembleRelease()); } + // ========== createAppForTeam Tests ========== + + function test_createAppForTeam_adminCanCreateForTeam() public { + // Developer first creates an app to become admin of their team + vm.prank(developer); + appController.createApp(keccak256("initial_app"), _assembleRelease()); + + // Grant admin role to adminAddress on developer's team + address adminAddress = makeAddr("teamAdmin"); + vm.prank(developer); + appController.grantTeamRole(developer, IAppController.TeamRole.ADMIN, adminAddress); + + // Admin creates app for developer's team + vm.prank(adminAddress); + IApp app = appController.createAppForTeam(developer, keccak256("team_app"), _assembleRelease()); + + // Verify app is owned by developer (team) + assertEq(appController.getAppOwner(app), developer); + // Verify quota was deducted from developer, not adminAddress + assertEq(appController.getActiveAppCount(developer), 2); // 1 initial + 1 team app + assertEq(appController.getActiveAppCount(adminAddress), 0); + } + + function test_createAppForTeam_ownerCanCreateForOwnTeam() public { + // Developer (team owner) can also use createAppForTeam for themselves + vm.prank(developer); + IApp app = appController.createAppForTeam(developer, keccak256("own_team_app"), _assembleRelease()); + + assertEq(appController.getAppOwner(app), developer); + assertEq(appController.getActiveAppCount(developer), 1); + } + + function test_createAppForTeam_nonAdminCannotCreate() public { + address nonAdmin = makeAddr("nonAdmin"); + + vm.prank(nonAdmin); + vm.expectRevert(PermissionControllerMixin.InvalidPermissions.selector); + appController.createAppForTeam(developer, keccak256("unauthorized"), _assembleRelease()); + } + + function test_createAppForTeam_pauserCannotCreate() public { + // Developer first creates an app to become admin of their team + vm.prank(developer); + appController.createApp(keccak256("initial_app"), _assembleRelease()); + + address pauser = makeAddr("pauser"); + vm.prank(developer); + appController.grantTeamRole(developer, IAppController.TeamRole.PAUSER, pauser); + + vm.prank(pauser); + vm.expectRevert(PermissionControllerMixin.InvalidPermissions.selector); + appController.createAppForTeam(developer, keccak256("pauser_app"), _assembleRelease()); + } + + function test_createAppForTeam_developerRoleCannotCreate() public { + // Developer first creates an app to become admin of their team + vm.prank(developer); + appController.createApp(keccak256("initial_app"), _assembleRelease()); + + address dev = makeAddr("dev"); + vm.prank(developer); + appController.grantTeamRole(developer, IAppController.TeamRole.DEVELOPER, dev); + + vm.prank(dev); + vm.expectRevert(PermissionControllerMixin.InvalidPermissions.selector); + appController.createAppForTeam(developer, keccak256("dev_app"), _assembleRelease()); + } + + function test_createAppForTeam_quotaDeductedFromTeam() public { + // Set up team with limited quota + _setMaxActiveAppsPerUser(developer, 3); + + // Developer first creates an app to become admin of their team + vm.prank(developer); + appController.createApp(keccak256("initial_app"), _assembleRelease()); + + address teamAdmin = makeAddr("teamAdmin"); + vm.prank(developer); + appController.grantTeamRole(developer, IAppController.TeamRole.ADMIN, teamAdmin); + + // Admin creates 2 more apps for the team + vm.startPrank(teamAdmin); + appController.createAppForTeam(developer, keccak256("app1"), _assembleRelease()); + appController.createAppForTeam(developer, keccak256("app2"), _assembleRelease()); + vm.stopPrank(); + + // Team quota is exhausted (1 initial + 2 admin created = 3) + assertEq(appController.getActiveAppCount(developer), 3); + + // Admin cannot create more apps for the team + vm.prank(teamAdmin); + vm.expectRevert(abi.encodeWithSelector(IAppController.MaxActiveAppsExceeded.selector)); + appController.createAppForTeam(developer, keccak256("app3"), _assembleRelease()); + } + + function test_createAppForTeam_deterministicAddress() public { + // Developer first creates an app to become admin of their team + vm.prank(developer); + appController.createApp(keccak256("initial_app"), _assembleRelease()); + + address teamAdmin = makeAddr("teamAdmin"); + vm.prank(developer); + appController.grantTeamRole(developer, IAppController.TeamRole.ADMIN, teamAdmin); + + // Calculate expected app address using team (developer), not caller (teamAdmin) + bytes32 salt = keccak256("deterministic"); + IApp expectedApp = appController.calculateAppId(developer, salt); + + vm.prank(teamAdmin); + IApp actualApp = appController.createAppForTeam(developer, salt, _assembleRelease()); + + assertEq(address(actualApp), address(expectedApp)); + } + // Admin and permission tests function test_setMaxGlobalActiveApps() public { vm.prank(admin); @@ -234,7 +345,6 @@ contract AppControllerTest is ComputeDeployer { // Create an app first vm.prank(developer); IApp app = appController.createApp(keccak256("upgrade_test"), _assembleRelease()); - _acceptAppAdmin(app); // Prepare a release IReleaseManagerTypes.Artifact[] memory artifacts = new IReleaseManagerTypes.Artifact[](1); @@ -282,7 +392,6 @@ contract AppControllerTest is ComputeDeployer { // Create an app vm.prank(developer); IApp app = appController.createApp(keccak256("stop_test"), _assembleRelease()); - _acceptAppAdmin(app); // Stop the app vm.prank(developer); @@ -297,7 +406,6 @@ contract AppControllerTest is ComputeDeployer { // Create an app vm.prank(developer); IApp app = appController.createApp(keccak256("stop_test"), _assembleRelease()); - _acceptAppAdmin(app); // Stop the app vm.prank(developer); @@ -313,7 +421,6 @@ contract AppControllerTest is ComputeDeployer { // Create an app vm.prank(developer); IApp app = appController.createApp(keccak256("start_test"), _assembleRelease()); - _acceptAppAdmin(app); // Stop the app first vm.prank(developer); @@ -332,7 +439,6 @@ contract AppControllerTest is ComputeDeployer { // Create an app vm.prank(developer); IApp app = appController.createApp(keccak256("start_test"), _assembleRelease()); - _acceptAppAdmin(app); // Verify status changed to STARTED IAppController.AppStatus statusBefore = appController.getAppStatus(app); @@ -351,7 +457,6 @@ contract AppControllerTest is ComputeDeployer { // Create and terminate an app vm.prank(developer); IApp app = appController.createApp(keccak256("start_terminated"), _assembleRelease()); - _acceptAppAdmin(app); vm.prank(developer); appController.terminateApp(app); @@ -382,7 +487,6 @@ contract AppControllerTest is ComputeDeployer { function test_terminateApp() public { vm.prank(developer); IApp app = appController.createApp(keccak256("terminate_test"), _assembleRelease()); - _acceptAppAdmin(app); // Terminate the app (can be done from any active status) vm.prank(developer); @@ -396,7 +500,6 @@ contract AppControllerTest is ComputeDeployer { function test_terminateApp_alreadyTerminated() public { vm.prank(developer); IApp app = appController.createApp(keccak256("double_terminate"), _assembleRelease()); - _acceptAppAdmin(app); vm.prank(developer); appController.terminateApp(app); @@ -442,7 +545,6 @@ contract AppControllerTest is ComputeDeployer { for (uint256 i = 0; i < 5; i++) { vm.prank(developer); createdApps[i] = appController.createApp(keccak256(abi.encodePacked("offset_test_", i)), _assembleRelease()); - _acceptAppAdmin(createdApps[i]); } // Test 1: Normal pagination - offset 0, limit 3 @@ -489,7 +591,6 @@ contract AppControllerTest is ComputeDeployer { vm.prank(developer); createdApps[i] = appController.createApp(keccak256(abi.encodePacked("dev_offset_test_", i)), _assembleRelease()); - _acceptAppAdmin(createdApps[i]); } // Test 1: Developer pagination - offset 0, limit 3 (first 3 of developer's apps) @@ -528,13 +629,9 @@ contract AppControllerTest is ComputeDeployer { _setMaxActiveAppsPerUser(otherDev, 10); vm.prank(otherDev); IApp otherApp1 = appController.createApp(keccak256("mixed_test_1"), _assembleRelease()); - vm.prank(otherDev); - permissionController.acceptAdmin(address(otherApp1)); vm.prank(otherDev); IApp otherApp2 = appController.createApp(keccak256("mixed_test_2"), _assembleRelease()); - vm.prank(otherDev); - permissionController.acceptAdmin(address(otherApp2)); // Test true pagination: first developer should still get their 5 apps in order (IApp[] memory devApps,) = appController.getAppsByDeveloper(developer, 0, 10); @@ -564,8 +661,7 @@ contract AppControllerTest is ComputeDeployer { IApp[] memory createdApps = new IApp[](5); for (uint256 i = 0; i < 5; i++) { vm.prank(developer); - createdApps[i] = - appController.createApp(keccak256(abi.encodePacked("creator_test_", i)), _assembleRelease()); + createdApps[i] = appController.createApp(keccak256(abi.encodePacked("owner_test_", i)), _assembleRelease()); } // Test 1: Creator pagination - offset 0, limit 3 (first 3 of creator's apps) @@ -596,16 +692,16 @@ contract AppControllerTest is ComputeDeployer { assertEq(apps5.length, 0); // Test 6: Unknown creator (should return empty) - address otherDev = makeAddr("otherCreator"); + address otherDev = makeAddr("otherOwner"); (IApp[] memory apps6,) = appController.getAppsByCreator(otherDev, 0, 10); assertEq(apps6.length, 0); // Test 7: Mixed ownership scenario - create app for another creator _setMaxActiveAppsPerUser(otherDev, 10); vm.prank(otherDev); - IApp otherApp1 = appController.createApp(keccak256("creator_mixed_test_1"), _assembleRelease()); + IApp otherApp1 = appController.createApp(keccak256("owner_mixed_test_1"), _assembleRelease()); vm.prank(otherDev); - IApp otherApp2 = appController.createApp(keccak256("creator_mixed_test_2"), _assembleRelease()); + IApp otherApp2 = appController.createApp(keccak256("owner_mixed_test_2"), _assembleRelease()); // Test pagination: first creator should still get their 5 apps in order (IApp[] memory devApps,) = appController.getAppsByCreator(developer, 0, 10); @@ -622,43 +718,34 @@ contract AppControllerTest is ComputeDeployer { } function test_getAppsByCreator_worksWithoutAdminRights() public { + // Developer creates two apps vm.prank(developer); IApp app1 = appController.createApp(keccak256("admin_test_1"), _assembleRelease()); vm.prank(developer); IApp app2 = appController.createApp(keccak256("admin_test_2"), _assembleRelease()); - // Only accept admin on app1, leave app2 without accepting admin - vm.prank(developer); - permissionController.acceptAdmin(address(app1)); - - // getAppsByCreator should return BOTH apps (filters by creator, not admin) + // getAppsByCreator should return BOTH apps (filters by creator) (IApp[] memory creatorApps,) = appController.getAppsByCreator(developer, 0, 10); assertEq(creatorApps.length, 2); assertEq(address(creatorApps[0]), address(app1)); assertEq(address(creatorApps[1]), address(app2)); - // getAppsByDeveloper should only return app1 (developer only accepted admin on app1) + // getAppsByDeveloper should also return both (developer has ADMIN role on their own team) (IApp[] memory devApps,) = appController.getAppsByDeveloper(developer, 0, 10); - assertEq(devApps.length, 1); + assertEq(devApps.length, 2); assertEq(address(devApps[0]), address(app1)); + assertEq(address(devApps[1]), address(app2)); - // Verify the creator field is set correctly for both apps - assertEq(appController.getAppCreator(app1), developer); - assertEq(appController.getAppCreator(app2), developer); + // Verify the owner field is set correctly for both apps + assertEq(appController.getAppOwner(app1), developer); + assertEq(appController.getAppOwner(app2), developer); - // Verify developer is only admin of app1 - assertTrue(permissionController.isAdmin(address(app1), developer)); - assertFalse(permissionController.isAdmin(address(app2), developer)); + // Verify developer has ADMIN role via AccessControl + assertTrue(appController.hasTeamRole(developer, IAppController.TeamRole.ADMIN, developer)); } // ========== Helper Functions ========== - function _acceptAppAdmin(IApp app) internal { - // Accept admin permissions on the app (developer should be pending admin after app creation) - vm.prank(developer); - permissionController.acceptAdmin(address(app)); - } - function test_activeAppCounting_terminationFreesUpCapacity() public { // Set user to have only 2 active apps max _setGlobalMaxActiveApps(100); @@ -679,10 +766,6 @@ contract AppControllerTest is ComputeDeployer { vm.expectRevert(abi.encodeWithSelector(IAppController.MaxActiveAppsExceeded.selector)); appController.createApp(keccak256("capacity_test_3"), _assembleRelease()); - // Accept admin for app1 so we can terminate it - vm.prank(user); - permissionController.acceptAdmin(address(app1)); - // Terminate app1 - should free up capacity vm.prank(user); appController.terminateApp(app1); @@ -699,8 +782,8 @@ contract AppControllerTest is ComputeDeployer { assertEq(appController.getActiveAppCount(user), 2); assertEq(appController.globalActiveAppCount(), 2); - // Verify app creator is tracked correctly - assertEq(appController.getAppCreator(app3), user); + // Verify app owner is tracked correctly + assertEq(appController.getAppOwner(app3), user); } function test_terminateAppByAdmin_notAuthorized() public { @@ -742,7 +825,6 @@ contract AppControllerTest is ComputeDeployer { // Create an app vm.prank(developer); IApp app = appController.createApp(keccak256("metadata_test"), _assembleRelease()); - _acceptAppAdmin(app); string memory newMetadataURI = "https://example.com/metadata"; @@ -770,7 +852,6 @@ contract AppControllerTest is ComputeDeployer { // Create an app vm.prank(developer); IApp app = appController.createApp(keccak256("metadata_terminated"), _assembleRelease()); - _acceptAppAdmin(app); // Terminate the app vm.prank(developer); @@ -970,14 +1051,6 @@ contract AppControllerTest is ComputeDeployer { vm.prank(admin); appController.setMaxActiveAppsPerUser(user, 10); - // Accept admin for apps we want to manipulate - vm.prank(user); - permissionController.acceptAdmin(address(app1)); - vm.prank(user); - permissionController.acceptAdmin(address(app2)); - vm.prank(user); - permissionController.acceptAdmin(address(app4)); - // Set up different states: // app1 -> STARTED vm.prank(user); @@ -1068,12 +1141,6 @@ contract AppControllerTest is ComputeDeployer { vm.prank(admin); appController.setMaxActiveAppsPerUser(user, 2); - // Accept admin to start apps - vm.prank(user); - permissionController.acceptAdmin(address(app1)); - vm.prank(user); - permissionController.acceptAdmin(address(app2)); - // User resumes apps vm.prank(user); appController.startApp(app1); @@ -1087,265 +1154,509 @@ contract AppControllerTest is ComputeDeployer { assertEq(appController.getMaxActiveAppsPerUser(user), 2); } - // ========== Isolated Billing App Tests ========== + // ========== Team Role-Based Access Control Tests ========== - function test_createAppWithIsolatedBilling() public { - // Pre-compute the app address - IApp expectedApp = appController.calculateAppId(developer, SALT); + function test_teamAdminHasImplicitAccess() public { + // Developer creates an app (developer is the team admin via PermissionController) + vm.prank(developer); + IApp app = appController.createApp(keccak256("admin_access"), _assembleRelease()); - // Set quota for the app address (not the developer) - _setMaxActiveAppsPerUser(address(expectedApp), 1); + // Team admin should have implicit access to all roles + assertTrue(appController.hasTeamRole(developer, IAppController.TeamRole.DEVELOPER, developer)); + assertTrue(appController.hasTeamRole(developer, IAppController.TeamRole.PAUSER, developer)); + // Team admin can perform all actions vm.prank(developer); - IApp app = appController.createAppWithIsolatedBilling(SALT, _assembleRelease()); + appController.stopApp(app); - // Verify app was created at the expected address - assertEq(address(app), address(expectedApp)); + vm.prank(developer); + appController.startApp(app); - // Verify billing is isolated - assertEq(uint256(appController.getBillingType(app)), uint256(IAppController.BillingType.ISOLATED)); + vm.prank(developer); + appController.updateAppMetadataURI(app, "https://example.com/admin"); + } - // Verify billing account is the app address itself - assertEq(appController.getBillingAccount(app), address(app)); + function test_grantTeamRole_byAdmin() public { + // Developer creates an app + vm.prank(developer); + appController.createApp(keccak256("grant_role"), _assembleRelease()); - // Verify app is started - assertEq(uint256(appController.getAppStatus(app)), uint256(IAppController.AppStatus.STARTED)); + // Admin grants PAUSER role to user + vm.prank(developer); + appController.grantTeamRole(developer, IAppController.TeamRole.PAUSER, user); - // Verify the app address's quota was used (not the developer's) - assertEq(appController.getActiveAppCount(address(app)), 1); - assertEq(appController.getActiveAppCount(developer), 0); + // Verify user has PAUSER role + assertTrue(appController.hasTeamRole(developer, IAppController.TeamRole.PAUSER, user)); + + // User should not have DEVELOPER role + assertFalse(appController.hasTeamRole(developer, IAppController.TeamRole.DEVELOPER, user)); } - function test_createAppWithIsolatedBilling_noQuota_reverts() public { - // Don't set any quota for the app address — should revert + function test_grantTeamRole_byGrantedAdmin() public { + // Developer creates an app vm.prank(developer); - vm.expectRevert(abi.encodeWithSelector(IAppController.MaxActiveAppsExceeded.selector)); - appController.createAppWithIsolatedBilling(SALT, _assembleRelease()); + appController.createApp(keccak256("granted_admin_grant"), _assembleRelease()); + + // Grant ADMIN role to user + vm.prank(developer); + appController.grantTeamRole(developer, IAppController.TeamRole.ADMIN, user); + + // User (now admin) can grant roles to others + address otherUser = makeAddr("otherUser"); + vm.prank(user); + appController.grantTeamRole(developer, IAppController.TeamRole.DEVELOPER, otherUser); + + // Verify otherUser has DEVELOPER role + assertTrue(appController.hasTeamRole(developer, IAppController.TeamRole.DEVELOPER, otherUser)); } - function test_createAppWithIsolatedBilling_terminateDecrementsAppQuota() public { - IApp expectedApp = appController.calculateAppId(developer, SALT); - _setMaxActiveAppsPerUser(address(expectedApp), 1); + function test_grantTeamRole_unauthorized() public { + // Developer creates an app + vm.prank(developer); + appController.createApp(keccak256("unauth_grant"), _assembleRelease()); + // User (not owner or admin) tries to grant role - should fail + vm.prank(user); + vm.expectRevert(PermissionControllerMixin.InvalidPermissions.selector); + appController.grantTeamRole(developer, IAppController.TeamRole.PAUSER, makeAddr("someone")); + } + + function test_revokeTeamRole() public { + // Developer creates an app vm.prank(developer); - IApp app = appController.createAppWithIsolatedBilling(SALT, _assembleRelease()); - _acceptAppAdmin(app); + appController.createApp(keccak256("revoke_role"), _assembleRelease()); - // Verify app address has 1 active app - assertEq(appController.getActiveAppCount(address(app)), 1); + // Owner grants DEVELOPER role to user + vm.prank(developer); + appController.grantTeamRole(developer, IAppController.TeamRole.DEVELOPER, user); + assertTrue(appController.hasTeamRole(developer, IAppController.TeamRole.DEVELOPER, user)); - // Terminate the app + // Owner revokes the role vm.prank(developer); - appController.terminateApp(app); + appController.revokeTeamRole(developer, IAppController.TeamRole.DEVELOPER, user); - // Verify the app address's count decremented (not the developer's) - assertEq(appController.getActiveAppCount(address(app)), 0); - assertEq(appController.getActiveAppCount(developer), 0); + // Verify role is revoked + assertFalse(appController.hasTeamRole(developer, IAppController.TeamRole.DEVELOPER, user)); } - function test_createAppWithIsolatedBilling_suspendByAppAddress() public { - IApp expectedApp = appController.calculateAppId(developer, SALT); - _setMaxActiveAppsPerUser(address(expectedApp), 1); + function test_renounceTeamRole() public { + // Developer creates an app + vm.prank(developer); + appController.createApp(keccak256("renounce_role"), _assembleRelease()); + // Admin grants DEVELOPER role to user vm.prank(developer); - IApp app = appController.createAppWithIsolatedBilling(SALT, _assembleRelease()); + appController.grantTeamRole(developer, IAppController.TeamRole.DEVELOPER, user); + assertTrue(appController.hasTeamRole(developer, IAppController.TeamRole.DEVELOPER, user)); - // Admin suspends the app using the app address as the account - IApp[] memory apps = new IApp[](1); - apps[0] = app; + // User renounces their own role + vm.prank(user); + appController.renounceTeamRole(developer, IAppController.TeamRole.DEVELOPER); - vm.prank(admin); - appController.suspend(address(app), apps); + // Verify role is renounced + assertFalse(appController.hasTeamRole(developer, IAppController.TeamRole.DEVELOPER, user)); + } + + function test_renounceTeamRole_cannotRenounceLastAdmin() public { + // Developer creates an app (becomes sole admin) + vm.prank(developer); + appController.createApp(keccak256("last_admin"), _assembleRelease()); - // Verify the app is suspended - assertEq(uint256(appController.getAppStatus(app)), uint256(IAppController.AppStatus.SUSPENDED)); - assertEq(appController.getActiveAppCount(address(app)), 0); - assertEq(appController.getMaxActiveAppsPerUser(address(app)), 0); + // Developer tries to renounce their admin role - should fail + vm.prank(developer); + vm.expectRevert(IAppController.CannotRevokeLastAdmin.selector); + appController.renounceTeamRole(developer, IAppController.TeamRole.ADMIN); + + // Verify developer is still admin + assertTrue(appController.hasTeamRole(developer, IAppController.TeamRole.ADMIN, developer)); } - function test_createAppWithIsolatedBilling_resumeFromSuspended() public { - IApp expectedApp = appController.calculateAppId(developer, SALT); - _setMaxActiveAppsPerUser(address(expectedApp), 1); + function test_renounceTeamRole_canRenounceIfNotLastAdmin() public { + // Developer creates an app (becomes sole admin) + vm.prank(developer); + appController.createApp(keccak256("multi_admin"), _assembleRelease()); + // Grant admin to another user vm.prank(developer); - IApp app = appController.createAppWithIsolatedBilling(SALT, _assembleRelease()); - _acceptAppAdmin(app); + appController.grantTeamRole(developer, IAppController.TeamRole.ADMIN, user); - // Suspend via admin - IApp[] memory apps = new IApp[](1); - apps[0] = app; - vm.prank(admin); - appController.suspend(address(app), apps); + // Now developer can renounce their admin role + vm.prank(developer); + appController.renounceTeamRole(developer, IAppController.TeamRole.ADMIN); - // Verify suspended - assertEq(uint256(appController.getAppStatus(app)), uint256(IAppController.AppStatus.SUSPENDED)); - assertEq(appController.getActiveAppCount(address(app)), 0); + // Verify developer is no longer admin + assertFalse(appController.hasTeamRole(developer, IAppController.TeamRole.ADMIN, developer)); + // But user is still admin + assertTrue(appController.hasTeamRole(developer, IAppController.TeamRole.ADMIN, user)); + } - // Restore quota for the app address - _setMaxActiveAppsPerUser(address(app), 1); + function test_revokeTeamRole_cannotRevokeLastAdmin() public { + // Developer creates an app (becomes sole admin) + vm.prank(developer); + appController.createApp(keccak256("revoke_last_admin"), _assembleRelease()); - // Developer resumes the app + // Developer tries to revoke their own admin role - should fail vm.prank(developer); - appController.startApp(app); + vm.expectRevert(IAppController.CannotRevokeLastAdmin.selector); + appController.revokeTeamRole(developer, IAppController.TeamRole.ADMIN, developer); - // Verify resumed and app quota re-checked - assertEq(uint256(appController.getAppStatus(app)), uint256(IAppController.AppStatus.STARTED)); - assertEq(appController.getActiveAppCount(address(app)), 1); + // Verify developer is still admin + assertTrue(appController.hasTeamRole(developer, IAppController.TeamRole.ADMIN, developer)); } - function test_createAppWithIsolatedBilling_developerStillControls() public { - IApp expectedApp = appController.calculateAppId(developer, SALT); - _setMaxActiveAppsPerUser(address(expectedApp), 1); + function test_getTeamRoleMemberCount() public { + // Developer creates an app + vm.prank(developer); + appController.createApp(keccak256("member_count"), _assembleRelease()); + // Initially only developer is admin + assertEq(appController.getTeamRoleMemberCount(developer, IAppController.TeamRole.ADMIN), 1); + assertEq(appController.getTeamRoleMemberCount(developer, IAppController.TeamRole.DEVELOPER), 0); + + // Grant admin to user vm.prank(developer); - IApp app = appController.createAppWithIsolatedBilling(SALT, _assembleRelease()); - _acceptAppAdmin(app); + appController.grantTeamRole(developer, IAppController.TeamRole.ADMIN, user); + assertEq(appController.getTeamRoleMemberCount(developer, IAppController.TeamRole.ADMIN), 2); - // Developer can stop the app + // Grant developer role to user vm.prank(developer); - appController.stopApp(app); - assertEq(uint256(appController.getAppStatus(app)), uint256(IAppController.AppStatus.STOPPED)); + appController.grantTeamRole(developer, IAppController.TeamRole.DEVELOPER, user); + assertEq(appController.getTeamRoleMemberCount(developer, IAppController.TeamRole.DEVELOPER), 1); + } + + function test_getTeamRoleMember() public { + // Developer creates an app + vm.prank(developer); + appController.createApp(keccak256("role_member"), _assembleRelease()); + + // Developer is at index 0 + assertEq(appController.getTeamRoleMember(developer, IAppController.TeamRole.ADMIN, 0), developer); - // Developer can start the app + // Grant admin to user vm.prank(developer); + appController.grantTeamRole(developer, IAppController.TeamRole.ADMIN, user); + + // User is at index 1 + assertEq(appController.getTeamRoleMember(developer, IAppController.TeamRole.ADMIN, 1), user); + } + + function test_getTeamRoleMembers() public { + // Developer creates an app + vm.prank(developer); + appController.createApp(keccak256("role_members"), _assembleRelease()); + + // Initially only developer is admin + address[] memory admins = appController.getTeamRoleMembers(developer, IAppController.TeamRole.ADMIN); + assertEq(admins.length, 1); + assertEq(admins[0], developer); + + // Empty role returns empty array + address[] memory pausers = appController.getTeamRoleMembers(developer, IAppController.TeamRole.PAUSER); + assertEq(pausers.length, 0); + + // Grant admin and pauser to user + vm.startPrank(developer); + appController.grantTeamRole(developer, IAppController.TeamRole.ADMIN, user); + appController.grantTeamRole(developer, IAppController.TeamRole.PAUSER, user); + vm.stopPrank(); + + // Check admins + admins = appController.getTeamRoleMembers(developer, IAppController.TeamRole.ADMIN); + assertEq(admins.length, 2); + assertEq(admins[0], developer); + assertEq(admins[1], user); + + // Check pausers + pausers = appController.getTeamRoleMembers(developer, IAppController.TeamRole.PAUSER); + assertEq(pausers.length, 1); + assertEq(pausers[0], user); + } + + function test_grantedAdmin_hasAllPermissions() public { + // Developer creates an app + vm.prank(developer); + IApp app = appController.createApp(keccak256("granted_admin_perms"), _assembleRelease()); + + // Grant ADMIN role to user + vm.prank(developer); + appController.grantTeamRole(developer, IAppController.TeamRole.ADMIN, user); + + // Admin should have all role permissions + assertTrue(appController.hasTeamRole(developer, IAppController.TeamRole.DEVELOPER, user)); + assertTrue(appController.hasTeamRole(developer, IAppController.TeamRole.PAUSER, user)); + + // Admin can do PAUSER actions (stop app) + vm.prank(user); + appController.stopApp(app); + + // Admin can do DEVELOPER actions (update metadata) + vm.prank(user); + appController.updateAppMetadataURI(app, "https://admin-updated.com"); + + // Admin can do ADMIN actions (start app) + vm.prank(user); appController.startApp(app); - assertEq(uint256(appController.getAppStatus(app)), uint256(IAppController.AppStatus.STARTED)); + } - // Developer can upgrade the app + function test_developerRole_canOnlyUpdateMetadata() public { + // Developer creates an app vm.prank(developer); - appController.upgradeApp(app, _assembleRelease()); + IApp app = appController.createApp(keccak256("dev_role"), _assembleRelease()); - // Developer can terminate the app + // Admin grants DEVELOPER role to user vm.prank(developer); - appController.terminateApp(app); - assertEq(uint256(appController.getAppStatus(app)), uint256(IAppController.AppStatus.TERMINATED)); + appController.grantTeamRole(developer, IAppController.TeamRole.DEVELOPER, user); + + // Developer should only have DEVELOPER permission (no overlap with PAUSER) + assertTrue(appController.hasTeamRole(developer, IAppController.TeamRole.DEVELOPER, user)); + assertFalse(appController.hasTeamRole(developer, IAppController.TeamRole.PAUSER, user)); + + // Developer can update metadata + vm.prank(user); + appController.updateAppMetadataURI(app, "https://dev-updated.com"); + + // Developer cannot stop app (PAUSER action - no overlap) + vm.prank(user); + vm.expectRevert(PermissionControllerMixin.InvalidPermissions.selector); + appController.stopApp(app); + + // Developer cannot start app (ADMIN action) + vm.prank(user); + vm.expectRevert(PermissionControllerMixin.InvalidPermissions.selector); + appController.startApp(app); } - function test_createApp_defaultBilling() public { + function test_pauserRole_canOnlyStopApps() public { + // Developer creates an app vm.prank(developer); - IApp app = appController.createApp(SALT, _assembleRelease()); + IApp app = appController.createApp(keccak256("pauser_role"), _assembleRelease()); + + // Admin grants PAUSER role to user + vm.prank(developer); + appController.grantTeamRole(developer, IAppController.TeamRole.PAUSER, user); - // Existing createApp should have default billing - assertEq(uint256(appController.getBillingType(app)), uint256(IAppController.BillingType.DEFAULT)); - assertEq(appController.getBillingAccount(app), developer); + // Pauser should only have PAUSER permission (no overlap with DEVELOPER) + assertTrue(appController.hasTeamRole(developer, IAppController.TeamRole.PAUSER, user)); + assertFalse(appController.hasTeamRole(developer, IAppController.TeamRole.DEVELOPER, user)); - // Billing should go to the developer - assertEq(appController.getActiveAppCount(developer), 1); + // Pauser can stop app + vm.prank(user); + appController.stopApp(app); + + // Pauser cannot update metadata (DEVELOPER action - no overlap) + vm.prank(user); + vm.expectRevert(PermissionControllerMixin.InvalidPermissions.selector); + appController.updateAppMetadataURI(app, "https://pauser-attempted.com"); } - // ========== getAppsByBillingAccount Tests ========== + function test_teamIsolation() public { + _setMaxActiveAppsPerUser(user, 10); - function test_getAppsByBillingAccount_regularApps() public { - // Create regular apps as developer + // Developer creates an app (owner = developer) vm.prank(developer); - IApp app1 = appController.createApp(keccak256("billing_1"), _assembleRelease()); + IApp devApp = appController.createApp(keccak256("dev_owner_app"), _assembleRelease()); + + // User creates their own app (owner = user) + vm.prank(user); + IApp userApp = appController.createApp(keccak256("user_owner_app"), _assembleRelease()); + + // Grant PAUSER role on developer's team to someone + address teamMember = makeAddr("teamMember"); vm.prank(developer); - IApp app2 = appController.createApp(keccak256("billing_2"), _assembleRelease()); + appController.grantTeamRole(developer, IAppController.TeamRole.PAUSER, teamMember); - // Query by developer address — should return both - (IApp[] memory apps,) = appController.getAppsByBillingAccount(developer, 0, 10); - assertEq(apps.length, 2); - assertEq(address(apps[0]), address(app1)); - assertEq(address(apps[1]), address(app2)); + // Team member can access developer's app + vm.prank(teamMember); + appController.stopApp(devApp); + + // Team member cannot access user's app (different owner) + vm.prank(teamMember); + vm.expectRevert(PermissionControllerMixin.InvalidPermissions.selector); + appController.stopApp(userApp); } - function test_getAppsByBillingAccount_isolatedBillingApp() public { - IApp expectedApp = appController.calculateAppId(developer, SALT); - _setMaxActiveAppsPerUser(address(expectedApp), 1); + function test_stopApp_withPauserRole() public { + vm.prank(developer); + IApp app = appController.createApp(keccak256("stop_pauser"), _assembleRelease()); + // Grant PAUSER role to user vm.prank(developer); - IApp app = appController.createAppWithIsolatedBilling(SALT, _assembleRelease()); + appController.grantTeamRole(developer, IAppController.TeamRole.PAUSER, user); - // Query by app address — should return the isolated billing app - (IApp[] memory appsByApp,) = appController.getAppsByBillingAccount(address(app), 0, 10); - assertEq(appsByApp.length, 1); - assertEq(address(appsByApp[0]), address(app)); + // User with PAUSER can stop the app + vm.prank(user); + appController.stopApp(app); - // Query by developer — should NOT return the isolated billing app - (IApp[] memory appsByDev,) = appController.getAppsByBillingAccount(developer, 0, 10); - assertEq(appsByDev.length, 0); + assertEq(uint256(appController.getAppStatus(app)), uint256(IAppController.AppStatus.STOPPED)); } - function test_getAppsByBillingAccount_mixed() public { - // Create a regular app billed to developer + function test_updateAppMetadataURI_withDeveloperRole() public { vm.prank(developer); - IApp regularApp = appController.createApp(keccak256("mixed_regular"), _assembleRelease()); + IApp app = appController.createApp(keccak256("metadata_dev"), _assembleRelease()); - // Create an isolated billing app billed to itself - IApp expectedApp = appController.calculateAppId(developer, SALT); - _setMaxActiveAppsPerUser(address(expectedApp), 1); + // Grant DEVELOPER role to user vm.prank(developer); - IApp isolatedApp = appController.createAppWithIsolatedBilling(SALT, _assembleRelease()); + appController.grantTeamRole(developer, IAppController.TeamRole.DEVELOPER, user); - // Verify billing accounts - assertEq(appController.getBillingAccount(regularApp), developer); - assertEq(appController.getBillingAccount(isolatedApp), address(isolatedApp)); + // User with DEVELOPER can update metadata + vm.prank(user); + appController.updateAppMetadataURI(app, "https://dev-updated.com"); + } - // Developer billing account returns only the regular app - (IApp[] memory devApps,) = appController.getAppsByBillingAccount(developer, 0, 10); - assertEq(devApps.length, 1); - assertEq(address(devApps[0]), address(regularApp)); + function test_upgradeApp_requiresAdmin() public { + vm.prank(developer); + IApp app = appController.createApp(keccak256("upgrade_admin"), _assembleRelease()); - // App address billing account returns only the isolated billing app - (IApp[] memory isoApps,) = appController.getAppsByBillingAccount(address(isolatedApp), 0, 10); - assertEq(isoApps.length, 1); - assertEq(address(isoApps[0]), address(isolatedApp)); + // Grant DEVELOPER role to user (not enough for upgrade) + vm.prank(developer); + appController.grantTeamRole(developer, IAppController.TeamRole.DEVELOPER, user); + + // User with DEVELOPER cannot upgrade + vm.prank(user); + vm.expectRevert(PermissionControllerMixin.InvalidPermissions.selector); + appController.upgradeApp(app, _assembleRelease()); + + // Grant ADMIN role to user + vm.prank(developer); + appController.grantTeamRole(developer, IAppController.TeamRole.ADMIN, user); + + // Now user can upgrade + vm.prank(user); + appController.upgradeApp(app, _assembleRelease()); } - // ========== Isolated Billing Edge Cases ========== + function test_startApp_requiresAdmin() public { + vm.prank(developer); + IApp app = appController.createApp(keccak256("start_admin"), _assembleRelease()); - function test_suspendIsolatedBillingApp_withCreatorAccount_reverts() public { - IApp expectedApp = appController.calculateAppId(developer, SALT); - _setMaxActiveAppsPerUser(address(expectedApp), 1); + // Stop the app first (as admin) + vm.prank(developer); + appController.stopApp(app); + // Grant PAUSER role to user (not enough for start) vm.prank(developer); - IApp app = appController.createAppWithIsolatedBilling(SALT, _assembleRelease()); + appController.grantTeamRole(developer, IAppController.TeamRole.PAUSER, user); - // Trying to suspend using the creator (developer) as account should revert - // because the isolated billing app's ownership check requires the app address, not the creator - IApp[] memory apps = new IApp[](1); - apps[0] = app; + // User with PAUSER cannot start + vm.prank(user); + vm.expectRevert(PermissionControllerMixin.InvalidPermissions.selector); + appController.startApp(app); - vm.prank(admin); - vm.expectRevert(abi.encodeWithSelector(IAppController.InvalidAppStatus.selector)); - appController.suspend(developer, apps); + // Grant ADMIN role to user + vm.prank(developer); + appController.grantTeamRole(developer, IAppController.TeamRole.ADMIN, user); + + // Now user can start + vm.prank(user); + appController.startApp(app); } - function test_getAppsByCreator_returnsIsolatedBillingApps() public { - IApp expectedApp = appController.calculateAppId(developer, SALT); - _setMaxActiveAppsPerUser(address(expectedApp), 1); + function test_terminateApp_requiresAdmin() public { + vm.prank(developer); + IApp app = appController.createApp(keccak256("terminate_admin"), _assembleRelease()); + // Grant DEVELOPER role to user (not enough for terminate) vm.prank(developer); - IApp app = appController.createAppWithIsolatedBilling(SALT, _assembleRelease()); + appController.grantTeamRole(developer, IAppController.TeamRole.DEVELOPER, user); + + // User with DEVELOPER cannot terminate + vm.prank(user); + vm.expectRevert(PermissionControllerMixin.InvalidPermissions.selector); + appController.terminateApp(app); - // getAppsByCreator should still return the isolated billing app (creator is still set) - (IApp[] memory apps,) = appController.getAppsByCreator(developer, 0, 10); - assertEq(apps.length, 1); - assertEq(address(apps[0]), address(app)); + // Grant ADMIN role to user + vm.prank(developer); + appController.grantTeamRole(developer, IAppController.TeamRole.ADMIN, user); - // But getAppsByBillingAccount with developer should NOT return it - (IApp[] memory billingApps,) = appController.getAppsByBillingAccount(developer, 0, 10); - assertEq(billingApps.length, 0); + // Now user can terminate + vm.prank(user); + appController.terminateApp(app); } - function test_terminateAppByAdmin_isolatedBilling_decrementsAppQuota() public { - IApp expectedApp = appController.calculateAppId(developer, SALT); - _setMaxActiveAppsPerUser(address(expectedApp), 1); + // ========== getAppsForAccount Tests ========== + + function test_getAppsForAccount() public { + _setMaxActiveAppsPerUser(user, 10); + // Developer creates 2 apps + vm.prank(developer); + IApp app1 = appController.createApp(keccak256("account_test_1"), _assembleRelease()); vm.prank(developer); - IApp app = appController.createAppWithIsolatedBilling(SALT, _assembleRelease()); + IApp app2 = appController.createApp(keccak256("account_test_2"), _assembleRelease()); - // Verify app address has 1 active app - assertEq(appController.getActiveAppCount(address(app)), 1); - assertEq(appController.getActiveAppCount(developer), 0); + // User creates 1 app + vm.prank(user); + IApp app3 = appController.createApp(keccak256("account_test_3"), _assembleRelease()); - // Admin terminates the app - vm.prank(admin); - appController.terminateAppByAdmin(app); + // Grant user PAUSER role on developer's team + vm.prank(developer); + appController.grantTeamRole(developer, IAppController.TeamRole.PAUSER, user); + + // Get apps for developer (should have 2 apps as owner + admin) + IAppController.AppRoles[] memory developerApps = appController.getAppsForAccount(developer, 0, 10); + assertEq(developerApps.length, 2); + assertEq(address(developerApps[0].app), address(app1)); + assertTrue(developerApps[0].isOwner); + assertEq(developerApps[0].roles.length, 1); + assertEq(uint256(developerApps[0].roles[0]), uint256(IAppController.TeamRole.ADMIN)); + + // Get apps for user (should have 2 apps - 1 as owner+admin, 1 as pauser) + IAppController.AppRoles[] memory userApps = appController.getAppsForAccount(user, 0, 10); + assertEq(userApps.length, 3); // app1, app2 (pauser), app3 (owner+admin) + + // Find user's own app (app3) + bool foundOwnApp = false; + for (uint256 i = 0; i < userApps.length; i++) { + if (address(userApps[i].app) == address(app3)) { + foundOwnApp = true; + assertTrue(userApps[i].isOwner); + assertEq(userApps[i].roles.length, 1); + assertEq(uint256(userApps[i].roles[0]), uint256(IAppController.TeamRole.ADMIN)); + } + } + assertTrue(foundOwnApp); + } - // Verify the app address's count decremented (not the developer's) - assertEq(appController.getActiveAppCount(address(app)), 0); - assertEq(appController.getActiveAppCount(developer), 0); - assertEq(uint256(appController.getAppStatus(app)), uint256(IAppController.AppStatus.TERMINATED)); + function test_getAppsForAccount_pagination() public { + // Create 5 apps as developer + IApp[] memory apps = new IApp[](5); + for (uint256 i = 0; i < 5; i++) { + vm.prank(developer); + apps[i] = appController.createApp(keccak256(abi.encodePacked("pagination_", i)), _assembleRelease()); + } + + // Test pagination - first 2 apps + IAppController.AppRoles[] memory page1 = appController.getAppsForAccount(developer, 0, 2); + assertEq(page1.length, 2); + + // Test pagination - next 2 apps + IAppController.AppRoles[] memory page2 = appController.getAppsForAccount(developer, 2, 2); + assertEq(page2.length, 2); + + // Test pagination - last app + IAppController.AppRoles[] memory page3 = appController.getAppsForAccount(developer, 4, 10); + assertEq(page3.length, 1); + + // Test pagination - beyond total + IAppController.AppRoles[] memory page4 = appController.getAppsForAccount(developer, 10, 10); + assertEq(page4.length, 0); + } + + function test_getAppsForAccount_multipleRoles() public { + // Developer creates an app + vm.prank(developer); + IApp app = appController.createApp(keccak256("multi_role"), _assembleRelease()); + + // Grant user both PAUSER and DEVELOPER roles + vm.prank(developer); + appController.grantTeamRole(developer, IAppController.TeamRole.PAUSER, user); + vm.prank(developer); + appController.grantTeamRole(developer, IAppController.TeamRole.DEVELOPER, user); + + // Get apps for user + IAppController.AppRoles[] memory userApps = appController.getAppsForAccount(user, 0, 10); + assertEq(userApps.length, 1); + assertFalse(userApps[0].isOwner); + assertEq(userApps[0].roles.length, 2); // PAUSER and DEVELOPER } } From afe309ba54c0c3461c800552d0894c450026aa31 Mon Sep 17 00:00:00 2001 From: Solimander Date: Wed, 10 Dec 2025 15:43:35 -0700 Subject: [PATCH 02/31] docs: clarify EOA role description in app operations trust model --- docs/APP_OPERATIONS_TRUST_MODEL.md | 33 +++++++++++++++++++++++------- 1 file changed, 26 insertions(+), 7 deletions(-) diff --git a/docs/APP_OPERATIONS_TRUST_MODEL.md b/docs/APP_OPERATIONS_TRUST_MODEL.md index ceaa2c7..4910a2d 100644 --- a/docs/APP_OPERATIONS_TRUST_MODEL.md +++ b/docs/APP_OPERATIONS_TRUST_MODEL.md @@ -21,11 +21,11 @@ This spec describes a new operational model for Eigen Compute apps, focusing on An app owner's address IS the team identity. This is similar to GitHub or Vercel teams, but the team is built around the owner address rather than a separate entity. This keeps things simple - no team entity to create, straightforward billing tied to the owner, and works naturally for the common case of a single EOA or multisig. Ownership can be transferred to a new address if the team structure changes (see Future Additions). Any role (including the team owner) can be: -- An EOA (solo dev or operator) +- An EOA (solo dev) - A multisig (shared control) -- A multisig behind a timelock (for enforced delays on sensitive operations) +- An EOA or multisig behind a timelock (for enforced delays on sensitive operations) -This also enables a cleaner UX: manage your team once, and all apps under that team inherit the same permissions - similar to how Vercel or GitHub organization access works. App-level permissions would require managing access separately for each app, and wouldn't align with billing which is at the owner level. +This also enables a cleaner UX: manage your team once, and all apps under that team inherit the same permissions. App-level permissions would require managing access separately for each app, and wouldn't align with billing which is at the owner level. ## Roles @@ -90,9 +90,19 @@ For emergency response, grant `PAUSER` to a lower-threshold multisig or EOA that ``` ecloud auth login -> Select identity type: - 1. EOA (private key) - 2. Gnosis Safe (enter address) +> Enter your address: 0x1234... + +# If address is a timelock, auto-detect: +> Detected timelock with 24h delay +> Proposer: 0x5678... (3/5 Safe) +> Logged in as: 0x1234... + +# If address is not a timelock: +> Is this address behind a timelock? (y/N) y +> Enter timelock address: 0x9999... + +> Logged in as: 0x9999... (timelock) +> Proposer: 0x1234... (EOA) ``` **Create new identity:** @@ -103,6 +113,7 @@ ecloud auth new > What would you like to create? 1. EOA (new private key) 2. Gnosis Safe + 3. Timelock (for existing EOA or Safe) # For Safe: > Enter owner addresses: 0x1111..., 0x2222..., 0x3333... @@ -112,9 +123,17 @@ ecloud auth new > Enter minimum delay (e.g., "24h", "7d"): 24h > Deploying Safe + Timelock via factory... + +# For Timelock: +> Enter proposer/executor address (your EOA or Safe): 0x1234... +> Enter minimum delay (e.g., "24h", "7d"): 24h + +> Deploying Timelock via factory... +> Your new identity: 0x5678... (timelock) +> Proposer/Executor: 0x1234... ``` -When a timelock is configured, the CLI deploys via SafeTimelockFactory with your identity as both proposer and executor. +When a timelock is configured, the CLI deploys via SafeTimelockFactory with the specified address as both proposer and executor. **App actions with Safe:** From c7ea6e4c730e501610348b52c1ffb02aacad452c Mon Sep 17 00:00:00 2001 From: Solimander Date: Fri, 12 Dec 2025 18:17:02 -0700 Subject: [PATCH 03/31] refactor: migrate TimelockController deployment from Create2 to minimal proxy pattern --- src/factories/SafeTimelockFactory.sol | 61 +++++++++------------- src/governance/TimelockControllerImpl.sol | 31 +++++++++++ src/interfaces/ISafeTimelockFactory.sol | 24 +++------ src/storage/SafeTimelockFactoryStorage.sol | 12 ++++- 4 files changed, 73 insertions(+), 55 deletions(-) create mode 100644 src/governance/TimelockControllerImpl.sol diff --git a/src/factories/SafeTimelockFactory.sol b/src/factories/SafeTimelockFactory.sol index 1624fd0..18573c7 100644 --- a/src/factories/SafeTimelockFactory.sol +++ b/src/factories/SafeTimelockFactory.sol @@ -2,13 +2,14 @@ pragma solidity ^0.8.27; import {Create2} from "@openzeppelin/contracts/utils/Create2.sol"; +import {Clones} from "@openzeppelin/contracts/proxy/Clones.sol"; import {Initializable} from "@openzeppelin-upgrades/contracts/proxy/utils/Initializable.sol"; import {EnumerableSet} from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol"; -import {TimelockController} from "@openzeppelin/contracts/governance/TimelockController.sol"; import {SafeTimelockFactoryStorage} from "../storage/SafeTimelockFactoryStorage.sol"; import {ISafeTimelockFactory} from "../interfaces/ISafeTimelockFactory.sol"; import {ISafe} from "../interfaces/ISafe.sol"; import {ISafeProxyFactory} from "../interfaces/ISafeProxyFactory.sol"; +import {TimelockControllerImpl} from "../governance/TimelockControllerImpl.sol"; /** * @title SafeTimelockFactory @@ -18,9 +19,12 @@ import {ISafeProxyFactory} from "../interfaces/ISafeProxyFactory.sol"; contract SafeTimelockFactory is Initializable, SafeTimelockFactoryStorage { using EnumerableSet for EnumerableSet.AddressSet; - constructor(address _safeSingleton, address _safeProxyFactory, address _defaultFallbackHandler) - SafeTimelockFactoryStorage(_safeSingleton, _safeProxyFactory, _defaultFallbackHandler) - { + constructor( + address _safeSingleton, + address _safeProxyFactory, + address _defaultFallbackHandler, + address _timelockImplementation + ) SafeTimelockFactoryStorage(_safeSingleton, _safeProxyFactory, _defaultFallbackHandler, _timelockImplementation) { _disableInitializers(); } @@ -30,7 +34,6 @@ contract SafeTimelockFactory is Initializable, SafeTimelockFactoryStorage { /// @inheritdoc ISafeTimelockFactory function deploySafe(SafeConfig calldata config, bytes32 salt) external returns (address safe) { - _validateSafeConfig(config); safe = _deploySafe(config, salt); _safes.add(safe); emit SafeDeployed(msg.sender, safe, config.owners, config.threshold, salt); @@ -63,40 +66,21 @@ contract SafeTimelockFactory is Initializable, SafeTimelockFactoryStorage { returns (address) { bytes memory initializer = _encodeSafeInitializer(config); - uint256 saltNonce = uint256(keccak256(abi.encodePacked(deployer, salt))); + uint256 saltNonce = uint256(_deriveSalt(deployer, salt)); bytes32 creationSalt = keccak256(abi.encodePacked(keccak256(initializer), saltNonce)); - bytes memory deploymentData = - abi.encodePacked(ISafeProxyFactory(safeProxyFactory).proxyCreationCode(), uint256(uint160(safeSingleton))); + bytes memory proxyCreationCode = ISafeProxyFactory(safeProxyFactory).proxyCreationCode(); + bytes memory deploymentData = abi.encodePacked(proxyCreationCode, uint256(uint160(safeSingleton))); return Create2.computeAddress(creationSalt, keccak256(deploymentData), safeProxyFactory); } /// @inheritdoc ISafeTimelockFactory - function calculateTimelockAddress(address deployer, TimelockConfig calldata config, bytes32 salt) - external - view - returns (address) - { - bytes32 mixedSalt = keccak256(abi.encodePacked(deployer, salt)); - bytes memory initCode = abi.encodePacked( - type(TimelockController).creationCode, - abi.encode(config.minDelay, config.proposers, config.executors, address(0)) - ); - return Create2.computeAddress(mixedSalt, keccak256(initCode)); + function calculateTimelockAddress(address deployer, bytes32 salt) external view returns (address) { + bytes32 mixedSalt = _deriveSalt(deployer, salt); + return Clones.predictDeterministicAddress(timelockImplementation, mixedSalt); } /// INTERNAL FUNCTIONS - function _validateSafeConfig(SafeConfig calldata config) internal pure { - require(config.owners.length > 0, NoOwners()); - require(config.threshold > 0 && config.threshold <= config.owners.length, InvalidThreshold()); - for (uint256 i = 0; i < config.owners.length; i++) { - require(config.owners[i] != address(0), ZeroAddressOwner()); - for (uint256 j = i + 1; j < config.owners.length; j++) { - require(config.owners[i] != config.owners[j], DuplicateOwner()); - } - } - } - function _validateTimelockConfig(TimelockConfig calldata config) internal pure { require(config.proposers.length > 0, NoProposers()); require(config.executors.length > 0, NoExecutors()); @@ -110,7 +94,7 @@ contract SafeTimelockFactory is Initializable, SafeTimelockFactoryStorage { function _deploySafe(SafeConfig calldata config, bytes32 salt) internal returns (address safe) { bytes memory initializer = _encodeSafeInitializer(config); - uint256 saltNonce = uint256(keccak256(abi.encodePacked(msg.sender, salt))); + uint256 saltNonce = uint256(_deriveSalt(msg.sender, salt)); safe = ISafeProxyFactory(safeProxyFactory).createProxyWithNonce(safeSingleton, initializer, saltNonce); } @@ -129,11 +113,14 @@ contract SafeTimelockFactory is Initializable, SafeTimelockFactoryStorage { } function _deployTimelock(TimelockConfig calldata config, bytes32 salt) internal returns (address timelock) { - bytes32 mixedSalt = keccak256(abi.encodePacked(msg.sender, salt)); - bytes memory initCode = abi.encodePacked( - type(TimelockController).creationCode, - abi.encode(config.minDelay, config.proposers, config.executors, address(0)) - ); - timelock = Create2.deploy(0, mixedSalt, initCode); + bytes32 mixedSalt = _deriveSalt(msg.sender, salt); + timelock = Clones.cloneDeterministic(timelockImplementation, mixedSalt); + + // forgefmt: disable-next-item + TimelockControllerImpl(payable(timelock)).initialize(config.minDelay, config.proposers, config.executors, address(0)); + } + + function _deriveSalt(address deployer, bytes32 salt) internal pure returns (bytes32) { + return keccak256(abi.encodePacked(deployer, salt)); } } diff --git a/src/governance/TimelockControllerImpl.sol b/src/governance/TimelockControllerImpl.sol new file mode 100644 index 0000000..966e38e --- /dev/null +++ b/src/governance/TimelockControllerImpl.sol @@ -0,0 +1,31 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity ^0.8.27; + +import { + TimelockControllerUpgradeable +} from "@openzeppelin-upgrades/contracts/governance/TimelockControllerUpgradeable.sol"; + +/** + * @title TimelockControllerImpl + * @notice Implementation contract for TimelockController minimal proxies + * @dev Wraps TimelockControllerUpgradeable to expose a public initialize function + */ +contract TimelockControllerImpl is TimelockControllerUpgradeable { + constructor() { + _disableInitializers(); + } + + /** + * @notice Initialize the timelock controller + * @param minDelay Minimum delay for operations + * @param proposers Addresses granted proposer and canceller roles + * @param executors Addresses granted executor role + * @param admin Optional admin address (use address(0) for self-administered) + */ + function initialize(uint256 minDelay, address[] memory proposers, address[] memory executors, address admin) + external + initializer + { + __TimelockController_init(minDelay, proposers, executors, admin); + } +} diff --git a/src/interfaces/ISafeTimelockFactory.sol b/src/interfaces/ISafeTimelockFactory.sol index e248ca0..2981ad4 100644 --- a/src/interfaces/ISafeTimelockFactory.sol +++ b/src/interfaces/ISafeTimelockFactory.sol @@ -40,30 +40,18 @@ interface ISafeTimelockFactory { /// ERRORS - /// @notice Thrown when threshold is zero or exceeds owner count - error InvalidThreshold(); - - /// @notice Thrown when owners array is empty - error NoOwners(); - /// @notice Thrown when proposers array is empty error NoProposers(); /// @notice Thrown when executors array is empty error NoExecutors(); - /// @notice Thrown when an owner address is zero - error ZeroAddressOwner(); - /// @notice Thrown when a proposer address is zero error ZeroAddressProposer(); /// @notice Thrown when an executor address is zero error ZeroAddressExecutor(); - /// @notice Thrown when duplicate owners are provided - error DuplicateOwner(); - /// EXTERNAL FUNCTIONS /** @@ -113,14 +101,10 @@ interface ISafeTimelockFactory { /** * @notice Pre-computes the address of a Timelock deployment * @param deployer The address that will deploy - * @param config Timelock configuration * @param salt User-provided salt * @return The computed TimelockController address */ - function calculateTimelockAddress(address deployer, TimelockConfig calldata config, bytes32 salt) - external - view - returns (address); + function calculateTimelockAddress(address deployer, bytes32 salt) external view returns (address); /** * @notice Returns the official Gnosis Safe singleton address @@ -133,4 +117,10 @@ interface ISafeTimelockFactory { * @return The SafeProxyFactory address */ function safeProxyFactory() external view returns (address); + + /** + * @notice Returns the TimelockController implementation address for minimal proxies + * @return The TimelockControllerImpl address + */ + function timelockImplementation() external view returns (address); } diff --git a/src/storage/SafeTimelockFactoryStorage.sol b/src/storage/SafeTimelockFactoryStorage.sol index e1d308f..4d27ed7 100644 --- a/src/storage/SafeTimelockFactoryStorage.sol +++ b/src/storage/SafeTimelockFactoryStorage.sol @@ -22,6 +22,9 @@ abstract contract SafeTimelockFactoryStorage is ISafeTimelockFactory { /// @notice The default fallback handler for Safes address public immutable defaultFallbackHandler; + /// @notice The TimelockController implementation for minimal proxies + address public immutable timelockImplementation; + /// STATE VARIABLES /// @notice Set of all Safes deployed by this factory @@ -41,10 +44,17 @@ abstract contract SafeTimelockFactoryStorage is ISafeTimelockFactory { * @param _safeSingleton The official Gnosis Safe singleton address * @param _safeProxyFactory The official Gnosis Safe proxy factory address * @param _defaultFallbackHandler The default fallback handler for Safes + * @param _timelockImplementation The TimelockController implementation for minimal proxies */ - constructor(address _safeSingleton, address _safeProxyFactory, address _defaultFallbackHandler) { + constructor( + address _safeSingleton, + address _safeProxyFactory, + address _defaultFallbackHandler, + address _timelockImplementation + ) { safeSingleton = _safeSingleton; safeProxyFactory = _safeProxyFactory; defaultFallbackHandler = _defaultFallbackHandler; + timelockImplementation = _timelockImplementation; } } From bdecd2a7d0ead7045da002ab43dcdaef84053b4f Mon Sep 17 00:00:00 2001 From: Solimander Date: Mon, 5 Jan 2026 12:09:45 -0500 Subject: [PATCH 04/31] docs: simplify auth login flow in app operations trust model documentation --- docs/APP_OPERATIONS_TRUST_MODEL.md | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/docs/APP_OPERATIONS_TRUST_MODEL.md b/docs/APP_OPERATIONS_TRUST_MODEL.md index 4910a2d..e66ee2b 100644 --- a/docs/APP_OPERATIONS_TRUST_MODEL.md +++ b/docs/APP_OPERATIONS_TRUST_MODEL.md @@ -90,19 +90,17 @@ For emergency response, grant `PAUSER` to a lower-threshold multisig or EOA that ``` ecloud auth login -> Enter your address: 0x1234... +> Connect wallet or enter EOA address: 0x1234... -# If address is a timelock, auto-detect: -> Detected timelock with 24h delay -> Proposer: 0x5678... (3/5 Safe) -> Logged in as: 0x1234... +> Select an identity: + 1. 0x1234... (your wallet) + ─── + 2. 0xABCD... (Timelock, 24h) via 2/3 Safe + 3. 0x9999... (3/5 Safe) -# If address is not a timelock: -> Is this address behind a timelock? (y/N) y -> Enter timelock address: 0x9999... +> Select: 1 -> Logged in as: 0x9999... (timelock) -> Proposer: 0x1234... (EOA) +> Logged in as: 0x1234... ``` **Create new identity:** From fa00bfae98930b6c487f9a78566fc64baf52f168 Mon Sep 17 00:00:00 2001 From: Taras Shchybovyk Date: Tue, 3 Mar 2026 13:26:52 -0800 Subject: [PATCH 05/31] feat: add v1.4.0-governance release scripts, tests, and bindings - Add script/releases/v1.4.0-governance/ with upgrade.json, EOA deploy script (TimelockControllerImpl + SafeTimelockFactory proxy + new AppController impl), and multisig upgrade script - Extend Env.sol with SafeTimelockFactory (proxy + impl), TimelockControllerImpl, and Safe infrastructure (safeSingleton, safeProxyFactory, defaultFallbackHandler) accessors - Add SafeTimelockFactory.t.sol with MockSafeProxyFactory and 13 test cases covering timelock/safe deployment, deterministic addresses, and revert paths - Add migrateAdmins tests to AppController.t.sol (happy path, auth, non-existent app, no-admins, idempotency) - Add SafeTimelockFactory and TimelockControllerImpl to compile-bindings.sh --- bin/compile-bindings.sh | 2 + script/releases/Env.sol | 29 ++ .../v1.4.0-governance/1-deployContracts.s.sol | 160 +++++++++++ .../2-upgradeAppController.s.sol | 31 +++ .../releases/v1.4.0-governance/upgrade.json | 9 + test/AppController.t.sol | 93 +++++++ test/SafeTimelockFactory.t.sol | 254 ++++++++++++++++++ 7 files changed, 578 insertions(+) create mode 100644 script/releases/v1.4.0-governance/1-deployContracts.s.sol create mode 100644 script/releases/v1.4.0-governance/2-upgradeAppController.s.sol create mode 100644 script/releases/v1.4.0-governance/upgrade.json create mode 100644 test/SafeTimelockFactory.t.sol diff --git a/bin/compile-bindings.sh b/bin/compile-bindings.sh index f93d89f..0ff3f6f 100755 --- a/bin/compile-bindings.sh +++ b/bin/compile-bindings.sh @@ -56,6 +56,8 @@ contracts=( "IReleaseManager" "IPermissionController" "USDCCredits" + "SafeTimelockFactory" + "TimelockControllerImpl" ) forge b --no-metadata diff --git a/script/releases/Env.sol b/script/releases/Env.sol index 639b398..22d0074 100644 --- a/script/releases/Env.sol +++ b/script/releases/Env.sol @@ -21,6 +21,8 @@ import {ComputeAVSRegistrar} from "../../src/ComputeAVSRegistrar.sol"; import {ComputeOperator} from "../../src/ComputeOperator.sol"; import {ImageAllowlist} from "../../src/ImageAllowlist.sol"; import {USDCCredits} from "../../src/USDCCredits.sol"; +import {SafeTimelockFactory} from "../../src/factories/SafeTimelockFactory.sol"; +import {TimelockControllerImpl} from "../../src/governance/TimelockControllerImpl.sol"; library Env { using ZEnvHelpers for *; @@ -109,6 +111,10 @@ library Env { return USDCCredits(_deployedProxy(type(USDCCredits).name)); } + function safeTimelockFactory(DeployedProxy) internal view returns (SafeTimelockFactory) { + return SafeTimelockFactory(_deployedProxy(type(SafeTimelockFactory).name)); + } + function appBeacon(DeployedBeacon) internal view returns (UpgradeableBeacon) { return UpgradeableBeacon(_deployedBeacon(type(App).name)); } @@ -140,6 +146,10 @@ library Env { return USDCCredits(_deployedImpl(type(USDCCredits).name)); } + function safeTimelockFactory(DeployedImpl) internal view returns (SafeTimelockFactory) { + return SafeTimelockFactory(_deployedImpl(type(SafeTimelockFactory).name)); + } + /** * governance contracts */ @@ -163,10 +173,29 @@ library Env { return _envAddress("billingAdmin"); } + function timelockControllerImpl() internal view returns (TimelockControllerImpl) { + return TimelockControllerImpl(payable(_deployedContract(type(TimelockControllerImpl).name))); + } + function proxyAdmin() internal view returns (ProxyAdmin) { return ProxyAdmin(_deployedContract(type(ProxyAdmin).name)); } + /** + * Safe infrastructure + */ + function safeSingleton() internal view returns (address) { + return _envAddress("safeSingleton"); + } + + function safeProxyFactory() internal view returns (address) { + return _envAddress("safeProxyFactory"); + } + + function defaultFallbackHandler() internal view returns (address) { + return _envAddress("defaultFallbackHandler"); + } + /** * helpers */ diff --git a/script/releases/v1.4.0-governance/1-deployContracts.s.sol b/script/releases/v1.4.0-governance/1-deployContracts.s.sol new file mode 100644 index 0000000..99cb5c1 --- /dev/null +++ b/script/releases/v1.4.0-governance/1-deployContracts.s.sol @@ -0,0 +1,160 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity ^0.8.27; + +import {EOADeployer} from "zeus-templates/templates/EOADeployer.sol"; +import "../Env.sol"; + +import "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol"; +import "@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol"; + +import {AppController} from "../../../src/AppController.sol"; +import {SafeTimelockFactory} from "../../../src/factories/SafeTimelockFactory.sol"; +import {TimelockControllerImpl} from "../../../src/governance/TimelockControllerImpl.sol"; + +/** + * Purpose: deploy TimelockControllerImpl, SafeTimelockFactory (impl + proxy), and new AppController implementation + */ +contract DeployContracts is EOADeployer { + using Env for *; + + function _runAsEOA() internal override { + vm.startBroadcast(); + + // 1. Deploy TimelockControllerImpl (no constructor args) + TimelockControllerImpl timelockControllerImpl = new TimelockControllerImpl(); + deployContract({name: type(TimelockControllerImpl).name, deployedTo: address(timelockControllerImpl)}); + + // 2. Deploy SafeTimelockFactory implementation + SafeTimelockFactory safeTimelockFactoryImpl = new SafeTimelockFactory({ + _safeSingleton: Env.safeSingleton(), + _safeProxyFactory: Env.safeProxyFactory(), + _defaultFallbackHandler: Env.defaultFallbackHandler(), + _timelockImplementation: address(timelockControllerImpl) + }); + deployImpl({name: type(SafeTimelockFactory).name, deployedTo: address(safeTimelockFactoryImpl)}); + + // 3. Deploy SafeTimelockFactory proxy + TransparentUpgradeableProxy safeTimelockFactoryProxy = new TransparentUpgradeableProxy( + address(safeTimelockFactoryImpl), + address(Env.proxyAdmin()), + abi.encodeCall(SafeTimelockFactory.initialize, ()) + ); + deployProxy({name: type(SafeTimelockFactory).name, deployedTo: address(safeTimelockFactoryProxy)}); + + // 4. Deploy new AppController implementation + AppController newAppControllerImpl = new AppController({ + _version: Env.deployVersion(), + _permissionController: Env.permissionController(), + _releaseManager: Env.releaseManager(), + _computeAVSRegistrar: Env.proxy.computeAVSRegistrar(), + _computeOperator: Env.proxy.computeOperator(), + _appBeacon: Env.beacon.appBeacon() + }); + deployImpl({name: type(AppController).name, deployedTo: address(newAppControllerImpl)}); + + vm.stopBroadcast(); + } + + function testScript() public virtual { + runAsEOA(); + + _validateNewAddresses({afterUpgrade: false}); + _validateConstructors(); + } + + /// @dev Validate that all deployed addresses are non-zero and proxy mappings are correct + function _validateNewAddresses(bool afterUpgrade) internal view { + // TimelockControllerImpl + assertTrue(address(Env.timelockControllerImpl()) != address(0), "TimelockControllerImpl is zero"); + + // SafeTimelockFactory impl and proxy + assertTrue(address(Env.impl.safeTimelockFactory()) != address(0), "SafeTimelockFactory impl is zero"); + assertTrue(address(Env.proxy.safeTimelockFactory()) != address(0), "SafeTimelockFactory proxy is zero"); + + // AppController impl + assertTrue(address(Env.impl.appController()) != address(0), "AppController impl is zero"); + + // SafeTimelockFactory proxy -> impl mapping + assertEq( + _getProxyImpl(address(Env.proxy.safeTimelockFactory())), + address(Env.impl.safeTimelockFactory()), + "SafeTimelockFactory proxy->impl mismatch" + ); + + // SafeTimelockFactory proxy admin + assertEq( + _getProxyAdmin(address(Env.proxy.safeTimelockFactory())), + address(Env.proxyAdmin()), + "SafeTimelockFactory proxyAdmin mismatch" + ); + + // AppController proxy -> impl mapping (only after upgrade) + if (afterUpgrade) { + assertEq( + _getProxyImpl(address(Env.proxy.appController())), + address(Env.impl.appController()), + "AppController proxy->impl mismatch" + ); + } + } + + /// @dev Validate constructor immutables on deployed contracts + function _validateConstructors() internal view { + // Validate SafeTimelockFactory impl immutables + SafeTimelockFactory safeTimelockFactoryImpl = Env.impl.safeTimelockFactory(); + assertEq( + safeTimelockFactoryImpl.safeSingleton(), + Env.safeSingleton(), + "SafeTimelockFactory safeSingleton mismatch" + ); + assertEq( + safeTimelockFactoryImpl.safeProxyFactory(), + Env.safeProxyFactory(), + "SafeTimelockFactory safeProxyFactory mismatch" + ); + assertEq( + safeTimelockFactoryImpl.timelockImplementation(), + address(Env.timelockControllerImpl()), + "SafeTimelockFactory timelockImplementation mismatch" + ); + + // Validate AppController impl constructor args + AppController appController = Env.impl.appController(); + assertEq( + address(appController.permissionController()), + address(Env.permissionController()), + "AppController permissionController mismatch" + ); + assertEq( + address(appController.releaseManager()), + address(Env.releaseManager()), + "AppController releaseManager mismatch" + ); + assertEq(appController.version(), Env.deployVersion(), "AppController version mismatch"); + assertEq( + address(appController.computeAVSRegistrar()), + address(Env.proxy.computeAVSRegistrar()), + "AppController computeAVSRegistrar mismatch" + ); + assertEq( + address(appController.computeOperator()), + address(Env.proxy.computeOperator()), + "AppController computeOperator mismatch" + ); + assertEq( + address(appController.appBeacon()), + address(Env.beacon.appBeacon()), + "AppController appBeacon mismatch" + ); + } + + /// @dev Query and return `proxyAdmin.getProxyImplementation(proxy)` + function _getProxyImpl(address proxy) internal view returns (address) { + return ProxyAdmin(Env.proxyAdmin()).getProxyImplementation(ITransparentUpgradeableProxy(proxy)); + } + + /// @dev Query and return `proxyAdmin.getProxyAdmin(proxy)` + function _getProxyAdmin(address proxy) internal view returns (address) { + return ProxyAdmin(Env.proxyAdmin()).getProxyAdmin(ITransparentUpgradeableProxy(proxy)); + } +} diff --git a/script/releases/v1.4.0-governance/2-upgradeAppController.s.sol b/script/releases/v1.4.0-governance/2-upgradeAppController.s.sol new file mode 100644 index 0000000..2053612 --- /dev/null +++ b/script/releases/v1.4.0-governance/2-upgradeAppController.s.sol @@ -0,0 +1,31 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity ^0.8.27; + +import {MultisigBuilder} from "zeus-templates/templates/MultisigBuilder.sol"; +import "./1-deployContracts.s.sol"; +import "../Env.sol"; + +import "@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol"; + +/** + * Purpose: upgrade AppController proxy to the new implementation with team RBAC and governance support + */ +contract UpgradeAppController is MultisigBuilder, DeployContracts { + using Env for *; + + function _runAsMultisig() internal override prank(Env.computeOpsMultisig()) { + Env.proxyAdmin().upgrade( + ITransparentUpgradeableProxy(address(Env.proxy.appController())), + address(Env.impl.appController()) + ); + } + + function testScript() public virtual override { + runAsEOA(); + + execute(); + + _validateNewAddresses({afterUpgrade: true}); + _validateConstructors(); + } +} diff --git a/script/releases/v1.4.0-governance/upgrade.json b/script/releases/v1.4.0-governance/upgrade.json new file mode 100644 index 0000000..4d974f0 --- /dev/null +++ b/script/releases/v1.4.0-governance/upgrade.json @@ -0,0 +1,9 @@ +{ + "name": "governance", + "from": "1.1.1", + "to": "1.4.0", + "phases": [ + { "type": "eoa", "filename": "1-deployContracts.s.sol" }, + { "type": "multisig", "filename": "2-upgradeAppController.s.sol" } + ] +} diff --git a/test/AppController.t.sol b/test/AppController.t.sol index 82a05ec..66e8d09 100644 --- a/test/AppController.t.sol +++ b/test/AppController.t.sol @@ -1659,4 +1659,97 @@ contract AppControllerTest is ComputeDeployer { assertFalse(userApps[0].isOwner); assertEq(userApps[0].roles.length, 2); // PAUSER and DEVELOPER } + + // ========== migrateAdmins Tests ========== + + function test_migrateAdmins() public { + vm.prank(developer); + IApp app = appController.createApp(keccak256("migrate_admins"), _assembleRelease()); + + // Set up a permissionController admin for the app + address appAdmin = makeAddr("appAdmin"); + vm.prank(address(app)); + permissionController.addPendingAdmin(address(app), appAdmin); + vm.prank(appAdmin); + permissionController.acceptAdmin(address(app)); + + // Migrate admins + IApp[] memory apps = new IApp[](1); + apps[0] = app; + vm.prank(admin); + appController.migrateAdmins(apps); + + // Verify the permissionController admin was granted the team ADMIN role + assertTrue( + appController.hasTeamRole(developer, IAppController.TeamRole.ADMIN, appAdmin), + "appAdmin should have ADMIN team role" + ); + } + + function test_migrateAdmins_revertsIfNotAuthorized() public { + vm.prank(developer); + IApp app = appController.createApp(keccak256("migrate_admins_auth"), _assembleRelease()); + + IApp[] memory apps = new IApp[](1); + apps[0] = app; + + vm.prank(developer); + vm.expectRevert(PermissionControllerMixin.InvalidPermissions.selector); + appController.migrateAdmins(apps); + } + + function test_migrateAdmins_revertsIfAppDoesNotExist() public { + IApp fakeApp = IApp(address(0xDEADBEEF)); + + IApp[] memory apps = new IApp[](1); + apps[0] = fakeApp; + + vm.prank(admin); + vm.expectRevert(abi.encodeWithSelector(IAppController.AppDoesNotExist.selector)); + appController.migrateAdmins(apps); + } + + function test_migrateAdmins_noAdmins() public { + vm.prank(developer); + IApp app = appController.createApp(keccak256("migrate_admins_empty"), _assembleRelease()); + + // No permissionController admins set — getAdmins returns empty array + IApp[] memory apps = new IApp[](1); + apps[0] = app; + + vm.prank(admin); + appController.migrateAdmins(apps); // should succeed with no roles granted + } + + function test_migrateAdmins_skipsAlreadyGranted() public { + vm.prank(developer); + IApp app = appController.createApp(keccak256("migrate_admins_idempotent"), _assembleRelease()); + + address appAdmin = makeAddr("appAdminIdempotent"); + vm.prank(address(app)); + permissionController.addPendingAdmin(address(app), appAdmin); + vm.prank(appAdmin); + permissionController.acceptAdmin(address(app)); + + IApp[] memory apps = new IApp[](1); + apps[0] = app; + + // First call + vm.prank(admin); + appController.migrateAdmins(apps); + + assertTrue( + appController.hasTeamRole(developer, IAppController.TeamRole.ADMIN, appAdmin), + "appAdmin should have ADMIN role after first migration" + ); + + // Second call — must not revert + vm.prank(admin); + appController.migrateAdmins(apps); + + assertTrue( + appController.hasTeamRole(developer, IAppController.TeamRole.ADMIN, appAdmin), + "appAdmin should still have ADMIN role after second migration" + ); + } } diff --git a/test/SafeTimelockFactory.t.sol b/test/SafeTimelockFactory.t.sol new file mode 100644 index 0000000..bceffe5 --- /dev/null +++ b/test/SafeTimelockFactory.t.sol @@ -0,0 +1,254 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity ^0.8.27; + +import "forge-std/Test.sol"; +import {TransparentUpgradeableProxy} from "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol"; +import {ProxyAdmin} from "@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol"; +import {ISafeProxyFactory} from "../src/interfaces/ISafeProxyFactory.sol"; +import {ISafeTimelockFactory} from "../src/interfaces/ISafeTimelockFactory.sol"; +import {SafeTimelockFactory} from "../src/factories/SafeTimelockFactory.sol"; +import {TimelockControllerImpl} from "../src/governance/TimelockControllerImpl.sol"; + +/** + * @dev Minimal mock for the Gnosis Safe proxy factory. + * + * proxyCreationCode() returns a 3-byte init code that deploys an empty contract: + * 3d 3d f3 → RETURNDATASIZE RETURNDATASIZE RETURN → returns 0 bytes → empty contract + * + * createProxyWithNonce mirrors the real Safe factory's create2 formula so that + * SafeTimelockFactory.calculateSafeAddress() produces an identical address. + */ +contract MockSafeProxyFactory is ISafeProxyFactory { + bytes internal constant PROXY_CODE = hex"3d3df3"; + + function proxyCreationCode() external pure returns (bytes memory) { + return PROXY_CODE; + } + + function createProxyWithNonce(address _singleton, bytes memory initializer, uint256 saltNonce) + external + returns (address proxy) + { + bytes memory deploymentData = abi.encodePacked(PROXY_CODE, uint256(uint160(_singleton))); + bytes32 salt = keccak256(abi.encodePacked(keccak256(initializer), saltNonce)); + assembly { + proxy := create2(0, add(deploymentData, 0x20), mload(deploymentData), salt) + } + require(proxy != address(0), "MockSafeProxyFactory: create2 failed"); + } +} + +contract SafeTimelockFactoryTest is Test { + SafeTimelockFactory public factory; + TimelockControllerImpl public timelockImpl; + MockSafeProxyFactory public mockSafeProxyFactory; + + address public proposer = makeAddr("proposer"); + address public executor = makeAddr("executor"); + + bytes32 public constant SALT = keccak256("test_salt"); + + event SafeDeployed( + address indexed deployer, address indexed safe, address[] owners, uint256 threshold, bytes32 salt + ); + event TimelockDeployed( + address indexed deployer, + address indexed timelock, + uint256 minDelay, + address[] proposers, + address[] executors, + bytes32 salt + ); + + function setUp() public { + timelockImpl = new TimelockControllerImpl(); + mockSafeProxyFactory = new MockSafeProxyFactory(); + + SafeTimelockFactory factoryImpl = new SafeTimelockFactory({ + _safeSingleton: address(0), + _safeProxyFactory: address(mockSafeProxyFactory), + _defaultFallbackHandler: address(0), + _timelockImplementation: address(timelockImpl) + }); + + ProxyAdmin proxyAdmin = new ProxyAdmin(); + factory = SafeTimelockFactory( + address( + new TransparentUpgradeableProxy( + address(factoryImpl), + address(proxyAdmin), + abi.encodeCall(SafeTimelockFactory.initialize, ()) + ) + ) + ); + } + + // ========== Timelock deployment tests ========== + + function test_deployTimelock() public { + address[] memory proposers = new address[](1); + proposers[0] = proposer; + address[] memory executors = new address[](1); + executors[0] = executor; + + ISafeTimelockFactory.TimelockConfig memory config = + ISafeTimelockFactory.TimelockConfig({minDelay: 1 days, proposers: proposers, executors: executors}); + + vm.expectEmit(true, false, false, true); + emit TimelockDeployed(address(this), address(0), 1 days, proposers, executors, SALT); + + address timelock = factory.deployTimelock(config, SALT); + + assertTrue(timelock != address(0), "timelock is zero"); + assertTrue(factory.isTimelock(timelock), "isTimelock should be true"); + assertEq(TimelockControllerImpl(payable(timelock)).getMinDelay(), 1 days, "minDelay mismatch"); + } + + function test_deployTimelock_timelockInitialized() public { + address[] memory proposers = new address[](1); + proposers[0] = proposer; + address[] memory executors = new address[](1); + executors[0] = executor; + + ISafeTimelockFactory.TimelockConfig memory config = + ISafeTimelockFactory.TimelockConfig({minDelay: 2 days, proposers: proposers, executors: executors}); + + address timelock = factory.deployTimelock(config, SALT); + TimelockControllerImpl tc = TimelockControllerImpl(payable(timelock)); + + bytes32 PROPOSER_ROLE = tc.PROPOSER_ROLE(); + bytes32 EXECUTOR_ROLE = tc.EXECUTOR_ROLE(); + bytes32 CANCELLER_ROLE = tc.CANCELLER_ROLE(); + + assertTrue(tc.hasRole(PROPOSER_ROLE, proposer), "proposer missing PROPOSER_ROLE"); + assertTrue(tc.hasRole(CANCELLER_ROLE, proposer), "proposer missing CANCELLER_ROLE"); + assertTrue(tc.hasRole(EXECUTOR_ROLE, executor), "executor missing EXECUTOR_ROLE"); + } + + function test_deployTimelock_deterministicAddress() public { + address[] memory proposers = new address[](1); + proposers[0] = proposer; + address[] memory executors = new address[](1); + executors[0] = executor; + + ISafeTimelockFactory.TimelockConfig memory config = + ISafeTimelockFactory.TimelockConfig({minDelay: 1 days, proposers: proposers, executors: executors}); + + address predicted = factory.calculateTimelockAddress(address(this), SALT); + address deployed = factory.deployTimelock(config, SALT); + + assertEq(deployed, predicted, "deployed address does not match predicted"); + } + + function test_deployTimelock_differentSalts() public { + address[] memory proposers = new address[](1); + proposers[0] = proposer; + address[] memory executors = new address[](1); + executors[0] = executor; + + ISafeTimelockFactory.TimelockConfig memory config = + ISafeTimelockFactory.TimelockConfig({minDelay: 1 days, proposers: proposers, executors: executors}); + + bytes32 salt1 = keccak256("salt1"); + bytes32 salt2 = keccak256("salt2"); + + address timelock1 = factory.deployTimelock(config, salt1); + address timelock2 = factory.deployTimelock(config, salt2); + + assertTrue(timelock1 != timelock2, "different salts should produce different addresses"); + assertTrue(factory.isTimelock(timelock1), "timelock1 not registered"); + assertTrue(factory.isTimelock(timelock2), "timelock2 not registered"); + } + + function test_deployTimelock_reverts_noProposers() public { + address[] memory proposers = new address[](0); + address[] memory executors = new address[](1); + executors[0] = executor; + + ISafeTimelockFactory.TimelockConfig memory config = + ISafeTimelockFactory.TimelockConfig({minDelay: 1 days, proposers: proposers, executors: executors}); + + vm.expectRevert(ISafeTimelockFactory.NoProposers.selector); + factory.deployTimelock(config, SALT); + } + + function test_deployTimelock_reverts_noExecutors() public { + address[] memory proposers = new address[](1); + proposers[0] = proposer; + address[] memory executors = new address[](0); + + ISafeTimelockFactory.TimelockConfig memory config = + ISafeTimelockFactory.TimelockConfig({minDelay: 1 days, proposers: proposers, executors: executors}); + + vm.expectRevert(ISafeTimelockFactory.NoExecutors.selector); + factory.deployTimelock(config, SALT); + } + + function test_deployTimelock_reverts_zeroAddressProposer() public { + address[] memory proposers = new address[](1); + proposers[0] = address(0); + address[] memory executors = new address[](1); + executors[0] = executor; + + ISafeTimelockFactory.TimelockConfig memory config = + ISafeTimelockFactory.TimelockConfig({minDelay: 1 days, proposers: proposers, executors: executors}); + + vm.expectRevert(ISafeTimelockFactory.ZeroAddressProposer.selector); + factory.deployTimelock(config, SALT); + } + + function test_deployTimelock_reverts_zeroAddressExecutor() public { + address[] memory proposers = new address[](1); + proposers[0] = proposer; + address[] memory executors = new address[](1); + executors[0] = address(0); + + ISafeTimelockFactory.TimelockConfig memory config = + ISafeTimelockFactory.TimelockConfig({minDelay: 1 days, proposers: proposers, executors: executors}); + + vm.expectRevert(ISafeTimelockFactory.ZeroAddressExecutor.selector); + factory.deployTimelock(config, SALT); + } + + // ========== Safe deployment tests ========== + + function test_deploySafe() public { + address[] memory owners = new address[](2); + owners[0] = makeAddr("owner1"); + owners[1] = makeAddr("owner2"); + + ISafeTimelockFactory.SafeConfig memory config = + ISafeTimelockFactory.SafeConfig({owners: owners, threshold: 2}); + + vm.expectEmit(true, false, false, true); + emit SafeDeployed(address(this), address(0), owners, 2, SALT); + + address safe = factory.deploySafe(config, SALT); + + assertTrue(safe != address(0), "safe is zero"); + assertTrue(factory.isSafe(safe), "isSafe should be true"); + } + + function test_deploySafe_deterministicAddress() public { + address[] memory owners = new address[](1); + owners[0] = makeAddr("owner"); + + ISafeTimelockFactory.SafeConfig memory config = + ISafeTimelockFactory.SafeConfig({owners: owners, threshold: 1}); + + address predicted = factory.calculateSafeAddress(address(this), config, SALT); + address deployed = factory.deploySafe(config, SALT); + + assertEq(deployed, predicted, "deployed Safe address does not match predicted"); + } + + // ========== Registry tests ========== + + function test_isTimelock_false_for_random_address() public view { + assertFalse(factory.isTimelock(address(0xDEAD)), "random address should not be a timelock"); + } + + function test_isSafe_false_for_random_address() public view { + assertFalse(factory.isSafe(address(0xBEEF)), "random address should not be a safe"); + } +} From 3a24e3976d1d25542108279915ffad7f89b3229d Mon Sep 17 00:00:00 2001 From: Taras Shchybovyk Date: Tue, 3 Mar 2026 14:42:32 -0800 Subject: [PATCH 06/31] chore: add Safe infrastructure addresses to sepolia-dev deployment --- script/deploys/sepolia-dev/deployment.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/script/deploys/sepolia-dev/deployment.json b/script/deploys/sepolia-dev/deployment.json index e32adef..68246ef 100644 --- a/script/deploys/sepolia-dev/deployment.json +++ b/script/deploys/sepolia-dev/deployment.json @@ -19,5 +19,8 @@ "ComputeOperator_Proxy": "0x7328950368eC7B09102741a527883B16964E4483", "App_Impl": "0x681E7d2122a703e246b08337539491b777331f5D", "App_Beacon": "0xeA876c5660F0cC3BDdC1b899e03FFfC84567756a", - "ProxyAdmin": "0x9fc6Af1d6dD9443184c9b78df6a105A7e7A85542" + "ProxyAdmin": "0x9fc6Af1d6dD9443184c9b78df6a105A7e7A85542", + "safeSingleton": "0x41675C099F32341bf84BFc5382aF534df5C7461a", + "safeProxyFactory": "0x4e1DCf7AD4e460CfD30791CCC4F9c8a4f820ec67", + "defaultFallbackHandler": "0xfd0732Dc9E303f09fCEf3a7388Ad10A83459Ec99" } \ No newline at end of file From 7db5ee7f3326d7677577c796ae40a6a01e16735e Mon Sep 17 00:00:00 2001 From: Taras Shchybovyk Date: Tue, 3 Mar 2026 14:46:48 -0800 Subject: [PATCH 07/31] refactor: rename defaultFallbackHandler to safeFallbackHandler --- script/deploys/sepolia-dev/deployment.json | 2 +- script/releases/Env.sol | 4 ++-- script/releases/v1.4.0-governance/1-deployContracts.s.sol | 2 +- src/factories/SafeTimelockFactory.sol | 6 +++--- src/storage/SafeTimelockFactoryStorage.sol | 8 ++++---- test/SafeTimelockFactory.t.sol | 2 +- 6 files changed, 12 insertions(+), 12 deletions(-) diff --git a/script/deploys/sepolia-dev/deployment.json b/script/deploys/sepolia-dev/deployment.json index 68246ef..0efde2d 100644 --- a/script/deploys/sepolia-dev/deployment.json +++ b/script/deploys/sepolia-dev/deployment.json @@ -22,5 +22,5 @@ "ProxyAdmin": "0x9fc6Af1d6dD9443184c9b78df6a105A7e7A85542", "safeSingleton": "0x41675C099F32341bf84BFc5382aF534df5C7461a", "safeProxyFactory": "0x4e1DCf7AD4e460CfD30791CCC4F9c8a4f820ec67", - "defaultFallbackHandler": "0xfd0732Dc9E303f09fCEf3a7388Ad10A83459Ec99" + "safeFallbackHandler": "0xfd0732Dc9E303f09fCEf3a7388Ad10A83459Ec99" } \ No newline at end of file diff --git a/script/releases/Env.sol b/script/releases/Env.sol index 22d0074..ab5b0cf 100644 --- a/script/releases/Env.sol +++ b/script/releases/Env.sol @@ -192,8 +192,8 @@ library Env { return _envAddress("safeProxyFactory"); } - function defaultFallbackHandler() internal view returns (address) { - return _envAddress("defaultFallbackHandler"); + function safeFallbackHandler() internal view returns (address) { + return _envAddress("safeFallbackHandler"); } /** diff --git a/script/releases/v1.4.0-governance/1-deployContracts.s.sol b/script/releases/v1.4.0-governance/1-deployContracts.s.sol index 99cb5c1..32afa7f 100644 --- a/script/releases/v1.4.0-governance/1-deployContracts.s.sol +++ b/script/releases/v1.4.0-governance/1-deployContracts.s.sol @@ -28,7 +28,7 @@ contract DeployContracts is EOADeployer { SafeTimelockFactory safeTimelockFactoryImpl = new SafeTimelockFactory({ _safeSingleton: Env.safeSingleton(), _safeProxyFactory: Env.safeProxyFactory(), - _defaultFallbackHandler: Env.defaultFallbackHandler(), + _safeFallbackHandler: Env.safeFallbackHandler(), _timelockImplementation: address(timelockControllerImpl) }); deployImpl({name: type(SafeTimelockFactory).name, deployedTo: address(safeTimelockFactoryImpl)}); diff --git a/src/factories/SafeTimelockFactory.sol b/src/factories/SafeTimelockFactory.sol index 18573c7..9f9e084 100644 --- a/src/factories/SafeTimelockFactory.sol +++ b/src/factories/SafeTimelockFactory.sol @@ -22,9 +22,9 @@ contract SafeTimelockFactory is Initializable, SafeTimelockFactoryStorage { constructor( address _safeSingleton, address _safeProxyFactory, - address _defaultFallbackHandler, + address _safeFallbackHandler, address _timelockImplementation - ) SafeTimelockFactoryStorage(_safeSingleton, _safeProxyFactory, _defaultFallbackHandler, _timelockImplementation) { + ) SafeTimelockFactoryStorage(_safeSingleton, _safeProxyFactory, _safeFallbackHandler, _timelockImplementation) { _disableInitializers(); } @@ -105,7 +105,7 @@ contract SafeTimelockFactory is Initializable, SafeTimelockFactoryStorage { config.threshold, address(0), "", - defaultFallbackHandler, + safeFallbackHandler, address(0), 0, payable(address(0)) diff --git a/src/storage/SafeTimelockFactoryStorage.sol b/src/storage/SafeTimelockFactoryStorage.sol index 4d27ed7..c8f30b8 100644 --- a/src/storage/SafeTimelockFactoryStorage.sol +++ b/src/storage/SafeTimelockFactoryStorage.sol @@ -20,7 +20,7 @@ abstract contract SafeTimelockFactoryStorage is ISafeTimelockFactory { address public immutable safeProxyFactory; /// @notice The default fallback handler for Safes - address public immutable defaultFallbackHandler; + address public immutable safeFallbackHandler; /// @notice The TimelockController implementation for minimal proxies address public immutable timelockImplementation; @@ -43,18 +43,18 @@ abstract contract SafeTimelockFactoryStorage is ISafeTimelockFactory { /** * @param _safeSingleton The official Gnosis Safe singleton address * @param _safeProxyFactory The official Gnosis Safe proxy factory address - * @param _defaultFallbackHandler The default fallback handler for Safes + * @param _safeFallbackHandler The default fallback handler for Safes * @param _timelockImplementation The TimelockController implementation for minimal proxies */ constructor( address _safeSingleton, address _safeProxyFactory, - address _defaultFallbackHandler, + address _safeFallbackHandler, address _timelockImplementation ) { safeSingleton = _safeSingleton; safeProxyFactory = _safeProxyFactory; - defaultFallbackHandler = _defaultFallbackHandler; + safeFallbackHandler = _safeFallbackHandler; timelockImplementation = _timelockImplementation; } } diff --git a/test/SafeTimelockFactory.t.sol b/test/SafeTimelockFactory.t.sol index bceffe5..547efd4 100644 --- a/test/SafeTimelockFactory.t.sol +++ b/test/SafeTimelockFactory.t.sol @@ -67,7 +67,7 @@ contract SafeTimelockFactoryTest is Test { SafeTimelockFactory factoryImpl = new SafeTimelockFactory({ _safeSingleton: address(0), _safeProxyFactory: address(mockSafeProxyFactory), - _defaultFallbackHandler: address(0), + _safeFallbackHandler: address(0), _timelockImplementation: address(timelockImpl) }); From 4421d8a7958efb5c26841611d0f8df60994941d3 Mon Sep 17 00:00:00 2001 From: Taras Shchybovyk Date: Tue, 3 Mar 2026 15:09:46 -0800 Subject: [PATCH 08/31] fix: set upgrade.json from version to 1.3.0 sepolia-dev Zeus environment is at 1.3.0, not 1.1.1. --- script/releases/v1.4.0-governance/upgrade.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/script/releases/v1.4.0-governance/upgrade.json b/script/releases/v1.4.0-governance/upgrade.json index 4d974f0..cd1c314 100644 --- a/script/releases/v1.4.0-governance/upgrade.json +++ b/script/releases/v1.4.0-governance/upgrade.json @@ -1,6 +1,6 @@ { "name": "governance", - "from": "1.1.1", + "from": "1.3.0", "to": "1.4.0", "phases": [ { "type": "eoa", "filename": "1-deployContracts.s.sol" }, From abed93fdbc947bbeaf2cbec0bb62cb6c0ae7eb93 Mon Sep 17 00:00:00 2001 From: Taras Shchybovyk Date: Fri, 6 Mar 2026 08:26:07 -0800 Subject: [PATCH 09/31] feat: add governed upgrade flow and Safe-detected ownership transfer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit EOA-owned apps retain direct upgradeApp() → AppUpgraded path. Transferring ownership to a SafeTimelockFactory-deployed Safe or Timelock auto-enables governance mode (governed=true), which blocks direct upgrades and requires the two-step flow: scheduleUpgrade(app, release, delay) → AppUpgradeScheduled (no controller action) executeUpgrade(app, release) → AppUpgraded (controller acts) Release data is committed by hash at schedule time and verified at execution, avoiding storage of dynamic arrays (OZ TimelockController pattern). SafeTimelockFactory wired as an immutable on AppController; Deploy.s.sol auto-deploys a stub factory when none is provided. --- script/Deploy.s.sol | 27 ++++++- script/Parser.s.sol | 11 ++- .../v1.0.4-init/1-deployContracts.s.sol | 3 +- .../1-deployAppControllerImpl.s.sol | 3 +- .../v1.4.0-governance/1-deployContracts.s.sol | 8 +- src/AppController.sol | 47 +++++++++++- src/interfaces/IAppController.sol | 73 +++++++++++++++++++ src/storage/AppControllerStorage.sol | 13 +++- test/utils/ComputeDeployer.sol | 4 +- 9 files changed, 177 insertions(+), 12 deletions(-) diff --git a/script/Deploy.s.sol b/script/Deploy.s.sol index 8cb680e..40b46ea 100644 --- a/script/Deploy.s.sol +++ b/script/Deploy.s.sol @@ -24,6 +24,9 @@ import {ComputeAVSRegistrar} from "../src/ComputeAVSRegistrar.sol"; import {ComputeOperator} from "../src/ComputeOperator.sol"; import {ImageAllowlist} from "../src/ImageAllowlist.sol"; import {IImageAllowlist} from "../src/interfaces/IImageAllowlist.sol"; +import {ISafeTimelockFactory} from "../src/interfaces/ISafeTimelockFactory.sol"; +import {SafeTimelockFactory} from "../src/factories/SafeTimelockFactory.sol"; +import {TimelockControllerImpl} from "../src/governance/TimelockControllerImpl.sol"; contract Deploy is Parser { struct Proxies { @@ -86,6 +89,24 @@ contract Deploy is Parser { ) }); + // Deploy SafeTimelockFactory if not provided + ISafeTimelockFactory safeTimelockFactory = params.safeTimelockFactory; + if (address(safeTimelockFactory) == address(0)) { + TimelockControllerImpl timelockImpl = new TimelockControllerImpl(); + SafeTimelockFactory factoryImpl = new SafeTimelockFactory({ + _safeSingleton: address(0), + _safeProxyFactory: address(0), + _safeFallbackHandler: address(0), + _timelockImplementation: address(timelockImpl) + }); + TransparentUpgradeableProxy factoryProxy = new TransparentUpgradeableProxy( + address(factoryImpl), + address(params.proxyAdmin), + abi.encodeCall(SafeTimelockFactory.initialize, ()) + ); + safeTimelockFactory = ISafeTimelockFactory(address(factoryProxy)); + } + // Deploy App beacon UpgradeableBeacon appBeacon = new UpgradeableBeacon(address(new App(params.version, IPermissionController(params.permissionController)))); @@ -114,7 +135,8 @@ contract Deploy is Parser { _releaseManager: params.releaseManager, _computeAVSRegistrar: IComputeAVSRegistrar(address(proxies.computeAVSRegistrar)), _computeOperator: IComputeOperator(address(proxies.computeOperator)), - _appBeacon: appBeacon + _appBeacon: appBeacon, + _safeTimelockFactory: safeTimelockFactory }), imageAllowlist: new ImageAllowlist() }); @@ -171,7 +193,8 @@ contract Deploy is Parser { computeOperator: IComputeOperator(address(proxies.computeOperator)), computeOperatorImpl: impls.computeOperator, imageAllowlist: IImageAllowlist(address(proxies.imageAllowlist)), - imageAllowlistImpl: impls.imageAllowlist + imageAllowlistImpl: impls.imageAllowlist, + safeTimelockFactory: safeTimelockFactory }); } diff --git a/script/Parser.s.sol b/script/Parser.s.sol index ab590ba..b33a7b7 100644 --- a/script/Parser.s.sol +++ b/script/Parser.s.sol @@ -19,6 +19,8 @@ import {ComputeAVSRegistrar} from "../src/ComputeAVSRegistrar.sol"; import {ComputeOperator} from "../src/ComputeOperator.sol"; import {ImageAllowlist} from "../src/ImageAllowlist.sol"; import {IImageAllowlist} from "../src/interfaces/IImageAllowlist.sol"; +import {ISafeTimelockFactory} from "../src/interfaces/ISafeTimelockFactory.sol"; +import {SafeTimelockFactory} from "../src/factories/SafeTimelockFactory.sol"; contract Parser is Script { struct DeployParams { @@ -34,6 +36,8 @@ contract Parser is Script { string avsMetadataURI; uint32 maxGlobalActiveApps; uint32 adminMaxActiveApps; + // Optional: if address(0), Deploy will deploy a new SafeTimelockFactory with stub Safe addresses + ISafeTimelockFactory safeTimelockFactory; } struct DeployedContracts { @@ -48,6 +52,7 @@ contract Parser is Script { ComputeOperator computeOperatorImpl; IImageAllowlist imageAllowlist; ImageAllowlist imageAllowlistImpl; + ISafeTimelockFactory safeTimelockFactory; } function parseDeployParams(string memory environment) public view returns (DeployParams memory) { @@ -66,7 +71,8 @@ contract Parser is Script { operatorMetadataURI: vm.parseJsonString(json, ".operatorMetadataURI"), avsMetadataURI: vm.parseJsonString(json, ".avsMetadataURI"), maxGlobalActiveApps: uint32(vm.parseJsonUint(json, ".maxGlobalActiveApps")), - adminMaxActiveApps: uint32(vm.parseJsonUint(json, ".adminMaxActiveApps")) + adminMaxActiveApps: uint32(vm.parseJsonUint(json, ".adminMaxActiveApps")), + safeTimelockFactory: ISafeTimelockFactory(address(0)) // Deploy will create one if not in config }); return params; @@ -89,7 +95,8 @@ contract Parser is Script { computeOperator: IComputeOperator(vm.parseJsonAddress(json, ".addresses.computeOperator")), computeOperatorImpl: ComputeOperator(vm.parseJsonAddress(json, ".addresses.computeOperatorImpl")), imageAllowlist: IImageAllowlist(vm.parseJsonAddress(json, ".addresses.imageAllowlist")), - imageAllowlistImpl: ImageAllowlist(vm.parseJsonAddress(json, ".addresses.imageAllowlistImpl")) + imageAllowlistImpl: ImageAllowlist(vm.parseJsonAddress(json, ".addresses.imageAllowlistImpl")), + safeTimelockFactory: ISafeTimelockFactory(vm.parseJsonAddress(json, ".addresses.safeTimelockFactory")) }); return deployedContracts; diff --git a/script/releases/v1.0.4-init/1-deployContracts.s.sol b/script/releases/v1.0.4-init/1-deployContracts.s.sol index 13be774..841cf85 100644 --- a/script/releases/v1.0.4-init/1-deployContracts.s.sol +++ b/script/releases/v1.0.4-init/1-deployContracts.s.sol @@ -77,7 +77,8 @@ contract Deploy is EOADeployer { _releaseManager: Env.releaseManager(), _computeAVSRegistrar: IComputeAVSRegistrar(address(computeAVSRegistrarProxy)), _computeOperator: IComputeOperator(address(computeOperatorProxy)), - _appBeacon: appBeacon + _appBeacon: appBeacon, + _safeTimelockFactory: Env.proxy.safeTimelockFactory() }); // Upgrade proxies using ProxyAdmin diff --git a/script/releases/v1.1.1-app-suspension/1-deployAppControllerImpl.s.sol b/script/releases/v1.1.1-app-suspension/1-deployAppControllerImpl.s.sol index b231135..cfabe16 100644 --- a/script/releases/v1.1.1-app-suspension/1-deployAppControllerImpl.s.sol +++ b/script/releases/v1.1.1-app-suspension/1-deployAppControllerImpl.s.sol @@ -26,7 +26,8 @@ contract DeployAppControllerImpl is EOADeployer { _releaseManager: Env.releaseManager(), _computeAVSRegistrar: Env.proxy.computeAVSRegistrar(), _computeOperator: Env.proxy.computeOperator(), - _appBeacon: Env.beacon.appBeacon() + _appBeacon: Env.beacon.appBeacon(), + _safeTimelockFactory: Env.proxy.safeTimelockFactory() }); // Register new implementation in Env system diff --git a/script/releases/v1.4.0-governance/1-deployContracts.s.sol b/script/releases/v1.4.0-governance/1-deployContracts.s.sol index 32afa7f..eca5004 100644 --- a/script/releases/v1.4.0-governance/1-deployContracts.s.sol +++ b/script/releases/v1.4.0-governance/1-deployContracts.s.sol @@ -48,7 +48,8 @@ contract DeployContracts is EOADeployer { _releaseManager: Env.releaseManager(), _computeAVSRegistrar: Env.proxy.computeAVSRegistrar(), _computeOperator: Env.proxy.computeOperator(), - _appBeacon: Env.beacon.appBeacon() + _appBeacon: Env.beacon.appBeacon(), + _safeTimelockFactory: Env.proxy.safeTimelockFactory() }); deployImpl({name: type(AppController).name, deployedTo: address(newAppControllerImpl)}); @@ -146,6 +147,11 @@ contract DeployContracts is EOADeployer { address(Env.beacon.appBeacon()), "AppController appBeacon mismatch" ); + assertEq( + address(appController.safeTimelockFactory()), + address(Env.proxy.safeTimelockFactory()), + "AppController safeTimelockFactory mismatch" + ); } /// @dev Query and return `proxyAdmin.getProxyImplementation(proxy)` diff --git a/src/AppController.sol b/src/AppController.sol index 5dc3036..5d132ee 100644 --- a/src/AppController.sol +++ b/src/AppController.sol @@ -23,6 +23,7 @@ import {IAppController} from "./interfaces/IAppController.sol"; import {BeaconProxy} from "@openzeppelin/contracts/proxy/beacon/BeaconProxy.sol"; import {IBeacon} from "@openzeppelin/contracts/proxy/beacon/IBeacon.sol"; import {IApp} from "./interfaces/IApp.sol"; +import {ISafeTimelockFactory} from "./interfaces/ISafeTimelockFactory.sol"; contract AppController is Initializable, @@ -72,11 +73,12 @@ contract AppController is IReleaseManager _releaseManager, IComputeAVSRegistrar _computeAVSRegistrar, IComputeOperator _computeOperator, - IBeacon _appBeacon + IBeacon _appBeacon, + ISafeTimelockFactory _safeTimelockFactory ) SignatureUtilsMixin(_version) PermissionControllerMixin(_permissionController) - AppControllerStorage(_releaseManager, _computeOperator, _computeAVSRegistrar, _appBeacon) + AppControllerStorage(_releaseManager, _computeOperator, _computeAVSRegistrar, _appBeacon, _safeTimelockFactory) { _disableInitializers(); } @@ -177,6 +179,42 @@ contract AppController is /// @inheritdoc IAppController function upgradeApp(IApp app, Release calldata release) external appIsActive(app) onlyAdmin(app) returns (uint256) { + require(!_appConfigs[app].governed, DirectUpgradeNotAllowed()); + return _upgradeApp(app, release); + } + + /// @inheritdoc IAppController + function transferOwnership(IApp app, address newOwner) external appExists(app) onlyAdmin(app) { + require(newOwner != address(0), InvalidPermissions()); + address previousOwner = _appConfigs[app].owner; + _appConfigs[app].owner = newOwner; + _appConfigs[app].governed = + safeTimelockFactory.isSafe(newOwner) || safeTimelockFactory.isTimelock(newOwner); + _grantRole(_teamRole(newOwner, TeamRole.ADMIN), newOwner); + emit AppOwnershipTransferred(app, previousOwner, newOwner); + } + + /// @inheritdoc IAppController + function scheduleUpgrade(IApp app, Release calldata release, uint256 delay) + external + appIsActive(app) + onlyAdmin(app) + { + require(_appConfigs[app].governed, GovernanceRequired()); + require(release.rmsRelease.artifacts.length == 1, MoreThanOneArtifact()); + uint256 readyAt = block.timestamp + delay; + _pendingUpgrades[app] = PendingUpgrade({releaseHash: keccak256(abi.encode(release)), readyAt: readyAt}); + emit AppUpgradeScheduled(app, readyAt, release); + } + + /// @inheritdoc IAppController + function executeUpgrade(IApp app, Release calldata release) external appIsActive(app) onlyAdmin(app) returns (uint256) { + require(_appConfigs[app].governed, GovernanceRequired()); + PendingUpgrade memory pending = _pendingUpgrades[app]; + require(pending.readyAt != 0, NoScheduledUpgrade()); + require(block.timestamp >= pending.readyAt, UpgradeNotReady()); + require(keccak256(abi.encode(release)) == pending.releaseHash, ReleaseMismatch()); + delete _pendingUpgrades[app]; return _upgradeApp(app, release); } @@ -534,6 +572,11 @@ contract AppController is /// VIEW FUNCTIONS + /// @inheritdoc IAppController + function getPendingUpgrade(IApp app) external view returns (PendingUpgrade memory) { + return _pendingUpgrades[app]; + } + /// @inheritdoc IAppController function getMaxActiveAppsPerUser(address user) external view returns (uint32) { return _userConfigs[user].maxActiveApps; diff --git a/src/interfaces/IAppController.sol b/src/interfaces/IAppController.sol index 5a9f015..6ea9952 100644 --- a/src/interfaces/IAppController.sol +++ b/src/interfaces/IAppController.sol @@ -3,6 +3,7 @@ pragma solidity ^0.8.27; import {IReleaseManagerTypes} from "@eigenlayer-contracts/src/contracts/interfaces/IReleaseManager.sol"; import {IApp} from "./IApp.sol"; +import {ISafeTimelockFactory} from "./ISafeTimelockFactory.sol"; interface IAppController { /// @notice Thrown when trying to create an app that already exists @@ -32,6 +33,21 @@ interface IAppController { /// @notice Thrown when trying to revoke or renounce the last admin error CannotRevokeLastAdmin(); + /// @notice Thrown when trying to directly upgrade an app that requires governance + error DirectUpgradeNotAllowed(); + + /// @notice Thrown when trying to schedule/execute an upgrade on a non-governed app + error GovernanceRequired(); + + /// @notice Thrown when trying to execute an upgrade before the delay has elapsed + error UpgradeNotReady(); + + /// @notice Thrown when trying to execute with no pending upgrade + error NoScheduledUpgrade(); + + /// @notice Thrown when the release supplied to executeUpgrade does not match the scheduled hash + error ReleaseMismatch(); + /// @notice Emitted when a new app is successfully created event AppCreated(address indexed owner, IApp indexed app, uint32 operatorSetId); @@ -62,6 +78,12 @@ interface IAppController { /// @notice Emitted when an app's metadata URI is updated event AppMetadataURIUpdated(IApp indexed app, string metadataURI); + /// @notice Emitted when app ownership is transferred and governance mode is enabled + event AppOwnershipTransferred(IApp indexed app, address indexed previousOwner, address indexed newOwner); + + /// @notice Emitted when an upgrade is scheduled for a governed app; off-chain controller takes no action + event AppUpgradeScheduled(IApp indexed app, uint256 readyAt, Release release); + /** * @notice Enum for app status */ @@ -109,6 +131,13 @@ interface IAppController { uint32 operatorSetId; uint32 latestReleaseBlockNumber; AppStatus status; + bool governed; // true = direct upgradeApp() blocked; must use scheduleUpgrade + executeUpgrade + } + + /// @notice A pending upgrade scheduled for a governed app + struct PendingUpgrade { + bytes32 releaseHash; // keccak256(abi.encode(release)) — verified at execution time + uint256 readyAt; // block.timestamp after which executeUpgrade() is allowed (0 = none pending) } /// @notice User configuration and state @@ -179,6 +208,45 @@ interface IAppController { */ function upgradeApp(IApp app, Release calldata release) external returns (uint256); + /** + * @notice Transfers app ownership to a new address and enables governance mode + * @param app The app to transfer ownership of + * @param newOwner The new owner address (multisig or timelock) + * @dev Caller must be an ADMIN for the app + * @dev Once transferred, governance mode is permanent: upgradeApp() is blocked + * @dev Grants ADMIN role to newOwner under the new team namespace + */ + function transferOwnership(IApp app, address newOwner) external; + + /** + * @notice Schedules an upgrade for a governed app + * @param app The app to schedule an upgrade for + * @param release The release to upgrade to + * @param delay Seconds from now until the upgrade can be executed + * @dev Caller must be an ADMIN for the app + * @dev App must be in governance mode (governed == true) + * @dev A new schedule call overwrites any existing pending upgrade + */ + function scheduleUpgrade(IApp app, Release calldata release, uint256 delay) external; + + /** + * @notice Executes a previously scheduled upgrade after the delay has elapsed + * @param app The app to execute the pending upgrade for + * @param release The release to upgrade to — must match the hash committed in scheduleUpgrade + * @return releaseId The unique identifier for the published release + * @dev Caller must be an ADMIN for the app + * @dev App must be in governance mode with a pending upgrade whose readyAt <= block.timestamp + * @dev The release is not stored on-chain; callers must retrieve it from the AppUpgradeScheduled event + */ + function executeUpgrade(IApp app, Release calldata release) external returns (uint256); + + /** + * @notice Returns the pending upgrade for a governed app + * @param app The app to query + * @return The PendingUpgrade struct (readyAt == 0 means no pending upgrade) + */ + function getPendingUpgrade(IApp app) external view returns (PendingUpgrade memory); + /** * @notice Updates the metadata URI for an app * @param app The app to update the metadata URI for @@ -229,6 +297,11 @@ interface IAppController { */ function suspend(address account, IApp[] calldata apps) external; + /** + * @notice Returns the SafeTimelockFactory used to detect governed ownership + */ + function safeTimelockFactory() external view returns (ISafeTimelockFactory); + /** * @notice Gets the maximum global active apps limit * @return The maximum number of active apps globally diff --git a/src/storage/AppControllerStorage.sol b/src/storage/AppControllerStorage.sol index 0bf97a4..c34816a 100644 --- a/src/storage/AppControllerStorage.sol +++ b/src/storage/AppControllerStorage.sol @@ -9,6 +9,7 @@ import {IApp} from "../interfaces/IApp.sol"; import {IAppController} from "../interfaces/IAppController.sol"; import {IBeacon} from "@openzeppelin/contracts/proxy/beacon/IBeacon.sol"; import {EnumerableSet} from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol"; +import {ISafeTimelockFactory} from "../interfaces/ISafeTimelockFactory.sol"; abstract contract AppControllerStorage is IAppController { using EnumerableSet for EnumerableSet.AddressSet; @@ -38,6 +39,9 @@ abstract contract AppControllerStorage is IAppController { /// @notice The beacon used for creating App proxies IBeacon public immutable appBeacon; + /// @notice Factory used to verify Safe and Timelock deployments for governance detection + ISafeTimelockFactory public immutable safeTimelockFactory; + /// @notice Set of all created apps EnumerableSet.AddressSet internal _allApps; @@ -47,6 +51,9 @@ abstract contract AppControllerStorage is IAppController { /// @notice User configuration and state mapping(address => UserConfig) internal _userConfigs; + /// @notice Pending upgrades for governed apps + mapping(IApp => PendingUpgrade) internal _pendingUpgrades; + /// @inheritdoc IAppController uint32 public maxGlobalActiveApps; @@ -57,12 +64,14 @@ abstract contract AppControllerStorage is IAppController { IReleaseManager _releaseManager, IComputeOperator _computeOperator, IComputeAVSRegistrar _computeAVSRegistrar, - IBeacon _appBeacon + IBeacon _appBeacon, + ISafeTimelockFactory _safeTimelockFactory ) { releaseManager = _releaseManager; computeOperator = _computeOperator; computeAVSRegistrar = _computeAVSRegistrar; appBeacon = _appBeacon; + safeTimelockFactory = _safeTimelockFactory; } /** @@ -70,5 +79,5 @@ abstract contract AppControllerStorage is IAppController { * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ - uint256[45] private __gap; + uint256[44] private __gap; } diff --git a/test/utils/ComputeDeployer.sol b/test/utils/ComputeDeployer.sol index 37ce85d..894a2f7 100644 --- a/test/utils/ComputeDeployer.sol +++ b/test/utils/ComputeDeployer.sol @@ -20,6 +20,7 @@ import {IStrategy} from "@eigenlayer-contracts/src/contracts/interfaces/IStrateg import {IETHPOSDeposit} from "@eigenlayer-contracts/src/contracts/interfaces/IETHPOSDeposit.sol"; import {IBeacon} from "@openzeppelin/contracts/proxy/beacon/IBeacon.sol"; import {ProxyAdmin} from "@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol"; +import {ISafeTimelockFactory} from "../../src/interfaces/ISafeTimelockFactory.sol"; contract ComputeDeployer is Test { address public developer = address(0x2); @@ -60,7 +61,8 @@ contract ComputeDeployer is Test { operatorMetadataURI: "https://example.com/operator-metadata", avsMetadataURI: "https://example.com/avs-metadata", maxGlobalActiveApps: 100, - adminMaxActiveApps: 100 + adminMaxActiveApps: 100, + safeTimelockFactory: ISafeTimelockFactory(address(0)) // Deploy will create one with stub Safe addresses }); Parser.DeployedContracts memory deployed = deployer.deployForTesting(params); From f7a14583ed4bbe17036522b3192f0d3dd95689ec Mon Sep 17 00:00:00 2001 From: Taras Shchybovyk Date: Fri, 6 Mar 2026 08:45:42 -0800 Subject: [PATCH 10/31] test: add governance flow tests (transferOwnership, scheduleUpgrade, executeUpgrade) --- test/AppController.t.sol | 384 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 384 insertions(+) diff --git a/test/AppController.t.sol b/test/AppController.t.sol index 66e8d09..fa9705d 100644 --- a/test/AppController.t.sol +++ b/test/AppController.t.sol @@ -6,6 +6,7 @@ import {ComputeDeployer} from "./utils/ComputeDeployer.sol"; import {IApp} from "../src/interfaces/IApp.sol"; import {PermissionControllerMixin} from "@eigenlayer-contracts/src/contracts/mixins/PermissionControllerMixin.sol"; import {IReleaseManagerTypes} from "@eigenlayer-contracts/src/contracts/interfaces/IReleaseManager.sol"; +import {ISafeTimelockFactory} from "../src/interfaces/ISafeTimelockFactory.sol"; contract AppControllerTest is ComputeDeployer { bytes32 public constant SALT = keccak256("test_salt"); @@ -16,6 +17,8 @@ contract AppControllerTest is ComputeDeployer { event AppSuspended(IApp indexed app); event AppSuspendedByAdmin(IApp indexed app); event AppMetadataURIUpdated(IApp indexed app, string metadataURI); + event AppOwnershipTransferred(IApp indexed app, address indexed previousOwner, address indexed newOwner); + event AppUpgradeScheduled(IApp indexed app, uint256 readyAt, IAppController.Release release); function setUp() public { _deployContracts(); @@ -1752,4 +1755,385 @@ contract AppControllerTest is ComputeDeployer { "appAdmin should still have ADMIN role after second migration" ); } + + // ========== transferOwnership Tests ========== + + function test_transferOwnership_toEOA_doesNotSetGoverned() public { + vm.prank(developer); + IApp app = appController.createApp(SALT, _assembleRelease()); + + address newOwner = makeAddr("newEOAOwner"); + vm.prank(developer); + appController.transferOwnership(app, newOwner); + + assertEq(appController.getAppOwner(app), newOwner); + // governed NOT set — new owner can still do direct upgrades + vm.prank(newOwner); + appController.upgradeApp(app, _assembleRelease()); + } + + function test_transferOwnership_toSafe_setsGoverned() public { + vm.prank(developer); + IApp app = appController.createApp(SALT, _assembleRelease()); + + address mockSafe = makeAddr("mockSafe"); + _mockIsSafe(mockSafe); + + vm.expectEmit(true, true, true, true); + emit AppOwnershipTransferred(app, developer, mockSafe); + + vm.prank(developer); + appController.transferOwnership(app, mockSafe); + + assertEq(appController.getAppOwner(app), mockSafe); + // governed set — direct upgrade blocked + vm.prank(mockSafe); + vm.expectRevert(IAppController.DirectUpgradeNotAllowed.selector); + appController.upgradeApp(app, _assembleRelease()); + } + + function test_transferOwnership_toTimelock_setsGoverned() public { + vm.prank(developer); + IApp app = appController.createApp(SALT, _assembleRelease()); + + address mockTimelock = makeAddr("mockTimelock"); + _mockIsTimelock(mockTimelock); + + vm.prank(developer); + appController.transferOwnership(app, mockTimelock); + + assertEq(appController.getAppOwner(app), mockTimelock); + vm.prank(mockTimelock); + vm.expectRevert(IAppController.DirectUpgradeNotAllowed.selector); + appController.upgradeApp(app, _assembleRelease()); + } + + function test_transferOwnership_grantsAdminToNewOwner() public { + vm.prank(developer); + IApp app = appController.createApp(SALT, _assembleRelease()); + + address newOwner = makeAddr("newOwner"); + vm.prank(developer); + appController.transferOwnership(app, newOwner); + + assertTrue(appController.hasTeamRole(newOwner, IAppController.TeamRole.ADMIN, newOwner)); + } + + function test_transferOwnership_oldOwnerLosesAdminAccess() public { + vm.prank(developer); + IApp app = appController.createApp(SALT, _assembleRelease()); + + address newOwner = makeAddr("newOwner"); + vm.prank(developer); + appController.transferOwnership(app, newOwner); + + // developer's roles are scoped to the old team namespace; app's owner is now newOwner + vm.prank(developer); + vm.expectRevert(PermissionControllerMixin.InvalidPermissions.selector); + appController.upgradeApp(app, _assembleRelease()); + } + + function test_transferOwnership_requiresAdmin() public { + vm.prank(developer); + IApp app = appController.createApp(SALT, _assembleRelease()); + + address rando = makeAddr("rando"); + vm.prank(rando); + vm.expectRevert(PermissionControllerMixin.InvalidPermissions.selector); + appController.transferOwnership(app, makeAddr("newOwner")); + } + + function test_transferOwnership_zeroAddressReverts() public { + vm.prank(developer); + IApp app = appController.createApp(SALT, _assembleRelease()); + + vm.prank(developer); + vm.expectRevert(PermissionControllerMixin.InvalidPermissions.selector); + appController.transferOwnership(app, address(0)); + } + + // ========== scheduleUpgrade Tests ========== + + function test_scheduleUpgrade() public { + (IApp app, address mockSafe) = _createGovernedApp(); + + IAppController.Release memory release = _assembleRelease(); + uint256 delay = 2 hours; + + vm.prank(mockSafe); + appController.scheduleUpgrade(app, release, delay); + + IAppController.PendingUpgrade memory pending = appController.getPendingUpgrade(app); + assertEq(pending.readyAt, block.timestamp + delay); + assertEq(pending.releaseHash, keccak256(abi.encode(release))); + } + + function test_scheduleUpgrade_emitsEvent() public { + (IApp app, address mockSafe) = _createGovernedApp(); + + IAppController.Release memory release = _assembleRelease(); + uint256 delay = 2 hours; + + // Only verify the indexed app topic; Release data is too dynamic to match exactly + vm.expectEmit(true, false, false, false); + emit AppUpgradeScheduled(app, block.timestamp + delay, release); + + vm.prank(mockSafe); + appController.scheduleUpgrade(app, release, delay); + } + + function test_scheduleUpgrade_requiresGovernance() public { + vm.prank(developer); + IApp app = appController.createApp(SALT, _assembleRelease()); + + vm.prank(developer); + vm.expectRevert(IAppController.GovernanceRequired.selector); + appController.scheduleUpgrade(app, _assembleRelease(), 1 hours); + } + + function test_scheduleUpgrade_requiresAdmin() public { + (IApp app,) = _createGovernedApp(); + + address rando = makeAddr("rando"); + vm.prank(rando); + vm.expectRevert(PermissionControllerMixin.InvalidPermissions.selector); + appController.scheduleUpgrade(app, _assembleRelease(), 1 hours); + } + + function test_scheduleUpgrade_overwritesPending() public { + (IApp app, address mockSafe) = _createGovernedApp(); + + IAppController.Release memory release1 = _assembleRelease(); + IAppController.Release memory release2 = _assembleAltRelease(); + + vm.prank(mockSafe); + appController.scheduleUpgrade(app, release1, 1 hours); + + vm.prank(mockSafe); + appController.scheduleUpgrade(app, release2, 3 hours); + + IAppController.PendingUpgrade memory pending = appController.getPendingUpgrade(app); + assertEq(pending.releaseHash, keccak256(abi.encode(release2))); + assertEq(pending.readyAt, block.timestamp + 3 hours); + } + + function test_scheduleUpgrade_zeroDelay() public { + (IApp app, address mockSafe) = _createGovernedApp(); + + IAppController.Release memory release = _assembleRelease(); + + vm.prank(mockSafe); + appController.scheduleUpgrade(app, release, 0); + + assertEq(appController.getPendingUpgrade(app).readyAt, block.timestamp); + } + + // ========== executeUpgrade Tests ========== + + function test_executeUpgrade() public { + (IApp app, address mockSafe) = _createGovernedApp(); + + IAppController.Release memory release = _assembleRelease(); + uint256 delay = 2 hours; + + vm.prank(mockSafe); + appController.scheduleUpgrade(app, release, delay); + + vm.warp(block.timestamp + delay); + + vm.prank(mockSafe); + uint256 releaseId = appController.executeUpgrade(app, release); + + assertTrue(releaseId > 0); + assertEq(appController.getPendingUpgrade(app).readyAt, 0, "pending upgrade should be cleared"); + assertEq(appController.getAppLatestReleaseBlockNumber(app), uint32(block.number)); + } + + function test_executeUpgrade_atExactDelay() public { + (IApp app, address mockSafe) = _createGovernedApp(); + + IAppController.Release memory release = _assembleRelease(); + uint256 delay = 1 hours; + + vm.prank(mockSafe); + appController.scheduleUpgrade(app, release, delay); + + vm.warp(block.timestamp + delay); // exactly at readyAt + + vm.prank(mockSafe); + appController.executeUpgrade(app, release); // should not revert + } + + function test_executeUpgrade_requiresGovernance() public { + vm.prank(developer); + IApp app = appController.createApp(SALT, _assembleRelease()); + + vm.prank(developer); + vm.expectRevert(IAppController.GovernanceRequired.selector); + appController.executeUpgrade(app, _assembleRelease()); + } + + function test_executeUpgrade_noScheduledUpgrade() public { + (IApp app, address mockSafe) = _createGovernedApp(); + + vm.prank(mockSafe); + vm.expectRevert(IAppController.NoScheduledUpgrade.selector); + appController.executeUpgrade(app, _assembleRelease()); + } + + function test_executeUpgrade_notReady() public { + (IApp app, address mockSafe) = _createGovernedApp(); + + IAppController.Release memory release = _assembleRelease(); + + vm.prank(mockSafe); + appController.scheduleUpgrade(app, release, 2 hours); + + vm.warp(block.timestamp + 2 hours - 1); + + vm.prank(mockSafe); + vm.expectRevert(IAppController.UpgradeNotReady.selector); + appController.executeUpgrade(app, release); + } + + function test_executeUpgrade_releaseMismatch() public { + (IApp app, address mockSafe) = _createGovernedApp(); + + vm.prank(mockSafe); + appController.scheduleUpgrade(app, _assembleRelease(), 1 hours); + + vm.warp(block.timestamp + 1 hours); + + vm.prank(mockSafe); + vm.expectRevert(IAppController.ReleaseMismatch.selector); + appController.executeUpgrade(app, _assembleAltRelease()); + } + + function test_executeUpgrade_requiresAdmin() public { + (IApp app, address mockSafe) = _createGovernedApp(); + + IAppController.Release memory release = _assembleRelease(); + + vm.prank(mockSafe); + appController.scheduleUpgrade(app, release, 1 hours); + + vm.warp(block.timestamp + 1 hours); + + address rando = makeAddr("rando"); + vm.prank(rando); + vm.expectRevert(PermissionControllerMixin.InvalidPermissions.selector); + appController.executeUpgrade(app, release); + } + + function test_executeUpgrade_clearsPendingAfterExecution() public { + (IApp app, address mockSafe) = _createGovernedApp(); + + IAppController.Release memory release = _assembleRelease(); + + vm.prank(mockSafe); + appController.scheduleUpgrade(app, release, 0); + + vm.prank(mockSafe); + appController.executeUpgrade(app, release); + + IAppController.PendingUpgrade memory pending = appController.getPendingUpgrade(app); + assertEq(pending.readyAt, 0); + assertEq(pending.releaseHash, bytes32(0)); + } + + // ========== upgradeApp blocked by governance ========== + + function test_upgradeApp_blockedWhenGoverned() public { + (IApp app, address mockSafe) = _createGovernedApp(); + + vm.prank(mockSafe); + vm.expectRevert(IAppController.DirectUpgradeNotAllowed.selector); + appController.upgradeApp(app, _assembleRelease()); + } + + // ========== Full governance flow ========== + + function test_governance_fullFlow() public { + // 1. EOA creates app — direct upgrade works + vm.prank(developer); + IApp app = appController.createApp(SALT, _assembleRelease()); + + vm.prank(developer); + appController.upgradeApp(app, _assembleRelease()); // no revert + + // 2. Transfer ownership to Safe — governance enabled + address mockSafe = makeAddr("mockSafe"); + _mockIsSafe(mockSafe); + + vm.prank(developer); + appController.transferOwnership(app, mockSafe); + + assertEq(appController.getAppOwner(app), mockSafe); + + // Direct upgrade now blocked + vm.prank(mockSafe); + vm.expectRevert(IAppController.DirectUpgradeNotAllowed.selector); + appController.upgradeApp(app, _assembleRelease()); + + // 3. Schedule upgrade + IAppController.Release memory release = _assembleRelease(); + uint256 delay = 2 hours; + + vm.prank(mockSafe); + appController.scheduleUpgrade(app, release, delay); + + // Can't execute before delay + vm.prank(mockSafe); + vm.expectRevert(IAppController.UpgradeNotReady.selector); + appController.executeUpgrade(app, release); + + // 4. Wait and execute + vm.warp(block.timestamp + delay); + + vm.prank(mockSafe); + uint256 releaseId = appController.executeUpgrade(app, release); + + assertTrue(releaseId > 0); + assertEq(appController.getPendingUpgrade(app).readyAt, 0, "pending upgrade should be cleared"); + } + + // ========== Governance helpers ========== + + function _createGovernedApp() internal returns (IApp app, address mockSafe) { + mockSafe = makeAddr("mockSafe"); + _mockIsSafe(mockSafe); + + vm.prank(developer); + app = appController.createApp(keccak256("governed_salt"), _assembleRelease()); + + vm.prank(developer); + appController.transferOwnership(app, mockSafe); + } + + function _mockIsSafe(address safe) internal { + vm.mockCall( + address(appController.safeTimelockFactory()), + abi.encodeWithSelector(ISafeTimelockFactory.isSafe.selector, safe), + abi.encode(true) + ); + } + + function _mockIsTimelock(address timelock) internal { + vm.mockCall( + address(appController.safeTimelockFactory()), + abi.encodeWithSelector(ISafeTimelockFactory.isTimelock.selector, timelock), + abi.encode(true) + ); + } + + function _assembleAltRelease() internal view returns (IAppController.Release memory) { + IReleaseManagerTypes.Artifact[] memory artifacts = new IReleaseManagerTypes.Artifact[](1); + artifacts[0] = + IReleaseManagerTypes.Artifact({digest: keccak256("alt-digest"), registry: "ipfs://alt-registry"}); + + IReleaseManagerTypes.Release memory rmsRelease = + IReleaseManagerTypes.Release({artifacts: artifacts, upgradeByTime: uint32(block.timestamp + 2 days)}); + + return IAppController.Release({rmsRelease: rmsRelease, publicEnv: "alt", encryptedEnv: "alt"}); + } } From 29aae11be79be2d0cbc3871416af5508cbb14dd7 Mon Sep 17 00:00:00 2001 From: Taras Shchybovyk Date: Fri, 6 Mar 2026 09:16:42 -0800 Subject: [PATCH 11/31] feat: add getAppGoverned view function to IAppController and AppController --- src/AppController.sol | 5 +++++ src/interfaces/IAppController.sol | 7 +++++++ 2 files changed, 12 insertions(+) diff --git a/src/AppController.sol b/src/AppController.sol index 5d132ee..f0840ff 100644 --- a/src/AppController.sol +++ b/src/AppController.sol @@ -617,6 +617,11 @@ contract AppController is return _appConfigs[app].latestReleaseBlockNumber; } + /// @inheritdoc IAppController + function getAppGoverned(IApp app) external view returns (bool) { + return _appConfigs[app].governed; + } + /// @inheritdoc IAppController function getApps(uint256 offset, uint256 limit) external diff --git a/src/interfaces/IAppController.sol b/src/interfaces/IAppController.sol index 6ea9952..1e5bb35 100644 --- a/src/interfaces/IAppController.sol +++ b/src/interfaces/IAppController.sol @@ -364,6 +364,13 @@ interface IAppController { */ function getAppLatestReleaseBlockNumber(IApp app) external view returns (uint32); + /** + * @notice Returns whether an app is in governance mode + * @param app The app to check + * @return True if the app requires scheduleUpgrade + executeUpgrade flow + */ + function getAppGoverned(IApp app) external view returns (bool); + /** * @notice Retrieves a paginated list of all apps and their configurations * @param offset The starting index for pagination (0-based) From 4a416bc1bfc23653ab3ba9e3f410e7fb37b3293d Mon Sep 17 00:00:00 2001 From: Taras Shchybovyk Date: Fri, 6 Mar 2026 11:05:22 -0800 Subject: [PATCH 12/31] =?UTF-8?q?fix:=20governed=20flag=20set=20only=20for?= =?UTF-8?q?=20Safe=20owners,=20not=20Timelock=20=E2=80=94=20Timelock=20enf?= =?UTF-8?q?orces=20delay=20natively?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/AppController.sol | 4 ++-- test/AppController.t.sol | 7 ++++--- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/AppController.sol b/src/AppController.sol index f0840ff..6aef415 100644 --- a/src/AppController.sol +++ b/src/AppController.sol @@ -188,8 +188,8 @@ contract AppController is require(newOwner != address(0), InvalidPermissions()); address previousOwner = _appConfigs[app].owner; _appConfigs[app].owner = newOwner; - _appConfigs[app].governed = - safeTimelockFactory.isSafe(newOwner) || safeTimelockFactory.isTimelock(newOwner); + // Timelocks enforce delays natively — only Safe owners need AppController-level governance + _appConfigs[app].governed = safeTimelockFactory.isSafe(newOwner); _grantRole(_teamRole(newOwner, TeamRole.ADMIN), newOwner); emit AppOwnershipTransferred(app, previousOwner, newOwner); } diff --git a/test/AppController.t.sol b/test/AppController.t.sol index fa9705d..8c48734 100644 --- a/test/AppController.t.sol +++ b/test/AppController.t.sol @@ -1792,7 +1792,7 @@ contract AppControllerTest is ComputeDeployer { appController.upgradeApp(app, _assembleRelease()); } - function test_transferOwnership_toTimelock_setsGoverned() public { + function test_transferOwnership_toTimelock_doesNotSetGoverned() public { vm.prank(developer); IApp app = appController.createApp(SALT, _assembleRelease()); @@ -1803,9 +1803,10 @@ contract AppControllerTest is ComputeDeployer { appController.transferOwnership(app, mockTimelock); assertEq(appController.getAppOwner(app), mockTimelock); + // Timelock enforces its own delay — governed must be false, direct upgrade allowed + assertFalse(appController.getAppGoverned(app), "Timelock owner should not set governed"); vm.prank(mockTimelock); - vm.expectRevert(IAppController.DirectUpgradeNotAllowed.selector); - appController.upgradeApp(app, _assembleRelease()); + appController.upgradeApp(app, _assembleRelease()); // must not revert } function test_transferOwnership_grantsAdminToNewOwner() public { From c1047ad230d68e04c6a116e1b0e8b957196749e1 Mon Sep 17 00:00:00 2001 From: Taras Shchybovyk Date: Thu, 12 Mar 2026 09:48:07 -0700 Subject: [PATCH 13/31] feat: add cancelUpgrade to AppController - cancelUpgrade(app): deletes _pendingUpgrades[app], emits AppUpgradeCancelled - scheduleUpgrade now emits AppUpgradeCancelled when overwriting an existing pending upgrade - Add AppUpgradeCancelled event to IAppController - 8 new tests covering cancel and overwrite-emits-cancel behaviour --- src/AppController.sol | 26 +++-- src/interfaces/IAppController.sol | 42 +++++--- test/AppController.t.sol | 163 +++++++++++++++++++++++++----- 3 files changed, 184 insertions(+), 47 deletions(-) diff --git a/src/AppController.sol b/src/AppController.sol index 6aef415..aa490ee 100644 --- a/src/AppController.sol +++ b/src/AppController.sol @@ -179,7 +179,7 @@ contract AppController is /// @inheritdoc IAppController function upgradeApp(IApp app, Release calldata release) external appIsActive(app) onlyAdmin(app) returns (uint256) { - require(!_appConfigs[app].governed, DirectUpgradeNotAllowed()); + require(!_appConfigs[app].timelocked, TimelockRequired()); return _upgradeApp(app, release); } @@ -188,8 +188,9 @@ contract AppController is require(newOwner != address(0), InvalidPermissions()); address previousOwner = _appConfigs[app].owner; _appConfigs[app].owner = newOwner; - // Timelocks enforce delays natively — only Safe owners need AppController-level governance - _appConfigs[app].governed = safeTimelockFactory.isSafe(newOwner); + // Timelock owner → timelocked = true (must use scheduleUpgrade/executeUpgrade) + // Safe or EOA owner → timelocked = false (upgradeApp directly; Safe handles threshold externally) + _appConfigs[app].timelocked = safeTimelockFactory.isTimelock(newOwner); _grantRole(_teamRole(newOwner, TeamRole.ADMIN), newOwner); emit AppOwnershipTransferred(app, previousOwner, newOwner); } @@ -200,8 +201,11 @@ contract AppController is appIsActive(app) onlyAdmin(app) { - require(_appConfigs[app].governed, GovernanceRequired()); + require(_appConfigs[app].timelocked, NotTimelocked()); require(release.rmsRelease.artifacts.length == 1, MoreThanOneArtifact()); + if (_pendingUpgrades[app].readyAt != 0) { + emit AppUpgradeCancelled(app); + } uint256 readyAt = block.timestamp + delay; _pendingUpgrades[app] = PendingUpgrade({releaseHash: keccak256(abi.encode(release)), readyAt: readyAt}); emit AppUpgradeScheduled(app, readyAt, release); @@ -209,7 +213,7 @@ contract AppController is /// @inheritdoc IAppController function executeUpgrade(IApp app, Release calldata release) external appIsActive(app) onlyAdmin(app) returns (uint256) { - require(_appConfigs[app].governed, GovernanceRequired()); + require(_appConfigs[app].timelocked, NotTimelocked()); PendingUpgrade memory pending = _pendingUpgrades[app]; require(pending.readyAt != 0, NoScheduledUpgrade()); require(block.timestamp >= pending.readyAt, UpgradeNotReady()); @@ -218,6 +222,14 @@ contract AppController is return _upgradeApp(app, release); } + /// @inheritdoc IAppController + function cancelUpgrade(IApp app) external appExists(app) onlyAdmin(app) { + require(_appConfigs[app].timelocked, NotTimelocked()); + require(_pendingUpgrades[app].readyAt != 0, NoScheduledUpgrade()); + delete _pendingUpgrades[app]; + emit AppUpgradeCancelled(app); + } + /// @inheritdoc IAppController function updateAppMetadataURI(IApp app, string calldata metadataURI) external @@ -618,8 +630,8 @@ contract AppController is } /// @inheritdoc IAppController - function getAppGoverned(IApp app) external view returns (bool) { - return _appConfigs[app].governed; + function getAppTimelocked(IApp app) external view returns (bool) { + return _appConfigs[app].timelocked; } /// @inheritdoc IAppController diff --git a/src/interfaces/IAppController.sol b/src/interfaces/IAppController.sol index 1e5bb35..c796516 100644 --- a/src/interfaces/IAppController.sol +++ b/src/interfaces/IAppController.sol @@ -33,11 +33,11 @@ interface IAppController { /// @notice Thrown when trying to revoke or renounce the last admin error CannotRevokeLastAdmin(); - /// @notice Thrown when trying to directly upgrade an app that requires governance - error DirectUpgradeNotAllowed(); + /// @notice Thrown when calling upgradeApp on an app whose owner is a Timelock — use scheduleUpgrade + executeUpgrade + error TimelockRequired(); - /// @notice Thrown when trying to schedule/execute an upgrade on a non-governed app - error GovernanceRequired(); + /// @notice Thrown when calling scheduleUpgrade/executeUpgrade on an app whose owner is not a Timelock + error NotTimelocked(); /// @notice Thrown when trying to execute an upgrade before the delay has elapsed error UpgradeNotReady(); @@ -78,12 +78,15 @@ interface IAppController { /// @notice Emitted when an app's metadata URI is updated event AppMetadataURIUpdated(IApp indexed app, string metadataURI); - /// @notice Emitted when app ownership is transferred and governance mode is enabled + /// @notice Emitted when app ownership is transferred event AppOwnershipTransferred(IApp indexed app, address indexed previousOwner, address indexed newOwner); - /// @notice Emitted when an upgrade is scheduled for a governed app; off-chain controller takes no action + /// @notice Emitted when an upgrade is scheduled for a timelocked app; off-chain controller takes no action event AppUpgradeScheduled(IApp indexed app, uint256 readyAt, Release release); + /// @notice Emitted when a pending upgrade is cancelled for a timelocked app + event AppUpgradeCancelled(IApp indexed app); + /** * @notice Enum for app status */ @@ -131,7 +134,7 @@ interface IAppController { uint32 operatorSetId; uint32 latestReleaseBlockNumber; AppStatus status; - bool governed; // true = direct upgradeApp() blocked; must use scheduleUpgrade + executeUpgrade + bool timelocked; // true = owner is a Timelock; upgradeApp() blocked, must use scheduleUpgrade + executeUpgrade } /// @notice A pending upgrade scheduled for a governed app @@ -219,13 +222,13 @@ interface IAppController { function transferOwnership(IApp app, address newOwner) external; /** - * @notice Schedules an upgrade for a governed app + * @notice Schedules an upgrade for a timelocked app * @param app The app to schedule an upgrade for * @param release The release to upgrade to * @param delay Seconds from now until the upgrade can be executed * @dev Caller must be an ADMIN for the app - * @dev App must be in governance mode (governed == true) - * @dev A new schedule call overwrites any existing pending upgrade + * @dev App owner must be a Timelock (timelocked == true) + * @dev A new schedule call overwrites any existing pending upgrade; emits AppUpgradeCancelled if one existed */ function scheduleUpgrade(IApp app, Release calldata release, uint256 delay) external; @@ -235,13 +238,22 @@ interface IAppController { * @param release The release to upgrade to — must match the hash committed in scheduleUpgrade * @return releaseId The unique identifier for the published release * @dev Caller must be an ADMIN for the app - * @dev App must be in governance mode with a pending upgrade whose readyAt <= block.timestamp + * @dev App owner must be a Timelock with a pending upgrade whose readyAt <= block.timestamp * @dev The release is not stored on-chain; callers must retrieve it from the AppUpgradeScheduled event */ function executeUpgrade(IApp app, Release calldata release) external returns (uint256); /** - * @notice Returns the pending upgrade for a governed app + * @notice Cancels a pending scheduled upgrade for a timelocked app + * @param app The app to cancel the pending upgrade for + * @dev Caller must be an ADMIN for the app + * @dev App owner must be a Timelock (timelocked == true) + * @dev Reverts with NoScheduledUpgrade if there is no pending upgrade to cancel + */ + function cancelUpgrade(IApp app) external; + + /** + * @notice Returns the pending upgrade for a timelocked app * @param app The app to query * @return The PendingUpgrade struct (readyAt == 0 means no pending upgrade) */ @@ -365,11 +377,11 @@ interface IAppController { function getAppLatestReleaseBlockNumber(IApp app) external view returns (uint32); /** - * @notice Returns whether an app is in governance mode + * @notice Returns whether an app owner is a Timelock (requires scheduleUpgrade + executeUpgrade) * @param app The app to check - * @return True if the app requires scheduleUpgrade + executeUpgrade flow + * @return True if the app's owner is a Timelock */ - function getAppGoverned(IApp app) external view returns (bool); + function getAppTimelocked(IApp app) external view returns (bool); /** * @notice Retrieves a paginated list of all apps and their configurations diff --git a/test/AppController.t.sol b/test/AppController.t.sol index 8c48734..fd37906 100644 --- a/test/AppController.t.sol +++ b/test/AppController.t.sol @@ -19,6 +19,7 @@ contract AppControllerTest is ComputeDeployer { event AppMetadataURIUpdated(IApp indexed app, string metadataURI); event AppOwnershipTransferred(IApp indexed app, address indexed previousOwner, address indexed newOwner); event AppUpgradeScheduled(IApp indexed app, uint256 readyAt, IAppController.Release release); + event AppUpgradeCancelled(IApp indexed app); function setUp() public { _deployContracts(); @@ -1772,7 +1773,7 @@ contract AppControllerTest is ComputeDeployer { appController.upgradeApp(app, _assembleRelease()); } - function test_transferOwnership_toSafe_setsGoverned() public { + function test_transferOwnership_toSafe_doesNotSetGoverned() public { vm.prank(developer); IApp app = appController.createApp(SALT, _assembleRelease()); @@ -1786,13 +1787,13 @@ contract AppControllerTest is ComputeDeployer { appController.transferOwnership(app, mockSafe); assertEq(appController.getAppOwner(app), mockSafe); - // governed set — direct upgrade blocked + // Safe handles threshold externally — timelocked must be false, direct upgrade allowed + assertFalse(appController.getAppTimelocked(app), "Safe owner should not set timelocked"); vm.prank(mockSafe); - vm.expectRevert(IAppController.DirectUpgradeNotAllowed.selector); - appController.upgradeApp(app, _assembleRelease()); + appController.upgradeApp(app, _assembleRelease()); // must not revert } - function test_transferOwnership_toTimelock_doesNotSetGoverned() public { + function test_transferOwnership_toTimelock_setsGoverned() public { vm.prank(developer); IApp app = appController.createApp(SALT, _assembleRelease()); @@ -1803,10 +1804,11 @@ contract AppControllerTest is ComputeDeployer { appController.transferOwnership(app, mockTimelock); assertEq(appController.getAppOwner(app), mockTimelock); - // Timelock enforces its own delay — governed must be false, direct upgrade allowed - assertFalse(appController.getAppGoverned(app), "Timelock owner should not set governed"); + // Timelock owner must use scheduleUpgrade/executeUpgrade — direct upgrade blocked + assertTrue(appController.getAppTimelocked(app), "Timelock owner should set timelocked"); vm.prank(mockTimelock); - appController.upgradeApp(app, _assembleRelease()); // must not revert + vm.expectRevert(IAppController.TimelockRequired.selector); + appController.upgradeApp(app, _assembleRelease()); } function test_transferOwnership_grantsAdminToNewOwner() public { @@ -1888,7 +1890,7 @@ contract AppControllerTest is ComputeDeployer { IApp app = appController.createApp(SALT, _assembleRelease()); vm.prank(developer); - vm.expectRevert(IAppController.GovernanceRequired.selector); + vm.expectRevert(IAppController.NotTimelocked.selector); appController.scheduleUpgrade(app, _assembleRelease(), 1 hours); } @@ -1901,6 +1903,20 @@ contract AppControllerTest is ComputeDeployer { appController.scheduleUpgrade(app, _assembleRelease(), 1 hours); } + function test_scheduleUpgrade_overwriteEmitsCancelled() public { + (IApp app, address mockSafe) = _createGovernedApp(); + + vm.prank(mockSafe); + appController.scheduleUpgrade(app, _assembleRelease(), 2 hours); + + // Rescheduling with a pending upgrade should emit AppUpgradeCancelled before AppUpgradeScheduled + vm.expectEmit(true, false, false, false); + emit AppUpgradeCancelled(app); + + vm.prank(mockSafe); + appController.scheduleUpgrade(app, _assembleAltRelease(), 1 hours); + } + function test_scheduleUpgrade_overwritesPending() public { (IApp app, address mockSafe) = _createGovernedApp(); @@ -1970,7 +1986,7 @@ contract AppControllerTest is ComputeDeployer { IApp app = appController.createApp(SALT, _assembleRelease()); vm.prank(developer); - vm.expectRevert(IAppController.GovernanceRequired.selector); + vm.expectRevert(IAppController.NotTimelocked.selector); appController.executeUpgrade(app, _assembleRelease()); } @@ -2042,13 +2058,109 @@ contract AppControllerTest is ComputeDeployer { assertEq(pending.releaseHash, bytes32(0)); } + // ========== cancelUpgrade Tests ========== + + function test_cancelUpgrade() public { + (IApp app, address mockSafe) = _createGovernedApp(); + + IAppController.Release memory release = _assembleRelease(); + + vm.prank(mockSafe); + appController.scheduleUpgrade(app, release, 2 hours); + + vm.prank(mockSafe); + appController.cancelUpgrade(app); + + IAppController.PendingUpgrade memory pending = appController.getPendingUpgrade(app); + assertEq(pending.readyAt, 0); + assertEq(pending.releaseHash, bytes32(0)); + } + + function test_cancelUpgrade_emitsEvent() public { + (IApp app, address mockSafe) = _createGovernedApp(); + + vm.prank(mockSafe); + appController.scheduleUpgrade(app, _assembleRelease(), 2 hours); + + vm.expectEmit(true, false, false, false); + emit AppUpgradeCancelled(app); + + vm.prank(mockSafe); + appController.cancelUpgrade(app); + } + + function test_cancelUpgrade_afterDelayElapsed() public { + (IApp app, address mockSafe) = _createGovernedApp(); + + IAppController.Release memory release = _assembleRelease(); + uint256 delay = 1 hours; + + vm.prank(mockSafe); + appController.scheduleUpgrade(app, release, delay); + + // Advance past readyAt — upgrade is executable but not yet executed + vm.warp(block.timestamp + delay + 1); + + vm.prank(mockSafe); + appController.cancelUpgrade(app); + + IAppController.PendingUpgrade memory pending = appController.getPendingUpgrade(app); + assertEq(pending.readyAt, 0); + } + + function test_cancelUpgrade_requiresGovernance() public { + vm.prank(developer); + IApp app = appController.createApp(SALT, _assembleRelease()); + + vm.prank(developer); + vm.expectRevert(IAppController.NotTimelocked.selector); + appController.cancelUpgrade(app); + } + + function test_cancelUpgrade_noPendingUpgrade() public { + (IApp app, address mockSafe) = _createGovernedApp(); + + vm.prank(mockSafe); + vm.expectRevert(IAppController.NoScheduledUpgrade.selector); + appController.cancelUpgrade(app); + } + + function test_cancelUpgrade_requiresAdmin() public { + (IApp app,) = _createGovernedApp(); + + address rando = makeAddr("rando"); + vm.prank(rando); + vm.expectRevert(PermissionControllerMixin.InvalidPermissions.selector); + appController.cancelUpgrade(app); + } + + function test_cancelUpgrade_allowsReschedule() public { + (IApp app, address mockSafe) = _createGovernedApp(); + + IAppController.Release memory release1 = _assembleRelease(); + + vm.prank(mockSafe); + appController.scheduleUpgrade(app, release1, 2 hours); + + vm.prank(mockSafe); + appController.cancelUpgrade(app); + + // Schedule again with a different release — should succeed + IAppController.Release memory release2 = _assembleAltRelease(); + vm.prank(mockSafe); + appController.scheduleUpgrade(app, release2, 1 hours); + + IAppController.PendingUpgrade memory pending = appController.getPendingUpgrade(app); + assertEq(pending.releaseHash, keccak256(abi.encode(release2))); + } + // ========== upgradeApp blocked by governance ========== function test_upgradeApp_blockedWhenGoverned() public { (IApp app, address mockSafe) = _createGovernedApp(); vm.prank(mockSafe); - vm.expectRevert(IAppController.DirectUpgradeNotAllowed.selector); + vm.expectRevert(IAppController.TimelockRequired.selector); appController.upgradeApp(app, _assembleRelease()); } @@ -2062,36 +2174,37 @@ contract AppControllerTest is ComputeDeployer { vm.prank(developer); appController.upgradeApp(app, _assembleRelease()); // no revert - // 2. Transfer ownership to Safe — governance enabled - address mockSafe = makeAddr("mockSafe"); - _mockIsSafe(mockSafe); + // 2. Transfer ownership to Timelock — timelocked mode enabled + address mockTimelock = makeAddr("mockTimelock"); + _mockIsTimelock(mockTimelock); vm.prank(developer); - appController.transferOwnership(app, mockSafe); + appController.transferOwnership(app, mockTimelock); - assertEq(appController.getAppOwner(app), mockSafe); + assertEq(appController.getAppOwner(app), mockTimelock); + assertTrue(appController.getAppTimelocked(app)); // Direct upgrade now blocked - vm.prank(mockSafe); - vm.expectRevert(IAppController.DirectUpgradeNotAllowed.selector); + vm.prank(mockTimelock); + vm.expectRevert(IAppController.TimelockRequired.selector); appController.upgradeApp(app, _assembleRelease()); // 3. Schedule upgrade IAppController.Release memory release = _assembleRelease(); uint256 delay = 2 hours; - vm.prank(mockSafe); + vm.prank(mockTimelock); appController.scheduleUpgrade(app, release, delay); // Can't execute before delay - vm.prank(mockSafe); + vm.prank(mockTimelock); vm.expectRevert(IAppController.UpgradeNotReady.selector); appController.executeUpgrade(app, release); // 4. Wait and execute vm.warp(block.timestamp + delay); - vm.prank(mockSafe); + vm.prank(mockTimelock); uint256 releaseId = appController.executeUpgrade(app, release); assertTrue(releaseId > 0); @@ -2100,15 +2213,15 @@ contract AppControllerTest is ComputeDeployer { // ========== Governance helpers ========== - function _createGovernedApp() internal returns (IApp app, address mockSafe) { - mockSafe = makeAddr("mockSafe"); - _mockIsSafe(mockSafe); + function _createGovernedApp() internal returns (IApp app, address mockTimelock) { + mockTimelock = makeAddr("mockTimelock"); + _mockIsTimelock(mockTimelock); vm.prank(developer); app = appController.createApp(keccak256("governed_salt"), _assembleRelease()); vm.prank(developer); - appController.transferOwnership(app, mockSafe); + appController.transferOwnership(app, mockTimelock); } function _mockIsSafe(address safe) internal { From 0c98eb031bca515ad4ba6057d9687681a6d24057 Mon Sep 17 00:00:00 2001 From: Taras Shchybovyk Date: Mon, 23 Mar 2026 10:41:15 -0700 Subject: [PATCH 14/31] feat: enforce timelock-only access for transferOwnership, terminateApp, and grantTeamRole(ADMIN) When an app is timelocked, transferOwnership and terminateApp now require msg.sender == owner (i.e. the Timelock itself), preventing any admin from bypassing the queue delay. Similarly, grantTeamRole(ADMIN) now requires the Timelock to be the caller when the team is a Timelock address. Also fixes a pre-existing bug in transferOwnership: activeAppCount was not moved from the old owner to the new owner, causing arithmetic underflow on terminate/suspend after an ownership transfer. --- src/AppController.sol | 22 +++++++ test/AppController.t.sol | 136 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 158 insertions(+) diff --git a/src/AppController.sol b/src/AppController.sol index aa490ee..b76a6b5 100644 --- a/src/AppController.sol +++ b/src/AppController.sol @@ -186,12 +186,23 @@ contract AppController is /// @inheritdoc IAppController function transferOwnership(IApp app, address newOwner) external appExists(app) onlyAdmin(app) { require(newOwner != address(0), InvalidPermissions()); + // When timelocked, only the Timelock (owner) can transfer ownership — any admin calling + // directly would bypass the required queue delay enforced by the Timelock contract. + if (_appConfigs[app].timelocked) { + require(msg.sender == _appConfigs[app].owner, InvalidPermissions()); + } address previousOwner = _appConfigs[app].owner; _appConfigs[app].owner = newOwner; // Timelock owner → timelocked = true (must use scheduleUpgrade/executeUpgrade) // Safe or EOA owner → timelocked = false (upgradeApp directly; Safe handles threshold externally) _appConfigs[app].timelocked = safeTimelockFactory.isTimelock(newOwner); _grantRole(_teamRole(newOwner, TeamRole.ADMIN), newOwner); + // Transfer active app accounting from old owner to new owner so that future + // terminate/suspend calls don't underflow the new owner's counter. + if (_isActive(_appConfigs[app].status)) { + _userConfigs[previousOwner].activeAppCount--; + _userConfigs[newOwner].activeAppCount++; + } emit AppOwnershipTransferred(app, previousOwner, newOwner); } @@ -255,6 +266,11 @@ contract AppController is /// @inheritdoc IAppController function terminateApp(IApp app) external appIsActive(app) onlyAdmin(app) { + // When timelocked, only the Timelock (owner) can terminate — any admin calling + // directly would bypass the required queue delay enforced by the Timelock contract. + if (_appConfigs[app].timelocked) { + require(msg.sender == _appConfigs[app].owner, InvalidPermissions()); + } _terminateApp(app); } @@ -295,6 +311,12 @@ contract AppController is /// @inheritdoc IAppController function grantTeamRole(address team, TeamRole role, address account) external { require(hasRole(_teamRole(team, TeamRole.ADMIN), msg.sender), InvalidPermissions()); + // When the team is a Timelock and an ADMIN is being granted, only the Timelock itself + // can make that change — otherwise any existing admin could add new admins without + // going through the queue delay. + if (role == TeamRole.ADMIN && safeTimelockFactory.isTimelock(team)) { + require(msg.sender == team, InvalidPermissions()); + } _grantRole(_teamRole(team, role), account); } diff --git a/test/AppController.t.sol b/test/AppController.t.sol index fd37906..ed0bcc6 100644 --- a/test/AppController.t.sol +++ b/test/AppController.t.sol @@ -1855,6 +1855,142 @@ contract AppControllerTest is ComputeDeployer { appController.transferOwnership(app, address(0)); } + function test_transferOwnership_timelocked_ownerCanTransfer() public { + (IApp app, address mockTimelock) = _createGovernedApp(); + + address newOwner = makeAddr("newOwner"); + + // The Timelock (owner) can transfer ownership even when timelocked + vm.prank(mockTimelock); + appController.transferOwnership(app, newOwner); + + assertEq(appController.getAppOwner(app), newOwner); + } + + function test_transferOwnership_timelocked_nonOwnerAdminReverts() public { + (IApp app, address mockTimelock) = _createGovernedApp(); + + // Grant ADMIN to a second admin under the Timelock's team namespace + address otherAdmin = makeAddr("otherAdmin"); + vm.prank(mockTimelock); + appController.grantTeamRole(mockTimelock, IAppController.TeamRole.ADMIN, otherAdmin); + + // That admin cannot transfer ownership — must go through the Timelock queue + address newOwner = makeAddr("newOwner"); + vm.prank(otherAdmin); + vm.expectRevert(PermissionControllerMixin.InvalidPermissions.selector); + appController.transferOwnership(app, newOwner); + } + + // ========== terminateApp timelocked enforcement ========== + + function test_terminateApp_timelocked_ownerCanTerminate() public { + (IApp app, address mockTimelock) = _createGovernedApp(); + + // The Timelock (owner) can terminate even when timelocked + vm.prank(mockTimelock); + appController.terminateApp(app); + + assertEq(uint256(appController.getAppStatus(app)), uint256(IAppController.AppStatus.TERMINATED)); + } + + function test_terminateApp_timelocked_nonOwnerAdminReverts() public { + (IApp app, address mockTimelock) = _createGovernedApp(); + + // Grant ADMIN to a second admin under the Timelock's team namespace + address otherAdmin = makeAddr("otherAdminTerminate"); + vm.prank(mockTimelock); + appController.grantTeamRole(mockTimelock, IAppController.TeamRole.ADMIN, otherAdmin); + + // That admin cannot terminate — must go through the Timelock queue + vm.prank(otherAdmin); + vm.expectRevert(PermissionControllerMixin.InvalidPermissions.selector); + appController.terminateApp(app); + } + + function test_terminateApp_nonTimelocked_anyAdminCanTerminate() public { + vm.prank(developer); + IApp app = appController.createApp(keccak256("terminate_eoa"), _assembleRelease()); + + // Grant ADMIN to another user + address otherAdmin = makeAddr("otherAdminEOA"); + vm.prank(developer); + appController.grantTeamRole(developer, IAppController.TeamRole.ADMIN, otherAdmin); + + // Any admin can terminate a non-timelocked app + vm.prank(otherAdmin); + appController.terminateApp(app); + + assertEq(uint256(appController.getAppStatus(app)), uint256(IAppController.AppStatus.TERMINATED)); + } + + // ========== grantTeamRole ADMIN with Timelock team ========== + + function test_grantTeamRole_admin_timelockTeam_timelockCanGrant() public { + (, address mockTimelock) = _createGovernedApp(); + + // The Timelock itself can grant ADMIN roles on its own team + address newAdmin = makeAddr("newAdmin"); + vm.prank(mockTimelock); + appController.grantTeamRole(mockTimelock, IAppController.TeamRole.ADMIN, newAdmin); + + assertTrue(appController.hasTeamRole(mockTimelock, IAppController.TeamRole.ADMIN, newAdmin)); + } + + function test_grantTeamRole_admin_timelockTeam_nonTimelockAdminReverts() public { + (, address mockTimelock) = _createGovernedApp(); + + // Grant ADMIN to a second admin under the Timelock's team namespace + address otherAdmin = makeAddr("otherAdminGrant"); + vm.prank(mockTimelock); + appController.grantTeamRole(mockTimelock, IAppController.TeamRole.ADMIN, otherAdmin); + + // That admin cannot grant further ADMIN roles — must go through the Timelock queue + address newAdmin = makeAddr("newAdminAttempt"); + vm.prank(otherAdmin); + vm.expectRevert(PermissionControllerMixin.InvalidPermissions.selector); + appController.grantTeamRole(mockTimelock, IAppController.TeamRole.ADMIN, newAdmin); + } + + function test_grantTeamRole_nonAdmin_timelockTeam_anyAdminCanGrant() public { + (, address mockTimelock) = _createGovernedApp(); + + // Grant ADMIN to a second admin first + address otherAdmin = makeAddr("otherAdminNonAdmin"); + vm.prank(mockTimelock); + appController.grantTeamRole(mockTimelock, IAppController.TeamRole.ADMIN, otherAdmin); + + // Any admin can grant non-ADMIN roles (PAUSER, DEVELOPER) — no Timelock restriction + address newPauser = makeAddr("newPauser"); + vm.prank(otherAdmin); + appController.grantTeamRole(mockTimelock, IAppController.TeamRole.PAUSER, newPauser); + + assertTrue(appController.hasTeamRole(mockTimelock, IAppController.TeamRole.PAUSER, newPauser)); + + address newDeveloper = makeAddr("newDeveloper"); + vm.prank(otherAdmin); + appController.grantTeamRole(mockTimelock, IAppController.TeamRole.DEVELOPER, newDeveloper); + + assertTrue(appController.hasTeamRole(mockTimelock, IAppController.TeamRole.DEVELOPER, newDeveloper)); + } + + function test_grantTeamRole_admin_nonTimelockTeam_anyAdminCanGrant() public { + // Developer (EOA team) creates an app — no timelock restriction on grantTeamRole ADMIN + vm.prank(developer); + appController.createApp(keccak256("eoa_grant_admin"), _assembleRelease()); + + address anotherAdmin = makeAddr("anotherAdmin"); + vm.prank(developer); + appController.grantTeamRole(developer, IAppController.TeamRole.ADMIN, anotherAdmin); + + // anotherAdmin (not the team address itself) can freely grant ADMIN since team is EOA + address newAdmin = makeAddr("newAdminEOA"); + vm.prank(anotherAdmin); + appController.grantTeamRole(developer, IAppController.TeamRole.ADMIN, newAdmin); + + assertTrue(appController.hasTeamRole(developer, IAppController.TeamRole.ADMIN, newAdmin)); + } + // ========== scheduleUpgrade Tests ========== function test_scheduleUpgrade() public { From 1ad801ce9fdea7fc6f13ccac7fa652d0fe557e74 Mon Sep 17 00:00:00 2001 From: Taras Shchybovyk Date: Wed, 8 Apr 2026 12:56:10 -0700 Subject: [PATCH 15/31] chore: run forge fmt Co-Authored-By: Claude Opus 4.6 (1M context) --- script/Deploy.s.sol | 4 +--- .../releases/v1.4.0-governance/1-deployContracts.s.sol | 8 ++------ .../v1.4.0-governance/2-upgradeAppController.s.sol | 8 ++++---- src/AppController.sol | 7 ++++++- src/interfaces/IAppController.sol | 2 +- test/AppController.t.sol | 3 +-- test/SafeTimelockFactory.t.sol | 10 +++------- 7 files changed, 18 insertions(+), 24 deletions(-) diff --git a/script/Deploy.s.sol b/script/Deploy.s.sol index 40b46ea..1132740 100644 --- a/script/Deploy.s.sol +++ b/script/Deploy.s.sol @@ -100,9 +100,7 @@ contract Deploy is Parser { _timelockImplementation: address(timelockImpl) }); TransparentUpgradeableProxy factoryProxy = new TransparentUpgradeableProxy( - address(factoryImpl), - address(params.proxyAdmin), - abi.encodeCall(SafeTimelockFactory.initialize, ()) + address(factoryImpl), address(params.proxyAdmin), abi.encodeCall(SafeTimelockFactory.initialize, ()) ); safeTimelockFactory = ISafeTimelockFactory(address(factoryProxy)); } diff --git a/script/releases/v1.4.0-governance/1-deployContracts.s.sol b/script/releases/v1.4.0-governance/1-deployContracts.s.sol index eca5004..e73ab99 100644 --- a/script/releases/v1.4.0-governance/1-deployContracts.s.sol +++ b/script/releases/v1.4.0-governance/1-deployContracts.s.sol @@ -104,9 +104,7 @@ contract DeployContracts is EOADeployer { // Validate SafeTimelockFactory impl immutables SafeTimelockFactory safeTimelockFactoryImpl = Env.impl.safeTimelockFactory(); assertEq( - safeTimelockFactoryImpl.safeSingleton(), - Env.safeSingleton(), - "SafeTimelockFactory safeSingleton mismatch" + safeTimelockFactoryImpl.safeSingleton(), Env.safeSingleton(), "SafeTimelockFactory safeSingleton mismatch" ); assertEq( safeTimelockFactoryImpl.safeProxyFactory(), @@ -143,9 +141,7 @@ contract DeployContracts is EOADeployer { "AppController computeOperator mismatch" ); assertEq( - address(appController.appBeacon()), - address(Env.beacon.appBeacon()), - "AppController appBeacon mismatch" + address(appController.appBeacon()), address(Env.beacon.appBeacon()), "AppController appBeacon mismatch" ); assertEq( address(appController.safeTimelockFactory()), diff --git a/script/releases/v1.4.0-governance/2-upgradeAppController.s.sol b/script/releases/v1.4.0-governance/2-upgradeAppController.s.sol index 2053612..b8751d8 100644 --- a/script/releases/v1.4.0-governance/2-upgradeAppController.s.sol +++ b/script/releases/v1.4.0-governance/2-upgradeAppController.s.sol @@ -14,10 +14,10 @@ contract UpgradeAppController is MultisigBuilder, DeployContracts { using Env for *; function _runAsMultisig() internal override prank(Env.computeOpsMultisig()) { - Env.proxyAdmin().upgrade( - ITransparentUpgradeableProxy(address(Env.proxy.appController())), - address(Env.impl.appController()) - ); + Env.proxyAdmin() + .upgrade( + ITransparentUpgradeableProxy(address(Env.proxy.appController())), address(Env.impl.appController()) + ); } function testScript() public virtual override { diff --git a/src/AppController.sol b/src/AppController.sol index b76a6b5..a6aff66 100644 --- a/src/AppController.sol +++ b/src/AppController.sol @@ -223,7 +223,12 @@ contract AppController is } /// @inheritdoc IAppController - function executeUpgrade(IApp app, Release calldata release) external appIsActive(app) onlyAdmin(app) returns (uint256) { + function executeUpgrade(IApp app, Release calldata release) + external + appIsActive(app) + onlyAdmin(app) + returns (uint256) + { require(_appConfigs[app].timelocked, NotTimelocked()); PendingUpgrade memory pending = _pendingUpgrades[app]; require(pending.readyAt != 0, NoScheduledUpgrade()); diff --git a/src/interfaces/IAppController.sol b/src/interfaces/IAppController.sol index c796516..d10aa3f 100644 --- a/src/interfaces/IAppController.sol +++ b/src/interfaces/IAppController.sol @@ -140,7 +140,7 @@ interface IAppController { /// @notice A pending upgrade scheduled for a governed app struct PendingUpgrade { bytes32 releaseHash; // keccak256(abi.encode(release)) — verified at execution time - uint256 readyAt; // block.timestamp after which executeUpgrade() is allowed (0 = none pending) + uint256 readyAt; // block.timestamp after which executeUpgrade() is allowed (0 = none pending) } /// @notice User configuration and state diff --git a/test/AppController.t.sol b/test/AppController.t.sol index ed0bcc6..cde9d31 100644 --- a/test/AppController.t.sol +++ b/test/AppController.t.sol @@ -2378,8 +2378,7 @@ contract AppControllerTest is ComputeDeployer { function _assembleAltRelease() internal view returns (IAppController.Release memory) { IReleaseManagerTypes.Artifact[] memory artifacts = new IReleaseManagerTypes.Artifact[](1); - artifacts[0] = - IReleaseManagerTypes.Artifact({digest: keccak256("alt-digest"), registry: "ipfs://alt-registry"}); + artifacts[0] = IReleaseManagerTypes.Artifact({digest: keccak256("alt-digest"), registry: "ipfs://alt-registry"}); IReleaseManagerTypes.Release memory rmsRelease = IReleaseManagerTypes.Release({artifacts: artifacts, upgradeByTime: uint32(block.timestamp + 2 days)}); diff --git a/test/SafeTimelockFactory.t.sol b/test/SafeTimelockFactory.t.sol index 547efd4..23c1c55 100644 --- a/test/SafeTimelockFactory.t.sol +++ b/test/SafeTimelockFactory.t.sol @@ -75,9 +75,7 @@ contract SafeTimelockFactoryTest is Test { factory = SafeTimelockFactory( address( new TransparentUpgradeableProxy( - address(factoryImpl), - address(proxyAdmin), - abi.encodeCall(SafeTimelockFactory.initialize, ()) + address(factoryImpl), address(proxyAdmin), abi.encodeCall(SafeTimelockFactory.initialize, ()) ) ) ); @@ -217,8 +215,7 @@ contract SafeTimelockFactoryTest is Test { owners[0] = makeAddr("owner1"); owners[1] = makeAddr("owner2"); - ISafeTimelockFactory.SafeConfig memory config = - ISafeTimelockFactory.SafeConfig({owners: owners, threshold: 2}); + ISafeTimelockFactory.SafeConfig memory config = ISafeTimelockFactory.SafeConfig({owners: owners, threshold: 2}); vm.expectEmit(true, false, false, true); emit SafeDeployed(address(this), address(0), owners, 2, SALT); @@ -233,8 +230,7 @@ contract SafeTimelockFactoryTest is Test { address[] memory owners = new address[](1); owners[0] = makeAddr("owner"); - ISafeTimelockFactory.SafeConfig memory config = - ISafeTimelockFactory.SafeConfig({owners: owners, threshold: 1}); + ISafeTimelockFactory.SafeConfig memory config = ISafeTimelockFactory.SafeConfig({owners: owners, threshold: 1}); address predicted = factory.calculateSafeAddress(address(this), config, SALT); address deployed = factory.deploySafe(config, SALT); From 4681f6dc52525579a0f87e6816a13e13699ab18a Mon Sep 17 00:00:00 2001 From: Taras Shchybovyk Date: Wed, 8 Apr 2026 13:03:27 -0700 Subject: [PATCH 16/31] fix: resolve AppConfigStorage rename and missing safeTimelockFactory constructor arg Co-Authored-By: Claude Opus 4.6 (1M context) --- .../v1.4.0-isolated-billing/1-deployAppControllerImpl.s.sol | 3 ++- src/storage/AppControllerStorage.sol | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/script/releases/v1.4.0-isolated-billing/1-deployAppControllerImpl.s.sol b/script/releases/v1.4.0-isolated-billing/1-deployAppControllerImpl.s.sol index 8fd0fe1..da8a541 100644 --- a/script/releases/v1.4.0-isolated-billing/1-deployAppControllerImpl.s.sol +++ b/script/releases/v1.4.0-isolated-billing/1-deployAppControllerImpl.s.sol @@ -26,7 +26,8 @@ contract DeployAppControllerImpl is EOADeployer { _releaseManager: Env.releaseManager(), _computeAVSRegistrar: Env.proxy.computeAVSRegistrar(), _computeOperator: Env.proxy.computeOperator(), - _appBeacon: Env.beacon.appBeacon() + _appBeacon: Env.beacon.appBeacon(), + _safeTimelockFactory: Env.proxy.safeTimelockFactory() }); // Register new implementation in Env system diff --git a/src/storage/AppControllerStorage.sol b/src/storage/AppControllerStorage.sol index c34816a..33d2402 100644 --- a/src/storage/AppControllerStorage.sol +++ b/src/storage/AppControllerStorage.sol @@ -46,7 +46,7 @@ abstract contract AppControllerStorage is IAppController { EnumerableSet.AddressSet internal _allApps; /// @notice The mapping of app address to app storage - mapping(IApp => AppConfigStorage) internal _appConfigs; + mapping(IApp => AppConfig) internal _appConfigs; /// @notice User configuration and state mapping(address => UserConfig) internal _userConfigs; From 395aece5ecb5317eaa463c67cd5d040bb17202ef Mon Sep 17 00:00:00 2001 From: Taras Shchybovyk Date: Wed, 8 Apr 2026 13:08:07 -0700 Subject: [PATCH 17/31] chore: regenerate Go bindings Co-Authored-By: Claude Opus 4.6 (1M context) --- pkg/bindings/v1/AppController/binding.go | 2932 +++++++++++++---- .../v1/SafeTimelockFactory/binding.go | 952 ++++++ .../v1/TimelockControllerImpl/binding.go | 2329 +++++++++++++ pkg/bindings/v2/AppController/binding.go | 1583 +++++++-- .../v2/SafeTimelockFactory/binding.go | 690 ++++ .../v2/TimelockControllerImpl/binding.go | 1323 ++++++++ 6 files changed, 8835 insertions(+), 974 deletions(-) create mode 100644 pkg/bindings/v1/SafeTimelockFactory/binding.go create mode 100644 pkg/bindings/v1/TimelockControllerImpl/binding.go create mode 100644 pkg/bindings/v2/SafeTimelockFactory/binding.go create mode 100644 pkg/bindings/v2/TimelockControllerImpl/binding.go diff --git a/pkg/bindings/v1/AppController/binding.go b/pkg/bindings/v1/AppController/binding.go index 96286c1..459aaf2 100644 --- a/pkg/bindings/v1/AppController/binding.go +++ b/pkg/bindings/v1/AppController/binding.go @@ -31,10 +31,24 @@ var ( // IAppControllerAppConfig is an auto generated low-level Go binding around an user-defined struct. type IAppControllerAppConfig struct { - Creator common.Address + Owner common.Address OperatorSetId uint32 LatestReleaseBlockNumber uint32 Status uint8 + Timelocked bool +} + +// IAppControllerAppRoles is an auto generated low-level Go binding around an user-defined struct. +type IAppControllerAppRoles struct { + App common.Address + IsOwner bool + Roles []uint8 +} + +// IAppControllerPendingUpgrade is an auto generated low-level Go binding around an user-defined struct. +type IAppControllerPendingUpgrade struct { + ReleaseHash [32]byte + ReadyAt *big.Int } // IAppControllerRelease is an auto generated low-level Go binding around an user-defined struct. @@ -58,7 +72,7 @@ type IReleaseManagerTypesRelease struct { // AppControllerMetaData contains all meta data concerning the AppController contract. var AppControllerMetaData = &bind.MetaData{ - ABI: "[{\"type\":\"constructor\",\"inputs\":[{\"name\":\"_version\",\"type\":\"string\",\"internalType\":\"string\"},{\"name\":\"_permissionController\",\"type\":\"address\",\"internalType\":\"contractIPermissionController\"},{\"name\":\"_releaseManager\",\"type\":\"address\",\"internalType\":\"contractIReleaseManager\"},{\"name\":\"_computeAVSRegistrar\",\"type\":\"address\",\"internalType\":\"contractIComputeAVSRegistrar\"},{\"name\":\"_computeOperator\",\"type\":\"address\",\"internalType\":\"contractIComputeOperator\"},{\"name\":\"_appBeacon\",\"type\":\"address\",\"internalType\":\"contractIBeacon\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"API_PERMISSION_TYPEHASH\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"appBeacon\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIBeacon\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"calculateApiPermissionDigestHash\",\"inputs\":[{\"name\":\"permission\",\"type\":\"bytes4\",\"internalType\":\"bytes4\"},{\"name\":\"expiry\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"calculateAppId\",\"inputs\":[{\"name\":\"deployer\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"salt\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"computeAVSRegistrar\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIComputeAVSRegistrar\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"computeOperator\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIComputeOperator\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"createApp\",\"inputs\":[{\"name\":\"salt\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"release\",\"type\":\"tuple\",\"internalType\":\"structIAppController.Release\",\"components\":[{\"name\":\"rmsRelease\",\"type\":\"tuple\",\"internalType\":\"structIReleaseManagerTypes.Release\",\"components\":[{\"name\":\"artifacts\",\"type\":\"tuple[]\",\"internalType\":\"structIReleaseManagerTypes.Artifact[]\",\"components\":[{\"name\":\"digest\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"registry\",\"type\":\"string\",\"internalType\":\"string\"}]},{\"name\":\"upgradeByTime\",\"type\":\"uint32\",\"internalType\":\"uint32\"}]},{\"name\":\"publicEnv\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"encryptedEnv\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]}],\"outputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"createAppWithIsolatedBilling\",\"inputs\":[{\"name\":\"salt\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"release\",\"type\":\"tuple\",\"internalType\":\"structIAppController.Release\",\"components\":[{\"name\":\"rmsRelease\",\"type\":\"tuple\",\"internalType\":\"structIReleaseManagerTypes.Release\",\"components\":[{\"name\":\"artifacts\",\"type\":\"tuple[]\",\"internalType\":\"structIReleaseManagerTypes.Artifact[]\",\"components\":[{\"name\":\"digest\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"registry\",\"type\":\"string\",\"internalType\":\"string\"}]},{\"name\":\"upgradeByTime\",\"type\":\"uint32\",\"internalType\":\"uint32\"}]},{\"name\":\"publicEnv\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"encryptedEnv\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]}],\"outputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"domainSeparator\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getActiveAppCount\",\"inputs\":[{\"name\":\"user\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getAppCreator\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getAppLatestReleaseBlockNumber\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getAppOperatorSetId\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getAppStatus\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint8\",\"internalType\":\"enumIAppController.AppStatus\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getApps\",\"inputs\":[{\"name\":\"offset\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"limit\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"apps\",\"type\":\"address[]\",\"internalType\":\"contractIApp[]\"},{\"name\":\"appConfigsMem\",\"type\":\"tuple[]\",\"internalType\":\"structIAppController.AppConfig[]\",\"components\":[{\"name\":\"creator\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"operatorSetId\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"latestReleaseBlockNumber\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"status\",\"type\":\"uint8\",\"internalType\":\"enumIAppController.AppStatus\"}]}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getAppsByBillingAccount\",\"inputs\":[{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"offset\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"limit\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"apps\",\"type\":\"address[]\",\"internalType\":\"contractIApp[]\"},{\"name\":\"appConfigsMem\",\"type\":\"tuple[]\",\"internalType\":\"structIAppController.AppConfig[]\",\"components\":[{\"name\":\"creator\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"operatorSetId\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"latestReleaseBlockNumber\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"status\",\"type\":\"uint8\",\"internalType\":\"enumIAppController.AppStatus\"}]}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getAppsByCreator\",\"inputs\":[{\"name\":\"creator\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"offset\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"limit\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"apps\",\"type\":\"address[]\",\"internalType\":\"contractIApp[]\"},{\"name\":\"appConfigsMem\",\"type\":\"tuple[]\",\"internalType\":\"structIAppController.AppConfig[]\",\"components\":[{\"name\":\"creator\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"operatorSetId\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"latestReleaseBlockNumber\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"status\",\"type\":\"uint8\",\"internalType\":\"enumIAppController.AppStatus\"}]}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getAppsByDeveloper\",\"inputs\":[{\"name\":\"developer\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"offset\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"limit\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"apps\",\"type\":\"address[]\",\"internalType\":\"contractIApp[]\"},{\"name\":\"appConfigsMem\",\"type\":\"tuple[]\",\"internalType\":\"structIAppController.AppConfig[]\",\"components\":[{\"name\":\"creator\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"operatorSetId\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"latestReleaseBlockNumber\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"status\",\"type\":\"uint8\",\"internalType\":\"enumIAppController.AppStatus\"}]}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getBillingAccount\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getBillingType\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint8\",\"internalType\":\"enumIAppController.BillingType\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getMaxActiveAppsPerUser\",\"inputs\":[{\"name\":\"user\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"globalActiveAppCount\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"initialize\",\"inputs\":[{\"name\":\"admin\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"maxGlobalActiveApps\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"permissionController\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIPermissionController\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"releaseManager\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIReleaseManager\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"setMaxActiveAppsPerUser\",\"inputs\":[{\"name\":\"user\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"limit\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"setMaxGlobalActiveApps\",\"inputs\":[{\"name\":\"limit\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"startApp\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"stopApp\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"suspend\",\"inputs\":[{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"apps\",\"type\":\"address[]\",\"internalType\":\"contractIApp[]\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"terminateApp\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"terminateAppByAdmin\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"updateAppMetadataURI\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"},{\"name\":\"metadataURI\",\"type\":\"string\",\"internalType\":\"string\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"upgradeApp\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"},{\"name\":\"release\",\"type\":\"tuple\",\"internalType\":\"structIAppController.Release\",\"components\":[{\"name\":\"rmsRelease\",\"type\":\"tuple\",\"internalType\":\"structIReleaseManagerTypes.Release\",\"components\":[{\"name\":\"artifacts\",\"type\":\"tuple[]\",\"internalType\":\"structIReleaseManagerTypes.Artifact[]\",\"components\":[{\"name\":\"digest\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"registry\",\"type\":\"string\",\"internalType\":\"string\"}]},{\"name\":\"upgradeByTime\",\"type\":\"uint32\",\"internalType\":\"uint32\"}]},{\"name\":\"publicEnv\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"encryptedEnv\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"version\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"string\",\"internalType\":\"string\"}],\"stateMutability\":\"view\"},{\"type\":\"event\",\"name\":\"AppCreated\",\"inputs\":[{\"name\":\"creator\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"app\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"contractIApp\"},{\"name\":\"operatorSetId\",\"type\":\"uint32\",\"indexed\":false,\"internalType\":\"uint32\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"AppMetadataURIUpdated\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"contractIApp\"},{\"name\":\"metadataURI\",\"type\":\"string\",\"indexed\":false,\"internalType\":\"string\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"AppStarted\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"contractIApp\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"AppStopped\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"contractIApp\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"AppSuspended\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"contractIApp\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"AppTerminated\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"contractIApp\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"AppTerminatedByAdmin\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"contractIApp\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"AppUpgraded\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"contractIApp\"},{\"name\":\"rmsReleaseId\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"release\",\"type\":\"tuple\",\"indexed\":false,\"internalType\":\"structIAppController.Release\",\"components\":[{\"name\":\"rmsRelease\",\"type\":\"tuple\",\"internalType\":\"structIReleaseManagerTypes.Release\",\"components\":[{\"name\":\"artifacts\",\"type\":\"tuple[]\",\"internalType\":\"structIReleaseManagerTypes.Artifact[]\",\"components\":[{\"name\":\"digest\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"registry\",\"type\":\"string\",\"internalType\":\"string\"}]},{\"name\":\"upgradeByTime\",\"type\":\"uint32\",\"internalType\":\"uint32\"}]},{\"name\":\"publicEnv\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"encryptedEnv\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"GlobalMaxActiveAppsSet\",\"inputs\":[{\"name\":\"limit\",\"type\":\"uint32\",\"indexed\":false,\"internalType\":\"uint32\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Initialized\",\"inputs\":[{\"name\":\"version\",\"type\":\"uint8\",\"indexed\":false,\"internalType\":\"uint8\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"MaxActiveAppsSet\",\"inputs\":[{\"name\":\"user\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"limit\",\"type\":\"uint32\",\"indexed\":false,\"internalType\":\"uint32\"}],\"anonymous\":false},{\"type\":\"error\",\"name\":\"AccountHasActiveApps\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"AppAlreadyExists\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"AppDoesNotExist\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"GlobalMaxActiveAppsExceeded\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidAppStatus\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidPermissions\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidReleaseMetadataURI\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidShortString\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidSignature\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"MaxActiveAppsExceeded\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"MoreThanOneArtifact\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"SignatureExpired\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"StringTooLong\",\"inputs\":[{\"name\":\"str\",\"type\":\"string\",\"internalType\":\"string\"}]}]", + ABI: "[{\"type\":\"constructor\",\"inputs\":[{\"name\":\"_version\",\"type\":\"string\",\"internalType\":\"string\"},{\"name\":\"_permissionController\",\"type\":\"address\",\"internalType\":\"contractIPermissionController\"},{\"name\":\"_releaseManager\",\"type\":\"address\",\"internalType\":\"contractIReleaseManager\"},{\"name\":\"_computeAVSRegistrar\",\"type\":\"address\",\"internalType\":\"contractIComputeAVSRegistrar\"},{\"name\":\"_computeOperator\",\"type\":\"address\",\"internalType\":\"contractIComputeOperator\"},{\"name\":\"_appBeacon\",\"type\":\"address\",\"internalType\":\"contractIBeacon\"},{\"name\":\"_safeTimelockFactory\",\"type\":\"address\",\"internalType\":\"contractISafeTimelockFactory\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"API_PERMISSION_TYPEHASH\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"DEFAULT_ADMIN_ROLE\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"appBeacon\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIBeacon\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"calculateApiPermissionDigestHash\",\"inputs\":[{\"name\":\"permission\",\"type\":\"bytes4\",\"internalType\":\"bytes4\"},{\"name\":\"expiry\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"calculateAppId\",\"inputs\":[{\"name\":\"deployer\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"salt\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"cancelUpgrade\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"computeAVSRegistrar\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIComputeAVSRegistrar\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"computeOperator\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIComputeOperator\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"createApp\",\"inputs\":[{\"name\":\"salt\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"release\",\"type\":\"tuple\",\"internalType\":\"structIAppController.Release\",\"components\":[{\"name\":\"rmsRelease\",\"type\":\"tuple\",\"internalType\":\"structIReleaseManagerTypes.Release\",\"components\":[{\"name\":\"artifacts\",\"type\":\"tuple[]\",\"internalType\":\"structIReleaseManagerTypes.Artifact[]\",\"components\":[{\"name\":\"digest\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"registry\",\"type\":\"string\",\"internalType\":\"string\"}]},{\"name\":\"upgradeByTime\",\"type\":\"uint32\",\"internalType\":\"uint32\"}]},{\"name\":\"publicEnv\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"encryptedEnv\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]}],\"outputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"createAppForTeam\",\"inputs\":[{\"name\":\"team\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"salt\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"release\",\"type\":\"tuple\",\"internalType\":\"structIAppController.Release\",\"components\":[{\"name\":\"rmsRelease\",\"type\":\"tuple\",\"internalType\":\"structIReleaseManagerTypes.Release\",\"components\":[{\"name\":\"artifacts\",\"type\":\"tuple[]\",\"internalType\":\"structIReleaseManagerTypes.Artifact[]\",\"components\":[{\"name\":\"digest\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"registry\",\"type\":\"string\",\"internalType\":\"string\"}]},{\"name\":\"upgradeByTime\",\"type\":\"uint32\",\"internalType\":\"uint32\"}]},{\"name\":\"publicEnv\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"encryptedEnv\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]}],\"outputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"domainSeparator\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"executeUpgrade\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"},{\"name\":\"release\",\"type\":\"tuple\",\"internalType\":\"structIAppController.Release\",\"components\":[{\"name\":\"rmsRelease\",\"type\":\"tuple\",\"internalType\":\"structIReleaseManagerTypes.Release\",\"components\":[{\"name\":\"artifacts\",\"type\":\"tuple[]\",\"internalType\":\"structIReleaseManagerTypes.Artifact[]\",\"components\":[{\"name\":\"digest\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"registry\",\"type\":\"string\",\"internalType\":\"string\"}]},{\"name\":\"upgradeByTime\",\"type\":\"uint32\",\"internalType\":\"uint32\"}]},{\"name\":\"publicEnv\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"encryptedEnv\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"getActiveAppCount\",\"inputs\":[{\"name\":\"user\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getAppLatestReleaseBlockNumber\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getAppOperatorSetId\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getAppOwner\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getAppStatus\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint8\",\"internalType\":\"enumIAppController.AppStatus\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getAppTimelocked\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getApps\",\"inputs\":[{\"name\":\"offset\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"limit\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"apps\",\"type\":\"address[]\",\"internalType\":\"contractIApp[]\"},{\"name\":\"appConfigsMem\",\"type\":\"tuple[]\",\"internalType\":\"structIAppController.AppConfig[]\",\"components\":[{\"name\":\"owner\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"operatorSetId\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"latestReleaseBlockNumber\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"status\",\"type\":\"uint8\",\"internalType\":\"enumIAppController.AppStatus\"},{\"name\":\"timelocked\",\"type\":\"bool\",\"internalType\":\"bool\"}]}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getAppsByCreator\",\"inputs\":[{\"name\":\"creator\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"offset\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"limit\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"apps\",\"type\":\"address[]\",\"internalType\":\"contractIApp[]\"},{\"name\":\"appConfigsMem\",\"type\":\"tuple[]\",\"internalType\":\"structIAppController.AppConfig[]\",\"components\":[{\"name\":\"owner\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"operatorSetId\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"latestReleaseBlockNumber\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"status\",\"type\":\"uint8\",\"internalType\":\"enumIAppController.AppStatus\"},{\"name\":\"timelocked\",\"type\":\"bool\",\"internalType\":\"bool\"}]}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getAppsByDeveloper\",\"inputs\":[{\"name\":\"developer\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"offset\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"limit\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"apps\",\"type\":\"address[]\",\"internalType\":\"contractIApp[]\"},{\"name\":\"appConfigsMem\",\"type\":\"tuple[]\",\"internalType\":\"structIAppController.AppConfig[]\",\"components\":[{\"name\":\"owner\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"operatorSetId\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"latestReleaseBlockNumber\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"status\",\"type\":\"uint8\",\"internalType\":\"enumIAppController.AppStatus\"},{\"name\":\"timelocked\",\"type\":\"bool\",\"internalType\":\"bool\"}]}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getAppsForAccount\",\"inputs\":[{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"offset\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"limit\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"appRoles\",\"type\":\"tuple[]\",\"internalType\":\"structIAppController.AppRoles[]\",\"components\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"},{\"name\":\"isOwner\",\"type\":\"bool\",\"internalType\":\"bool\"},{\"name\":\"roles\",\"type\":\"uint8[]\",\"internalType\":\"enumIAppController.TeamRole[]\"}]}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getMaxActiveAppsPerUser\",\"inputs\":[{\"name\":\"user\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getPendingUpgrade\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"outputs\":[{\"name\":\"\",\"type\":\"tuple\",\"internalType\":\"structIAppController.PendingUpgrade\",\"components\":[{\"name\":\"releaseHash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"readyAt\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getRoleAdmin\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getRoleMember\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"index\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getRoleMemberCount\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getTeamRoleMember\",\"inputs\":[{\"name\":\"team\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"role\",\"type\":\"uint8\",\"internalType\":\"enumIAppController.TeamRole\"},{\"name\":\"index\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getTeamRoleMemberCount\",\"inputs\":[{\"name\":\"team\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"role\",\"type\":\"uint8\",\"internalType\":\"enumIAppController.TeamRole\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getTeamRoleMembers\",\"inputs\":[{\"name\":\"team\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"role\",\"type\":\"uint8\",\"internalType\":\"enumIAppController.TeamRole\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address[]\",\"internalType\":\"address[]\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"globalActiveAppCount\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"grantRole\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"grantTeamRole\",\"inputs\":[{\"name\":\"team\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"role\",\"type\":\"uint8\",\"internalType\":\"enumIAppController.TeamRole\"},{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"hasRole\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"hasTeamRole\",\"inputs\":[{\"name\":\"team\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"role\",\"type\":\"uint8\",\"internalType\":\"enumIAppController.TeamRole\"},{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"initialize\",\"inputs\":[{\"name\":\"admin\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"maxGlobalActiveApps\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"migrateAdmins\",\"inputs\":[{\"name\":\"apps\",\"type\":\"address[]\",\"internalType\":\"contractIApp[]\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"permissionController\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIPermissionController\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"releaseManager\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIReleaseManager\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"renounceRole\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"renounceTeamRole\",\"inputs\":[{\"name\":\"team\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"role\",\"type\":\"uint8\",\"internalType\":\"enumIAppController.TeamRole\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"revokeRole\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"revokeTeamRole\",\"inputs\":[{\"name\":\"team\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"role\",\"type\":\"uint8\",\"internalType\":\"enumIAppController.TeamRole\"},{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"safeTimelockFactory\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractISafeTimelockFactory\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"scheduleUpgrade\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"},{\"name\":\"release\",\"type\":\"tuple\",\"internalType\":\"structIAppController.Release\",\"components\":[{\"name\":\"rmsRelease\",\"type\":\"tuple\",\"internalType\":\"structIReleaseManagerTypes.Release\",\"components\":[{\"name\":\"artifacts\",\"type\":\"tuple[]\",\"internalType\":\"structIReleaseManagerTypes.Artifact[]\",\"components\":[{\"name\":\"digest\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"registry\",\"type\":\"string\",\"internalType\":\"string\"}]},{\"name\":\"upgradeByTime\",\"type\":\"uint32\",\"internalType\":\"uint32\"}]},{\"name\":\"publicEnv\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"encryptedEnv\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]},{\"name\":\"delay\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"setMaxActiveAppsPerUser\",\"inputs\":[{\"name\":\"user\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"limit\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"setMaxGlobalActiveApps\",\"inputs\":[{\"name\":\"limit\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"startApp\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"stopApp\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"supportsInterface\",\"inputs\":[{\"name\":\"interfaceId\",\"type\":\"bytes4\",\"internalType\":\"bytes4\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"suspend\",\"inputs\":[{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"apps\",\"type\":\"address[]\",\"internalType\":\"contractIApp[]\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"terminateApp\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"terminateAppByAdmin\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"transferOwnership\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"},{\"name\":\"newOwner\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"updateAppMetadataURI\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"},{\"name\":\"metadataURI\",\"type\":\"string\",\"internalType\":\"string\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"upgradeApp\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"},{\"name\":\"release\",\"type\":\"tuple\",\"internalType\":\"structIAppController.Release\",\"components\":[{\"name\":\"rmsRelease\",\"type\":\"tuple\",\"internalType\":\"structIReleaseManagerTypes.Release\",\"components\":[{\"name\":\"artifacts\",\"type\":\"tuple[]\",\"internalType\":\"structIReleaseManagerTypes.Artifact[]\",\"components\":[{\"name\":\"digest\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"registry\",\"type\":\"string\",\"internalType\":\"string\"}]},{\"name\":\"upgradeByTime\",\"type\":\"uint32\",\"internalType\":\"uint32\"}]},{\"name\":\"publicEnv\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"encryptedEnv\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"version\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"string\",\"internalType\":\"string\"}],\"stateMutability\":\"view\"},{\"type\":\"event\",\"name\":\"AppCreated\",\"inputs\":[{\"name\":\"owner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"app\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"contractIApp\"},{\"name\":\"operatorSetId\",\"type\":\"uint32\",\"indexed\":false,\"internalType\":\"uint32\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"AppMetadataURIUpdated\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"contractIApp\"},{\"name\":\"metadataURI\",\"type\":\"string\",\"indexed\":false,\"internalType\":\"string\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"AppOwnershipTransferred\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"contractIApp\"},{\"name\":\"previousOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"newOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"AppStarted\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"contractIApp\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"AppStopped\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"contractIApp\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"AppSuspended\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"contractIApp\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"AppTerminated\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"contractIApp\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"AppTerminatedByAdmin\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"contractIApp\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"AppUpgradeCancelled\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"contractIApp\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"AppUpgradeScheduled\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"contractIApp\"},{\"name\":\"readyAt\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"release\",\"type\":\"tuple\",\"indexed\":false,\"internalType\":\"structIAppController.Release\",\"components\":[{\"name\":\"rmsRelease\",\"type\":\"tuple\",\"internalType\":\"structIReleaseManagerTypes.Release\",\"components\":[{\"name\":\"artifacts\",\"type\":\"tuple[]\",\"internalType\":\"structIReleaseManagerTypes.Artifact[]\",\"components\":[{\"name\":\"digest\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"registry\",\"type\":\"string\",\"internalType\":\"string\"}]},{\"name\":\"upgradeByTime\",\"type\":\"uint32\",\"internalType\":\"uint32\"}]},{\"name\":\"publicEnv\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"encryptedEnv\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"AppUpgraded\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"contractIApp\"},{\"name\":\"rmsReleaseId\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"release\",\"type\":\"tuple\",\"indexed\":false,\"internalType\":\"structIAppController.Release\",\"components\":[{\"name\":\"rmsRelease\",\"type\":\"tuple\",\"internalType\":\"structIReleaseManagerTypes.Release\",\"components\":[{\"name\":\"artifacts\",\"type\":\"tuple[]\",\"internalType\":\"structIReleaseManagerTypes.Artifact[]\",\"components\":[{\"name\":\"digest\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"registry\",\"type\":\"string\",\"internalType\":\"string\"}]},{\"name\":\"upgradeByTime\",\"type\":\"uint32\",\"internalType\":\"uint32\"}]},{\"name\":\"publicEnv\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"encryptedEnv\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"GlobalMaxActiveAppsSet\",\"inputs\":[{\"name\":\"limit\",\"type\":\"uint32\",\"indexed\":false,\"internalType\":\"uint32\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Initialized\",\"inputs\":[{\"name\":\"version\",\"type\":\"uint8\",\"indexed\":false,\"internalType\":\"uint8\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"MaxActiveAppsSet\",\"inputs\":[{\"name\":\"user\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"limit\",\"type\":\"uint32\",\"indexed\":false,\"internalType\":\"uint32\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"RoleAdminChanged\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"previousAdminRole\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"newAdminRole\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"RoleGranted\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"account\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"sender\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"RoleRevoked\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"account\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"sender\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"error\",\"name\":\"AccountHasActiveApps\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"AppAlreadyExists\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"AppDoesNotExist\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"CannotRevokeLastAdmin\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"GlobalMaxActiveAppsExceeded\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidAppStatus\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidPermissions\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidReleaseMetadataURI\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidShortString\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidSignature\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"MaxActiveAppsExceeded\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"MoreThanOneArtifact\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"NoScheduledUpgrade\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"NotTimelocked\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"ReleaseMismatch\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"SignatureExpired\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"StringTooLong\",\"inputs\":[{\"name\":\"str\",\"type\":\"string\",\"internalType\":\"string\"}]},{\"type\":\"error\",\"name\":\"TimelockRequired\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"UpgradeNotReady\",\"inputs\":[]}]", } // AppControllerABI is the input ABI used to generate the binding from. @@ -238,6 +252,37 @@ func (_AppController *AppControllerCallerSession) APIPERMISSIONTYPEHASH() ([32]b return _AppController.Contract.APIPERMISSIONTYPEHASH(&_AppController.CallOpts) } +// DEFAULTADMINROLE is a free data retrieval call binding the contract method 0xa217fddf. +// +// Solidity: function DEFAULT_ADMIN_ROLE() view returns(bytes32) +func (_AppController *AppControllerCaller) DEFAULTADMINROLE(opts *bind.CallOpts) ([32]byte, error) { + var out []interface{} + err := _AppController.contract.Call(opts, &out, "DEFAULT_ADMIN_ROLE") + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// DEFAULTADMINROLE is a free data retrieval call binding the contract method 0xa217fddf. +// +// Solidity: function DEFAULT_ADMIN_ROLE() view returns(bytes32) +func (_AppController *AppControllerSession) DEFAULTADMINROLE() ([32]byte, error) { + return _AppController.Contract.DEFAULTADMINROLE(&_AppController.CallOpts) +} + +// DEFAULTADMINROLE is a free data retrieval call binding the contract method 0xa217fddf. +// +// Solidity: function DEFAULT_ADMIN_ROLE() view returns(bytes32) +func (_AppController *AppControllerCallerSession) DEFAULTADMINROLE() ([32]byte, error) { + return _AppController.Contract.DEFAULTADMINROLE(&_AppController.CallOpts) +} + // AppBeacon is a free data retrieval call binding the contract method 0x8a52d0b5. // // Solidity: function appBeacon() view returns(address) @@ -455,37 +500,6 @@ func (_AppController *AppControllerCallerSession) GetActiveAppCount(user common. return _AppController.Contract.GetActiveAppCount(&_AppController.CallOpts, user) } -// GetAppCreator is a free data retrieval call binding the contract method 0x67962d48. -// -// Solidity: function getAppCreator(address app) view returns(address) -func (_AppController *AppControllerCaller) GetAppCreator(opts *bind.CallOpts, app common.Address) (common.Address, error) { - var out []interface{} - err := _AppController.contract.Call(opts, &out, "getAppCreator", app) - - if err != nil { - return *new(common.Address), err - } - - out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) - - return out0, err - -} - -// GetAppCreator is a free data retrieval call binding the contract method 0x67962d48. -// -// Solidity: function getAppCreator(address app) view returns(address) -func (_AppController *AppControllerSession) GetAppCreator(app common.Address) (common.Address, error) { - return _AppController.Contract.GetAppCreator(&_AppController.CallOpts, app) -} - -// GetAppCreator is a free data retrieval call binding the contract method 0x67962d48. -// -// Solidity: function getAppCreator(address app) view returns(address) -func (_AppController *AppControllerCallerSession) GetAppCreator(app common.Address) (common.Address, error) { - return _AppController.Contract.GetAppCreator(&_AppController.CallOpts, app) -} - // GetAppLatestReleaseBlockNumber is a free data retrieval call binding the contract method 0x9ffbdce6. // // Solidity: function getAppLatestReleaseBlockNumber(address app) view returns(uint32) @@ -548,6 +562,37 @@ func (_AppController *AppControllerCallerSession) GetAppOperatorSetId(app common return _AppController.Contract.GetAppOperatorSetId(&_AppController.CallOpts, app) } +// GetAppOwner is a free data retrieval call binding the contract method 0xffb42b51. +// +// Solidity: function getAppOwner(address app) view returns(address) +func (_AppController *AppControllerCaller) GetAppOwner(opts *bind.CallOpts, app common.Address) (common.Address, error) { + var out []interface{} + err := _AppController.contract.Call(opts, &out, "getAppOwner", app) + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// GetAppOwner is a free data retrieval call binding the contract method 0xffb42b51. +// +// Solidity: function getAppOwner(address app) view returns(address) +func (_AppController *AppControllerSession) GetAppOwner(app common.Address) (common.Address, error) { + return _AppController.Contract.GetAppOwner(&_AppController.CallOpts, app) +} + +// GetAppOwner is a free data retrieval call binding the contract method 0xffb42b51. +// +// Solidity: function getAppOwner(address app) view returns(address) +func (_AppController *AppControllerCallerSession) GetAppOwner(app common.Address) (common.Address, error) { + return _AppController.Contract.GetAppOwner(&_AppController.CallOpts, app) +} + // GetAppStatus is a free data retrieval call binding the contract method 0xd5aae178. // // Solidity: function getAppStatus(address app) view returns(uint8) @@ -579,60 +624,46 @@ func (_AppController *AppControllerCallerSession) GetAppStatus(app common.Addres return _AppController.Contract.GetAppStatus(&_AppController.CallOpts, app) } -// GetApps is a free data retrieval call binding the contract method 0xa37e7e44. +// GetAppTimelocked is a free data retrieval call binding the contract method 0x508ac1d6. // -// Solidity: function getApps(uint256 offset, uint256 limit) view returns(address[] apps, (address,uint32,uint32,uint8)[] appConfigsMem) -func (_AppController *AppControllerCaller) GetApps(opts *bind.CallOpts, offset *big.Int, limit *big.Int) (struct { - Apps []common.Address - AppConfigsMem []IAppControllerAppConfig -}, error) { +// Solidity: function getAppTimelocked(address app) view returns(bool) +func (_AppController *AppControllerCaller) GetAppTimelocked(opts *bind.CallOpts, app common.Address) (bool, error) { var out []interface{} - err := _AppController.contract.Call(opts, &out, "getApps", offset, limit) + err := _AppController.contract.Call(opts, &out, "getAppTimelocked", app) - outstruct := new(struct { - Apps []common.Address - AppConfigsMem []IAppControllerAppConfig - }) if err != nil { - return *outstruct, err + return *new(bool), err } - outstruct.Apps = *abi.ConvertType(out[0], new([]common.Address)).(*[]common.Address) - outstruct.AppConfigsMem = *abi.ConvertType(out[1], new([]IAppControllerAppConfig)).(*[]IAppControllerAppConfig) + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) - return *outstruct, err + return out0, err } -// GetApps is a free data retrieval call binding the contract method 0xa37e7e44. +// GetAppTimelocked is a free data retrieval call binding the contract method 0x508ac1d6. // -// Solidity: function getApps(uint256 offset, uint256 limit) view returns(address[] apps, (address,uint32,uint32,uint8)[] appConfigsMem) -func (_AppController *AppControllerSession) GetApps(offset *big.Int, limit *big.Int) (struct { - Apps []common.Address - AppConfigsMem []IAppControllerAppConfig -}, error) { - return _AppController.Contract.GetApps(&_AppController.CallOpts, offset, limit) +// Solidity: function getAppTimelocked(address app) view returns(bool) +func (_AppController *AppControllerSession) GetAppTimelocked(app common.Address) (bool, error) { + return _AppController.Contract.GetAppTimelocked(&_AppController.CallOpts, app) } -// GetApps is a free data retrieval call binding the contract method 0xa37e7e44. +// GetAppTimelocked is a free data retrieval call binding the contract method 0x508ac1d6. // -// Solidity: function getApps(uint256 offset, uint256 limit) view returns(address[] apps, (address,uint32,uint32,uint8)[] appConfigsMem) -func (_AppController *AppControllerCallerSession) GetApps(offset *big.Int, limit *big.Int) (struct { - Apps []common.Address - AppConfigsMem []IAppControllerAppConfig -}, error) { - return _AppController.Contract.GetApps(&_AppController.CallOpts, offset, limit) +// Solidity: function getAppTimelocked(address app) view returns(bool) +func (_AppController *AppControllerCallerSession) GetAppTimelocked(app common.Address) (bool, error) { + return _AppController.Contract.GetAppTimelocked(&_AppController.CallOpts, app) } -// GetAppsByBillingAccount is a free data retrieval call binding the contract method 0xdbb1c4e1. +// GetApps is a free data retrieval call binding the contract method 0xa37e7e44. // -// Solidity: function getAppsByBillingAccount(address account, uint256 offset, uint256 limit) view returns(address[] apps, (address,uint32,uint32,uint8)[] appConfigsMem) -func (_AppController *AppControllerCaller) GetAppsByBillingAccount(opts *bind.CallOpts, account common.Address, offset *big.Int, limit *big.Int) (struct { +// Solidity: function getApps(uint256 offset, uint256 limit) view returns(address[] apps, (address,uint32,uint32,uint8,bool)[] appConfigsMem) +func (_AppController *AppControllerCaller) GetApps(opts *bind.CallOpts, offset *big.Int, limit *big.Int) (struct { Apps []common.Address AppConfigsMem []IAppControllerAppConfig }, error) { var out []interface{} - err := _AppController.contract.Call(opts, &out, "getAppsByBillingAccount", account, offset, limit) + err := _AppController.contract.Call(opts, &out, "getApps", offset, limit) outstruct := new(struct { Apps []common.Address @@ -649,29 +680,29 @@ func (_AppController *AppControllerCaller) GetAppsByBillingAccount(opts *bind.Ca } -// GetAppsByBillingAccount is a free data retrieval call binding the contract method 0xdbb1c4e1. +// GetApps is a free data retrieval call binding the contract method 0xa37e7e44. // -// Solidity: function getAppsByBillingAccount(address account, uint256 offset, uint256 limit) view returns(address[] apps, (address,uint32,uint32,uint8)[] appConfigsMem) -func (_AppController *AppControllerSession) GetAppsByBillingAccount(account common.Address, offset *big.Int, limit *big.Int) (struct { +// Solidity: function getApps(uint256 offset, uint256 limit) view returns(address[] apps, (address,uint32,uint32,uint8,bool)[] appConfigsMem) +func (_AppController *AppControllerSession) GetApps(offset *big.Int, limit *big.Int) (struct { Apps []common.Address AppConfigsMem []IAppControllerAppConfig }, error) { - return _AppController.Contract.GetAppsByBillingAccount(&_AppController.CallOpts, account, offset, limit) + return _AppController.Contract.GetApps(&_AppController.CallOpts, offset, limit) } -// GetAppsByBillingAccount is a free data retrieval call binding the contract method 0xdbb1c4e1. +// GetApps is a free data retrieval call binding the contract method 0xa37e7e44. // -// Solidity: function getAppsByBillingAccount(address account, uint256 offset, uint256 limit) view returns(address[] apps, (address,uint32,uint32,uint8)[] appConfigsMem) -func (_AppController *AppControllerCallerSession) GetAppsByBillingAccount(account common.Address, offset *big.Int, limit *big.Int) (struct { +// Solidity: function getApps(uint256 offset, uint256 limit) view returns(address[] apps, (address,uint32,uint32,uint8,bool)[] appConfigsMem) +func (_AppController *AppControllerCallerSession) GetApps(offset *big.Int, limit *big.Int) (struct { Apps []common.Address AppConfigsMem []IAppControllerAppConfig }, error) { - return _AppController.Contract.GetAppsByBillingAccount(&_AppController.CallOpts, account, offset, limit) + return _AppController.Contract.GetApps(&_AppController.CallOpts, offset, limit) } // GetAppsByCreator is a free data retrieval call binding the contract method 0x8099ef2e. // -// Solidity: function getAppsByCreator(address creator, uint256 offset, uint256 limit) view returns(address[] apps, (address,uint32,uint32,uint8)[] appConfigsMem) +// Solidity: function getAppsByCreator(address creator, uint256 offset, uint256 limit) view returns(address[] apps, (address,uint32,uint32,uint8,bool)[] appConfigsMem) func (_AppController *AppControllerCaller) GetAppsByCreator(opts *bind.CallOpts, creator common.Address, offset *big.Int, limit *big.Int) (struct { Apps []common.Address AppConfigsMem []IAppControllerAppConfig @@ -696,7 +727,7 @@ func (_AppController *AppControllerCaller) GetAppsByCreator(opts *bind.CallOpts, // GetAppsByCreator is a free data retrieval call binding the contract method 0x8099ef2e. // -// Solidity: function getAppsByCreator(address creator, uint256 offset, uint256 limit) view returns(address[] apps, (address,uint32,uint32,uint8)[] appConfigsMem) +// Solidity: function getAppsByCreator(address creator, uint256 offset, uint256 limit) view returns(address[] apps, (address,uint32,uint32,uint8,bool)[] appConfigsMem) func (_AppController *AppControllerSession) GetAppsByCreator(creator common.Address, offset *big.Int, limit *big.Int) (struct { Apps []common.Address AppConfigsMem []IAppControllerAppConfig @@ -706,7 +737,7 @@ func (_AppController *AppControllerSession) GetAppsByCreator(creator common.Addr // GetAppsByCreator is a free data retrieval call binding the contract method 0x8099ef2e. // -// Solidity: function getAppsByCreator(address creator, uint256 offset, uint256 limit) view returns(address[] apps, (address,uint32,uint32,uint8)[] appConfigsMem) +// Solidity: function getAppsByCreator(address creator, uint256 offset, uint256 limit) view returns(address[] apps, (address,uint32,uint32,uint8,bool)[] appConfigsMem) func (_AppController *AppControllerCallerSession) GetAppsByCreator(creator common.Address, offset *big.Int, limit *big.Int) (struct { Apps []common.Address AppConfigsMem []IAppControllerAppConfig @@ -716,7 +747,7 @@ func (_AppController *AppControllerCallerSession) GetAppsByCreator(creator commo // GetAppsByDeveloper is a free data retrieval call binding the contract method 0xf36618ac. // -// Solidity: function getAppsByDeveloper(address developer, uint256 offset, uint256 limit) view returns(address[] apps, (address,uint32,uint32,uint8)[] appConfigsMem) +// Solidity: function getAppsByDeveloper(address developer, uint256 offset, uint256 limit) view returns(address[] apps, (address,uint32,uint32,uint8,bool)[] appConfigsMem) func (_AppController *AppControllerCaller) GetAppsByDeveloper(opts *bind.CallOpts, developer common.Address, offset *big.Int, limit *big.Int) (struct { Apps []common.Address AppConfigsMem []IAppControllerAppConfig @@ -741,7 +772,7 @@ func (_AppController *AppControllerCaller) GetAppsByDeveloper(opts *bind.CallOpt // GetAppsByDeveloper is a free data retrieval call binding the contract method 0xf36618ac. // -// Solidity: function getAppsByDeveloper(address developer, uint256 offset, uint256 limit) view returns(address[] apps, (address,uint32,uint32,uint8)[] appConfigsMem) +// Solidity: function getAppsByDeveloper(address developer, uint256 offset, uint256 limit) view returns(address[] apps, (address,uint32,uint32,uint8,bool)[] appConfigsMem) func (_AppController *AppControllerSession) GetAppsByDeveloper(developer common.Address, offset *big.Int, limit *big.Int) (struct { Apps []common.Address AppConfigsMem []IAppControllerAppConfig @@ -751,7 +782,7 @@ func (_AppController *AppControllerSession) GetAppsByDeveloper(developer common. // GetAppsByDeveloper is a free data retrieval call binding the contract method 0xf36618ac. // -// Solidity: function getAppsByDeveloper(address developer, uint256 offset, uint256 limit) view returns(address[] apps, (address,uint32,uint32,uint8)[] appConfigsMem) +// Solidity: function getAppsByDeveloper(address developer, uint256 offset, uint256 limit) view returns(address[] apps, (address,uint32,uint32,uint8,bool)[] appConfigsMem) func (_AppController *AppControllerCallerSession) GetAppsByDeveloper(developer common.Address, offset *big.Int, limit *big.Int) (struct { Apps []common.Address AppConfigsMem []IAppControllerAppConfig @@ -759,66 +790,35 @@ func (_AppController *AppControllerCallerSession) GetAppsByDeveloper(developer c return _AppController.Contract.GetAppsByDeveloper(&_AppController.CallOpts, developer, offset, limit) } -// GetBillingAccount is a free data retrieval call binding the contract method 0x3e032115. -// -// Solidity: function getBillingAccount(address app) view returns(address) -func (_AppController *AppControllerCaller) GetBillingAccount(opts *bind.CallOpts, app common.Address) (common.Address, error) { - var out []interface{} - err := _AppController.contract.Call(opts, &out, "getBillingAccount", app) - - if err != nil { - return *new(common.Address), err - } - - out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) - - return out0, err - -} - -// GetBillingAccount is a free data retrieval call binding the contract method 0x3e032115. -// -// Solidity: function getBillingAccount(address app) view returns(address) -func (_AppController *AppControllerSession) GetBillingAccount(app common.Address) (common.Address, error) { - return _AppController.Contract.GetBillingAccount(&_AppController.CallOpts, app) -} - -// GetBillingAccount is a free data retrieval call binding the contract method 0x3e032115. -// -// Solidity: function getBillingAccount(address app) view returns(address) -func (_AppController *AppControllerCallerSession) GetBillingAccount(app common.Address) (common.Address, error) { - return _AppController.Contract.GetBillingAccount(&_AppController.CallOpts, app) -} - -// GetBillingType is a free data retrieval call binding the contract method 0x85e9babb. +// GetAppsForAccount is a free data retrieval call binding the contract method 0xf61b3a25. // -// Solidity: function getBillingType(address app) view returns(uint8) -func (_AppController *AppControllerCaller) GetBillingType(opts *bind.CallOpts, app common.Address) (uint8, error) { +// Solidity: function getAppsForAccount(address account, uint256 offset, uint256 limit) view returns((address,bool,uint8[])[] appRoles) +func (_AppController *AppControllerCaller) GetAppsForAccount(opts *bind.CallOpts, account common.Address, offset *big.Int, limit *big.Int) ([]IAppControllerAppRoles, error) { var out []interface{} - err := _AppController.contract.Call(opts, &out, "getBillingType", app) + err := _AppController.contract.Call(opts, &out, "getAppsForAccount", account, offset, limit) if err != nil { - return *new(uint8), err + return *new([]IAppControllerAppRoles), err } - out0 := *abi.ConvertType(out[0], new(uint8)).(*uint8) + out0 := *abi.ConvertType(out[0], new([]IAppControllerAppRoles)).(*[]IAppControllerAppRoles) return out0, err } -// GetBillingType is a free data retrieval call binding the contract method 0x85e9babb. +// GetAppsForAccount is a free data retrieval call binding the contract method 0xf61b3a25. // -// Solidity: function getBillingType(address app) view returns(uint8) -func (_AppController *AppControllerSession) GetBillingType(app common.Address) (uint8, error) { - return _AppController.Contract.GetBillingType(&_AppController.CallOpts, app) +// Solidity: function getAppsForAccount(address account, uint256 offset, uint256 limit) view returns((address,bool,uint8[])[] appRoles) +func (_AppController *AppControllerSession) GetAppsForAccount(account common.Address, offset *big.Int, limit *big.Int) ([]IAppControllerAppRoles, error) { + return _AppController.Contract.GetAppsForAccount(&_AppController.CallOpts, account, offset, limit) } -// GetBillingType is a free data retrieval call binding the contract method 0x85e9babb. +// GetAppsForAccount is a free data retrieval call binding the contract method 0xf61b3a25. // -// Solidity: function getBillingType(address app) view returns(uint8) -func (_AppController *AppControllerCallerSession) GetBillingType(app common.Address) (uint8, error) { - return _AppController.Contract.GetBillingType(&_AppController.CallOpts, app) +// Solidity: function getAppsForAccount(address account, uint256 offset, uint256 limit) view returns((address,bool,uint8[])[] appRoles) +func (_AppController *AppControllerCallerSession) GetAppsForAccount(account common.Address, offset *big.Int, limit *big.Int) ([]IAppControllerAppRoles, error) { + return _AppController.Contract.GetAppsForAccount(&_AppController.CallOpts, account, offset, limit) } // GetMaxActiveAppsPerUser is a free data retrieval call binding the contract method 0x40f70a9e. @@ -852,74 +852,74 @@ func (_AppController *AppControllerCallerSession) GetMaxActiveAppsPerUser(user c return _AppController.Contract.GetMaxActiveAppsPerUser(&_AppController.CallOpts, user) } -// GlobalActiveAppCount is a free data retrieval call binding the contract method 0xa8aa2bd3. +// GetPendingUpgrade is a free data retrieval call binding the contract method 0x57ececcd. // -// Solidity: function globalActiveAppCount() view returns(uint32) -func (_AppController *AppControllerCaller) GlobalActiveAppCount(opts *bind.CallOpts) (uint32, error) { +// Solidity: function getPendingUpgrade(address app) view returns((bytes32,uint256)) +func (_AppController *AppControllerCaller) GetPendingUpgrade(opts *bind.CallOpts, app common.Address) (IAppControllerPendingUpgrade, error) { var out []interface{} - err := _AppController.contract.Call(opts, &out, "globalActiveAppCount") + err := _AppController.contract.Call(opts, &out, "getPendingUpgrade", app) if err != nil { - return *new(uint32), err + return *new(IAppControllerPendingUpgrade), err } - out0 := *abi.ConvertType(out[0], new(uint32)).(*uint32) + out0 := *abi.ConvertType(out[0], new(IAppControllerPendingUpgrade)).(*IAppControllerPendingUpgrade) return out0, err } -// GlobalActiveAppCount is a free data retrieval call binding the contract method 0xa8aa2bd3. +// GetPendingUpgrade is a free data retrieval call binding the contract method 0x57ececcd. // -// Solidity: function globalActiveAppCount() view returns(uint32) -func (_AppController *AppControllerSession) GlobalActiveAppCount() (uint32, error) { - return _AppController.Contract.GlobalActiveAppCount(&_AppController.CallOpts) +// Solidity: function getPendingUpgrade(address app) view returns((bytes32,uint256)) +func (_AppController *AppControllerSession) GetPendingUpgrade(app common.Address) (IAppControllerPendingUpgrade, error) { + return _AppController.Contract.GetPendingUpgrade(&_AppController.CallOpts, app) } -// GlobalActiveAppCount is a free data retrieval call binding the contract method 0xa8aa2bd3. +// GetPendingUpgrade is a free data retrieval call binding the contract method 0x57ececcd. // -// Solidity: function globalActiveAppCount() view returns(uint32) -func (_AppController *AppControllerCallerSession) GlobalActiveAppCount() (uint32, error) { - return _AppController.Contract.GlobalActiveAppCount(&_AppController.CallOpts) +// Solidity: function getPendingUpgrade(address app) view returns((bytes32,uint256)) +func (_AppController *AppControllerCallerSession) GetPendingUpgrade(app common.Address) (IAppControllerPendingUpgrade, error) { + return _AppController.Contract.GetPendingUpgrade(&_AppController.CallOpts, app) } -// MaxGlobalActiveApps is a free data retrieval call binding the contract method 0xa46530a2. +// GetRoleAdmin is a free data retrieval call binding the contract method 0x248a9ca3. // -// Solidity: function maxGlobalActiveApps() view returns(uint32) -func (_AppController *AppControllerCaller) MaxGlobalActiveApps(opts *bind.CallOpts) (uint32, error) { +// Solidity: function getRoleAdmin(bytes32 role) view returns(bytes32) +func (_AppController *AppControllerCaller) GetRoleAdmin(opts *bind.CallOpts, role [32]byte) ([32]byte, error) { var out []interface{} - err := _AppController.contract.Call(opts, &out, "maxGlobalActiveApps") + err := _AppController.contract.Call(opts, &out, "getRoleAdmin", role) if err != nil { - return *new(uint32), err + return *new([32]byte), err } - out0 := *abi.ConvertType(out[0], new(uint32)).(*uint32) + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) return out0, err } -// MaxGlobalActiveApps is a free data retrieval call binding the contract method 0xa46530a2. +// GetRoleAdmin is a free data retrieval call binding the contract method 0x248a9ca3. // -// Solidity: function maxGlobalActiveApps() view returns(uint32) -func (_AppController *AppControllerSession) MaxGlobalActiveApps() (uint32, error) { - return _AppController.Contract.MaxGlobalActiveApps(&_AppController.CallOpts) +// Solidity: function getRoleAdmin(bytes32 role) view returns(bytes32) +func (_AppController *AppControllerSession) GetRoleAdmin(role [32]byte) ([32]byte, error) { + return _AppController.Contract.GetRoleAdmin(&_AppController.CallOpts, role) } -// MaxGlobalActiveApps is a free data retrieval call binding the contract method 0xa46530a2. +// GetRoleAdmin is a free data retrieval call binding the contract method 0x248a9ca3. // -// Solidity: function maxGlobalActiveApps() view returns(uint32) -func (_AppController *AppControllerCallerSession) MaxGlobalActiveApps() (uint32, error) { - return _AppController.Contract.MaxGlobalActiveApps(&_AppController.CallOpts) +// Solidity: function getRoleAdmin(bytes32 role) view returns(bytes32) +func (_AppController *AppControllerCallerSession) GetRoleAdmin(role [32]byte) ([32]byte, error) { + return _AppController.Contract.GetRoleAdmin(&_AppController.CallOpts, role) } -// PermissionController is a free data retrieval call binding the contract method 0x4657e26a. +// GetRoleMember is a free data retrieval call binding the contract method 0x9010d07c. // -// Solidity: function permissionController() view returns(address) -func (_AppController *AppControllerCaller) PermissionController(opts *bind.CallOpts) (common.Address, error) { +// Solidity: function getRoleMember(bytes32 role, uint256 index) view returns(address) +func (_AppController *AppControllerCaller) GetRoleMember(opts *bind.CallOpts, role [32]byte, index *big.Int) (common.Address, error) { var out []interface{} - err := _AppController.contract.Call(opts, &out, "permissionController") + err := _AppController.contract.Call(opts, &out, "getRoleMember", role, index) if err != nil { return *new(common.Address), err @@ -931,337 +931,1802 @@ func (_AppController *AppControllerCaller) PermissionController(opts *bind.CallO } -// PermissionController is a free data retrieval call binding the contract method 0x4657e26a. +// GetRoleMember is a free data retrieval call binding the contract method 0x9010d07c. // -// Solidity: function permissionController() view returns(address) -func (_AppController *AppControllerSession) PermissionController() (common.Address, error) { - return _AppController.Contract.PermissionController(&_AppController.CallOpts) +// Solidity: function getRoleMember(bytes32 role, uint256 index) view returns(address) +func (_AppController *AppControllerSession) GetRoleMember(role [32]byte, index *big.Int) (common.Address, error) { + return _AppController.Contract.GetRoleMember(&_AppController.CallOpts, role, index) } -// PermissionController is a free data retrieval call binding the contract method 0x4657e26a. +// GetRoleMember is a free data retrieval call binding the contract method 0x9010d07c. // -// Solidity: function permissionController() view returns(address) -func (_AppController *AppControllerCallerSession) PermissionController() (common.Address, error) { - return _AppController.Contract.PermissionController(&_AppController.CallOpts) +// Solidity: function getRoleMember(bytes32 role, uint256 index) view returns(address) +func (_AppController *AppControllerCallerSession) GetRoleMember(role [32]byte, index *big.Int) (common.Address, error) { + return _AppController.Contract.GetRoleMember(&_AppController.CallOpts, role, index) } -// ReleaseManager is a free data retrieval call binding the contract method 0x0d78573e. +// GetRoleMemberCount is a free data retrieval call binding the contract method 0xca15c873. // -// Solidity: function releaseManager() view returns(address) -func (_AppController *AppControllerCaller) ReleaseManager(opts *bind.CallOpts) (common.Address, error) { +// Solidity: function getRoleMemberCount(bytes32 role) view returns(uint256) +func (_AppController *AppControllerCaller) GetRoleMemberCount(opts *bind.CallOpts, role [32]byte) (*big.Int, error) { var out []interface{} - err := _AppController.contract.Call(opts, &out, "releaseManager") + err := _AppController.contract.Call(opts, &out, "getRoleMemberCount", role) if err != nil { - return *new(common.Address), err + return *new(*big.Int), err } - out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) return out0, err } -// ReleaseManager is a free data retrieval call binding the contract method 0x0d78573e. +// GetRoleMemberCount is a free data retrieval call binding the contract method 0xca15c873. // -// Solidity: function releaseManager() view returns(address) -func (_AppController *AppControllerSession) ReleaseManager() (common.Address, error) { - return _AppController.Contract.ReleaseManager(&_AppController.CallOpts) +// Solidity: function getRoleMemberCount(bytes32 role) view returns(uint256) +func (_AppController *AppControllerSession) GetRoleMemberCount(role [32]byte) (*big.Int, error) { + return _AppController.Contract.GetRoleMemberCount(&_AppController.CallOpts, role) } -// ReleaseManager is a free data retrieval call binding the contract method 0x0d78573e. +// GetRoleMemberCount is a free data retrieval call binding the contract method 0xca15c873. // -// Solidity: function releaseManager() view returns(address) -func (_AppController *AppControllerCallerSession) ReleaseManager() (common.Address, error) { - return _AppController.Contract.ReleaseManager(&_AppController.CallOpts) +// Solidity: function getRoleMemberCount(bytes32 role) view returns(uint256) +func (_AppController *AppControllerCallerSession) GetRoleMemberCount(role [32]byte) (*big.Int, error) { + return _AppController.Contract.GetRoleMemberCount(&_AppController.CallOpts, role) } -// Version is a free data retrieval call binding the contract method 0x54fd4d50. +// GetTeamRoleMember is a free data retrieval call binding the contract method 0x1d349e61. // -// Solidity: function version() view returns(string) -func (_AppController *AppControllerCaller) Version(opts *bind.CallOpts) (string, error) { +// Solidity: function getTeamRoleMember(address team, uint8 role, uint256 index) view returns(address) +func (_AppController *AppControllerCaller) GetTeamRoleMember(opts *bind.CallOpts, team common.Address, role uint8, index *big.Int) (common.Address, error) { var out []interface{} - err := _AppController.contract.Call(opts, &out, "version") + err := _AppController.contract.Call(opts, &out, "getTeamRoleMember", team, role, index) if err != nil { - return *new(string), err + return *new(common.Address), err } - out0 := *abi.ConvertType(out[0], new(string)).(*string) + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) return out0, err } -// Version is a free data retrieval call binding the contract method 0x54fd4d50. +// GetTeamRoleMember is a free data retrieval call binding the contract method 0x1d349e61. // -// Solidity: function version() view returns(string) -func (_AppController *AppControllerSession) Version() (string, error) { - return _AppController.Contract.Version(&_AppController.CallOpts) +// Solidity: function getTeamRoleMember(address team, uint8 role, uint256 index) view returns(address) +func (_AppController *AppControllerSession) GetTeamRoleMember(team common.Address, role uint8, index *big.Int) (common.Address, error) { + return _AppController.Contract.GetTeamRoleMember(&_AppController.CallOpts, team, role, index) } -// Version is a free data retrieval call binding the contract method 0x54fd4d50. +// GetTeamRoleMember is a free data retrieval call binding the contract method 0x1d349e61. // -// Solidity: function version() view returns(string) -func (_AppController *AppControllerCallerSession) Version() (string, error) { - return _AppController.Contract.Version(&_AppController.CallOpts) +// Solidity: function getTeamRoleMember(address team, uint8 role, uint256 index) view returns(address) +func (_AppController *AppControllerCallerSession) GetTeamRoleMember(team common.Address, role uint8, index *big.Int) (common.Address, error) { + return _AppController.Contract.GetTeamRoleMember(&_AppController.CallOpts, team, role, index) } -// CreateApp is a paid mutator transaction binding the contract method 0xa60daa8f. +// GetTeamRoleMemberCount is a free data retrieval call binding the contract method 0x3c98ff65. // -// Solidity: function createApp(bytes32 salt, (((bytes32,string)[],uint32),bytes,bytes) release) returns(address app) -func (_AppController *AppControllerTransactor) CreateApp(opts *bind.TransactOpts, salt [32]byte, release IAppControllerRelease) (*types.Transaction, error) { - return _AppController.contract.Transact(opts, "createApp", salt, release) +// Solidity: function getTeamRoleMemberCount(address team, uint8 role) view returns(uint256) +func (_AppController *AppControllerCaller) GetTeamRoleMemberCount(opts *bind.CallOpts, team common.Address, role uint8) (*big.Int, error) { + var out []interface{} + err := _AppController.contract.Call(opts, &out, "getTeamRoleMemberCount", team, role) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + } -// CreateApp is a paid mutator transaction binding the contract method 0xa60daa8f. +// GetTeamRoleMemberCount is a free data retrieval call binding the contract method 0x3c98ff65. // -// Solidity: function createApp(bytes32 salt, (((bytes32,string)[],uint32),bytes,bytes) release) returns(address app) -func (_AppController *AppControllerSession) CreateApp(salt [32]byte, release IAppControllerRelease) (*types.Transaction, error) { - return _AppController.Contract.CreateApp(&_AppController.TransactOpts, salt, release) +// Solidity: function getTeamRoleMemberCount(address team, uint8 role) view returns(uint256) +func (_AppController *AppControllerSession) GetTeamRoleMemberCount(team common.Address, role uint8) (*big.Int, error) { + return _AppController.Contract.GetTeamRoleMemberCount(&_AppController.CallOpts, team, role) } -// CreateApp is a paid mutator transaction binding the contract method 0xa60daa8f. +// GetTeamRoleMemberCount is a free data retrieval call binding the contract method 0x3c98ff65. // -// Solidity: function createApp(bytes32 salt, (((bytes32,string)[],uint32),bytes,bytes) release) returns(address app) -func (_AppController *AppControllerTransactorSession) CreateApp(salt [32]byte, release IAppControllerRelease) (*types.Transaction, error) { - return _AppController.Contract.CreateApp(&_AppController.TransactOpts, salt, release) +// Solidity: function getTeamRoleMemberCount(address team, uint8 role) view returns(uint256) +func (_AppController *AppControllerCallerSession) GetTeamRoleMemberCount(team common.Address, role uint8) (*big.Int, error) { + return _AppController.Contract.GetTeamRoleMemberCount(&_AppController.CallOpts, team, role) } -// CreateAppWithIsolatedBilling is a paid mutator transaction binding the contract method 0x559cf359. +// GetTeamRoleMembers is a free data retrieval call binding the contract method 0x60257ae6. // -// Solidity: function createAppWithIsolatedBilling(bytes32 salt, (((bytes32,string)[],uint32),bytes,bytes) release) returns(address app) -func (_AppController *AppControllerTransactor) CreateAppWithIsolatedBilling(opts *bind.TransactOpts, salt [32]byte, release IAppControllerRelease) (*types.Transaction, error) { - return _AppController.contract.Transact(opts, "createAppWithIsolatedBilling", salt, release) +// Solidity: function getTeamRoleMembers(address team, uint8 role) view returns(address[]) +func (_AppController *AppControllerCaller) GetTeamRoleMembers(opts *bind.CallOpts, team common.Address, role uint8) ([]common.Address, error) { + var out []interface{} + err := _AppController.contract.Call(opts, &out, "getTeamRoleMembers", team, role) + + if err != nil { + return *new([]common.Address), err + } + + out0 := *abi.ConvertType(out[0], new([]common.Address)).(*[]common.Address) + + return out0, err + } -// CreateAppWithIsolatedBilling is a paid mutator transaction binding the contract method 0x559cf359. +// GetTeamRoleMembers is a free data retrieval call binding the contract method 0x60257ae6. // -// Solidity: function createAppWithIsolatedBilling(bytes32 salt, (((bytes32,string)[],uint32),bytes,bytes) release) returns(address app) -func (_AppController *AppControllerSession) CreateAppWithIsolatedBilling(salt [32]byte, release IAppControllerRelease) (*types.Transaction, error) { - return _AppController.Contract.CreateAppWithIsolatedBilling(&_AppController.TransactOpts, salt, release) +// Solidity: function getTeamRoleMembers(address team, uint8 role) view returns(address[]) +func (_AppController *AppControllerSession) GetTeamRoleMembers(team common.Address, role uint8) ([]common.Address, error) { + return _AppController.Contract.GetTeamRoleMembers(&_AppController.CallOpts, team, role) } -// CreateAppWithIsolatedBilling is a paid mutator transaction binding the contract method 0x559cf359. +// GetTeamRoleMembers is a free data retrieval call binding the contract method 0x60257ae6. // -// Solidity: function createAppWithIsolatedBilling(bytes32 salt, (((bytes32,string)[],uint32),bytes,bytes) release) returns(address app) -func (_AppController *AppControllerTransactorSession) CreateAppWithIsolatedBilling(salt [32]byte, release IAppControllerRelease) (*types.Transaction, error) { - return _AppController.Contract.CreateAppWithIsolatedBilling(&_AppController.TransactOpts, salt, release) +// Solidity: function getTeamRoleMembers(address team, uint8 role) view returns(address[]) +func (_AppController *AppControllerCallerSession) GetTeamRoleMembers(team common.Address, role uint8) ([]common.Address, error) { + return _AppController.Contract.GetTeamRoleMembers(&_AppController.CallOpts, team, role) } -// Initialize is a paid mutator transaction binding the contract method 0xc4d66de8. +// GlobalActiveAppCount is a free data retrieval call binding the contract method 0xa8aa2bd3. // -// Solidity: function initialize(address admin) returns() -func (_AppController *AppControllerTransactor) Initialize(opts *bind.TransactOpts, admin common.Address) (*types.Transaction, error) { - return _AppController.contract.Transact(opts, "initialize", admin) +// Solidity: function globalActiveAppCount() view returns(uint32) +func (_AppController *AppControllerCaller) GlobalActiveAppCount(opts *bind.CallOpts) (uint32, error) { + var out []interface{} + err := _AppController.contract.Call(opts, &out, "globalActiveAppCount") + + if err != nil { + return *new(uint32), err + } + + out0 := *abi.ConvertType(out[0], new(uint32)).(*uint32) + + return out0, err + } -// Initialize is a paid mutator transaction binding the contract method 0xc4d66de8. +// GlobalActiveAppCount is a free data retrieval call binding the contract method 0xa8aa2bd3. // -// Solidity: function initialize(address admin) returns() -func (_AppController *AppControllerSession) Initialize(admin common.Address) (*types.Transaction, error) { - return _AppController.Contract.Initialize(&_AppController.TransactOpts, admin) +// Solidity: function globalActiveAppCount() view returns(uint32) +func (_AppController *AppControllerSession) GlobalActiveAppCount() (uint32, error) { + return _AppController.Contract.GlobalActiveAppCount(&_AppController.CallOpts) } -// Initialize is a paid mutator transaction binding the contract method 0xc4d66de8. +// GlobalActiveAppCount is a free data retrieval call binding the contract method 0xa8aa2bd3. // -// Solidity: function initialize(address admin) returns() -func (_AppController *AppControllerTransactorSession) Initialize(admin common.Address) (*types.Transaction, error) { - return _AppController.Contract.Initialize(&_AppController.TransactOpts, admin) +// Solidity: function globalActiveAppCount() view returns(uint32) +func (_AppController *AppControllerCallerSession) GlobalActiveAppCount() (uint32, error) { + return _AppController.Contract.GlobalActiveAppCount(&_AppController.CallOpts) } -// SetMaxActiveAppsPerUser is a paid mutator transaction binding the contract method 0xd49fec2b. +// HasRole is a free data retrieval call binding the contract method 0x91d14854. // -// Solidity: function setMaxActiveAppsPerUser(address user, uint32 limit) returns() -func (_AppController *AppControllerTransactor) SetMaxActiveAppsPerUser(opts *bind.TransactOpts, user common.Address, limit uint32) (*types.Transaction, error) { - return _AppController.contract.Transact(opts, "setMaxActiveAppsPerUser", user, limit) +// Solidity: function hasRole(bytes32 role, address account) view returns(bool) +func (_AppController *AppControllerCaller) HasRole(opts *bind.CallOpts, role [32]byte, account common.Address) (bool, error) { + var out []interface{} + err := _AppController.contract.Call(opts, &out, "hasRole", role, account) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + } -// SetMaxActiveAppsPerUser is a paid mutator transaction binding the contract method 0xd49fec2b. +// HasRole is a free data retrieval call binding the contract method 0x91d14854. // -// Solidity: function setMaxActiveAppsPerUser(address user, uint32 limit) returns() -func (_AppController *AppControllerSession) SetMaxActiveAppsPerUser(user common.Address, limit uint32) (*types.Transaction, error) { - return _AppController.Contract.SetMaxActiveAppsPerUser(&_AppController.TransactOpts, user, limit) +// Solidity: function hasRole(bytes32 role, address account) view returns(bool) +func (_AppController *AppControllerSession) HasRole(role [32]byte, account common.Address) (bool, error) { + return _AppController.Contract.HasRole(&_AppController.CallOpts, role, account) } -// SetMaxActiveAppsPerUser is a paid mutator transaction binding the contract method 0xd49fec2b. +// HasRole is a free data retrieval call binding the contract method 0x91d14854. // -// Solidity: function setMaxActiveAppsPerUser(address user, uint32 limit) returns() -func (_AppController *AppControllerTransactorSession) SetMaxActiveAppsPerUser(user common.Address, limit uint32) (*types.Transaction, error) { - return _AppController.Contract.SetMaxActiveAppsPerUser(&_AppController.TransactOpts, user, limit) +// Solidity: function hasRole(bytes32 role, address account) view returns(bool) +func (_AppController *AppControllerCallerSession) HasRole(role [32]byte, account common.Address) (bool, error) { + return _AppController.Contract.HasRole(&_AppController.CallOpts, role, account) } -// SetMaxGlobalActiveApps is a paid mutator transaction binding the contract method 0xb438c141. +// HasTeamRole is a free data retrieval call binding the contract method 0x54bfb170. // -// Solidity: function setMaxGlobalActiveApps(uint32 limit) returns() -func (_AppController *AppControllerTransactor) SetMaxGlobalActiveApps(opts *bind.TransactOpts, limit uint32) (*types.Transaction, error) { - return _AppController.contract.Transact(opts, "setMaxGlobalActiveApps", limit) +// Solidity: function hasTeamRole(address team, uint8 role, address account) view returns(bool) +func (_AppController *AppControllerCaller) HasTeamRole(opts *bind.CallOpts, team common.Address, role uint8, account common.Address) (bool, error) { + var out []interface{} + err := _AppController.contract.Call(opts, &out, "hasTeamRole", team, role, account) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + } -// SetMaxGlobalActiveApps is a paid mutator transaction binding the contract method 0xb438c141. +// HasTeamRole is a free data retrieval call binding the contract method 0x54bfb170. // -// Solidity: function setMaxGlobalActiveApps(uint32 limit) returns() -func (_AppController *AppControllerSession) SetMaxGlobalActiveApps(limit uint32) (*types.Transaction, error) { - return _AppController.Contract.SetMaxGlobalActiveApps(&_AppController.TransactOpts, limit) +// Solidity: function hasTeamRole(address team, uint8 role, address account) view returns(bool) +func (_AppController *AppControllerSession) HasTeamRole(team common.Address, role uint8, account common.Address) (bool, error) { + return _AppController.Contract.HasTeamRole(&_AppController.CallOpts, team, role, account) } -// SetMaxGlobalActiveApps is a paid mutator transaction binding the contract method 0xb438c141. +// HasTeamRole is a free data retrieval call binding the contract method 0x54bfb170. // -// Solidity: function setMaxGlobalActiveApps(uint32 limit) returns() -func (_AppController *AppControllerTransactorSession) SetMaxGlobalActiveApps(limit uint32) (*types.Transaction, error) { - return _AppController.Contract.SetMaxGlobalActiveApps(&_AppController.TransactOpts, limit) +// Solidity: function hasTeamRole(address team, uint8 role, address account) view returns(bool) +func (_AppController *AppControllerCallerSession) HasTeamRole(team common.Address, role uint8, account common.Address) (bool, error) { + return _AppController.Contract.HasTeamRole(&_AppController.CallOpts, team, role, account) } -// StartApp is a paid mutator transaction binding the contract method 0x4dd8ef81. +// MaxGlobalActiveApps is a free data retrieval call binding the contract method 0xa46530a2. // -// Solidity: function startApp(address app) returns() -func (_AppController *AppControllerTransactor) StartApp(opts *bind.TransactOpts, app common.Address) (*types.Transaction, error) { - return _AppController.contract.Transact(opts, "startApp", app) +// Solidity: function maxGlobalActiveApps() view returns(uint32) +func (_AppController *AppControllerCaller) MaxGlobalActiveApps(opts *bind.CallOpts) (uint32, error) { + var out []interface{} + err := _AppController.contract.Call(opts, &out, "maxGlobalActiveApps") + + if err != nil { + return *new(uint32), err + } + + out0 := *abi.ConvertType(out[0], new(uint32)).(*uint32) + + return out0, err + } -// StartApp is a paid mutator transaction binding the contract method 0x4dd8ef81. +// MaxGlobalActiveApps is a free data retrieval call binding the contract method 0xa46530a2. // -// Solidity: function startApp(address app) returns() -func (_AppController *AppControllerSession) StartApp(app common.Address) (*types.Transaction, error) { - return _AppController.Contract.StartApp(&_AppController.TransactOpts, app) +// Solidity: function maxGlobalActiveApps() view returns(uint32) +func (_AppController *AppControllerSession) MaxGlobalActiveApps() (uint32, error) { + return _AppController.Contract.MaxGlobalActiveApps(&_AppController.CallOpts) } -// StartApp is a paid mutator transaction binding the contract method 0x4dd8ef81. +// MaxGlobalActiveApps is a free data retrieval call binding the contract method 0xa46530a2. // -// Solidity: function startApp(address app) returns() -func (_AppController *AppControllerTransactorSession) StartApp(app common.Address) (*types.Transaction, error) { - return _AppController.Contract.StartApp(&_AppController.TransactOpts, app) +// Solidity: function maxGlobalActiveApps() view returns(uint32) +func (_AppController *AppControllerCallerSession) MaxGlobalActiveApps() (uint32, error) { + return _AppController.Contract.MaxGlobalActiveApps(&_AppController.CallOpts) +} + +// PermissionController is a free data retrieval call binding the contract method 0x4657e26a. +// +// Solidity: function permissionController() view returns(address) +func (_AppController *AppControllerCaller) PermissionController(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _AppController.contract.Call(opts, &out, "permissionController") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// PermissionController is a free data retrieval call binding the contract method 0x4657e26a. +// +// Solidity: function permissionController() view returns(address) +func (_AppController *AppControllerSession) PermissionController() (common.Address, error) { + return _AppController.Contract.PermissionController(&_AppController.CallOpts) +} + +// PermissionController is a free data retrieval call binding the contract method 0x4657e26a. +// +// Solidity: function permissionController() view returns(address) +func (_AppController *AppControllerCallerSession) PermissionController() (common.Address, error) { + return _AppController.Contract.PermissionController(&_AppController.CallOpts) +} + +// ReleaseManager is a free data retrieval call binding the contract method 0x0d78573e. +// +// Solidity: function releaseManager() view returns(address) +func (_AppController *AppControllerCaller) ReleaseManager(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _AppController.contract.Call(opts, &out, "releaseManager") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// ReleaseManager is a free data retrieval call binding the contract method 0x0d78573e. +// +// Solidity: function releaseManager() view returns(address) +func (_AppController *AppControllerSession) ReleaseManager() (common.Address, error) { + return _AppController.Contract.ReleaseManager(&_AppController.CallOpts) +} + +// ReleaseManager is a free data retrieval call binding the contract method 0x0d78573e. +// +// Solidity: function releaseManager() view returns(address) +func (_AppController *AppControllerCallerSession) ReleaseManager() (common.Address, error) { + return _AppController.Contract.ReleaseManager(&_AppController.CallOpts) +} + +// SafeTimelockFactory is a free data retrieval call binding the contract method 0xa03d2a81. +// +// Solidity: function safeTimelockFactory() view returns(address) +func (_AppController *AppControllerCaller) SafeTimelockFactory(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _AppController.contract.Call(opts, &out, "safeTimelockFactory") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// SafeTimelockFactory is a free data retrieval call binding the contract method 0xa03d2a81. +// +// Solidity: function safeTimelockFactory() view returns(address) +func (_AppController *AppControllerSession) SafeTimelockFactory() (common.Address, error) { + return _AppController.Contract.SafeTimelockFactory(&_AppController.CallOpts) +} + +// SafeTimelockFactory is a free data retrieval call binding the contract method 0xa03d2a81. +// +// Solidity: function safeTimelockFactory() view returns(address) +func (_AppController *AppControllerCallerSession) SafeTimelockFactory() (common.Address, error) { + return _AppController.Contract.SafeTimelockFactory(&_AppController.CallOpts) +} + +// SupportsInterface is a free data retrieval call binding the contract method 0x01ffc9a7. +// +// Solidity: function supportsInterface(bytes4 interfaceId) view returns(bool) +func (_AppController *AppControllerCaller) SupportsInterface(opts *bind.CallOpts, interfaceId [4]byte) (bool, error) { + var out []interface{} + err := _AppController.contract.Call(opts, &out, "supportsInterface", interfaceId) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +// SupportsInterface is a free data retrieval call binding the contract method 0x01ffc9a7. +// +// Solidity: function supportsInterface(bytes4 interfaceId) view returns(bool) +func (_AppController *AppControllerSession) SupportsInterface(interfaceId [4]byte) (bool, error) { + return _AppController.Contract.SupportsInterface(&_AppController.CallOpts, interfaceId) +} + +// SupportsInterface is a free data retrieval call binding the contract method 0x01ffc9a7. +// +// Solidity: function supportsInterface(bytes4 interfaceId) view returns(bool) +func (_AppController *AppControllerCallerSession) SupportsInterface(interfaceId [4]byte) (bool, error) { + return _AppController.Contract.SupportsInterface(&_AppController.CallOpts, interfaceId) +} + +// Version is a free data retrieval call binding the contract method 0x54fd4d50. +// +// Solidity: function version() view returns(string) +func (_AppController *AppControllerCaller) Version(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _AppController.contract.Call(opts, &out, "version") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +// Version is a free data retrieval call binding the contract method 0x54fd4d50. +// +// Solidity: function version() view returns(string) +func (_AppController *AppControllerSession) Version() (string, error) { + return _AppController.Contract.Version(&_AppController.CallOpts) +} + +// Version is a free data retrieval call binding the contract method 0x54fd4d50. +// +// Solidity: function version() view returns(string) +func (_AppController *AppControllerCallerSession) Version() (string, error) { + return _AppController.Contract.Version(&_AppController.CallOpts) +} + +// CancelUpgrade is a paid mutator transaction binding the contract method 0xc44fb8ec. +// +// Solidity: function cancelUpgrade(address app) returns() +func (_AppController *AppControllerTransactor) CancelUpgrade(opts *bind.TransactOpts, app common.Address) (*types.Transaction, error) { + return _AppController.contract.Transact(opts, "cancelUpgrade", app) +} + +// CancelUpgrade is a paid mutator transaction binding the contract method 0xc44fb8ec. +// +// Solidity: function cancelUpgrade(address app) returns() +func (_AppController *AppControllerSession) CancelUpgrade(app common.Address) (*types.Transaction, error) { + return _AppController.Contract.CancelUpgrade(&_AppController.TransactOpts, app) +} + +// CancelUpgrade is a paid mutator transaction binding the contract method 0xc44fb8ec. +// +// Solidity: function cancelUpgrade(address app) returns() +func (_AppController *AppControllerTransactorSession) CancelUpgrade(app common.Address) (*types.Transaction, error) { + return _AppController.Contract.CancelUpgrade(&_AppController.TransactOpts, app) +} + +// CreateApp is a paid mutator transaction binding the contract method 0xa60daa8f. +// +// Solidity: function createApp(bytes32 salt, (((bytes32,string)[],uint32),bytes,bytes) release) returns(address app) +func (_AppController *AppControllerTransactor) CreateApp(opts *bind.TransactOpts, salt [32]byte, release IAppControllerRelease) (*types.Transaction, error) { + return _AppController.contract.Transact(opts, "createApp", salt, release) +} + +// CreateApp is a paid mutator transaction binding the contract method 0xa60daa8f. +// +// Solidity: function createApp(bytes32 salt, (((bytes32,string)[],uint32),bytes,bytes) release) returns(address app) +func (_AppController *AppControllerSession) CreateApp(salt [32]byte, release IAppControllerRelease) (*types.Transaction, error) { + return _AppController.Contract.CreateApp(&_AppController.TransactOpts, salt, release) +} + +// CreateApp is a paid mutator transaction binding the contract method 0xa60daa8f. +// +// Solidity: function createApp(bytes32 salt, (((bytes32,string)[],uint32),bytes,bytes) release) returns(address app) +func (_AppController *AppControllerTransactorSession) CreateApp(salt [32]byte, release IAppControllerRelease) (*types.Transaction, error) { + return _AppController.Contract.CreateApp(&_AppController.TransactOpts, salt, release) +} + +// CreateAppForTeam is a paid mutator transaction binding the contract method 0x688c3ec3. +// +// Solidity: function createAppForTeam(address team, bytes32 salt, (((bytes32,string)[],uint32),bytes,bytes) release) returns(address app) +func (_AppController *AppControllerTransactor) CreateAppForTeam(opts *bind.TransactOpts, team common.Address, salt [32]byte, release IAppControllerRelease) (*types.Transaction, error) { + return _AppController.contract.Transact(opts, "createAppForTeam", team, salt, release) +} + +// CreateAppForTeam is a paid mutator transaction binding the contract method 0x688c3ec3. +// +// Solidity: function createAppForTeam(address team, bytes32 salt, (((bytes32,string)[],uint32),bytes,bytes) release) returns(address app) +func (_AppController *AppControllerSession) CreateAppForTeam(team common.Address, salt [32]byte, release IAppControllerRelease) (*types.Transaction, error) { + return _AppController.Contract.CreateAppForTeam(&_AppController.TransactOpts, team, salt, release) +} + +// CreateAppForTeam is a paid mutator transaction binding the contract method 0x688c3ec3. +// +// Solidity: function createAppForTeam(address team, bytes32 salt, (((bytes32,string)[],uint32),bytes,bytes) release) returns(address app) +func (_AppController *AppControllerTransactorSession) CreateAppForTeam(team common.Address, salt [32]byte, release IAppControllerRelease) (*types.Transaction, error) { + return _AppController.Contract.CreateAppForTeam(&_AppController.TransactOpts, team, salt, release) +} + +// ExecuteUpgrade is a paid mutator transaction binding the contract method 0x57d1a51b. +// +// Solidity: function executeUpgrade(address app, (((bytes32,string)[],uint32),bytes,bytes) release) returns(uint256) +func (_AppController *AppControllerTransactor) ExecuteUpgrade(opts *bind.TransactOpts, app common.Address, release IAppControllerRelease) (*types.Transaction, error) { + return _AppController.contract.Transact(opts, "executeUpgrade", app, release) +} + +// ExecuteUpgrade is a paid mutator transaction binding the contract method 0x57d1a51b. +// +// Solidity: function executeUpgrade(address app, (((bytes32,string)[],uint32),bytes,bytes) release) returns(uint256) +func (_AppController *AppControllerSession) ExecuteUpgrade(app common.Address, release IAppControllerRelease) (*types.Transaction, error) { + return _AppController.Contract.ExecuteUpgrade(&_AppController.TransactOpts, app, release) +} + +// ExecuteUpgrade is a paid mutator transaction binding the contract method 0x57d1a51b. +// +// Solidity: function executeUpgrade(address app, (((bytes32,string)[],uint32),bytes,bytes) release) returns(uint256) +func (_AppController *AppControllerTransactorSession) ExecuteUpgrade(app common.Address, release IAppControllerRelease) (*types.Transaction, error) { + return _AppController.Contract.ExecuteUpgrade(&_AppController.TransactOpts, app, release) +} + +// GrantRole is a paid mutator transaction binding the contract method 0x2f2ff15d. +// +// Solidity: function grantRole(bytes32 role, address account) returns() +func (_AppController *AppControllerTransactor) GrantRole(opts *bind.TransactOpts, role [32]byte, account common.Address) (*types.Transaction, error) { + return _AppController.contract.Transact(opts, "grantRole", role, account) +} + +// GrantRole is a paid mutator transaction binding the contract method 0x2f2ff15d. +// +// Solidity: function grantRole(bytes32 role, address account) returns() +func (_AppController *AppControllerSession) GrantRole(role [32]byte, account common.Address) (*types.Transaction, error) { + return _AppController.Contract.GrantRole(&_AppController.TransactOpts, role, account) +} + +// GrantRole is a paid mutator transaction binding the contract method 0x2f2ff15d. +// +// Solidity: function grantRole(bytes32 role, address account) returns() +func (_AppController *AppControllerTransactorSession) GrantRole(role [32]byte, account common.Address) (*types.Transaction, error) { + return _AppController.Contract.GrantRole(&_AppController.TransactOpts, role, account) +} + +// GrantTeamRole is a paid mutator transaction binding the contract method 0x58f2c536. +// +// Solidity: function grantTeamRole(address team, uint8 role, address account) returns() +func (_AppController *AppControllerTransactor) GrantTeamRole(opts *bind.TransactOpts, team common.Address, role uint8, account common.Address) (*types.Transaction, error) { + return _AppController.contract.Transact(opts, "grantTeamRole", team, role, account) +} + +// GrantTeamRole is a paid mutator transaction binding the contract method 0x58f2c536. +// +// Solidity: function grantTeamRole(address team, uint8 role, address account) returns() +func (_AppController *AppControllerSession) GrantTeamRole(team common.Address, role uint8, account common.Address) (*types.Transaction, error) { + return _AppController.Contract.GrantTeamRole(&_AppController.TransactOpts, team, role, account) +} + +// GrantTeamRole is a paid mutator transaction binding the contract method 0x58f2c536. +// +// Solidity: function grantTeamRole(address team, uint8 role, address account) returns() +func (_AppController *AppControllerTransactorSession) GrantTeamRole(team common.Address, role uint8, account common.Address) (*types.Transaction, error) { + return _AppController.Contract.GrantTeamRole(&_AppController.TransactOpts, team, role, account) +} + +// Initialize is a paid mutator transaction binding the contract method 0xc4d66de8. +// +// Solidity: function initialize(address admin) returns() +func (_AppController *AppControllerTransactor) Initialize(opts *bind.TransactOpts, admin common.Address) (*types.Transaction, error) { + return _AppController.contract.Transact(opts, "initialize", admin) +} + +// Initialize is a paid mutator transaction binding the contract method 0xc4d66de8. +// +// Solidity: function initialize(address admin) returns() +func (_AppController *AppControllerSession) Initialize(admin common.Address) (*types.Transaction, error) { + return _AppController.Contract.Initialize(&_AppController.TransactOpts, admin) +} + +// Initialize is a paid mutator transaction binding the contract method 0xc4d66de8. +// +// Solidity: function initialize(address admin) returns() +func (_AppController *AppControllerTransactorSession) Initialize(admin common.Address) (*types.Transaction, error) { + return _AppController.Contract.Initialize(&_AppController.TransactOpts, admin) +} + +// MigrateAdmins is a paid mutator transaction binding the contract method 0x00b73d4c. +// +// Solidity: function migrateAdmins(address[] apps) returns() +func (_AppController *AppControllerTransactor) MigrateAdmins(opts *bind.TransactOpts, apps []common.Address) (*types.Transaction, error) { + return _AppController.contract.Transact(opts, "migrateAdmins", apps) +} + +// MigrateAdmins is a paid mutator transaction binding the contract method 0x00b73d4c. +// +// Solidity: function migrateAdmins(address[] apps) returns() +func (_AppController *AppControllerSession) MigrateAdmins(apps []common.Address) (*types.Transaction, error) { + return _AppController.Contract.MigrateAdmins(&_AppController.TransactOpts, apps) +} + +// MigrateAdmins is a paid mutator transaction binding the contract method 0x00b73d4c. +// +// Solidity: function migrateAdmins(address[] apps) returns() +func (_AppController *AppControllerTransactorSession) MigrateAdmins(apps []common.Address) (*types.Transaction, error) { + return _AppController.Contract.MigrateAdmins(&_AppController.TransactOpts, apps) +} + +// RenounceRole is a paid mutator transaction binding the contract method 0x36568abe. +// +// Solidity: function renounceRole(bytes32 role, address account) returns() +func (_AppController *AppControllerTransactor) RenounceRole(opts *bind.TransactOpts, role [32]byte, account common.Address) (*types.Transaction, error) { + return _AppController.contract.Transact(opts, "renounceRole", role, account) +} + +// RenounceRole is a paid mutator transaction binding the contract method 0x36568abe. +// +// Solidity: function renounceRole(bytes32 role, address account) returns() +func (_AppController *AppControllerSession) RenounceRole(role [32]byte, account common.Address) (*types.Transaction, error) { + return _AppController.Contract.RenounceRole(&_AppController.TransactOpts, role, account) +} + +// RenounceRole is a paid mutator transaction binding the contract method 0x36568abe. +// +// Solidity: function renounceRole(bytes32 role, address account) returns() +func (_AppController *AppControllerTransactorSession) RenounceRole(role [32]byte, account common.Address) (*types.Transaction, error) { + return _AppController.Contract.RenounceRole(&_AppController.TransactOpts, role, account) +} + +// RenounceTeamRole is a paid mutator transaction binding the contract method 0x17f4c90b. +// +// Solidity: function renounceTeamRole(address team, uint8 role) returns() +func (_AppController *AppControllerTransactor) RenounceTeamRole(opts *bind.TransactOpts, team common.Address, role uint8) (*types.Transaction, error) { + return _AppController.contract.Transact(opts, "renounceTeamRole", team, role) +} + +// RenounceTeamRole is a paid mutator transaction binding the contract method 0x17f4c90b. +// +// Solidity: function renounceTeamRole(address team, uint8 role) returns() +func (_AppController *AppControllerSession) RenounceTeamRole(team common.Address, role uint8) (*types.Transaction, error) { + return _AppController.Contract.RenounceTeamRole(&_AppController.TransactOpts, team, role) +} + +// RenounceTeamRole is a paid mutator transaction binding the contract method 0x17f4c90b. +// +// Solidity: function renounceTeamRole(address team, uint8 role) returns() +func (_AppController *AppControllerTransactorSession) RenounceTeamRole(team common.Address, role uint8) (*types.Transaction, error) { + return _AppController.Contract.RenounceTeamRole(&_AppController.TransactOpts, team, role) +} + +// RevokeRole is a paid mutator transaction binding the contract method 0xd547741f. +// +// Solidity: function revokeRole(bytes32 role, address account) returns() +func (_AppController *AppControllerTransactor) RevokeRole(opts *bind.TransactOpts, role [32]byte, account common.Address) (*types.Transaction, error) { + return _AppController.contract.Transact(opts, "revokeRole", role, account) +} + +// RevokeRole is a paid mutator transaction binding the contract method 0xd547741f. +// +// Solidity: function revokeRole(bytes32 role, address account) returns() +func (_AppController *AppControllerSession) RevokeRole(role [32]byte, account common.Address) (*types.Transaction, error) { + return _AppController.Contract.RevokeRole(&_AppController.TransactOpts, role, account) +} + +// RevokeRole is a paid mutator transaction binding the contract method 0xd547741f. +// +// Solidity: function revokeRole(bytes32 role, address account) returns() +func (_AppController *AppControllerTransactorSession) RevokeRole(role [32]byte, account common.Address) (*types.Transaction, error) { + return _AppController.Contract.RevokeRole(&_AppController.TransactOpts, role, account) +} + +// RevokeTeamRole is a paid mutator transaction binding the contract method 0x11b652e2. +// +// Solidity: function revokeTeamRole(address team, uint8 role, address account) returns() +func (_AppController *AppControllerTransactor) RevokeTeamRole(opts *bind.TransactOpts, team common.Address, role uint8, account common.Address) (*types.Transaction, error) { + return _AppController.contract.Transact(opts, "revokeTeamRole", team, role, account) +} + +// RevokeTeamRole is a paid mutator transaction binding the contract method 0x11b652e2. +// +// Solidity: function revokeTeamRole(address team, uint8 role, address account) returns() +func (_AppController *AppControllerSession) RevokeTeamRole(team common.Address, role uint8, account common.Address) (*types.Transaction, error) { + return _AppController.Contract.RevokeTeamRole(&_AppController.TransactOpts, team, role, account) +} + +// RevokeTeamRole is a paid mutator transaction binding the contract method 0x11b652e2. +// +// Solidity: function revokeTeamRole(address team, uint8 role, address account) returns() +func (_AppController *AppControllerTransactorSession) RevokeTeamRole(team common.Address, role uint8, account common.Address) (*types.Transaction, error) { + return _AppController.Contract.RevokeTeamRole(&_AppController.TransactOpts, team, role, account) +} + +// ScheduleUpgrade is a paid mutator transaction binding the contract method 0x890b78c4. +// +// Solidity: function scheduleUpgrade(address app, (((bytes32,string)[],uint32),bytes,bytes) release, uint256 delay) returns() +func (_AppController *AppControllerTransactor) ScheduleUpgrade(opts *bind.TransactOpts, app common.Address, release IAppControllerRelease, delay *big.Int) (*types.Transaction, error) { + return _AppController.contract.Transact(opts, "scheduleUpgrade", app, release, delay) +} + +// ScheduleUpgrade is a paid mutator transaction binding the contract method 0x890b78c4. +// +// Solidity: function scheduleUpgrade(address app, (((bytes32,string)[],uint32),bytes,bytes) release, uint256 delay) returns() +func (_AppController *AppControllerSession) ScheduleUpgrade(app common.Address, release IAppControllerRelease, delay *big.Int) (*types.Transaction, error) { + return _AppController.Contract.ScheduleUpgrade(&_AppController.TransactOpts, app, release, delay) +} + +// ScheduleUpgrade is a paid mutator transaction binding the contract method 0x890b78c4. +// +// Solidity: function scheduleUpgrade(address app, (((bytes32,string)[],uint32),bytes,bytes) release, uint256 delay) returns() +func (_AppController *AppControllerTransactorSession) ScheduleUpgrade(app common.Address, release IAppControllerRelease, delay *big.Int) (*types.Transaction, error) { + return _AppController.Contract.ScheduleUpgrade(&_AppController.TransactOpts, app, release, delay) +} + +// SetMaxActiveAppsPerUser is a paid mutator transaction binding the contract method 0xd49fec2b. +// +// Solidity: function setMaxActiveAppsPerUser(address user, uint32 limit) returns() +func (_AppController *AppControllerTransactor) SetMaxActiveAppsPerUser(opts *bind.TransactOpts, user common.Address, limit uint32) (*types.Transaction, error) { + return _AppController.contract.Transact(opts, "setMaxActiveAppsPerUser", user, limit) +} + +// SetMaxActiveAppsPerUser is a paid mutator transaction binding the contract method 0xd49fec2b. +// +// Solidity: function setMaxActiveAppsPerUser(address user, uint32 limit) returns() +func (_AppController *AppControllerSession) SetMaxActiveAppsPerUser(user common.Address, limit uint32) (*types.Transaction, error) { + return _AppController.Contract.SetMaxActiveAppsPerUser(&_AppController.TransactOpts, user, limit) +} + +// SetMaxActiveAppsPerUser is a paid mutator transaction binding the contract method 0xd49fec2b. +// +// Solidity: function setMaxActiveAppsPerUser(address user, uint32 limit) returns() +func (_AppController *AppControllerTransactorSession) SetMaxActiveAppsPerUser(user common.Address, limit uint32) (*types.Transaction, error) { + return _AppController.Contract.SetMaxActiveAppsPerUser(&_AppController.TransactOpts, user, limit) +} + +// SetMaxGlobalActiveApps is a paid mutator transaction binding the contract method 0xb438c141. +// +// Solidity: function setMaxGlobalActiveApps(uint32 limit) returns() +func (_AppController *AppControllerTransactor) SetMaxGlobalActiveApps(opts *bind.TransactOpts, limit uint32) (*types.Transaction, error) { + return _AppController.contract.Transact(opts, "setMaxGlobalActiveApps", limit) +} + +// SetMaxGlobalActiveApps is a paid mutator transaction binding the contract method 0xb438c141. +// +// Solidity: function setMaxGlobalActiveApps(uint32 limit) returns() +func (_AppController *AppControllerSession) SetMaxGlobalActiveApps(limit uint32) (*types.Transaction, error) { + return _AppController.Contract.SetMaxGlobalActiveApps(&_AppController.TransactOpts, limit) +} + +// SetMaxGlobalActiveApps is a paid mutator transaction binding the contract method 0xb438c141. +// +// Solidity: function setMaxGlobalActiveApps(uint32 limit) returns() +func (_AppController *AppControllerTransactorSession) SetMaxGlobalActiveApps(limit uint32) (*types.Transaction, error) { + return _AppController.Contract.SetMaxGlobalActiveApps(&_AppController.TransactOpts, limit) +} + +// StartApp is a paid mutator transaction binding the contract method 0x4dd8ef81. +// +// Solidity: function startApp(address app) returns() +func (_AppController *AppControllerTransactor) StartApp(opts *bind.TransactOpts, app common.Address) (*types.Transaction, error) { + return _AppController.contract.Transact(opts, "startApp", app) +} + +// StartApp is a paid mutator transaction binding the contract method 0x4dd8ef81. +// +// Solidity: function startApp(address app) returns() +func (_AppController *AppControllerSession) StartApp(app common.Address) (*types.Transaction, error) { + return _AppController.Contract.StartApp(&_AppController.TransactOpts, app) +} + +// StartApp is a paid mutator transaction binding the contract method 0x4dd8ef81. +// +// Solidity: function startApp(address app) returns() +func (_AppController *AppControllerTransactorSession) StartApp(app common.Address) (*types.Transaction, error) { + return _AppController.Contract.StartApp(&_AppController.TransactOpts, app) +} + +// StopApp is a paid mutator transaction binding the contract method 0xe70b81b1. +// +// Solidity: function stopApp(address app) returns() +func (_AppController *AppControllerTransactor) StopApp(opts *bind.TransactOpts, app common.Address) (*types.Transaction, error) { + return _AppController.contract.Transact(opts, "stopApp", app) +} + +// StopApp is a paid mutator transaction binding the contract method 0xe70b81b1. +// +// Solidity: function stopApp(address app) returns() +func (_AppController *AppControllerSession) StopApp(app common.Address) (*types.Transaction, error) { + return _AppController.Contract.StopApp(&_AppController.TransactOpts, app) +} + +// StopApp is a paid mutator transaction binding the contract method 0xe70b81b1. +// +// Solidity: function stopApp(address app) returns() +func (_AppController *AppControllerTransactorSession) StopApp(app common.Address) (*types.Transaction, error) { + return _AppController.Contract.StopApp(&_AppController.TransactOpts, app) +} + +// Suspend is a paid mutator transaction binding the contract method 0xcb1e6ff7. +// +// Solidity: function suspend(address account, address[] apps) returns() +func (_AppController *AppControllerTransactor) Suspend(opts *bind.TransactOpts, account common.Address, apps []common.Address) (*types.Transaction, error) { + return _AppController.contract.Transact(opts, "suspend", account, apps) +} + +// Suspend is a paid mutator transaction binding the contract method 0xcb1e6ff7. +// +// Solidity: function suspend(address account, address[] apps) returns() +func (_AppController *AppControllerSession) Suspend(account common.Address, apps []common.Address) (*types.Transaction, error) { + return _AppController.Contract.Suspend(&_AppController.TransactOpts, account, apps) +} + +// Suspend is a paid mutator transaction binding the contract method 0xcb1e6ff7. +// +// Solidity: function suspend(address account, address[] apps) returns() +func (_AppController *AppControllerTransactorSession) Suspend(account common.Address, apps []common.Address) (*types.Transaction, error) { + return _AppController.Contract.Suspend(&_AppController.TransactOpts, account, apps) +} + +// TerminateApp is a paid mutator transaction binding the contract method 0x90e2196b. +// +// Solidity: function terminateApp(address app) returns() +func (_AppController *AppControllerTransactor) TerminateApp(opts *bind.TransactOpts, app common.Address) (*types.Transaction, error) { + return _AppController.contract.Transact(opts, "terminateApp", app) +} + +// TerminateApp is a paid mutator transaction binding the contract method 0x90e2196b. +// +// Solidity: function terminateApp(address app) returns() +func (_AppController *AppControllerSession) TerminateApp(app common.Address) (*types.Transaction, error) { + return _AppController.Contract.TerminateApp(&_AppController.TransactOpts, app) +} + +// TerminateApp is a paid mutator transaction binding the contract method 0x90e2196b. +// +// Solidity: function terminateApp(address app) returns() +func (_AppController *AppControllerTransactorSession) TerminateApp(app common.Address) (*types.Transaction, error) { + return _AppController.Contract.TerminateApp(&_AppController.TransactOpts, app) +} + +// TerminateAppByAdmin is a paid mutator transaction binding the contract method 0xd66f7771. +// +// Solidity: function terminateAppByAdmin(address app) returns() +func (_AppController *AppControllerTransactor) TerminateAppByAdmin(opts *bind.TransactOpts, app common.Address) (*types.Transaction, error) { + return _AppController.contract.Transact(opts, "terminateAppByAdmin", app) +} + +// TerminateAppByAdmin is a paid mutator transaction binding the contract method 0xd66f7771. +// +// Solidity: function terminateAppByAdmin(address app) returns() +func (_AppController *AppControllerSession) TerminateAppByAdmin(app common.Address) (*types.Transaction, error) { + return _AppController.Contract.TerminateAppByAdmin(&_AppController.TransactOpts, app) +} + +// TerminateAppByAdmin is a paid mutator transaction binding the contract method 0xd66f7771. +// +// Solidity: function terminateAppByAdmin(address app) returns() +func (_AppController *AppControllerTransactorSession) TerminateAppByAdmin(app common.Address) (*types.Transaction, error) { + return _AppController.Contract.TerminateAppByAdmin(&_AppController.TransactOpts, app) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0x6d435421. +// +// Solidity: function transferOwnership(address app, address newOwner) returns() +func (_AppController *AppControllerTransactor) TransferOwnership(opts *bind.TransactOpts, app common.Address, newOwner common.Address) (*types.Transaction, error) { + return _AppController.contract.Transact(opts, "transferOwnership", app, newOwner) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0x6d435421. +// +// Solidity: function transferOwnership(address app, address newOwner) returns() +func (_AppController *AppControllerSession) TransferOwnership(app common.Address, newOwner common.Address) (*types.Transaction, error) { + return _AppController.Contract.TransferOwnership(&_AppController.TransactOpts, app, newOwner) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0x6d435421. +// +// Solidity: function transferOwnership(address app, address newOwner) returns() +func (_AppController *AppControllerTransactorSession) TransferOwnership(app common.Address, newOwner common.Address) (*types.Transaction, error) { + return _AppController.Contract.TransferOwnership(&_AppController.TransactOpts, app, newOwner) +} + +// UpdateAppMetadataURI is a paid mutator transaction binding the contract method 0x65aa9a65. +// +// Solidity: function updateAppMetadataURI(address app, string metadataURI) returns() +func (_AppController *AppControllerTransactor) UpdateAppMetadataURI(opts *bind.TransactOpts, app common.Address, metadataURI string) (*types.Transaction, error) { + return _AppController.contract.Transact(opts, "updateAppMetadataURI", app, metadataURI) +} + +// UpdateAppMetadataURI is a paid mutator transaction binding the contract method 0x65aa9a65. +// +// Solidity: function updateAppMetadataURI(address app, string metadataURI) returns() +func (_AppController *AppControllerSession) UpdateAppMetadataURI(app common.Address, metadataURI string) (*types.Transaction, error) { + return _AppController.Contract.UpdateAppMetadataURI(&_AppController.TransactOpts, app, metadataURI) +} + +// UpdateAppMetadataURI is a paid mutator transaction binding the contract method 0x65aa9a65. +// +// Solidity: function updateAppMetadataURI(address app, string metadataURI) returns() +func (_AppController *AppControllerTransactorSession) UpdateAppMetadataURI(app common.Address, metadataURI string) (*types.Transaction, error) { + return _AppController.Contract.UpdateAppMetadataURI(&_AppController.TransactOpts, app, metadataURI) +} + +// UpgradeApp is a paid mutator transaction binding the contract method 0xd80a956b. +// +// Solidity: function upgradeApp(address app, (((bytes32,string)[],uint32),bytes,bytes) release) returns(uint256) +func (_AppController *AppControllerTransactor) UpgradeApp(opts *bind.TransactOpts, app common.Address, release IAppControllerRelease) (*types.Transaction, error) { + return _AppController.contract.Transact(opts, "upgradeApp", app, release) +} + +// UpgradeApp is a paid mutator transaction binding the contract method 0xd80a956b. +// +// Solidity: function upgradeApp(address app, (((bytes32,string)[],uint32),bytes,bytes) release) returns(uint256) +func (_AppController *AppControllerSession) UpgradeApp(app common.Address, release IAppControllerRelease) (*types.Transaction, error) { + return _AppController.Contract.UpgradeApp(&_AppController.TransactOpts, app, release) +} + +// UpgradeApp is a paid mutator transaction binding the contract method 0xd80a956b. +// +// Solidity: function upgradeApp(address app, (((bytes32,string)[],uint32),bytes,bytes) release) returns(uint256) +func (_AppController *AppControllerTransactorSession) UpgradeApp(app common.Address, release IAppControllerRelease) (*types.Transaction, error) { + return _AppController.Contract.UpgradeApp(&_AppController.TransactOpts, app, release) +} + +// AppControllerAppCreatedIterator is returned from FilterAppCreated and is used to iterate over the raw logs and unpacked data for AppCreated events raised by the AppController contract. +type AppControllerAppCreatedIterator struct { + Event *AppControllerAppCreated // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *AppControllerAppCreatedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(AppControllerAppCreated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(AppControllerAppCreated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *AppControllerAppCreatedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *AppControllerAppCreatedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// AppControllerAppCreated represents a AppCreated event raised by the AppController contract. +type AppControllerAppCreated struct { + Owner common.Address + App common.Address + OperatorSetId uint32 + Raw types.Log // Blockchain specific contextual infos +} + +// FilterAppCreated is a free log retrieval operation binding the contract event 0xe9e6e5409b80e2dab7d38194fb370b2e8045a1af28177b94ddcf19d2495d7589. +// +// Solidity: event AppCreated(address indexed owner, address indexed app, uint32 operatorSetId) +func (_AppController *AppControllerFilterer) FilterAppCreated(opts *bind.FilterOpts, owner []common.Address, app []common.Address) (*AppControllerAppCreatedIterator, error) { + + var ownerRule []interface{} + for _, ownerItem := range owner { + ownerRule = append(ownerRule, ownerItem) + } + var appRule []interface{} + for _, appItem := range app { + appRule = append(appRule, appItem) + } + + logs, sub, err := _AppController.contract.FilterLogs(opts, "AppCreated", ownerRule, appRule) + if err != nil { + return nil, err + } + return &AppControllerAppCreatedIterator{contract: _AppController.contract, event: "AppCreated", logs: logs, sub: sub}, nil +} + +// WatchAppCreated is a free log subscription operation binding the contract event 0xe9e6e5409b80e2dab7d38194fb370b2e8045a1af28177b94ddcf19d2495d7589. +// +// Solidity: event AppCreated(address indexed owner, address indexed app, uint32 operatorSetId) +func (_AppController *AppControllerFilterer) WatchAppCreated(opts *bind.WatchOpts, sink chan<- *AppControllerAppCreated, owner []common.Address, app []common.Address) (event.Subscription, error) { + + var ownerRule []interface{} + for _, ownerItem := range owner { + ownerRule = append(ownerRule, ownerItem) + } + var appRule []interface{} + for _, appItem := range app { + appRule = append(appRule, appItem) + } + + logs, sub, err := _AppController.contract.WatchLogs(opts, "AppCreated", ownerRule, appRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(AppControllerAppCreated) + if err := _AppController.contract.UnpackLog(event, "AppCreated", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseAppCreated is a log parse operation binding the contract event 0xe9e6e5409b80e2dab7d38194fb370b2e8045a1af28177b94ddcf19d2495d7589. +// +// Solidity: event AppCreated(address indexed owner, address indexed app, uint32 operatorSetId) +func (_AppController *AppControllerFilterer) ParseAppCreated(log types.Log) (*AppControllerAppCreated, error) { + event := new(AppControllerAppCreated) + if err := _AppController.contract.UnpackLog(event, "AppCreated", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// AppControllerAppMetadataURIUpdatedIterator is returned from FilterAppMetadataURIUpdated and is used to iterate over the raw logs and unpacked data for AppMetadataURIUpdated events raised by the AppController contract. +type AppControllerAppMetadataURIUpdatedIterator struct { + Event *AppControllerAppMetadataURIUpdated // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *AppControllerAppMetadataURIUpdatedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(AppControllerAppMetadataURIUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(AppControllerAppMetadataURIUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *AppControllerAppMetadataURIUpdatedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *AppControllerAppMetadataURIUpdatedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// AppControllerAppMetadataURIUpdated represents a AppMetadataURIUpdated event raised by the AppController contract. +type AppControllerAppMetadataURIUpdated struct { + App common.Address + MetadataURI string + Raw types.Log // Blockchain specific contextual infos +} + +// FilterAppMetadataURIUpdated is a free log retrieval operation binding the contract event 0xc874c4e2852c19bd03d42a5232ce93e85f2da325dddac46c2472043b7f0d7e8d. +// +// Solidity: event AppMetadataURIUpdated(address indexed app, string metadataURI) +func (_AppController *AppControllerFilterer) FilterAppMetadataURIUpdated(opts *bind.FilterOpts, app []common.Address) (*AppControllerAppMetadataURIUpdatedIterator, error) { + + var appRule []interface{} + for _, appItem := range app { + appRule = append(appRule, appItem) + } + + logs, sub, err := _AppController.contract.FilterLogs(opts, "AppMetadataURIUpdated", appRule) + if err != nil { + return nil, err + } + return &AppControllerAppMetadataURIUpdatedIterator{contract: _AppController.contract, event: "AppMetadataURIUpdated", logs: logs, sub: sub}, nil +} + +// WatchAppMetadataURIUpdated is a free log subscription operation binding the contract event 0xc874c4e2852c19bd03d42a5232ce93e85f2da325dddac46c2472043b7f0d7e8d. +// +// Solidity: event AppMetadataURIUpdated(address indexed app, string metadataURI) +func (_AppController *AppControllerFilterer) WatchAppMetadataURIUpdated(opts *bind.WatchOpts, sink chan<- *AppControllerAppMetadataURIUpdated, app []common.Address) (event.Subscription, error) { + + var appRule []interface{} + for _, appItem := range app { + appRule = append(appRule, appItem) + } + + logs, sub, err := _AppController.contract.WatchLogs(opts, "AppMetadataURIUpdated", appRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(AppControllerAppMetadataURIUpdated) + if err := _AppController.contract.UnpackLog(event, "AppMetadataURIUpdated", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseAppMetadataURIUpdated is a log parse operation binding the contract event 0xc874c4e2852c19bd03d42a5232ce93e85f2da325dddac46c2472043b7f0d7e8d. +// +// Solidity: event AppMetadataURIUpdated(address indexed app, string metadataURI) +func (_AppController *AppControllerFilterer) ParseAppMetadataURIUpdated(log types.Log) (*AppControllerAppMetadataURIUpdated, error) { + event := new(AppControllerAppMetadataURIUpdated) + if err := _AppController.contract.UnpackLog(event, "AppMetadataURIUpdated", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// AppControllerAppOwnershipTransferredIterator is returned from FilterAppOwnershipTransferred and is used to iterate over the raw logs and unpacked data for AppOwnershipTransferred events raised by the AppController contract. +type AppControllerAppOwnershipTransferredIterator struct { + Event *AppControllerAppOwnershipTransferred // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *AppControllerAppOwnershipTransferredIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(AppControllerAppOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(AppControllerAppOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *AppControllerAppOwnershipTransferredIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *AppControllerAppOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// AppControllerAppOwnershipTransferred represents a AppOwnershipTransferred event raised by the AppController contract. +type AppControllerAppOwnershipTransferred struct { + App common.Address + PreviousOwner common.Address + NewOwner common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterAppOwnershipTransferred is a free log retrieval operation binding the contract event 0x3fa03516e5ee455b2d2779f21b254735e2c1f82cf338619c1b96816df2a467a4. +// +// Solidity: event AppOwnershipTransferred(address indexed app, address indexed previousOwner, address indexed newOwner) +func (_AppController *AppControllerFilterer) FilterAppOwnershipTransferred(opts *bind.FilterOpts, app []common.Address, previousOwner []common.Address, newOwner []common.Address) (*AppControllerAppOwnershipTransferredIterator, error) { + + var appRule []interface{} + for _, appItem := range app { + appRule = append(appRule, appItem) + } + var previousOwnerRule []interface{} + for _, previousOwnerItem := range previousOwner { + previousOwnerRule = append(previousOwnerRule, previousOwnerItem) + } + var newOwnerRule []interface{} + for _, newOwnerItem := range newOwner { + newOwnerRule = append(newOwnerRule, newOwnerItem) + } + + logs, sub, err := _AppController.contract.FilterLogs(opts, "AppOwnershipTransferred", appRule, previousOwnerRule, newOwnerRule) + if err != nil { + return nil, err + } + return &AppControllerAppOwnershipTransferredIterator{contract: _AppController.contract, event: "AppOwnershipTransferred", logs: logs, sub: sub}, nil +} + +// WatchAppOwnershipTransferred is a free log subscription operation binding the contract event 0x3fa03516e5ee455b2d2779f21b254735e2c1f82cf338619c1b96816df2a467a4. +// +// Solidity: event AppOwnershipTransferred(address indexed app, address indexed previousOwner, address indexed newOwner) +func (_AppController *AppControllerFilterer) WatchAppOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *AppControllerAppOwnershipTransferred, app []common.Address, previousOwner []common.Address, newOwner []common.Address) (event.Subscription, error) { + + var appRule []interface{} + for _, appItem := range app { + appRule = append(appRule, appItem) + } + var previousOwnerRule []interface{} + for _, previousOwnerItem := range previousOwner { + previousOwnerRule = append(previousOwnerRule, previousOwnerItem) + } + var newOwnerRule []interface{} + for _, newOwnerItem := range newOwner { + newOwnerRule = append(newOwnerRule, newOwnerItem) + } + + logs, sub, err := _AppController.contract.WatchLogs(opts, "AppOwnershipTransferred", appRule, previousOwnerRule, newOwnerRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(AppControllerAppOwnershipTransferred) + if err := _AppController.contract.UnpackLog(event, "AppOwnershipTransferred", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseAppOwnershipTransferred is a log parse operation binding the contract event 0x3fa03516e5ee455b2d2779f21b254735e2c1f82cf338619c1b96816df2a467a4. +// +// Solidity: event AppOwnershipTransferred(address indexed app, address indexed previousOwner, address indexed newOwner) +func (_AppController *AppControllerFilterer) ParseAppOwnershipTransferred(log types.Log) (*AppControllerAppOwnershipTransferred, error) { + event := new(AppControllerAppOwnershipTransferred) + if err := _AppController.contract.UnpackLog(event, "AppOwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// AppControllerAppStartedIterator is returned from FilterAppStarted and is used to iterate over the raw logs and unpacked data for AppStarted events raised by the AppController contract. +type AppControllerAppStartedIterator struct { + Event *AppControllerAppStarted // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *AppControllerAppStartedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(AppControllerAppStarted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(AppControllerAppStarted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *AppControllerAppStartedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *AppControllerAppStartedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// AppControllerAppStarted represents a AppStarted event raised by the AppController contract. +type AppControllerAppStarted struct { + App common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterAppStarted is a free log retrieval operation binding the contract event 0x8426864999f5f9244a203f75107b05f8b474838bc43ff0d8abe18ee5f4427513. +// +// Solidity: event AppStarted(address indexed app) +func (_AppController *AppControllerFilterer) FilterAppStarted(opts *bind.FilterOpts, app []common.Address) (*AppControllerAppStartedIterator, error) { + + var appRule []interface{} + for _, appItem := range app { + appRule = append(appRule, appItem) + } + + logs, sub, err := _AppController.contract.FilterLogs(opts, "AppStarted", appRule) + if err != nil { + return nil, err + } + return &AppControllerAppStartedIterator{contract: _AppController.contract, event: "AppStarted", logs: logs, sub: sub}, nil +} + +// WatchAppStarted is a free log subscription operation binding the contract event 0x8426864999f5f9244a203f75107b05f8b474838bc43ff0d8abe18ee5f4427513. +// +// Solidity: event AppStarted(address indexed app) +func (_AppController *AppControllerFilterer) WatchAppStarted(opts *bind.WatchOpts, sink chan<- *AppControllerAppStarted, app []common.Address) (event.Subscription, error) { + + var appRule []interface{} + for _, appItem := range app { + appRule = append(appRule, appItem) + } + + logs, sub, err := _AppController.contract.WatchLogs(opts, "AppStarted", appRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(AppControllerAppStarted) + if err := _AppController.contract.UnpackLog(event, "AppStarted", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseAppStarted is a log parse operation binding the contract event 0x8426864999f5f9244a203f75107b05f8b474838bc43ff0d8abe18ee5f4427513. +// +// Solidity: event AppStarted(address indexed app) +func (_AppController *AppControllerFilterer) ParseAppStarted(log types.Log) (*AppControllerAppStarted, error) { + event := new(AppControllerAppStarted) + if err := _AppController.contract.UnpackLog(event, "AppStarted", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// AppControllerAppStoppedIterator is returned from FilterAppStopped and is used to iterate over the raw logs and unpacked data for AppStopped events raised by the AppController contract. +type AppControllerAppStoppedIterator struct { + Event *AppControllerAppStopped // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *AppControllerAppStoppedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(AppControllerAppStopped) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(AppControllerAppStopped) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *AppControllerAppStoppedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *AppControllerAppStoppedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// AppControllerAppStopped represents a AppStopped event raised by the AppController contract. +type AppControllerAppStopped struct { + App common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterAppStopped is a free log retrieval operation binding the contract event 0x143b9e3b5aa0fb8cf19b1bdb2eb8d7a94657d4b505070c667433d322b90b1f78. +// +// Solidity: event AppStopped(address indexed app) +func (_AppController *AppControllerFilterer) FilterAppStopped(opts *bind.FilterOpts, app []common.Address) (*AppControllerAppStoppedIterator, error) { + + var appRule []interface{} + for _, appItem := range app { + appRule = append(appRule, appItem) + } + + logs, sub, err := _AppController.contract.FilterLogs(opts, "AppStopped", appRule) + if err != nil { + return nil, err + } + return &AppControllerAppStoppedIterator{contract: _AppController.contract, event: "AppStopped", logs: logs, sub: sub}, nil +} + +// WatchAppStopped is a free log subscription operation binding the contract event 0x143b9e3b5aa0fb8cf19b1bdb2eb8d7a94657d4b505070c667433d322b90b1f78. +// +// Solidity: event AppStopped(address indexed app) +func (_AppController *AppControllerFilterer) WatchAppStopped(opts *bind.WatchOpts, sink chan<- *AppControllerAppStopped, app []common.Address) (event.Subscription, error) { + + var appRule []interface{} + for _, appItem := range app { + appRule = append(appRule, appItem) + } + + logs, sub, err := _AppController.contract.WatchLogs(opts, "AppStopped", appRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(AppControllerAppStopped) + if err := _AppController.contract.UnpackLog(event, "AppStopped", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil } -// StopApp is a paid mutator transaction binding the contract method 0xe70b81b1. +// ParseAppStopped is a log parse operation binding the contract event 0x143b9e3b5aa0fb8cf19b1bdb2eb8d7a94657d4b505070c667433d322b90b1f78. // -// Solidity: function stopApp(address app) returns() -func (_AppController *AppControllerTransactor) StopApp(opts *bind.TransactOpts, app common.Address) (*types.Transaction, error) { - return _AppController.contract.Transact(opts, "stopApp", app) +// Solidity: event AppStopped(address indexed app) +func (_AppController *AppControllerFilterer) ParseAppStopped(log types.Log) (*AppControllerAppStopped, error) { + event := new(AppControllerAppStopped) + if err := _AppController.contract.UnpackLog(event, "AppStopped", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil } -// StopApp is a paid mutator transaction binding the contract method 0xe70b81b1. -// -// Solidity: function stopApp(address app) returns() -func (_AppController *AppControllerSession) StopApp(app common.Address) (*types.Transaction, error) { - return _AppController.Contract.StopApp(&_AppController.TransactOpts, app) -} +// AppControllerAppSuspendedIterator is returned from FilterAppSuspended and is used to iterate over the raw logs and unpacked data for AppSuspended events raised by the AppController contract. +type AppControllerAppSuspendedIterator struct { + Event *AppControllerAppSuspended // Event containing the contract specifics and raw log -// StopApp is a paid mutator transaction binding the contract method 0xe70b81b1. -// -// Solidity: function stopApp(address app) returns() -func (_AppController *AppControllerTransactorSession) StopApp(app common.Address) (*types.Transaction, error) { - return _AppController.Contract.StopApp(&_AppController.TransactOpts, app) -} + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data -// Suspend is a paid mutator transaction binding the contract method 0xcb1e6ff7. -// -// Solidity: function suspend(address account, address[] apps) returns() -func (_AppController *AppControllerTransactor) Suspend(opts *bind.TransactOpts, account common.Address, apps []common.Address) (*types.Transaction, error) { - return _AppController.contract.Transact(opts, "suspend", account, apps) + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration } -// Suspend is a paid mutator transaction binding the contract method 0xcb1e6ff7. -// -// Solidity: function suspend(address account, address[] apps) returns() -func (_AppController *AppControllerSession) Suspend(account common.Address, apps []common.Address) (*types.Transaction, error) { - return _AppController.Contract.Suspend(&_AppController.TransactOpts, account, apps) -} +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *AppControllerAppSuspendedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(AppControllerAppSuspended) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true -// Suspend is a paid mutator transaction binding the contract method 0xcb1e6ff7. -// -// Solidity: function suspend(address account, address[] apps) returns() -func (_AppController *AppControllerTransactorSession) Suspend(account common.Address, apps []common.Address) (*types.Transaction, error) { - return _AppController.Contract.Suspend(&_AppController.TransactOpts, account, apps) -} + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(AppControllerAppSuspended) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true -// TerminateApp is a paid mutator transaction binding the contract method 0x90e2196b. -// -// Solidity: function terminateApp(address app) returns() -func (_AppController *AppControllerTransactor) TerminateApp(opts *bind.TransactOpts, app common.Address) (*types.Transaction, error) { - return _AppController.contract.Transact(opts, "terminateApp", app) + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } } -// TerminateApp is a paid mutator transaction binding the contract method 0x90e2196b. -// -// Solidity: function terminateApp(address app) returns() -func (_AppController *AppControllerSession) TerminateApp(app common.Address) (*types.Transaction, error) { - return _AppController.Contract.TerminateApp(&_AppController.TransactOpts, app) +// Error returns any retrieval or parsing error occurred during filtering. +func (it *AppControllerAppSuspendedIterator) Error() error { + return it.fail } -// TerminateApp is a paid mutator transaction binding the contract method 0x90e2196b. -// -// Solidity: function terminateApp(address app) returns() -func (_AppController *AppControllerTransactorSession) TerminateApp(app common.Address) (*types.Transaction, error) { - return _AppController.Contract.TerminateApp(&_AppController.TransactOpts, app) +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *AppControllerAppSuspendedIterator) Close() error { + it.sub.Unsubscribe() + return nil } -// TerminateAppByAdmin is a paid mutator transaction binding the contract method 0xd66f7771. -// -// Solidity: function terminateAppByAdmin(address app) returns() -func (_AppController *AppControllerTransactor) TerminateAppByAdmin(opts *bind.TransactOpts, app common.Address) (*types.Transaction, error) { - return _AppController.contract.Transact(opts, "terminateAppByAdmin", app) +// AppControllerAppSuspended represents a AppSuspended event raised by the AppController contract. +type AppControllerAppSuspended struct { + App common.Address + Raw types.Log // Blockchain specific contextual infos } -// TerminateAppByAdmin is a paid mutator transaction binding the contract method 0xd66f7771. +// FilterAppSuspended is a free log retrieval operation binding the contract event 0xbb85757a09bd73484c9fb6857c3e9f8dbf92c3e22ce1655213c9481dacf81c62. // -// Solidity: function terminateAppByAdmin(address app) returns() -func (_AppController *AppControllerSession) TerminateAppByAdmin(app common.Address) (*types.Transaction, error) { - return _AppController.Contract.TerminateAppByAdmin(&_AppController.TransactOpts, app) -} +// Solidity: event AppSuspended(address indexed app) +func (_AppController *AppControllerFilterer) FilterAppSuspended(opts *bind.FilterOpts, app []common.Address) (*AppControllerAppSuspendedIterator, error) { -// TerminateAppByAdmin is a paid mutator transaction binding the contract method 0xd66f7771. -// -// Solidity: function terminateAppByAdmin(address app) returns() -func (_AppController *AppControllerTransactorSession) TerminateAppByAdmin(app common.Address) (*types.Transaction, error) { - return _AppController.Contract.TerminateAppByAdmin(&_AppController.TransactOpts, app) -} + var appRule []interface{} + for _, appItem := range app { + appRule = append(appRule, appItem) + } -// UpdateAppMetadataURI is a paid mutator transaction binding the contract method 0x65aa9a65. -// -// Solidity: function updateAppMetadataURI(address app, string metadataURI) returns() -func (_AppController *AppControllerTransactor) UpdateAppMetadataURI(opts *bind.TransactOpts, app common.Address, metadataURI string) (*types.Transaction, error) { - return _AppController.contract.Transact(opts, "updateAppMetadataURI", app, metadataURI) + logs, sub, err := _AppController.contract.FilterLogs(opts, "AppSuspended", appRule) + if err != nil { + return nil, err + } + return &AppControllerAppSuspendedIterator{contract: _AppController.contract, event: "AppSuspended", logs: logs, sub: sub}, nil } -// UpdateAppMetadataURI is a paid mutator transaction binding the contract method 0x65aa9a65. +// WatchAppSuspended is a free log subscription operation binding the contract event 0xbb85757a09bd73484c9fb6857c3e9f8dbf92c3e22ce1655213c9481dacf81c62. // -// Solidity: function updateAppMetadataURI(address app, string metadataURI) returns() -func (_AppController *AppControllerSession) UpdateAppMetadataURI(app common.Address, metadataURI string) (*types.Transaction, error) { - return _AppController.Contract.UpdateAppMetadataURI(&_AppController.TransactOpts, app, metadataURI) -} +// Solidity: event AppSuspended(address indexed app) +func (_AppController *AppControllerFilterer) WatchAppSuspended(opts *bind.WatchOpts, sink chan<- *AppControllerAppSuspended, app []common.Address) (event.Subscription, error) { -// UpdateAppMetadataURI is a paid mutator transaction binding the contract method 0x65aa9a65. -// -// Solidity: function updateAppMetadataURI(address app, string metadataURI) returns() -func (_AppController *AppControllerTransactorSession) UpdateAppMetadataURI(app common.Address, metadataURI string) (*types.Transaction, error) { - return _AppController.Contract.UpdateAppMetadataURI(&_AppController.TransactOpts, app, metadataURI) -} + var appRule []interface{} + for _, appItem := range app { + appRule = append(appRule, appItem) + } -// UpgradeApp is a paid mutator transaction binding the contract method 0xd80a956b. -// -// Solidity: function upgradeApp(address app, (((bytes32,string)[],uint32),bytes,bytes) release) returns(uint256) -func (_AppController *AppControllerTransactor) UpgradeApp(opts *bind.TransactOpts, app common.Address, release IAppControllerRelease) (*types.Transaction, error) { - return _AppController.contract.Transact(opts, "upgradeApp", app, release) -} + logs, sub, err := _AppController.contract.WatchLogs(opts, "AppSuspended", appRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(AppControllerAppSuspended) + if err := _AppController.contract.UnpackLog(event, "AppSuspended", log); err != nil { + return err + } + event.Raw = log -// UpgradeApp is a paid mutator transaction binding the contract method 0xd80a956b. -// -// Solidity: function upgradeApp(address app, (((bytes32,string)[],uint32),bytes,bytes) release) returns(uint256) -func (_AppController *AppControllerSession) UpgradeApp(app common.Address, release IAppControllerRelease) (*types.Transaction, error) { - return _AppController.Contract.UpgradeApp(&_AppController.TransactOpts, app, release) + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil } -// UpgradeApp is a paid mutator transaction binding the contract method 0xd80a956b. +// ParseAppSuspended is a log parse operation binding the contract event 0xbb85757a09bd73484c9fb6857c3e9f8dbf92c3e22ce1655213c9481dacf81c62. // -// Solidity: function upgradeApp(address app, (((bytes32,string)[],uint32),bytes,bytes) release) returns(uint256) -func (_AppController *AppControllerTransactorSession) UpgradeApp(app common.Address, release IAppControllerRelease) (*types.Transaction, error) { - return _AppController.Contract.UpgradeApp(&_AppController.TransactOpts, app, release) +// Solidity: event AppSuspended(address indexed app) +func (_AppController *AppControllerFilterer) ParseAppSuspended(log types.Log) (*AppControllerAppSuspended, error) { + event := new(AppControllerAppSuspended) + if err := _AppController.contract.UnpackLog(event, "AppSuspended", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil } -// AppControllerAppCreatedIterator is returned from FilterAppCreated and is used to iterate over the raw logs and unpacked data for AppCreated events raised by the AppController contract. -type AppControllerAppCreatedIterator struct { - Event *AppControllerAppCreated // Event containing the contract specifics and raw log +// AppControllerAppTerminatedIterator is returned from FilterAppTerminated and is used to iterate over the raw logs and unpacked data for AppTerminated events raised by the AppController contract. +type AppControllerAppTerminatedIterator struct { + Event *AppControllerAppTerminated // Event containing the contract specifics and raw log contract *bind.BoundContract // Generic contract to use for unpacking event data event string // Event name to use for unpacking event data @@ -1275,7 +2740,7 @@ type AppControllerAppCreatedIterator struct { // Next advances the iterator to the subsequent event, returning whether there // are any more events found. In case of a retrieval or parsing error, false is // returned and Error() can be queried for the exact failure. -func (it *AppControllerAppCreatedIterator) Next() bool { +func (it *AppControllerAppTerminatedIterator) Next() bool { // If the iterator failed, stop iterating if it.fail != nil { return false @@ -1284,7 +2749,7 @@ func (it *AppControllerAppCreatedIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(AppControllerAppCreated) + it.Event = new(AppControllerAppTerminated) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1299,7 +2764,7 @@ func (it *AppControllerAppCreatedIterator) Next() bool { // Iterator still in progress, wait for either a data or an error event select { case log := <-it.logs: - it.Event = new(AppControllerAppCreated) + it.Event = new(AppControllerAppTerminated) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1315,61 +2780,51 @@ func (it *AppControllerAppCreatedIterator) Next() bool { } // Error returns any retrieval or parsing error occurred during filtering. -func (it *AppControllerAppCreatedIterator) Error() error { +func (it *AppControllerAppTerminatedIterator) Error() error { return it.fail } // Close terminates the iteration process, releasing any pending underlying // resources. -func (it *AppControllerAppCreatedIterator) Close() error { +func (it *AppControllerAppTerminatedIterator) Close() error { it.sub.Unsubscribe() return nil } -// AppControllerAppCreated represents a AppCreated event raised by the AppController contract. -type AppControllerAppCreated struct { - Creator common.Address - App common.Address - OperatorSetId uint32 - Raw types.Log // Blockchain specific contextual infos +// AppControllerAppTerminated represents a AppTerminated event raised by the AppController contract. +type AppControllerAppTerminated struct { + App common.Address + Raw types.Log // Blockchain specific contextual infos } -// FilterAppCreated is a free log retrieval operation binding the contract event 0xe9e6e5409b80e2dab7d38194fb370b2e8045a1af28177b94ddcf19d2495d7589. +// FilterAppTerminated is a free log retrieval operation binding the contract event 0x2465e924a1e9a02843493e65702fd09152c8a631caf7b9b58e4b01ee20ced416. // -// Solidity: event AppCreated(address indexed creator, address indexed app, uint32 operatorSetId) -func (_AppController *AppControllerFilterer) FilterAppCreated(opts *bind.FilterOpts, creator []common.Address, app []common.Address) (*AppControllerAppCreatedIterator, error) { +// Solidity: event AppTerminated(address indexed app) +func (_AppController *AppControllerFilterer) FilterAppTerminated(opts *bind.FilterOpts, app []common.Address) (*AppControllerAppTerminatedIterator, error) { - var creatorRule []interface{} - for _, creatorItem := range creator { - creatorRule = append(creatorRule, creatorItem) - } var appRule []interface{} for _, appItem := range app { appRule = append(appRule, appItem) } - logs, sub, err := _AppController.contract.FilterLogs(opts, "AppCreated", creatorRule, appRule) + logs, sub, err := _AppController.contract.FilterLogs(opts, "AppTerminated", appRule) if err != nil { return nil, err } - return &AppControllerAppCreatedIterator{contract: _AppController.contract, event: "AppCreated", logs: logs, sub: sub}, nil + return &AppControllerAppTerminatedIterator{contract: _AppController.contract, event: "AppTerminated", logs: logs, sub: sub}, nil } -// WatchAppCreated is a free log subscription operation binding the contract event 0xe9e6e5409b80e2dab7d38194fb370b2e8045a1af28177b94ddcf19d2495d7589. +// WatchAppTerminated is a free log subscription operation binding the contract event 0x2465e924a1e9a02843493e65702fd09152c8a631caf7b9b58e4b01ee20ced416. // -// Solidity: event AppCreated(address indexed creator, address indexed app, uint32 operatorSetId) -func (_AppController *AppControllerFilterer) WatchAppCreated(opts *bind.WatchOpts, sink chan<- *AppControllerAppCreated, creator []common.Address, app []common.Address) (event.Subscription, error) { +// Solidity: event AppTerminated(address indexed app) +func (_AppController *AppControllerFilterer) WatchAppTerminated(opts *bind.WatchOpts, sink chan<- *AppControllerAppTerminated, app []common.Address) (event.Subscription, error) { - var creatorRule []interface{} - for _, creatorItem := range creator { - creatorRule = append(creatorRule, creatorItem) - } var appRule []interface{} for _, appItem := range app { appRule = append(appRule, appItem) } - logs, sub, err := _AppController.contract.WatchLogs(opts, "AppCreated", creatorRule, appRule) + logs, sub, err := _AppController.contract.WatchLogs(opts, "AppTerminated", appRule) if err != nil { return nil, err } @@ -1379,8 +2834,8 @@ func (_AppController *AppControllerFilterer) WatchAppCreated(opts *bind.WatchOpt select { case log := <-logs: // New log arrived, parse the event and forward to the user - event := new(AppControllerAppCreated) - if err := _AppController.contract.UnpackLog(event, "AppCreated", log); err != nil { + event := new(AppControllerAppTerminated) + if err := _AppController.contract.UnpackLog(event, "AppTerminated", log); err != nil { return err } event.Raw = log @@ -1401,21 +2856,21 @@ func (_AppController *AppControllerFilterer) WatchAppCreated(opts *bind.WatchOpt }), nil } -// ParseAppCreated is a log parse operation binding the contract event 0xe9e6e5409b80e2dab7d38194fb370b2e8045a1af28177b94ddcf19d2495d7589. +// ParseAppTerminated is a log parse operation binding the contract event 0x2465e924a1e9a02843493e65702fd09152c8a631caf7b9b58e4b01ee20ced416. // -// Solidity: event AppCreated(address indexed creator, address indexed app, uint32 operatorSetId) -func (_AppController *AppControllerFilterer) ParseAppCreated(log types.Log) (*AppControllerAppCreated, error) { - event := new(AppControllerAppCreated) - if err := _AppController.contract.UnpackLog(event, "AppCreated", log); err != nil { +// Solidity: event AppTerminated(address indexed app) +func (_AppController *AppControllerFilterer) ParseAppTerminated(log types.Log) (*AppControllerAppTerminated, error) { + event := new(AppControllerAppTerminated) + if err := _AppController.contract.UnpackLog(event, "AppTerminated", log); err != nil { return nil, err } event.Raw = log return event, nil } -// AppControllerAppMetadataURIUpdatedIterator is returned from FilterAppMetadataURIUpdated and is used to iterate over the raw logs and unpacked data for AppMetadataURIUpdated events raised by the AppController contract. -type AppControllerAppMetadataURIUpdatedIterator struct { - Event *AppControllerAppMetadataURIUpdated // Event containing the contract specifics and raw log +// AppControllerAppTerminatedByAdminIterator is returned from FilterAppTerminatedByAdmin and is used to iterate over the raw logs and unpacked data for AppTerminatedByAdmin events raised by the AppController contract. +type AppControllerAppTerminatedByAdminIterator struct { + Event *AppControllerAppTerminatedByAdmin // Event containing the contract specifics and raw log contract *bind.BoundContract // Generic contract to use for unpacking event data event string // Event name to use for unpacking event data @@ -1429,7 +2884,7 @@ type AppControllerAppMetadataURIUpdatedIterator struct { // Next advances the iterator to the subsequent event, returning whether there // are any more events found. In case of a retrieval or parsing error, false is // returned and Error() can be queried for the exact failure. -func (it *AppControllerAppMetadataURIUpdatedIterator) Next() bool { +func (it *AppControllerAppTerminatedByAdminIterator) Next() bool { // If the iterator failed, stop iterating if it.fail != nil { return false @@ -1438,7 +2893,7 @@ func (it *AppControllerAppMetadataURIUpdatedIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(AppControllerAppMetadataURIUpdated) + it.Event = new(AppControllerAppTerminatedByAdmin) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1453,7 +2908,7 @@ func (it *AppControllerAppMetadataURIUpdatedIterator) Next() bool { // Iterator still in progress, wait for either a data or an error event select { case log := <-it.logs: - it.Event = new(AppControllerAppMetadataURIUpdated) + it.Event = new(AppControllerAppTerminatedByAdmin) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1469,52 +2924,51 @@ func (it *AppControllerAppMetadataURIUpdatedIterator) Next() bool { } // Error returns any retrieval or parsing error occurred during filtering. -func (it *AppControllerAppMetadataURIUpdatedIterator) Error() error { +func (it *AppControllerAppTerminatedByAdminIterator) Error() error { return it.fail } // Close terminates the iteration process, releasing any pending underlying // resources. -func (it *AppControllerAppMetadataURIUpdatedIterator) Close() error { +func (it *AppControllerAppTerminatedByAdminIterator) Close() error { it.sub.Unsubscribe() return nil } -// AppControllerAppMetadataURIUpdated represents a AppMetadataURIUpdated event raised by the AppController contract. -type AppControllerAppMetadataURIUpdated struct { - App common.Address - MetadataURI string - Raw types.Log // Blockchain specific contextual infos +// AppControllerAppTerminatedByAdmin represents a AppTerminatedByAdmin event raised by the AppController contract. +type AppControllerAppTerminatedByAdmin struct { + App common.Address + Raw types.Log // Blockchain specific contextual infos } -// FilterAppMetadataURIUpdated is a free log retrieval operation binding the contract event 0xc874c4e2852c19bd03d42a5232ce93e85f2da325dddac46c2472043b7f0d7e8d. +// FilterAppTerminatedByAdmin is a free log retrieval operation binding the contract event 0x4636ad9a0a072d9c8b05a5bcda7d33256c5401515e612c25c13273b378cb2809. // -// Solidity: event AppMetadataURIUpdated(address indexed app, string metadataURI) -func (_AppController *AppControllerFilterer) FilterAppMetadataURIUpdated(opts *bind.FilterOpts, app []common.Address) (*AppControllerAppMetadataURIUpdatedIterator, error) { +// Solidity: event AppTerminatedByAdmin(address indexed app) +func (_AppController *AppControllerFilterer) FilterAppTerminatedByAdmin(opts *bind.FilterOpts, app []common.Address) (*AppControllerAppTerminatedByAdminIterator, error) { var appRule []interface{} for _, appItem := range app { appRule = append(appRule, appItem) } - logs, sub, err := _AppController.contract.FilterLogs(opts, "AppMetadataURIUpdated", appRule) + logs, sub, err := _AppController.contract.FilterLogs(opts, "AppTerminatedByAdmin", appRule) if err != nil { return nil, err } - return &AppControllerAppMetadataURIUpdatedIterator{contract: _AppController.contract, event: "AppMetadataURIUpdated", logs: logs, sub: sub}, nil + return &AppControllerAppTerminatedByAdminIterator{contract: _AppController.contract, event: "AppTerminatedByAdmin", logs: logs, sub: sub}, nil } -// WatchAppMetadataURIUpdated is a free log subscription operation binding the contract event 0xc874c4e2852c19bd03d42a5232ce93e85f2da325dddac46c2472043b7f0d7e8d. +// WatchAppTerminatedByAdmin is a free log subscription operation binding the contract event 0x4636ad9a0a072d9c8b05a5bcda7d33256c5401515e612c25c13273b378cb2809. // -// Solidity: event AppMetadataURIUpdated(address indexed app, string metadataURI) -func (_AppController *AppControllerFilterer) WatchAppMetadataURIUpdated(opts *bind.WatchOpts, sink chan<- *AppControllerAppMetadataURIUpdated, app []common.Address) (event.Subscription, error) { +// Solidity: event AppTerminatedByAdmin(address indexed app) +func (_AppController *AppControllerFilterer) WatchAppTerminatedByAdmin(opts *bind.WatchOpts, sink chan<- *AppControllerAppTerminatedByAdmin, app []common.Address) (event.Subscription, error) { var appRule []interface{} for _, appItem := range app { appRule = append(appRule, appItem) } - logs, sub, err := _AppController.contract.WatchLogs(opts, "AppMetadataURIUpdated", appRule) + logs, sub, err := _AppController.contract.WatchLogs(opts, "AppTerminatedByAdmin", appRule) if err != nil { return nil, err } @@ -1524,8 +2978,8 @@ func (_AppController *AppControllerFilterer) WatchAppMetadataURIUpdated(opts *bi select { case log := <-logs: // New log arrived, parse the event and forward to the user - event := new(AppControllerAppMetadataURIUpdated) - if err := _AppController.contract.UnpackLog(event, "AppMetadataURIUpdated", log); err != nil { + event := new(AppControllerAppTerminatedByAdmin) + if err := _AppController.contract.UnpackLog(event, "AppTerminatedByAdmin", log); err != nil { return err } event.Raw = log @@ -1546,21 +3000,21 @@ func (_AppController *AppControllerFilterer) WatchAppMetadataURIUpdated(opts *bi }), nil } -// ParseAppMetadataURIUpdated is a log parse operation binding the contract event 0xc874c4e2852c19bd03d42a5232ce93e85f2da325dddac46c2472043b7f0d7e8d. +// ParseAppTerminatedByAdmin is a log parse operation binding the contract event 0x4636ad9a0a072d9c8b05a5bcda7d33256c5401515e612c25c13273b378cb2809. // -// Solidity: event AppMetadataURIUpdated(address indexed app, string metadataURI) -func (_AppController *AppControllerFilterer) ParseAppMetadataURIUpdated(log types.Log) (*AppControllerAppMetadataURIUpdated, error) { - event := new(AppControllerAppMetadataURIUpdated) - if err := _AppController.contract.UnpackLog(event, "AppMetadataURIUpdated", log); err != nil { +// Solidity: event AppTerminatedByAdmin(address indexed app) +func (_AppController *AppControllerFilterer) ParseAppTerminatedByAdmin(log types.Log) (*AppControllerAppTerminatedByAdmin, error) { + event := new(AppControllerAppTerminatedByAdmin) + if err := _AppController.contract.UnpackLog(event, "AppTerminatedByAdmin", log); err != nil { return nil, err } event.Raw = log return event, nil } -// AppControllerAppStartedIterator is returned from FilterAppStarted and is used to iterate over the raw logs and unpacked data for AppStarted events raised by the AppController contract. -type AppControllerAppStartedIterator struct { - Event *AppControllerAppStarted // Event containing the contract specifics and raw log +// AppControllerAppUpgradeCancelledIterator is returned from FilterAppUpgradeCancelled and is used to iterate over the raw logs and unpacked data for AppUpgradeCancelled events raised by the AppController contract. +type AppControllerAppUpgradeCancelledIterator struct { + Event *AppControllerAppUpgradeCancelled // Event containing the contract specifics and raw log contract *bind.BoundContract // Generic contract to use for unpacking event data event string // Event name to use for unpacking event data @@ -1574,7 +3028,7 @@ type AppControllerAppStartedIterator struct { // Next advances the iterator to the subsequent event, returning whether there // are any more events found. In case of a retrieval or parsing error, false is // returned and Error() can be queried for the exact failure. -func (it *AppControllerAppStartedIterator) Next() bool { +func (it *AppControllerAppUpgradeCancelledIterator) Next() bool { // If the iterator failed, stop iterating if it.fail != nil { return false @@ -1583,7 +3037,7 @@ func (it *AppControllerAppStartedIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(AppControllerAppStarted) + it.Event = new(AppControllerAppUpgradeCancelled) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1598,7 +3052,7 @@ func (it *AppControllerAppStartedIterator) Next() bool { // Iterator still in progress, wait for either a data or an error event select { case log := <-it.logs: - it.Event = new(AppControllerAppStarted) + it.Event = new(AppControllerAppUpgradeCancelled) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1614,51 +3068,51 @@ func (it *AppControllerAppStartedIterator) Next() bool { } // Error returns any retrieval or parsing error occurred during filtering. -func (it *AppControllerAppStartedIterator) Error() error { +func (it *AppControllerAppUpgradeCancelledIterator) Error() error { return it.fail } // Close terminates the iteration process, releasing any pending underlying // resources. -func (it *AppControllerAppStartedIterator) Close() error { +func (it *AppControllerAppUpgradeCancelledIterator) Close() error { it.sub.Unsubscribe() return nil } -// AppControllerAppStarted represents a AppStarted event raised by the AppController contract. -type AppControllerAppStarted struct { +// AppControllerAppUpgradeCancelled represents a AppUpgradeCancelled event raised by the AppController contract. +type AppControllerAppUpgradeCancelled struct { App common.Address Raw types.Log // Blockchain specific contextual infos } -// FilterAppStarted is a free log retrieval operation binding the contract event 0x8426864999f5f9244a203f75107b05f8b474838bc43ff0d8abe18ee5f4427513. +// FilterAppUpgradeCancelled is a free log retrieval operation binding the contract event 0x0be18385bb55003c4f94a806abad0f73a8e17c169c3efa800bf869245112f465. // -// Solidity: event AppStarted(address indexed app) -func (_AppController *AppControllerFilterer) FilterAppStarted(opts *bind.FilterOpts, app []common.Address) (*AppControllerAppStartedIterator, error) { +// Solidity: event AppUpgradeCancelled(address indexed app) +func (_AppController *AppControllerFilterer) FilterAppUpgradeCancelled(opts *bind.FilterOpts, app []common.Address) (*AppControllerAppUpgradeCancelledIterator, error) { var appRule []interface{} for _, appItem := range app { appRule = append(appRule, appItem) } - logs, sub, err := _AppController.contract.FilterLogs(opts, "AppStarted", appRule) + logs, sub, err := _AppController.contract.FilterLogs(opts, "AppUpgradeCancelled", appRule) if err != nil { return nil, err } - return &AppControllerAppStartedIterator{contract: _AppController.contract, event: "AppStarted", logs: logs, sub: sub}, nil + return &AppControllerAppUpgradeCancelledIterator{contract: _AppController.contract, event: "AppUpgradeCancelled", logs: logs, sub: sub}, nil } -// WatchAppStarted is a free log subscription operation binding the contract event 0x8426864999f5f9244a203f75107b05f8b474838bc43ff0d8abe18ee5f4427513. +// WatchAppUpgradeCancelled is a free log subscription operation binding the contract event 0x0be18385bb55003c4f94a806abad0f73a8e17c169c3efa800bf869245112f465. // -// Solidity: event AppStarted(address indexed app) -func (_AppController *AppControllerFilterer) WatchAppStarted(opts *bind.WatchOpts, sink chan<- *AppControllerAppStarted, app []common.Address) (event.Subscription, error) { +// Solidity: event AppUpgradeCancelled(address indexed app) +func (_AppController *AppControllerFilterer) WatchAppUpgradeCancelled(opts *bind.WatchOpts, sink chan<- *AppControllerAppUpgradeCancelled, app []common.Address) (event.Subscription, error) { var appRule []interface{} for _, appItem := range app { appRule = append(appRule, appItem) } - logs, sub, err := _AppController.contract.WatchLogs(opts, "AppStarted", appRule) + logs, sub, err := _AppController.contract.WatchLogs(opts, "AppUpgradeCancelled", appRule) if err != nil { return nil, err } @@ -1668,8 +3122,8 @@ func (_AppController *AppControllerFilterer) WatchAppStarted(opts *bind.WatchOpt select { case log := <-logs: // New log arrived, parse the event and forward to the user - event := new(AppControllerAppStarted) - if err := _AppController.contract.UnpackLog(event, "AppStarted", log); err != nil { + event := new(AppControllerAppUpgradeCancelled) + if err := _AppController.contract.UnpackLog(event, "AppUpgradeCancelled", log); err != nil { return err } event.Raw = log @@ -1690,21 +3144,21 @@ func (_AppController *AppControllerFilterer) WatchAppStarted(opts *bind.WatchOpt }), nil } -// ParseAppStarted is a log parse operation binding the contract event 0x8426864999f5f9244a203f75107b05f8b474838bc43ff0d8abe18ee5f4427513. +// ParseAppUpgradeCancelled is a log parse operation binding the contract event 0x0be18385bb55003c4f94a806abad0f73a8e17c169c3efa800bf869245112f465. // -// Solidity: event AppStarted(address indexed app) -func (_AppController *AppControllerFilterer) ParseAppStarted(log types.Log) (*AppControllerAppStarted, error) { - event := new(AppControllerAppStarted) - if err := _AppController.contract.UnpackLog(event, "AppStarted", log); err != nil { +// Solidity: event AppUpgradeCancelled(address indexed app) +func (_AppController *AppControllerFilterer) ParseAppUpgradeCancelled(log types.Log) (*AppControllerAppUpgradeCancelled, error) { + event := new(AppControllerAppUpgradeCancelled) + if err := _AppController.contract.UnpackLog(event, "AppUpgradeCancelled", log); err != nil { return nil, err } event.Raw = log return event, nil } -// AppControllerAppStoppedIterator is returned from FilterAppStopped and is used to iterate over the raw logs and unpacked data for AppStopped events raised by the AppController contract. -type AppControllerAppStoppedIterator struct { - Event *AppControllerAppStopped // Event containing the contract specifics and raw log +// AppControllerAppUpgradeScheduledIterator is returned from FilterAppUpgradeScheduled and is used to iterate over the raw logs and unpacked data for AppUpgradeScheduled events raised by the AppController contract. +type AppControllerAppUpgradeScheduledIterator struct { + Event *AppControllerAppUpgradeScheduled // Event containing the contract specifics and raw log contract *bind.BoundContract // Generic contract to use for unpacking event data event string // Event name to use for unpacking event data @@ -1718,7 +3172,7 @@ type AppControllerAppStoppedIterator struct { // Next advances the iterator to the subsequent event, returning whether there // are any more events found. In case of a retrieval or parsing error, false is // returned and Error() can be queried for the exact failure. -func (it *AppControllerAppStoppedIterator) Next() bool { +func (it *AppControllerAppUpgradeScheduledIterator) Next() bool { // If the iterator failed, stop iterating if it.fail != nil { return false @@ -1727,7 +3181,7 @@ func (it *AppControllerAppStoppedIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(AppControllerAppStopped) + it.Event = new(AppControllerAppUpgradeScheduled) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1742,7 +3196,7 @@ func (it *AppControllerAppStoppedIterator) Next() bool { // Iterator still in progress, wait for either a data or an error event select { case log := <-it.logs: - it.Event = new(AppControllerAppStopped) + it.Event = new(AppControllerAppUpgradeScheduled) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1758,51 +3212,53 @@ func (it *AppControllerAppStoppedIterator) Next() bool { } // Error returns any retrieval or parsing error occurred during filtering. -func (it *AppControllerAppStoppedIterator) Error() error { +func (it *AppControllerAppUpgradeScheduledIterator) Error() error { return it.fail } // Close terminates the iteration process, releasing any pending underlying // resources. -func (it *AppControllerAppStoppedIterator) Close() error { +func (it *AppControllerAppUpgradeScheduledIterator) Close() error { it.sub.Unsubscribe() return nil } -// AppControllerAppStopped represents a AppStopped event raised by the AppController contract. -type AppControllerAppStopped struct { - App common.Address - Raw types.Log // Blockchain specific contextual infos +// AppControllerAppUpgradeScheduled represents a AppUpgradeScheduled event raised by the AppController contract. +type AppControllerAppUpgradeScheduled struct { + App common.Address + ReadyAt *big.Int + Release IAppControllerRelease + Raw types.Log // Blockchain specific contextual infos } -// FilterAppStopped is a free log retrieval operation binding the contract event 0x143b9e3b5aa0fb8cf19b1bdb2eb8d7a94657d4b505070c667433d322b90b1f78. +// FilterAppUpgradeScheduled is a free log retrieval operation binding the contract event 0x03309d4e2c0aeff0eb5b642fa98b38401692c0d68249374693f397e06ae6077b. // -// Solidity: event AppStopped(address indexed app) -func (_AppController *AppControllerFilterer) FilterAppStopped(opts *bind.FilterOpts, app []common.Address) (*AppControllerAppStoppedIterator, error) { +// Solidity: event AppUpgradeScheduled(address indexed app, uint256 readyAt, (((bytes32,string)[],uint32),bytes,bytes) release) +func (_AppController *AppControllerFilterer) FilterAppUpgradeScheduled(opts *bind.FilterOpts, app []common.Address) (*AppControllerAppUpgradeScheduledIterator, error) { var appRule []interface{} for _, appItem := range app { appRule = append(appRule, appItem) } - logs, sub, err := _AppController.contract.FilterLogs(opts, "AppStopped", appRule) + logs, sub, err := _AppController.contract.FilterLogs(opts, "AppUpgradeScheduled", appRule) if err != nil { return nil, err } - return &AppControllerAppStoppedIterator{contract: _AppController.contract, event: "AppStopped", logs: logs, sub: sub}, nil + return &AppControllerAppUpgradeScheduledIterator{contract: _AppController.contract, event: "AppUpgradeScheduled", logs: logs, sub: sub}, nil } -// WatchAppStopped is a free log subscription operation binding the contract event 0x143b9e3b5aa0fb8cf19b1bdb2eb8d7a94657d4b505070c667433d322b90b1f78. +// WatchAppUpgradeScheduled is a free log subscription operation binding the contract event 0x03309d4e2c0aeff0eb5b642fa98b38401692c0d68249374693f397e06ae6077b. // -// Solidity: event AppStopped(address indexed app) -func (_AppController *AppControllerFilterer) WatchAppStopped(opts *bind.WatchOpts, sink chan<- *AppControllerAppStopped, app []common.Address) (event.Subscription, error) { +// Solidity: event AppUpgradeScheduled(address indexed app, uint256 readyAt, (((bytes32,string)[],uint32),bytes,bytes) release) +func (_AppController *AppControllerFilterer) WatchAppUpgradeScheduled(opts *bind.WatchOpts, sink chan<- *AppControllerAppUpgradeScheduled, app []common.Address) (event.Subscription, error) { var appRule []interface{} for _, appItem := range app { appRule = append(appRule, appItem) } - logs, sub, err := _AppController.contract.WatchLogs(opts, "AppStopped", appRule) + logs, sub, err := _AppController.contract.WatchLogs(opts, "AppUpgradeScheduled", appRule) if err != nil { return nil, err } @@ -1812,8 +3268,8 @@ func (_AppController *AppControllerFilterer) WatchAppStopped(opts *bind.WatchOpt select { case log := <-logs: // New log arrived, parse the event and forward to the user - event := new(AppControllerAppStopped) - if err := _AppController.contract.UnpackLog(event, "AppStopped", log); err != nil { + event := new(AppControllerAppUpgradeScheduled) + if err := _AppController.contract.UnpackLog(event, "AppUpgradeScheduled", log); err != nil { return err } event.Raw = log @@ -1834,21 +3290,21 @@ func (_AppController *AppControllerFilterer) WatchAppStopped(opts *bind.WatchOpt }), nil } -// ParseAppStopped is a log parse operation binding the contract event 0x143b9e3b5aa0fb8cf19b1bdb2eb8d7a94657d4b505070c667433d322b90b1f78. +// ParseAppUpgradeScheduled is a log parse operation binding the contract event 0x03309d4e2c0aeff0eb5b642fa98b38401692c0d68249374693f397e06ae6077b. // -// Solidity: event AppStopped(address indexed app) -func (_AppController *AppControllerFilterer) ParseAppStopped(log types.Log) (*AppControllerAppStopped, error) { - event := new(AppControllerAppStopped) - if err := _AppController.contract.UnpackLog(event, "AppStopped", log); err != nil { +// Solidity: event AppUpgradeScheduled(address indexed app, uint256 readyAt, (((bytes32,string)[],uint32),bytes,bytes) release) +func (_AppController *AppControllerFilterer) ParseAppUpgradeScheduled(log types.Log) (*AppControllerAppUpgradeScheduled, error) { + event := new(AppControllerAppUpgradeScheduled) + if err := _AppController.contract.UnpackLog(event, "AppUpgradeScheduled", log); err != nil { return nil, err } event.Raw = log return event, nil } -// AppControllerAppSuspendedIterator is returned from FilterAppSuspended and is used to iterate over the raw logs and unpacked data for AppSuspended events raised by the AppController contract. -type AppControllerAppSuspendedIterator struct { - Event *AppControllerAppSuspended // Event containing the contract specifics and raw log +// AppControllerAppUpgradedIterator is returned from FilterAppUpgraded and is used to iterate over the raw logs and unpacked data for AppUpgraded events raised by the AppController contract. +type AppControllerAppUpgradedIterator struct { + Event *AppControllerAppUpgraded // Event containing the contract specifics and raw log contract *bind.BoundContract // Generic contract to use for unpacking event data event string // Event name to use for unpacking event data @@ -1862,7 +3318,7 @@ type AppControllerAppSuspendedIterator struct { // Next advances the iterator to the subsequent event, returning whether there // are any more events found. In case of a retrieval or parsing error, false is // returned and Error() can be queried for the exact failure. -func (it *AppControllerAppSuspendedIterator) Next() bool { +func (it *AppControllerAppUpgradedIterator) Next() bool { // If the iterator failed, stop iterating if it.fail != nil { return false @@ -1871,7 +3327,7 @@ func (it *AppControllerAppSuspendedIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(AppControllerAppSuspended) + it.Event = new(AppControllerAppUpgraded) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1886,7 +3342,7 @@ func (it *AppControllerAppSuspendedIterator) Next() bool { // Iterator still in progress, wait for either a data or an error event select { case log := <-it.logs: - it.Event = new(AppControllerAppSuspended) + it.Event = new(AppControllerAppUpgraded) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1902,51 +3358,53 @@ func (it *AppControllerAppSuspendedIterator) Next() bool { } // Error returns any retrieval or parsing error occurred during filtering. -func (it *AppControllerAppSuspendedIterator) Error() error { +func (it *AppControllerAppUpgradedIterator) Error() error { return it.fail } // Close terminates the iteration process, releasing any pending underlying // resources. -func (it *AppControllerAppSuspendedIterator) Close() error { +func (it *AppControllerAppUpgradedIterator) Close() error { it.sub.Unsubscribe() return nil } -// AppControllerAppSuspended represents a AppSuspended event raised by the AppController contract. -type AppControllerAppSuspended struct { - App common.Address - Raw types.Log // Blockchain specific contextual infos +// AppControllerAppUpgraded represents a AppUpgraded event raised by the AppController contract. +type AppControllerAppUpgraded struct { + App common.Address + RmsReleaseId *big.Int + Release IAppControllerRelease + Raw types.Log // Blockchain specific contextual infos } -// FilterAppSuspended is a free log retrieval operation binding the contract event 0xbb85757a09bd73484c9fb6857c3e9f8dbf92c3e22ce1655213c9481dacf81c62. +// FilterAppUpgraded is a free log retrieval operation binding the contract event 0xb5d2b7df0352a87a587a430bfceab43859b3b3c404f0425c4c1ab0675ed57b94. // -// Solidity: event AppSuspended(address indexed app) -func (_AppController *AppControllerFilterer) FilterAppSuspended(opts *bind.FilterOpts, app []common.Address) (*AppControllerAppSuspendedIterator, error) { +// Solidity: event AppUpgraded(address indexed app, uint256 rmsReleaseId, (((bytes32,string)[],uint32),bytes,bytes) release) +func (_AppController *AppControllerFilterer) FilterAppUpgraded(opts *bind.FilterOpts, app []common.Address) (*AppControllerAppUpgradedIterator, error) { var appRule []interface{} for _, appItem := range app { appRule = append(appRule, appItem) } - logs, sub, err := _AppController.contract.FilterLogs(opts, "AppSuspended", appRule) + logs, sub, err := _AppController.contract.FilterLogs(opts, "AppUpgraded", appRule) if err != nil { return nil, err } - return &AppControllerAppSuspendedIterator{contract: _AppController.contract, event: "AppSuspended", logs: logs, sub: sub}, nil + return &AppControllerAppUpgradedIterator{contract: _AppController.contract, event: "AppUpgraded", logs: logs, sub: sub}, nil } -// WatchAppSuspended is a free log subscription operation binding the contract event 0xbb85757a09bd73484c9fb6857c3e9f8dbf92c3e22ce1655213c9481dacf81c62. +// WatchAppUpgraded is a free log subscription operation binding the contract event 0xb5d2b7df0352a87a587a430bfceab43859b3b3c404f0425c4c1ab0675ed57b94. // -// Solidity: event AppSuspended(address indexed app) -func (_AppController *AppControllerFilterer) WatchAppSuspended(opts *bind.WatchOpts, sink chan<- *AppControllerAppSuspended, app []common.Address) (event.Subscription, error) { +// Solidity: event AppUpgraded(address indexed app, uint256 rmsReleaseId, (((bytes32,string)[],uint32),bytes,bytes) release) +func (_AppController *AppControllerFilterer) WatchAppUpgraded(opts *bind.WatchOpts, sink chan<- *AppControllerAppUpgraded, app []common.Address) (event.Subscription, error) { var appRule []interface{} for _, appItem := range app { appRule = append(appRule, appItem) } - logs, sub, err := _AppController.contract.WatchLogs(opts, "AppSuspended", appRule) + logs, sub, err := _AppController.contract.WatchLogs(opts, "AppUpgraded", appRule) if err != nil { return nil, err } @@ -1956,8 +3414,8 @@ func (_AppController *AppControllerFilterer) WatchAppSuspended(opts *bind.WatchO select { case log := <-logs: // New log arrived, parse the event and forward to the user - event := new(AppControllerAppSuspended) - if err := _AppController.contract.UnpackLog(event, "AppSuspended", log); err != nil { + event := new(AppControllerAppUpgraded) + if err := _AppController.contract.UnpackLog(event, "AppUpgraded", log); err != nil { return err } event.Raw = log @@ -1978,21 +3436,21 @@ func (_AppController *AppControllerFilterer) WatchAppSuspended(opts *bind.WatchO }), nil } -// ParseAppSuspended is a log parse operation binding the contract event 0xbb85757a09bd73484c9fb6857c3e9f8dbf92c3e22ce1655213c9481dacf81c62. +// ParseAppUpgraded is a log parse operation binding the contract event 0xb5d2b7df0352a87a587a430bfceab43859b3b3c404f0425c4c1ab0675ed57b94. // -// Solidity: event AppSuspended(address indexed app) -func (_AppController *AppControllerFilterer) ParseAppSuspended(log types.Log) (*AppControllerAppSuspended, error) { - event := new(AppControllerAppSuspended) - if err := _AppController.contract.UnpackLog(event, "AppSuspended", log); err != nil { +// Solidity: event AppUpgraded(address indexed app, uint256 rmsReleaseId, (((bytes32,string)[],uint32),bytes,bytes) release) +func (_AppController *AppControllerFilterer) ParseAppUpgraded(log types.Log) (*AppControllerAppUpgraded, error) { + event := new(AppControllerAppUpgraded) + if err := _AppController.contract.UnpackLog(event, "AppUpgraded", log); err != nil { return nil, err } event.Raw = log return event, nil } -// AppControllerAppTerminatedIterator is returned from FilterAppTerminated and is used to iterate over the raw logs and unpacked data for AppTerminated events raised by the AppController contract. -type AppControllerAppTerminatedIterator struct { - Event *AppControllerAppTerminated // Event containing the contract specifics and raw log +// AppControllerGlobalMaxActiveAppsSetIterator is returned from FilterGlobalMaxActiveAppsSet and is used to iterate over the raw logs and unpacked data for GlobalMaxActiveAppsSet events raised by the AppController contract. +type AppControllerGlobalMaxActiveAppsSetIterator struct { + Event *AppControllerGlobalMaxActiveAppsSet // Event containing the contract specifics and raw log contract *bind.BoundContract // Generic contract to use for unpacking event data event string // Event name to use for unpacking event data @@ -2006,7 +3464,7 @@ type AppControllerAppTerminatedIterator struct { // Next advances the iterator to the subsequent event, returning whether there // are any more events found. In case of a retrieval or parsing error, false is // returned and Error() can be queried for the exact failure. -func (it *AppControllerAppTerminatedIterator) Next() bool { +func (it *AppControllerGlobalMaxActiveAppsSetIterator) Next() bool { // If the iterator failed, stop iterating if it.fail != nil { return false @@ -2015,7 +3473,7 @@ func (it *AppControllerAppTerminatedIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(AppControllerAppTerminated) + it.Event = new(AppControllerGlobalMaxActiveAppsSet) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -2030,7 +3488,7 @@ func (it *AppControllerAppTerminatedIterator) Next() bool { // Iterator still in progress, wait for either a data or an error event select { case log := <-it.logs: - it.Event = new(AppControllerAppTerminated) + it.Event = new(AppControllerGlobalMaxActiveAppsSet) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -2046,51 +3504,41 @@ func (it *AppControllerAppTerminatedIterator) Next() bool { } // Error returns any retrieval or parsing error occurred during filtering. -func (it *AppControllerAppTerminatedIterator) Error() error { +func (it *AppControllerGlobalMaxActiveAppsSetIterator) Error() error { return it.fail } // Close terminates the iteration process, releasing any pending underlying // resources. -func (it *AppControllerAppTerminatedIterator) Close() error { +func (it *AppControllerGlobalMaxActiveAppsSetIterator) Close() error { it.sub.Unsubscribe() return nil } -// AppControllerAppTerminated represents a AppTerminated event raised by the AppController contract. -type AppControllerAppTerminated struct { - App common.Address - Raw types.Log // Blockchain specific contextual infos +// AppControllerGlobalMaxActiveAppsSet represents a GlobalMaxActiveAppsSet event raised by the AppController contract. +type AppControllerGlobalMaxActiveAppsSet struct { + Limit uint32 + Raw types.Log // Blockchain specific contextual infos } -// FilterAppTerminated is a free log retrieval operation binding the contract event 0x2465e924a1e9a02843493e65702fd09152c8a631caf7b9b58e4b01ee20ced416. +// FilterGlobalMaxActiveAppsSet is a free log retrieval operation binding the contract event 0xc3c99803ad2e80be7382791ca0b23147a94739b9e66a656b9c8c47f9d6963414. // -// Solidity: event AppTerminated(address indexed app) -func (_AppController *AppControllerFilterer) FilterAppTerminated(opts *bind.FilterOpts, app []common.Address) (*AppControllerAppTerminatedIterator, error) { - - var appRule []interface{} - for _, appItem := range app { - appRule = append(appRule, appItem) - } +// Solidity: event GlobalMaxActiveAppsSet(uint32 limit) +func (_AppController *AppControllerFilterer) FilterGlobalMaxActiveAppsSet(opts *bind.FilterOpts) (*AppControllerGlobalMaxActiveAppsSetIterator, error) { - logs, sub, err := _AppController.contract.FilterLogs(opts, "AppTerminated", appRule) + logs, sub, err := _AppController.contract.FilterLogs(opts, "GlobalMaxActiveAppsSet") if err != nil { return nil, err } - return &AppControllerAppTerminatedIterator{contract: _AppController.contract, event: "AppTerminated", logs: logs, sub: sub}, nil + return &AppControllerGlobalMaxActiveAppsSetIterator{contract: _AppController.contract, event: "GlobalMaxActiveAppsSet", logs: logs, sub: sub}, nil } -// WatchAppTerminated is a free log subscription operation binding the contract event 0x2465e924a1e9a02843493e65702fd09152c8a631caf7b9b58e4b01ee20ced416. +// WatchGlobalMaxActiveAppsSet is a free log subscription operation binding the contract event 0xc3c99803ad2e80be7382791ca0b23147a94739b9e66a656b9c8c47f9d6963414. // -// Solidity: event AppTerminated(address indexed app) -func (_AppController *AppControllerFilterer) WatchAppTerminated(opts *bind.WatchOpts, sink chan<- *AppControllerAppTerminated, app []common.Address) (event.Subscription, error) { - - var appRule []interface{} - for _, appItem := range app { - appRule = append(appRule, appItem) - } +// Solidity: event GlobalMaxActiveAppsSet(uint32 limit) +func (_AppController *AppControllerFilterer) WatchGlobalMaxActiveAppsSet(opts *bind.WatchOpts, sink chan<- *AppControllerGlobalMaxActiveAppsSet) (event.Subscription, error) { - logs, sub, err := _AppController.contract.WatchLogs(opts, "AppTerminated", appRule) + logs, sub, err := _AppController.contract.WatchLogs(opts, "GlobalMaxActiveAppsSet") if err != nil { return nil, err } @@ -2100,8 +3548,8 @@ func (_AppController *AppControllerFilterer) WatchAppTerminated(opts *bind.Watch select { case log := <-logs: // New log arrived, parse the event and forward to the user - event := new(AppControllerAppTerminated) - if err := _AppController.contract.UnpackLog(event, "AppTerminated", log); err != nil { + event := new(AppControllerGlobalMaxActiveAppsSet) + if err := _AppController.contract.UnpackLog(event, "GlobalMaxActiveAppsSet", log); err != nil { return err } event.Raw = log @@ -2122,21 +3570,21 @@ func (_AppController *AppControllerFilterer) WatchAppTerminated(opts *bind.Watch }), nil } -// ParseAppTerminated is a log parse operation binding the contract event 0x2465e924a1e9a02843493e65702fd09152c8a631caf7b9b58e4b01ee20ced416. +// ParseGlobalMaxActiveAppsSet is a log parse operation binding the contract event 0xc3c99803ad2e80be7382791ca0b23147a94739b9e66a656b9c8c47f9d6963414. // -// Solidity: event AppTerminated(address indexed app) -func (_AppController *AppControllerFilterer) ParseAppTerminated(log types.Log) (*AppControllerAppTerminated, error) { - event := new(AppControllerAppTerminated) - if err := _AppController.contract.UnpackLog(event, "AppTerminated", log); err != nil { +// Solidity: event GlobalMaxActiveAppsSet(uint32 limit) +func (_AppController *AppControllerFilterer) ParseGlobalMaxActiveAppsSet(log types.Log) (*AppControllerGlobalMaxActiveAppsSet, error) { + event := new(AppControllerGlobalMaxActiveAppsSet) + if err := _AppController.contract.UnpackLog(event, "GlobalMaxActiveAppsSet", log); err != nil { return nil, err } event.Raw = log return event, nil } -// AppControllerAppTerminatedByAdminIterator is returned from FilterAppTerminatedByAdmin and is used to iterate over the raw logs and unpacked data for AppTerminatedByAdmin events raised by the AppController contract. -type AppControllerAppTerminatedByAdminIterator struct { - Event *AppControllerAppTerminatedByAdmin // Event containing the contract specifics and raw log +// AppControllerInitializedIterator is returned from FilterInitialized and is used to iterate over the raw logs and unpacked data for Initialized events raised by the AppController contract. +type AppControllerInitializedIterator struct { + Event *AppControllerInitialized // Event containing the contract specifics and raw log contract *bind.BoundContract // Generic contract to use for unpacking event data event string // Event name to use for unpacking event data @@ -2150,7 +3598,7 @@ type AppControllerAppTerminatedByAdminIterator struct { // Next advances the iterator to the subsequent event, returning whether there // are any more events found. In case of a retrieval or parsing error, false is // returned and Error() can be queried for the exact failure. -func (it *AppControllerAppTerminatedByAdminIterator) Next() bool { +func (it *AppControllerInitializedIterator) Next() bool { // If the iterator failed, stop iterating if it.fail != nil { return false @@ -2159,7 +3607,7 @@ func (it *AppControllerAppTerminatedByAdminIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(AppControllerAppTerminatedByAdmin) + it.Event = new(AppControllerInitialized) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -2174,7 +3622,7 @@ func (it *AppControllerAppTerminatedByAdminIterator) Next() bool { // Iterator still in progress, wait for either a data or an error event select { case log := <-it.logs: - it.Event = new(AppControllerAppTerminatedByAdmin) + it.Event = new(AppControllerInitialized) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -2190,51 +3638,41 @@ func (it *AppControllerAppTerminatedByAdminIterator) Next() bool { } // Error returns any retrieval or parsing error occurred during filtering. -func (it *AppControllerAppTerminatedByAdminIterator) Error() error { +func (it *AppControllerInitializedIterator) Error() error { return it.fail } // Close terminates the iteration process, releasing any pending underlying // resources. -func (it *AppControllerAppTerminatedByAdminIterator) Close() error { +func (it *AppControllerInitializedIterator) Close() error { it.sub.Unsubscribe() return nil } -// AppControllerAppTerminatedByAdmin represents a AppTerminatedByAdmin event raised by the AppController contract. -type AppControllerAppTerminatedByAdmin struct { - App common.Address - Raw types.Log // Blockchain specific contextual infos +// AppControllerInitialized represents a Initialized event raised by the AppController contract. +type AppControllerInitialized struct { + Version uint8 + Raw types.Log // Blockchain specific contextual infos } -// FilterAppTerminatedByAdmin is a free log retrieval operation binding the contract event 0x4636ad9a0a072d9c8b05a5bcda7d33256c5401515e612c25c13273b378cb2809. +// FilterInitialized is a free log retrieval operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. // -// Solidity: event AppTerminatedByAdmin(address indexed app) -func (_AppController *AppControllerFilterer) FilterAppTerminatedByAdmin(opts *bind.FilterOpts, app []common.Address) (*AppControllerAppTerminatedByAdminIterator, error) { - - var appRule []interface{} - for _, appItem := range app { - appRule = append(appRule, appItem) - } +// Solidity: event Initialized(uint8 version) +func (_AppController *AppControllerFilterer) FilterInitialized(opts *bind.FilterOpts) (*AppControllerInitializedIterator, error) { - logs, sub, err := _AppController.contract.FilterLogs(opts, "AppTerminatedByAdmin", appRule) + logs, sub, err := _AppController.contract.FilterLogs(opts, "Initialized") if err != nil { return nil, err } - return &AppControllerAppTerminatedByAdminIterator{contract: _AppController.contract, event: "AppTerminatedByAdmin", logs: logs, sub: sub}, nil + return &AppControllerInitializedIterator{contract: _AppController.contract, event: "Initialized", logs: logs, sub: sub}, nil } -// WatchAppTerminatedByAdmin is a free log subscription operation binding the contract event 0x4636ad9a0a072d9c8b05a5bcda7d33256c5401515e612c25c13273b378cb2809. +// WatchInitialized is a free log subscription operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. // -// Solidity: event AppTerminatedByAdmin(address indexed app) -func (_AppController *AppControllerFilterer) WatchAppTerminatedByAdmin(opts *bind.WatchOpts, sink chan<- *AppControllerAppTerminatedByAdmin, app []common.Address) (event.Subscription, error) { - - var appRule []interface{} - for _, appItem := range app { - appRule = append(appRule, appItem) - } +// Solidity: event Initialized(uint8 version) +func (_AppController *AppControllerFilterer) WatchInitialized(opts *bind.WatchOpts, sink chan<- *AppControllerInitialized) (event.Subscription, error) { - logs, sub, err := _AppController.contract.WatchLogs(opts, "AppTerminatedByAdmin", appRule) + logs, sub, err := _AppController.contract.WatchLogs(opts, "Initialized") if err != nil { return nil, err } @@ -2244,8 +3682,8 @@ func (_AppController *AppControllerFilterer) WatchAppTerminatedByAdmin(opts *bin select { case log := <-logs: // New log arrived, parse the event and forward to the user - event := new(AppControllerAppTerminatedByAdmin) - if err := _AppController.contract.UnpackLog(event, "AppTerminatedByAdmin", log); err != nil { + event := new(AppControllerInitialized) + if err := _AppController.contract.UnpackLog(event, "Initialized", log); err != nil { return err } event.Raw = log @@ -2266,21 +3704,21 @@ func (_AppController *AppControllerFilterer) WatchAppTerminatedByAdmin(opts *bin }), nil } -// ParseAppTerminatedByAdmin is a log parse operation binding the contract event 0x4636ad9a0a072d9c8b05a5bcda7d33256c5401515e612c25c13273b378cb2809. +// ParseInitialized is a log parse operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. // -// Solidity: event AppTerminatedByAdmin(address indexed app) -func (_AppController *AppControllerFilterer) ParseAppTerminatedByAdmin(log types.Log) (*AppControllerAppTerminatedByAdmin, error) { - event := new(AppControllerAppTerminatedByAdmin) - if err := _AppController.contract.UnpackLog(event, "AppTerminatedByAdmin", log); err != nil { +// Solidity: event Initialized(uint8 version) +func (_AppController *AppControllerFilterer) ParseInitialized(log types.Log) (*AppControllerInitialized, error) { + event := new(AppControllerInitialized) + if err := _AppController.contract.UnpackLog(event, "Initialized", log); err != nil { return nil, err } event.Raw = log return event, nil } -// AppControllerAppUpgradedIterator is returned from FilterAppUpgraded and is used to iterate over the raw logs and unpacked data for AppUpgraded events raised by the AppController contract. -type AppControllerAppUpgradedIterator struct { - Event *AppControllerAppUpgraded // Event containing the contract specifics and raw log +// AppControllerMaxActiveAppsSetIterator is returned from FilterMaxActiveAppsSet and is used to iterate over the raw logs and unpacked data for MaxActiveAppsSet events raised by the AppController contract. +type AppControllerMaxActiveAppsSetIterator struct { + Event *AppControllerMaxActiveAppsSet // Event containing the contract specifics and raw log contract *bind.BoundContract // Generic contract to use for unpacking event data event string // Event name to use for unpacking event data @@ -2294,7 +3732,7 @@ type AppControllerAppUpgradedIterator struct { // Next advances the iterator to the subsequent event, returning whether there // are any more events found. In case of a retrieval or parsing error, false is // returned and Error() can be queried for the exact failure. -func (it *AppControllerAppUpgradedIterator) Next() bool { +func (it *AppControllerMaxActiveAppsSetIterator) Next() bool { // If the iterator failed, stop iterating if it.fail != nil { return false @@ -2303,7 +3741,7 @@ func (it *AppControllerAppUpgradedIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(AppControllerAppUpgraded) + it.Event = new(AppControllerMaxActiveAppsSet) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -2318,7 +3756,7 @@ func (it *AppControllerAppUpgradedIterator) Next() bool { // Iterator still in progress, wait for either a data or an error event select { case log := <-it.logs: - it.Event = new(AppControllerAppUpgraded) + it.Event = new(AppControllerMaxActiveAppsSet) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -2334,53 +3772,52 @@ func (it *AppControllerAppUpgradedIterator) Next() bool { } // Error returns any retrieval or parsing error occurred during filtering. -func (it *AppControllerAppUpgradedIterator) Error() error { +func (it *AppControllerMaxActiveAppsSetIterator) Error() error { return it.fail } // Close terminates the iteration process, releasing any pending underlying // resources. -func (it *AppControllerAppUpgradedIterator) Close() error { +func (it *AppControllerMaxActiveAppsSetIterator) Close() error { it.sub.Unsubscribe() return nil } -// AppControllerAppUpgraded represents a AppUpgraded event raised by the AppController contract. -type AppControllerAppUpgraded struct { - App common.Address - RmsReleaseId *big.Int - Release IAppControllerRelease - Raw types.Log // Blockchain specific contextual infos +// AppControllerMaxActiveAppsSet represents a MaxActiveAppsSet event raised by the AppController contract. +type AppControllerMaxActiveAppsSet struct { + User common.Address + Limit uint32 + Raw types.Log // Blockchain specific contextual infos } -// FilterAppUpgraded is a free log retrieval operation binding the contract event 0xb5d2b7df0352a87a587a430bfceab43859b3b3c404f0425c4c1ab0675ed57b94. +// FilterMaxActiveAppsSet is a free log retrieval operation binding the contract event 0x708c955faa87ece750a9700c153a20797167e2fcbde9fca9186801f874663a99. // -// Solidity: event AppUpgraded(address indexed app, uint256 rmsReleaseId, (((bytes32,string)[],uint32),bytes,bytes) release) -func (_AppController *AppControllerFilterer) FilterAppUpgraded(opts *bind.FilterOpts, app []common.Address) (*AppControllerAppUpgradedIterator, error) { +// Solidity: event MaxActiveAppsSet(address indexed user, uint32 limit) +func (_AppController *AppControllerFilterer) FilterMaxActiveAppsSet(opts *bind.FilterOpts, user []common.Address) (*AppControllerMaxActiveAppsSetIterator, error) { - var appRule []interface{} - for _, appItem := range app { - appRule = append(appRule, appItem) + var userRule []interface{} + for _, userItem := range user { + userRule = append(userRule, userItem) } - logs, sub, err := _AppController.contract.FilterLogs(opts, "AppUpgraded", appRule) + logs, sub, err := _AppController.contract.FilterLogs(opts, "MaxActiveAppsSet", userRule) if err != nil { return nil, err } - return &AppControllerAppUpgradedIterator{contract: _AppController.contract, event: "AppUpgraded", logs: logs, sub: sub}, nil + return &AppControllerMaxActiveAppsSetIterator{contract: _AppController.contract, event: "MaxActiveAppsSet", logs: logs, sub: sub}, nil } -// WatchAppUpgraded is a free log subscription operation binding the contract event 0xb5d2b7df0352a87a587a430bfceab43859b3b3c404f0425c4c1ab0675ed57b94. +// WatchMaxActiveAppsSet is a free log subscription operation binding the contract event 0x708c955faa87ece750a9700c153a20797167e2fcbde9fca9186801f874663a99. // -// Solidity: event AppUpgraded(address indexed app, uint256 rmsReleaseId, (((bytes32,string)[],uint32),bytes,bytes) release) -func (_AppController *AppControllerFilterer) WatchAppUpgraded(opts *bind.WatchOpts, sink chan<- *AppControllerAppUpgraded, app []common.Address) (event.Subscription, error) { +// Solidity: event MaxActiveAppsSet(address indexed user, uint32 limit) +func (_AppController *AppControllerFilterer) WatchMaxActiveAppsSet(opts *bind.WatchOpts, sink chan<- *AppControllerMaxActiveAppsSet, user []common.Address) (event.Subscription, error) { - var appRule []interface{} - for _, appItem := range app { - appRule = append(appRule, appItem) + var userRule []interface{} + for _, userItem := range user { + userRule = append(userRule, userItem) } - logs, sub, err := _AppController.contract.WatchLogs(opts, "AppUpgraded", appRule) + logs, sub, err := _AppController.contract.WatchLogs(opts, "MaxActiveAppsSet", userRule) if err != nil { return nil, err } @@ -2390,8 +3827,8 @@ func (_AppController *AppControllerFilterer) WatchAppUpgraded(opts *bind.WatchOp select { case log := <-logs: // New log arrived, parse the event and forward to the user - event := new(AppControllerAppUpgraded) - if err := _AppController.contract.UnpackLog(event, "AppUpgraded", log); err != nil { + event := new(AppControllerMaxActiveAppsSet) + if err := _AppController.contract.UnpackLog(event, "MaxActiveAppsSet", log); err != nil { return err } event.Raw = log @@ -2412,21 +3849,21 @@ func (_AppController *AppControllerFilterer) WatchAppUpgraded(opts *bind.WatchOp }), nil } -// ParseAppUpgraded is a log parse operation binding the contract event 0xb5d2b7df0352a87a587a430bfceab43859b3b3c404f0425c4c1ab0675ed57b94. +// ParseMaxActiveAppsSet is a log parse operation binding the contract event 0x708c955faa87ece750a9700c153a20797167e2fcbde9fca9186801f874663a99. // -// Solidity: event AppUpgraded(address indexed app, uint256 rmsReleaseId, (((bytes32,string)[],uint32),bytes,bytes) release) -func (_AppController *AppControllerFilterer) ParseAppUpgraded(log types.Log) (*AppControllerAppUpgraded, error) { - event := new(AppControllerAppUpgraded) - if err := _AppController.contract.UnpackLog(event, "AppUpgraded", log); err != nil { +// Solidity: event MaxActiveAppsSet(address indexed user, uint32 limit) +func (_AppController *AppControllerFilterer) ParseMaxActiveAppsSet(log types.Log) (*AppControllerMaxActiveAppsSet, error) { + event := new(AppControllerMaxActiveAppsSet) + if err := _AppController.contract.UnpackLog(event, "MaxActiveAppsSet", log); err != nil { return nil, err } event.Raw = log return event, nil } -// AppControllerGlobalMaxActiveAppsSetIterator is returned from FilterGlobalMaxActiveAppsSet and is used to iterate over the raw logs and unpacked data for GlobalMaxActiveAppsSet events raised by the AppController contract. -type AppControllerGlobalMaxActiveAppsSetIterator struct { - Event *AppControllerGlobalMaxActiveAppsSet // Event containing the contract specifics and raw log +// AppControllerRoleAdminChangedIterator is returned from FilterRoleAdminChanged and is used to iterate over the raw logs and unpacked data for RoleAdminChanged events raised by the AppController contract. +type AppControllerRoleAdminChangedIterator struct { + Event *AppControllerRoleAdminChanged // Event containing the contract specifics and raw log contract *bind.BoundContract // Generic contract to use for unpacking event data event string // Event name to use for unpacking event data @@ -2440,7 +3877,7 @@ type AppControllerGlobalMaxActiveAppsSetIterator struct { // Next advances the iterator to the subsequent event, returning whether there // are any more events found. In case of a retrieval or parsing error, false is // returned and Error() can be queried for the exact failure. -func (it *AppControllerGlobalMaxActiveAppsSetIterator) Next() bool { +func (it *AppControllerRoleAdminChangedIterator) Next() bool { // If the iterator failed, stop iterating if it.fail != nil { return false @@ -2449,7 +3886,7 @@ func (it *AppControllerGlobalMaxActiveAppsSetIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(AppControllerGlobalMaxActiveAppsSet) + it.Event = new(AppControllerRoleAdminChanged) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -2464,7 +3901,7 @@ func (it *AppControllerGlobalMaxActiveAppsSetIterator) Next() bool { // Iterator still in progress, wait for either a data or an error event select { case log := <-it.logs: - it.Event = new(AppControllerGlobalMaxActiveAppsSet) + it.Event = new(AppControllerRoleAdminChanged) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -2480,41 +3917,69 @@ func (it *AppControllerGlobalMaxActiveAppsSetIterator) Next() bool { } // Error returns any retrieval or parsing error occurred during filtering. -func (it *AppControllerGlobalMaxActiveAppsSetIterator) Error() error { +func (it *AppControllerRoleAdminChangedIterator) Error() error { return it.fail } // Close terminates the iteration process, releasing any pending underlying // resources. -func (it *AppControllerGlobalMaxActiveAppsSetIterator) Close() error { +func (it *AppControllerRoleAdminChangedIterator) Close() error { it.sub.Unsubscribe() return nil } -// AppControllerGlobalMaxActiveAppsSet represents a GlobalMaxActiveAppsSet event raised by the AppController contract. -type AppControllerGlobalMaxActiveAppsSet struct { - Limit uint32 - Raw types.Log // Blockchain specific contextual infos +// AppControllerRoleAdminChanged represents a RoleAdminChanged event raised by the AppController contract. +type AppControllerRoleAdminChanged struct { + Role [32]byte + PreviousAdminRole [32]byte + NewAdminRole [32]byte + Raw types.Log // Blockchain specific contextual infos } -// FilterGlobalMaxActiveAppsSet is a free log retrieval operation binding the contract event 0xc3c99803ad2e80be7382791ca0b23147a94739b9e66a656b9c8c47f9d6963414. +// FilterRoleAdminChanged is a free log retrieval operation binding the contract event 0xbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff. // -// Solidity: event GlobalMaxActiveAppsSet(uint32 limit) -func (_AppController *AppControllerFilterer) FilterGlobalMaxActiveAppsSet(opts *bind.FilterOpts) (*AppControllerGlobalMaxActiveAppsSetIterator, error) { +// Solidity: event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole) +func (_AppController *AppControllerFilterer) FilterRoleAdminChanged(opts *bind.FilterOpts, role [][32]byte, previousAdminRole [][32]byte, newAdminRole [][32]byte) (*AppControllerRoleAdminChangedIterator, error) { - logs, sub, err := _AppController.contract.FilterLogs(opts, "GlobalMaxActiveAppsSet") + var roleRule []interface{} + for _, roleItem := range role { + roleRule = append(roleRule, roleItem) + } + var previousAdminRoleRule []interface{} + for _, previousAdminRoleItem := range previousAdminRole { + previousAdminRoleRule = append(previousAdminRoleRule, previousAdminRoleItem) + } + var newAdminRoleRule []interface{} + for _, newAdminRoleItem := range newAdminRole { + newAdminRoleRule = append(newAdminRoleRule, newAdminRoleItem) + } + + logs, sub, err := _AppController.contract.FilterLogs(opts, "RoleAdminChanged", roleRule, previousAdminRoleRule, newAdminRoleRule) if err != nil { return nil, err } - return &AppControllerGlobalMaxActiveAppsSetIterator{contract: _AppController.contract, event: "GlobalMaxActiveAppsSet", logs: logs, sub: sub}, nil + return &AppControllerRoleAdminChangedIterator{contract: _AppController.contract, event: "RoleAdminChanged", logs: logs, sub: sub}, nil } -// WatchGlobalMaxActiveAppsSet is a free log subscription operation binding the contract event 0xc3c99803ad2e80be7382791ca0b23147a94739b9e66a656b9c8c47f9d6963414. +// WatchRoleAdminChanged is a free log subscription operation binding the contract event 0xbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff. // -// Solidity: event GlobalMaxActiveAppsSet(uint32 limit) -func (_AppController *AppControllerFilterer) WatchGlobalMaxActiveAppsSet(opts *bind.WatchOpts, sink chan<- *AppControllerGlobalMaxActiveAppsSet) (event.Subscription, error) { +// Solidity: event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole) +func (_AppController *AppControllerFilterer) WatchRoleAdminChanged(opts *bind.WatchOpts, sink chan<- *AppControllerRoleAdminChanged, role [][32]byte, previousAdminRole [][32]byte, newAdminRole [][32]byte) (event.Subscription, error) { - logs, sub, err := _AppController.contract.WatchLogs(opts, "GlobalMaxActiveAppsSet") + var roleRule []interface{} + for _, roleItem := range role { + roleRule = append(roleRule, roleItem) + } + var previousAdminRoleRule []interface{} + for _, previousAdminRoleItem := range previousAdminRole { + previousAdminRoleRule = append(previousAdminRoleRule, previousAdminRoleItem) + } + var newAdminRoleRule []interface{} + for _, newAdminRoleItem := range newAdminRole { + newAdminRoleRule = append(newAdminRoleRule, newAdminRoleItem) + } + + logs, sub, err := _AppController.contract.WatchLogs(opts, "RoleAdminChanged", roleRule, previousAdminRoleRule, newAdminRoleRule) if err != nil { return nil, err } @@ -2524,8 +3989,8 @@ func (_AppController *AppControllerFilterer) WatchGlobalMaxActiveAppsSet(opts *b select { case log := <-logs: // New log arrived, parse the event and forward to the user - event := new(AppControllerGlobalMaxActiveAppsSet) - if err := _AppController.contract.UnpackLog(event, "GlobalMaxActiveAppsSet", log); err != nil { + event := new(AppControllerRoleAdminChanged) + if err := _AppController.contract.UnpackLog(event, "RoleAdminChanged", log); err != nil { return err } event.Raw = log @@ -2546,21 +4011,21 @@ func (_AppController *AppControllerFilterer) WatchGlobalMaxActiveAppsSet(opts *b }), nil } -// ParseGlobalMaxActiveAppsSet is a log parse operation binding the contract event 0xc3c99803ad2e80be7382791ca0b23147a94739b9e66a656b9c8c47f9d6963414. +// ParseRoleAdminChanged is a log parse operation binding the contract event 0xbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff. // -// Solidity: event GlobalMaxActiveAppsSet(uint32 limit) -func (_AppController *AppControllerFilterer) ParseGlobalMaxActiveAppsSet(log types.Log) (*AppControllerGlobalMaxActiveAppsSet, error) { - event := new(AppControllerGlobalMaxActiveAppsSet) - if err := _AppController.contract.UnpackLog(event, "GlobalMaxActiveAppsSet", log); err != nil { +// Solidity: event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole) +func (_AppController *AppControllerFilterer) ParseRoleAdminChanged(log types.Log) (*AppControllerRoleAdminChanged, error) { + event := new(AppControllerRoleAdminChanged) + if err := _AppController.contract.UnpackLog(event, "RoleAdminChanged", log); err != nil { return nil, err } event.Raw = log return event, nil } -// AppControllerInitializedIterator is returned from FilterInitialized and is used to iterate over the raw logs and unpacked data for Initialized events raised by the AppController contract. -type AppControllerInitializedIterator struct { - Event *AppControllerInitialized // Event containing the contract specifics and raw log +// AppControllerRoleGrantedIterator is returned from FilterRoleGranted and is used to iterate over the raw logs and unpacked data for RoleGranted events raised by the AppController contract. +type AppControllerRoleGrantedIterator struct { + Event *AppControllerRoleGranted // Event containing the contract specifics and raw log contract *bind.BoundContract // Generic contract to use for unpacking event data event string // Event name to use for unpacking event data @@ -2574,7 +4039,7 @@ type AppControllerInitializedIterator struct { // Next advances the iterator to the subsequent event, returning whether there // are any more events found. In case of a retrieval or parsing error, false is // returned and Error() can be queried for the exact failure. -func (it *AppControllerInitializedIterator) Next() bool { +func (it *AppControllerRoleGrantedIterator) Next() bool { // If the iterator failed, stop iterating if it.fail != nil { return false @@ -2583,7 +4048,7 @@ func (it *AppControllerInitializedIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(AppControllerInitialized) + it.Event = new(AppControllerRoleGranted) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -2598,7 +4063,7 @@ func (it *AppControllerInitializedIterator) Next() bool { // Iterator still in progress, wait for either a data or an error event select { case log := <-it.logs: - it.Event = new(AppControllerInitialized) + it.Event = new(AppControllerRoleGranted) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -2614,41 +4079,69 @@ func (it *AppControllerInitializedIterator) Next() bool { } // Error returns any retrieval or parsing error occurred during filtering. -func (it *AppControllerInitializedIterator) Error() error { +func (it *AppControllerRoleGrantedIterator) Error() error { return it.fail } // Close terminates the iteration process, releasing any pending underlying // resources. -func (it *AppControllerInitializedIterator) Close() error { +func (it *AppControllerRoleGrantedIterator) Close() error { it.sub.Unsubscribe() return nil } -// AppControllerInitialized represents a Initialized event raised by the AppController contract. -type AppControllerInitialized struct { - Version uint8 +// AppControllerRoleGranted represents a RoleGranted event raised by the AppController contract. +type AppControllerRoleGranted struct { + Role [32]byte + Account common.Address + Sender common.Address Raw types.Log // Blockchain specific contextual infos } -// FilterInitialized is a free log retrieval operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. +// FilterRoleGranted is a free log retrieval operation binding the contract event 0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d. // -// Solidity: event Initialized(uint8 version) -func (_AppController *AppControllerFilterer) FilterInitialized(opts *bind.FilterOpts) (*AppControllerInitializedIterator, error) { +// Solidity: event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender) +func (_AppController *AppControllerFilterer) FilterRoleGranted(opts *bind.FilterOpts, role [][32]byte, account []common.Address, sender []common.Address) (*AppControllerRoleGrantedIterator, error) { - logs, sub, err := _AppController.contract.FilterLogs(opts, "Initialized") + var roleRule []interface{} + for _, roleItem := range role { + roleRule = append(roleRule, roleItem) + } + var accountRule []interface{} + for _, accountItem := range account { + accountRule = append(accountRule, accountItem) + } + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _AppController.contract.FilterLogs(opts, "RoleGranted", roleRule, accountRule, senderRule) if err != nil { return nil, err } - return &AppControllerInitializedIterator{contract: _AppController.contract, event: "Initialized", logs: logs, sub: sub}, nil + return &AppControllerRoleGrantedIterator{contract: _AppController.contract, event: "RoleGranted", logs: logs, sub: sub}, nil } -// WatchInitialized is a free log subscription operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. +// WatchRoleGranted is a free log subscription operation binding the contract event 0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d. // -// Solidity: event Initialized(uint8 version) -func (_AppController *AppControllerFilterer) WatchInitialized(opts *bind.WatchOpts, sink chan<- *AppControllerInitialized) (event.Subscription, error) { +// Solidity: event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender) +func (_AppController *AppControllerFilterer) WatchRoleGranted(opts *bind.WatchOpts, sink chan<- *AppControllerRoleGranted, role [][32]byte, account []common.Address, sender []common.Address) (event.Subscription, error) { - logs, sub, err := _AppController.contract.WatchLogs(opts, "Initialized") + var roleRule []interface{} + for _, roleItem := range role { + roleRule = append(roleRule, roleItem) + } + var accountRule []interface{} + for _, accountItem := range account { + accountRule = append(accountRule, accountItem) + } + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _AppController.contract.WatchLogs(opts, "RoleGranted", roleRule, accountRule, senderRule) if err != nil { return nil, err } @@ -2658,8 +4151,8 @@ func (_AppController *AppControllerFilterer) WatchInitialized(opts *bind.WatchOp select { case log := <-logs: // New log arrived, parse the event and forward to the user - event := new(AppControllerInitialized) - if err := _AppController.contract.UnpackLog(event, "Initialized", log); err != nil { + event := new(AppControllerRoleGranted) + if err := _AppController.contract.UnpackLog(event, "RoleGranted", log); err != nil { return err } event.Raw = log @@ -2680,21 +4173,21 @@ func (_AppController *AppControllerFilterer) WatchInitialized(opts *bind.WatchOp }), nil } -// ParseInitialized is a log parse operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. +// ParseRoleGranted is a log parse operation binding the contract event 0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d. // -// Solidity: event Initialized(uint8 version) -func (_AppController *AppControllerFilterer) ParseInitialized(log types.Log) (*AppControllerInitialized, error) { - event := new(AppControllerInitialized) - if err := _AppController.contract.UnpackLog(event, "Initialized", log); err != nil { +// Solidity: event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender) +func (_AppController *AppControllerFilterer) ParseRoleGranted(log types.Log) (*AppControllerRoleGranted, error) { + event := new(AppControllerRoleGranted) + if err := _AppController.contract.UnpackLog(event, "RoleGranted", log); err != nil { return nil, err } event.Raw = log return event, nil } -// AppControllerMaxActiveAppsSetIterator is returned from FilterMaxActiveAppsSet and is used to iterate over the raw logs and unpacked data for MaxActiveAppsSet events raised by the AppController contract. -type AppControllerMaxActiveAppsSetIterator struct { - Event *AppControllerMaxActiveAppsSet // Event containing the contract specifics and raw log +// AppControllerRoleRevokedIterator is returned from FilterRoleRevoked and is used to iterate over the raw logs and unpacked data for RoleRevoked events raised by the AppController contract. +type AppControllerRoleRevokedIterator struct { + Event *AppControllerRoleRevoked // Event containing the contract specifics and raw log contract *bind.BoundContract // Generic contract to use for unpacking event data event string // Event name to use for unpacking event data @@ -2708,7 +4201,7 @@ type AppControllerMaxActiveAppsSetIterator struct { // Next advances the iterator to the subsequent event, returning whether there // are any more events found. In case of a retrieval or parsing error, false is // returned and Error() can be queried for the exact failure. -func (it *AppControllerMaxActiveAppsSetIterator) Next() bool { +func (it *AppControllerRoleRevokedIterator) Next() bool { // If the iterator failed, stop iterating if it.fail != nil { return false @@ -2717,7 +4210,7 @@ func (it *AppControllerMaxActiveAppsSetIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(AppControllerMaxActiveAppsSet) + it.Event = new(AppControllerRoleRevoked) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -2732,7 +4225,7 @@ func (it *AppControllerMaxActiveAppsSetIterator) Next() bool { // Iterator still in progress, wait for either a data or an error event select { case log := <-it.logs: - it.Event = new(AppControllerMaxActiveAppsSet) + it.Event = new(AppControllerRoleRevoked) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -2748,52 +4241,69 @@ func (it *AppControllerMaxActiveAppsSetIterator) Next() bool { } // Error returns any retrieval or parsing error occurred during filtering. -func (it *AppControllerMaxActiveAppsSetIterator) Error() error { +func (it *AppControllerRoleRevokedIterator) Error() error { return it.fail } // Close terminates the iteration process, releasing any pending underlying // resources. -func (it *AppControllerMaxActiveAppsSetIterator) Close() error { +func (it *AppControllerRoleRevokedIterator) Close() error { it.sub.Unsubscribe() return nil } -// AppControllerMaxActiveAppsSet represents a MaxActiveAppsSet event raised by the AppController contract. -type AppControllerMaxActiveAppsSet struct { - User common.Address - Limit uint32 - Raw types.Log // Blockchain specific contextual infos +// AppControllerRoleRevoked represents a RoleRevoked event raised by the AppController contract. +type AppControllerRoleRevoked struct { + Role [32]byte + Account common.Address + Sender common.Address + Raw types.Log // Blockchain specific contextual infos } -// FilterMaxActiveAppsSet is a free log retrieval operation binding the contract event 0x708c955faa87ece750a9700c153a20797167e2fcbde9fca9186801f874663a99. +// FilterRoleRevoked is a free log retrieval operation binding the contract event 0xf6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b. // -// Solidity: event MaxActiveAppsSet(address indexed user, uint32 limit) -func (_AppController *AppControllerFilterer) FilterMaxActiveAppsSet(opts *bind.FilterOpts, user []common.Address) (*AppControllerMaxActiveAppsSetIterator, error) { +// Solidity: event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender) +func (_AppController *AppControllerFilterer) FilterRoleRevoked(opts *bind.FilterOpts, role [][32]byte, account []common.Address, sender []common.Address) (*AppControllerRoleRevokedIterator, error) { - var userRule []interface{} - for _, userItem := range user { - userRule = append(userRule, userItem) + var roleRule []interface{} + for _, roleItem := range role { + roleRule = append(roleRule, roleItem) + } + var accountRule []interface{} + for _, accountItem := range account { + accountRule = append(accountRule, accountItem) + } + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) } - logs, sub, err := _AppController.contract.FilterLogs(opts, "MaxActiveAppsSet", userRule) + logs, sub, err := _AppController.contract.FilterLogs(opts, "RoleRevoked", roleRule, accountRule, senderRule) if err != nil { return nil, err } - return &AppControllerMaxActiveAppsSetIterator{contract: _AppController.contract, event: "MaxActiveAppsSet", logs: logs, sub: sub}, nil + return &AppControllerRoleRevokedIterator{contract: _AppController.contract, event: "RoleRevoked", logs: logs, sub: sub}, nil } -// WatchMaxActiveAppsSet is a free log subscription operation binding the contract event 0x708c955faa87ece750a9700c153a20797167e2fcbde9fca9186801f874663a99. +// WatchRoleRevoked is a free log subscription operation binding the contract event 0xf6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b. // -// Solidity: event MaxActiveAppsSet(address indexed user, uint32 limit) -func (_AppController *AppControllerFilterer) WatchMaxActiveAppsSet(opts *bind.WatchOpts, sink chan<- *AppControllerMaxActiveAppsSet, user []common.Address) (event.Subscription, error) { +// Solidity: event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender) +func (_AppController *AppControllerFilterer) WatchRoleRevoked(opts *bind.WatchOpts, sink chan<- *AppControllerRoleRevoked, role [][32]byte, account []common.Address, sender []common.Address) (event.Subscription, error) { - var userRule []interface{} - for _, userItem := range user { - userRule = append(userRule, userItem) + var roleRule []interface{} + for _, roleItem := range role { + roleRule = append(roleRule, roleItem) + } + var accountRule []interface{} + for _, accountItem := range account { + accountRule = append(accountRule, accountItem) + } + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) } - logs, sub, err := _AppController.contract.WatchLogs(opts, "MaxActiveAppsSet", userRule) + logs, sub, err := _AppController.contract.WatchLogs(opts, "RoleRevoked", roleRule, accountRule, senderRule) if err != nil { return nil, err } @@ -2803,8 +4313,8 @@ func (_AppController *AppControllerFilterer) WatchMaxActiveAppsSet(opts *bind.Wa select { case log := <-logs: // New log arrived, parse the event and forward to the user - event := new(AppControllerMaxActiveAppsSet) - if err := _AppController.contract.UnpackLog(event, "MaxActiveAppsSet", log); err != nil { + event := new(AppControllerRoleRevoked) + if err := _AppController.contract.UnpackLog(event, "RoleRevoked", log); err != nil { return err } event.Raw = log @@ -2825,12 +4335,12 @@ func (_AppController *AppControllerFilterer) WatchMaxActiveAppsSet(opts *bind.Wa }), nil } -// ParseMaxActiveAppsSet is a log parse operation binding the contract event 0x708c955faa87ece750a9700c153a20797167e2fcbde9fca9186801f874663a99. +// ParseRoleRevoked is a log parse operation binding the contract event 0xf6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b. // -// Solidity: event MaxActiveAppsSet(address indexed user, uint32 limit) -func (_AppController *AppControllerFilterer) ParseMaxActiveAppsSet(log types.Log) (*AppControllerMaxActiveAppsSet, error) { - event := new(AppControllerMaxActiveAppsSet) - if err := _AppController.contract.UnpackLog(event, "MaxActiveAppsSet", log); err != nil { +// Solidity: event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender) +func (_AppController *AppControllerFilterer) ParseRoleRevoked(log types.Log) (*AppControllerRoleRevoked, error) { + event := new(AppControllerRoleRevoked) + if err := _AppController.contract.UnpackLog(event, "RoleRevoked", log); err != nil { return nil, err } event.Raw = log diff --git a/pkg/bindings/v1/SafeTimelockFactory/binding.go b/pkg/bindings/v1/SafeTimelockFactory/binding.go new file mode 100644 index 0000000..f226d78 --- /dev/null +++ b/pkg/bindings/v1/SafeTimelockFactory/binding.go @@ -0,0 +1,952 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package SafeTimelockFactory + +import ( + "errors" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +// ISafeTimelockFactorySafeConfig is an auto generated low-level Go binding around an user-defined struct. +type ISafeTimelockFactorySafeConfig struct { + Owners []common.Address + Threshold *big.Int +} + +// ISafeTimelockFactoryTimelockConfig is an auto generated low-level Go binding around an user-defined struct. +type ISafeTimelockFactoryTimelockConfig struct { + MinDelay *big.Int + Proposers []common.Address + Executors []common.Address +} + +// SafeTimelockFactoryMetaData contains all meta data concerning the SafeTimelockFactory contract. +var SafeTimelockFactoryMetaData = &bind.MetaData{ + ABI: "[{\"type\":\"constructor\",\"inputs\":[{\"name\":\"_safeSingleton\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_safeProxyFactory\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_safeFallbackHandler\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_timelockImplementation\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"calculateSafeAddress\",\"inputs\":[{\"name\":\"deployer\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"config\",\"type\":\"tuple\",\"internalType\":\"structISafeTimelockFactory.SafeConfig\",\"components\":[{\"name\":\"owners\",\"type\":\"address[]\",\"internalType\":\"address[]\"},{\"name\":\"threshold\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]},{\"name\":\"salt\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"calculateTimelockAddress\",\"inputs\":[{\"name\":\"deployer\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"salt\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"deploySafe\",\"inputs\":[{\"name\":\"config\",\"type\":\"tuple\",\"internalType\":\"structISafeTimelockFactory.SafeConfig\",\"components\":[{\"name\":\"owners\",\"type\":\"address[]\",\"internalType\":\"address[]\"},{\"name\":\"threshold\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]},{\"name\":\"salt\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"safe\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"deployTimelock\",\"inputs\":[{\"name\":\"config\",\"type\":\"tuple\",\"internalType\":\"structISafeTimelockFactory.TimelockConfig\",\"components\":[{\"name\":\"minDelay\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"proposers\",\"type\":\"address[]\",\"internalType\":\"address[]\"},{\"name\":\"executors\",\"type\":\"address[]\",\"internalType\":\"address[]\"}]},{\"name\":\"salt\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"timelock\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"initialize\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"isSafe\",\"inputs\":[{\"name\":\"safe\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"isTimelock\",\"inputs\":[{\"name\":\"timelock\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"safeFallbackHandler\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"safeProxyFactory\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"safeSingleton\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"timelockImplementation\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"event\",\"name\":\"Initialized\",\"inputs\":[{\"name\":\"version\",\"type\":\"uint8\",\"indexed\":false,\"internalType\":\"uint8\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"SafeDeployed\",\"inputs\":[{\"name\":\"deployer\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"safe\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"owners\",\"type\":\"address[]\",\"indexed\":false,\"internalType\":\"address[]\"},{\"name\":\"threshold\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"salt\",\"type\":\"bytes32\",\"indexed\":false,\"internalType\":\"bytes32\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"TimelockDeployed\",\"inputs\":[{\"name\":\"deployer\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"timelock\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"minDelay\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"proposers\",\"type\":\"address[]\",\"indexed\":false,\"internalType\":\"address[]\"},{\"name\":\"executors\",\"type\":\"address[]\",\"indexed\":false,\"internalType\":\"address[]\"},{\"name\":\"salt\",\"type\":\"bytes32\",\"indexed\":false,\"internalType\":\"bytes32\"}],\"anonymous\":false},{\"type\":\"error\",\"name\":\"NoExecutors\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"NoProposers\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"ZeroAddressExecutor\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"ZeroAddressProposer\",\"inputs\":[]}]", +} + +// SafeTimelockFactoryABI is the input ABI used to generate the binding from. +// Deprecated: Use SafeTimelockFactoryMetaData.ABI instead. +var SafeTimelockFactoryABI = SafeTimelockFactoryMetaData.ABI + +// SafeTimelockFactory is an auto generated Go binding around an Ethereum contract. +type SafeTimelockFactory struct { + SafeTimelockFactoryCaller // Read-only binding to the contract + SafeTimelockFactoryTransactor // Write-only binding to the contract + SafeTimelockFactoryFilterer // Log filterer for contract events +} + +// SafeTimelockFactoryCaller is an auto generated read-only Go binding around an Ethereum contract. +type SafeTimelockFactoryCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// SafeTimelockFactoryTransactor is an auto generated write-only Go binding around an Ethereum contract. +type SafeTimelockFactoryTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// SafeTimelockFactoryFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type SafeTimelockFactoryFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// SafeTimelockFactorySession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type SafeTimelockFactorySession struct { + Contract *SafeTimelockFactory // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// SafeTimelockFactoryCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type SafeTimelockFactoryCallerSession struct { + Contract *SafeTimelockFactoryCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// SafeTimelockFactoryTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type SafeTimelockFactoryTransactorSession struct { + Contract *SafeTimelockFactoryTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// SafeTimelockFactoryRaw is an auto generated low-level Go binding around an Ethereum contract. +type SafeTimelockFactoryRaw struct { + Contract *SafeTimelockFactory // Generic contract binding to access the raw methods on +} + +// SafeTimelockFactoryCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type SafeTimelockFactoryCallerRaw struct { + Contract *SafeTimelockFactoryCaller // Generic read-only contract binding to access the raw methods on +} + +// SafeTimelockFactoryTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type SafeTimelockFactoryTransactorRaw struct { + Contract *SafeTimelockFactoryTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewSafeTimelockFactory creates a new instance of SafeTimelockFactory, bound to a specific deployed contract. +func NewSafeTimelockFactory(address common.Address, backend bind.ContractBackend) (*SafeTimelockFactory, error) { + contract, err := bindSafeTimelockFactory(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &SafeTimelockFactory{SafeTimelockFactoryCaller: SafeTimelockFactoryCaller{contract: contract}, SafeTimelockFactoryTransactor: SafeTimelockFactoryTransactor{contract: contract}, SafeTimelockFactoryFilterer: SafeTimelockFactoryFilterer{contract: contract}}, nil +} + +// NewSafeTimelockFactoryCaller creates a new read-only instance of SafeTimelockFactory, bound to a specific deployed contract. +func NewSafeTimelockFactoryCaller(address common.Address, caller bind.ContractCaller) (*SafeTimelockFactoryCaller, error) { + contract, err := bindSafeTimelockFactory(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &SafeTimelockFactoryCaller{contract: contract}, nil +} + +// NewSafeTimelockFactoryTransactor creates a new write-only instance of SafeTimelockFactory, bound to a specific deployed contract. +func NewSafeTimelockFactoryTransactor(address common.Address, transactor bind.ContractTransactor) (*SafeTimelockFactoryTransactor, error) { + contract, err := bindSafeTimelockFactory(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &SafeTimelockFactoryTransactor{contract: contract}, nil +} + +// NewSafeTimelockFactoryFilterer creates a new log filterer instance of SafeTimelockFactory, bound to a specific deployed contract. +func NewSafeTimelockFactoryFilterer(address common.Address, filterer bind.ContractFilterer) (*SafeTimelockFactoryFilterer, error) { + contract, err := bindSafeTimelockFactory(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &SafeTimelockFactoryFilterer{contract: contract}, nil +} + +// bindSafeTimelockFactory binds a generic wrapper to an already deployed contract. +func bindSafeTimelockFactory(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := SafeTimelockFactoryMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_SafeTimelockFactory *SafeTimelockFactoryRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _SafeTimelockFactory.Contract.SafeTimelockFactoryCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_SafeTimelockFactory *SafeTimelockFactoryRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _SafeTimelockFactory.Contract.SafeTimelockFactoryTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_SafeTimelockFactory *SafeTimelockFactoryRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _SafeTimelockFactory.Contract.SafeTimelockFactoryTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_SafeTimelockFactory *SafeTimelockFactoryCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _SafeTimelockFactory.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_SafeTimelockFactory *SafeTimelockFactoryTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _SafeTimelockFactory.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_SafeTimelockFactory *SafeTimelockFactoryTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _SafeTimelockFactory.Contract.contract.Transact(opts, method, params...) +} + +// CalculateSafeAddress is a free data retrieval call binding the contract method 0x68282cf3. +// +// Solidity: function calculateSafeAddress(address deployer, (address[],uint256) config, bytes32 salt) view returns(address) +func (_SafeTimelockFactory *SafeTimelockFactoryCaller) CalculateSafeAddress(opts *bind.CallOpts, deployer common.Address, config ISafeTimelockFactorySafeConfig, salt [32]byte) (common.Address, error) { + var out []interface{} + err := _SafeTimelockFactory.contract.Call(opts, &out, "calculateSafeAddress", deployer, config, salt) + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// CalculateSafeAddress is a free data retrieval call binding the contract method 0x68282cf3. +// +// Solidity: function calculateSafeAddress(address deployer, (address[],uint256) config, bytes32 salt) view returns(address) +func (_SafeTimelockFactory *SafeTimelockFactorySession) CalculateSafeAddress(deployer common.Address, config ISafeTimelockFactorySafeConfig, salt [32]byte) (common.Address, error) { + return _SafeTimelockFactory.Contract.CalculateSafeAddress(&_SafeTimelockFactory.CallOpts, deployer, config, salt) +} + +// CalculateSafeAddress is a free data retrieval call binding the contract method 0x68282cf3. +// +// Solidity: function calculateSafeAddress(address deployer, (address[],uint256) config, bytes32 salt) view returns(address) +func (_SafeTimelockFactory *SafeTimelockFactoryCallerSession) CalculateSafeAddress(deployer common.Address, config ISafeTimelockFactorySafeConfig, salt [32]byte) (common.Address, error) { + return _SafeTimelockFactory.Contract.CalculateSafeAddress(&_SafeTimelockFactory.CallOpts, deployer, config, salt) +} + +// CalculateTimelockAddress is a free data retrieval call binding the contract method 0x0e5ceba7. +// +// Solidity: function calculateTimelockAddress(address deployer, bytes32 salt) view returns(address) +func (_SafeTimelockFactory *SafeTimelockFactoryCaller) CalculateTimelockAddress(opts *bind.CallOpts, deployer common.Address, salt [32]byte) (common.Address, error) { + var out []interface{} + err := _SafeTimelockFactory.contract.Call(opts, &out, "calculateTimelockAddress", deployer, salt) + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// CalculateTimelockAddress is a free data retrieval call binding the contract method 0x0e5ceba7. +// +// Solidity: function calculateTimelockAddress(address deployer, bytes32 salt) view returns(address) +func (_SafeTimelockFactory *SafeTimelockFactorySession) CalculateTimelockAddress(deployer common.Address, salt [32]byte) (common.Address, error) { + return _SafeTimelockFactory.Contract.CalculateTimelockAddress(&_SafeTimelockFactory.CallOpts, deployer, salt) +} + +// CalculateTimelockAddress is a free data retrieval call binding the contract method 0x0e5ceba7. +// +// Solidity: function calculateTimelockAddress(address deployer, bytes32 salt) view returns(address) +func (_SafeTimelockFactory *SafeTimelockFactoryCallerSession) CalculateTimelockAddress(deployer common.Address, salt [32]byte) (common.Address, error) { + return _SafeTimelockFactory.Contract.CalculateTimelockAddress(&_SafeTimelockFactory.CallOpts, deployer, salt) +} + +// IsSafe is a free data retrieval call binding the contract method 0x769a28ac. +// +// Solidity: function isSafe(address safe) view returns(bool) +func (_SafeTimelockFactory *SafeTimelockFactoryCaller) IsSafe(opts *bind.CallOpts, safe common.Address) (bool, error) { + var out []interface{} + err := _SafeTimelockFactory.contract.Call(opts, &out, "isSafe", safe) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +// IsSafe is a free data retrieval call binding the contract method 0x769a28ac. +// +// Solidity: function isSafe(address safe) view returns(bool) +func (_SafeTimelockFactory *SafeTimelockFactorySession) IsSafe(safe common.Address) (bool, error) { + return _SafeTimelockFactory.Contract.IsSafe(&_SafeTimelockFactory.CallOpts, safe) +} + +// IsSafe is a free data retrieval call binding the contract method 0x769a28ac. +// +// Solidity: function isSafe(address safe) view returns(bool) +func (_SafeTimelockFactory *SafeTimelockFactoryCallerSession) IsSafe(safe common.Address) (bool, error) { + return _SafeTimelockFactory.Contract.IsSafe(&_SafeTimelockFactory.CallOpts, safe) +} + +// IsTimelock is a free data retrieval call binding the contract method 0x9e93963c. +// +// Solidity: function isTimelock(address timelock) view returns(bool) +func (_SafeTimelockFactory *SafeTimelockFactoryCaller) IsTimelock(opts *bind.CallOpts, timelock common.Address) (bool, error) { + var out []interface{} + err := _SafeTimelockFactory.contract.Call(opts, &out, "isTimelock", timelock) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +// IsTimelock is a free data retrieval call binding the contract method 0x9e93963c. +// +// Solidity: function isTimelock(address timelock) view returns(bool) +func (_SafeTimelockFactory *SafeTimelockFactorySession) IsTimelock(timelock common.Address) (bool, error) { + return _SafeTimelockFactory.Contract.IsTimelock(&_SafeTimelockFactory.CallOpts, timelock) +} + +// IsTimelock is a free data retrieval call binding the contract method 0x9e93963c. +// +// Solidity: function isTimelock(address timelock) view returns(bool) +func (_SafeTimelockFactory *SafeTimelockFactoryCallerSession) IsTimelock(timelock common.Address) (bool, error) { + return _SafeTimelockFactory.Contract.IsTimelock(&_SafeTimelockFactory.CallOpts, timelock) +} + +// SafeFallbackHandler is a free data retrieval call binding the contract method 0xa03bad5a. +// +// Solidity: function safeFallbackHandler() view returns(address) +func (_SafeTimelockFactory *SafeTimelockFactoryCaller) SafeFallbackHandler(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _SafeTimelockFactory.contract.Call(opts, &out, "safeFallbackHandler") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// SafeFallbackHandler is a free data retrieval call binding the contract method 0xa03bad5a. +// +// Solidity: function safeFallbackHandler() view returns(address) +func (_SafeTimelockFactory *SafeTimelockFactorySession) SafeFallbackHandler() (common.Address, error) { + return _SafeTimelockFactory.Contract.SafeFallbackHandler(&_SafeTimelockFactory.CallOpts) +} + +// SafeFallbackHandler is a free data retrieval call binding the contract method 0xa03bad5a. +// +// Solidity: function safeFallbackHandler() view returns(address) +func (_SafeTimelockFactory *SafeTimelockFactoryCallerSession) SafeFallbackHandler() (common.Address, error) { + return _SafeTimelockFactory.Contract.SafeFallbackHandler(&_SafeTimelockFactory.CallOpts) +} + +// SafeProxyFactory is a free data retrieval call binding the contract method 0x19964501. +// +// Solidity: function safeProxyFactory() view returns(address) +func (_SafeTimelockFactory *SafeTimelockFactoryCaller) SafeProxyFactory(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _SafeTimelockFactory.contract.Call(opts, &out, "safeProxyFactory") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// SafeProxyFactory is a free data retrieval call binding the contract method 0x19964501. +// +// Solidity: function safeProxyFactory() view returns(address) +func (_SafeTimelockFactory *SafeTimelockFactorySession) SafeProxyFactory() (common.Address, error) { + return _SafeTimelockFactory.Contract.SafeProxyFactory(&_SafeTimelockFactory.CallOpts) +} + +// SafeProxyFactory is a free data retrieval call binding the contract method 0x19964501. +// +// Solidity: function safeProxyFactory() view returns(address) +func (_SafeTimelockFactory *SafeTimelockFactoryCallerSession) SafeProxyFactory() (common.Address, error) { + return _SafeTimelockFactory.Contract.SafeProxyFactory(&_SafeTimelockFactory.CallOpts) +} + +// SafeSingleton is a free data retrieval call binding the contract method 0xac7d146b. +// +// Solidity: function safeSingleton() view returns(address) +func (_SafeTimelockFactory *SafeTimelockFactoryCaller) SafeSingleton(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _SafeTimelockFactory.contract.Call(opts, &out, "safeSingleton") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// SafeSingleton is a free data retrieval call binding the contract method 0xac7d146b. +// +// Solidity: function safeSingleton() view returns(address) +func (_SafeTimelockFactory *SafeTimelockFactorySession) SafeSingleton() (common.Address, error) { + return _SafeTimelockFactory.Contract.SafeSingleton(&_SafeTimelockFactory.CallOpts) +} + +// SafeSingleton is a free data retrieval call binding the contract method 0xac7d146b. +// +// Solidity: function safeSingleton() view returns(address) +func (_SafeTimelockFactory *SafeTimelockFactoryCallerSession) SafeSingleton() (common.Address, error) { + return _SafeTimelockFactory.Contract.SafeSingleton(&_SafeTimelockFactory.CallOpts) +} + +// TimelockImplementation is a free data retrieval call binding the contract method 0xc5e8f3e5. +// +// Solidity: function timelockImplementation() view returns(address) +func (_SafeTimelockFactory *SafeTimelockFactoryCaller) TimelockImplementation(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _SafeTimelockFactory.contract.Call(opts, &out, "timelockImplementation") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// TimelockImplementation is a free data retrieval call binding the contract method 0xc5e8f3e5. +// +// Solidity: function timelockImplementation() view returns(address) +func (_SafeTimelockFactory *SafeTimelockFactorySession) TimelockImplementation() (common.Address, error) { + return _SafeTimelockFactory.Contract.TimelockImplementation(&_SafeTimelockFactory.CallOpts) +} + +// TimelockImplementation is a free data retrieval call binding the contract method 0xc5e8f3e5. +// +// Solidity: function timelockImplementation() view returns(address) +func (_SafeTimelockFactory *SafeTimelockFactoryCallerSession) TimelockImplementation() (common.Address, error) { + return _SafeTimelockFactory.Contract.TimelockImplementation(&_SafeTimelockFactory.CallOpts) +} + +// DeploySafe is a paid mutator transaction binding the contract method 0xd15a64ce. +// +// Solidity: function deploySafe((address[],uint256) config, bytes32 salt) returns(address safe) +func (_SafeTimelockFactory *SafeTimelockFactoryTransactor) DeploySafe(opts *bind.TransactOpts, config ISafeTimelockFactorySafeConfig, salt [32]byte) (*types.Transaction, error) { + return _SafeTimelockFactory.contract.Transact(opts, "deploySafe", config, salt) +} + +// DeploySafe is a paid mutator transaction binding the contract method 0xd15a64ce. +// +// Solidity: function deploySafe((address[],uint256) config, bytes32 salt) returns(address safe) +func (_SafeTimelockFactory *SafeTimelockFactorySession) DeploySafe(config ISafeTimelockFactorySafeConfig, salt [32]byte) (*types.Transaction, error) { + return _SafeTimelockFactory.Contract.DeploySafe(&_SafeTimelockFactory.TransactOpts, config, salt) +} + +// DeploySafe is a paid mutator transaction binding the contract method 0xd15a64ce. +// +// Solidity: function deploySafe((address[],uint256) config, bytes32 salt) returns(address safe) +func (_SafeTimelockFactory *SafeTimelockFactoryTransactorSession) DeploySafe(config ISafeTimelockFactorySafeConfig, salt [32]byte) (*types.Transaction, error) { + return _SafeTimelockFactory.Contract.DeploySafe(&_SafeTimelockFactory.TransactOpts, config, salt) +} + +// DeployTimelock is a paid mutator transaction binding the contract method 0xb7638897. +// +// Solidity: function deployTimelock((uint256,address[],address[]) config, bytes32 salt) returns(address timelock) +func (_SafeTimelockFactory *SafeTimelockFactoryTransactor) DeployTimelock(opts *bind.TransactOpts, config ISafeTimelockFactoryTimelockConfig, salt [32]byte) (*types.Transaction, error) { + return _SafeTimelockFactory.contract.Transact(opts, "deployTimelock", config, salt) +} + +// DeployTimelock is a paid mutator transaction binding the contract method 0xb7638897. +// +// Solidity: function deployTimelock((uint256,address[],address[]) config, bytes32 salt) returns(address timelock) +func (_SafeTimelockFactory *SafeTimelockFactorySession) DeployTimelock(config ISafeTimelockFactoryTimelockConfig, salt [32]byte) (*types.Transaction, error) { + return _SafeTimelockFactory.Contract.DeployTimelock(&_SafeTimelockFactory.TransactOpts, config, salt) +} + +// DeployTimelock is a paid mutator transaction binding the contract method 0xb7638897. +// +// Solidity: function deployTimelock((uint256,address[],address[]) config, bytes32 salt) returns(address timelock) +func (_SafeTimelockFactory *SafeTimelockFactoryTransactorSession) DeployTimelock(config ISafeTimelockFactoryTimelockConfig, salt [32]byte) (*types.Transaction, error) { + return _SafeTimelockFactory.Contract.DeployTimelock(&_SafeTimelockFactory.TransactOpts, config, salt) +} + +// Initialize is a paid mutator transaction binding the contract method 0x8129fc1c. +// +// Solidity: function initialize() returns() +func (_SafeTimelockFactory *SafeTimelockFactoryTransactor) Initialize(opts *bind.TransactOpts) (*types.Transaction, error) { + return _SafeTimelockFactory.contract.Transact(opts, "initialize") +} + +// Initialize is a paid mutator transaction binding the contract method 0x8129fc1c. +// +// Solidity: function initialize() returns() +func (_SafeTimelockFactory *SafeTimelockFactorySession) Initialize() (*types.Transaction, error) { + return _SafeTimelockFactory.Contract.Initialize(&_SafeTimelockFactory.TransactOpts) +} + +// Initialize is a paid mutator transaction binding the contract method 0x8129fc1c. +// +// Solidity: function initialize() returns() +func (_SafeTimelockFactory *SafeTimelockFactoryTransactorSession) Initialize() (*types.Transaction, error) { + return _SafeTimelockFactory.Contract.Initialize(&_SafeTimelockFactory.TransactOpts) +} + +// SafeTimelockFactoryInitializedIterator is returned from FilterInitialized and is used to iterate over the raw logs and unpacked data for Initialized events raised by the SafeTimelockFactory contract. +type SafeTimelockFactoryInitializedIterator struct { + Event *SafeTimelockFactoryInitialized // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *SafeTimelockFactoryInitializedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(SafeTimelockFactoryInitialized) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(SafeTimelockFactoryInitialized) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *SafeTimelockFactoryInitializedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *SafeTimelockFactoryInitializedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// SafeTimelockFactoryInitialized represents a Initialized event raised by the SafeTimelockFactory contract. +type SafeTimelockFactoryInitialized struct { + Version uint8 + Raw types.Log // Blockchain specific contextual infos +} + +// FilterInitialized is a free log retrieval operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. +// +// Solidity: event Initialized(uint8 version) +func (_SafeTimelockFactory *SafeTimelockFactoryFilterer) FilterInitialized(opts *bind.FilterOpts) (*SafeTimelockFactoryInitializedIterator, error) { + + logs, sub, err := _SafeTimelockFactory.contract.FilterLogs(opts, "Initialized") + if err != nil { + return nil, err + } + return &SafeTimelockFactoryInitializedIterator{contract: _SafeTimelockFactory.contract, event: "Initialized", logs: logs, sub: sub}, nil +} + +// WatchInitialized is a free log subscription operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. +// +// Solidity: event Initialized(uint8 version) +func (_SafeTimelockFactory *SafeTimelockFactoryFilterer) WatchInitialized(opts *bind.WatchOpts, sink chan<- *SafeTimelockFactoryInitialized) (event.Subscription, error) { + + logs, sub, err := _SafeTimelockFactory.contract.WatchLogs(opts, "Initialized") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(SafeTimelockFactoryInitialized) + if err := _SafeTimelockFactory.contract.UnpackLog(event, "Initialized", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseInitialized is a log parse operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. +// +// Solidity: event Initialized(uint8 version) +func (_SafeTimelockFactory *SafeTimelockFactoryFilterer) ParseInitialized(log types.Log) (*SafeTimelockFactoryInitialized, error) { + event := new(SafeTimelockFactoryInitialized) + if err := _SafeTimelockFactory.contract.UnpackLog(event, "Initialized", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// SafeTimelockFactorySafeDeployedIterator is returned from FilterSafeDeployed and is used to iterate over the raw logs and unpacked data for SafeDeployed events raised by the SafeTimelockFactory contract. +type SafeTimelockFactorySafeDeployedIterator struct { + Event *SafeTimelockFactorySafeDeployed // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *SafeTimelockFactorySafeDeployedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(SafeTimelockFactorySafeDeployed) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(SafeTimelockFactorySafeDeployed) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *SafeTimelockFactorySafeDeployedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *SafeTimelockFactorySafeDeployedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// SafeTimelockFactorySafeDeployed represents a SafeDeployed event raised by the SafeTimelockFactory contract. +type SafeTimelockFactorySafeDeployed struct { + Deployer common.Address + Safe common.Address + Owners []common.Address + Threshold *big.Int + Salt [32]byte + Raw types.Log // Blockchain specific contextual infos +} + +// FilterSafeDeployed is a free log retrieval operation binding the contract event 0x1f1cf52f43299bdf7c10abfb65dc19bb454f2e61c2d5f2de2c1d6efbfd1e7a69. +// +// Solidity: event SafeDeployed(address indexed deployer, address indexed safe, address[] owners, uint256 threshold, bytes32 salt) +func (_SafeTimelockFactory *SafeTimelockFactoryFilterer) FilterSafeDeployed(opts *bind.FilterOpts, deployer []common.Address, safe []common.Address) (*SafeTimelockFactorySafeDeployedIterator, error) { + + var deployerRule []interface{} + for _, deployerItem := range deployer { + deployerRule = append(deployerRule, deployerItem) + } + var safeRule []interface{} + for _, safeItem := range safe { + safeRule = append(safeRule, safeItem) + } + + logs, sub, err := _SafeTimelockFactory.contract.FilterLogs(opts, "SafeDeployed", deployerRule, safeRule) + if err != nil { + return nil, err + } + return &SafeTimelockFactorySafeDeployedIterator{contract: _SafeTimelockFactory.contract, event: "SafeDeployed", logs: logs, sub: sub}, nil +} + +// WatchSafeDeployed is a free log subscription operation binding the contract event 0x1f1cf52f43299bdf7c10abfb65dc19bb454f2e61c2d5f2de2c1d6efbfd1e7a69. +// +// Solidity: event SafeDeployed(address indexed deployer, address indexed safe, address[] owners, uint256 threshold, bytes32 salt) +func (_SafeTimelockFactory *SafeTimelockFactoryFilterer) WatchSafeDeployed(opts *bind.WatchOpts, sink chan<- *SafeTimelockFactorySafeDeployed, deployer []common.Address, safe []common.Address) (event.Subscription, error) { + + var deployerRule []interface{} + for _, deployerItem := range deployer { + deployerRule = append(deployerRule, deployerItem) + } + var safeRule []interface{} + for _, safeItem := range safe { + safeRule = append(safeRule, safeItem) + } + + logs, sub, err := _SafeTimelockFactory.contract.WatchLogs(opts, "SafeDeployed", deployerRule, safeRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(SafeTimelockFactorySafeDeployed) + if err := _SafeTimelockFactory.contract.UnpackLog(event, "SafeDeployed", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseSafeDeployed is a log parse operation binding the contract event 0x1f1cf52f43299bdf7c10abfb65dc19bb454f2e61c2d5f2de2c1d6efbfd1e7a69. +// +// Solidity: event SafeDeployed(address indexed deployer, address indexed safe, address[] owners, uint256 threshold, bytes32 salt) +func (_SafeTimelockFactory *SafeTimelockFactoryFilterer) ParseSafeDeployed(log types.Log) (*SafeTimelockFactorySafeDeployed, error) { + event := new(SafeTimelockFactorySafeDeployed) + if err := _SafeTimelockFactory.contract.UnpackLog(event, "SafeDeployed", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// SafeTimelockFactoryTimelockDeployedIterator is returned from FilterTimelockDeployed and is used to iterate over the raw logs and unpacked data for TimelockDeployed events raised by the SafeTimelockFactory contract. +type SafeTimelockFactoryTimelockDeployedIterator struct { + Event *SafeTimelockFactoryTimelockDeployed // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *SafeTimelockFactoryTimelockDeployedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(SafeTimelockFactoryTimelockDeployed) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(SafeTimelockFactoryTimelockDeployed) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *SafeTimelockFactoryTimelockDeployedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *SafeTimelockFactoryTimelockDeployedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// SafeTimelockFactoryTimelockDeployed represents a TimelockDeployed event raised by the SafeTimelockFactory contract. +type SafeTimelockFactoryTimelockDeployed struct { + Deployer common.Address + Timelock common.Address + MinDelay *big.Int + Proposers []common.Address + Executors []common.Address + Salt [32]byte + Raw types.Log // Blockchain specific contextual infos +} + +// FilterTimelockDeployed is a free log retrieval operation binding the contract event 0xfc86ac6f4767b3d388def1785cb7b0d7e671696f3261dc8942332f779b9cde52. +// +// Solidity: event TimelockDeployed(address indexed deployer, address indexed timelock, uint256 minDelay, address[] proposers, address[] executors, bytes32 salt) +func (_SafeTimelockFactory *SafeTimelockFactoryFilterer) FilterTimelockDeployed(opts *bind.FilterOpts, deployer []common.Address, timelock []common.Address) (*SafeTimelockFactoryTimelockDeployedIterator, error) { + + var deployerRule []interface{} + for _, deployerItem := range deployer { + deployerRule = append(deployerRule, deployerItem) + } + var timelockRule []interface{} + for _, timelockItem := range timelock { + timelockRule = append(timelockRule, timelockItem) + } + + logs, sub, err := _SafeTimelockFactory.contract.FilterLogs(opts, "TimelockDeployed", deployerRule, timelockRule) + if err != nil { + return nil, err + } + return &SafeTimelockFactoryTimelockDeployedIterator{contract: _SafeTimelockFactory.contract, event: "TimelockDeployed", logs: logs, sub: sub}, nil +} + +// WatchTimelockDeployed is a free log subscription operation binding the contract event 0xfc86ac6f4767b3d388def1785cb7b0d7e671696f3261dc8942332f779b9cde52. +// +// Solidity: event TimelockDeployed(address indexed deployer, address indexed timelock, uint256 minDelay, address[] proposers, address[] executors, bytes32 salt) +func (_SafeTimelockFactory *SafeTimelockFactoryFilterer) WatchTimelockDeployed(opts *bind.WatchOpts, sink chan<- *SafeTimelockFactoryTimelockDeployed, deployer []common.Address, timelock []common.Address) (event.Subscription, error) { + + var deployerRule []interface{} + for _, deployerItem := range deployer { + deployerRule = append(deployerRule, deployerItem) + } + var timelockRule []interface{} + for _, timelockItem := range timelock { + timelockRule = append(timelockRule, timelockItem) + } + + logs, sub, err := _SafeTimelockFactory.contract.WatchLogs(opts, "TimelockDeployed", deployerRule, timelockRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(SafeTimelockFactoryTimelockDeployed) + if err := _SafeTimelockFactory.contract.UnpackLog(event, "TimelockDeployed", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseTimelockDeployed is a log parse operation binding the contract event 0xfc86ac6f4767b3d388def1785cb7b0d7e671696f3261dc8942332f779b9cde52. +// +// Solidity: event TimelockDeployed(address indexed deployer, address indexed timelock, uint256 minDelay, address[] proposers, address[] executors, bytes32 salt) +func (_SafeTimelockFactory *SafeTimelockFactoryFilterer) ParseTimelockDeployed(log types.Log) (*SafeTimelockFactoryTimelockDeployed, error) { + event := new(SafeTimelockFactoryTimelockDeployed) + if err := _SafeTimelockFactory.contract.UnpackLog(event, "TimelockDeployed", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} diff --git a/pkg/bindings/v1/TimelockControllerImpl/binding.go b/pkg/bindings/v1/TimelockControllerImpl/binding.go new file mode 100644 index 0000000..01fedc7 --- /dev/null +++ b/pkg/bindings/v1/TimelockControllerImpl/binding.go @@ -0,0 +1,2329 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package TimelockControllerImpl + +import ( + "errors" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +// TimelockControllerImplMetaData contains all meta data concerning the TimelockControllerImpl contract. +var TimelockControllerImplMetaData = &bind.MetaData{ + ABI: "[{\"type\":\"constructor\",\"inputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"receive\",\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"CANCELLER_ROLE\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"DEFAULT_ADMIN_ROLE\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"EXECUTOR_ROLE\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"PROPOSER_ROLE\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"TIMELOCK_ADMIN_ROLE\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"cancel\",\"inputs\":[{\"name\":\"id\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"execute\",\"inputs\":[{\"name\":\"target\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"value\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"payload\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"predecessor\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"salt\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"executeBatch\",\"inputs\":[{\"name\":\"targets\",\"type\":\"address[]\",\"internalType\":\"address[]\"},{\"name\":\"values\",\"type\":\"uint256[]\",\"internalType\":\"uint256[]\"},{\"name\":\"payloads\",\"type\":\"bytes[]\",\"internalType\":\"bytes[]\"},{\"name\":\"predecessor\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"salt\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"getMinDelay\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getRoleAdmin\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getTimestamp\",\"inputs\":[{\"name\":\"id\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"grantRole\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"hasRole\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"hashOperation\",\"inputs\":[{\"name\":\"target\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"value\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"data\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"predecessor\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"salt\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"pure\"},{\"type\":\"function\",\"name\":\"hashOperationBatch\",\"inputs\":[{\"name\":\"targets\",\"type\":\"address[]\",\"internalType\":\"address[]\"},{\"name\":\"values\",\"type\":\"uint256[]\",\"internalType\":\"uint256[]\"},{\"name\":\"payloads\",\"type\":\"bytes[]\",\"internalType\":\"bytes[]\"},{\"name\":\"predecessor\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"salt\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"pure\"},{\"type\":\"function\",\"name\":\"initialize\",\"inputs\":[{\"name\":\"minDelay\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"proposers\",\"type\":\"address[]\",\"internalType\":\"address[]\"},{\"name\":\"executors\",\"type\":\"address[]\",\"internalType\":\"address[]\"},{\"name\":\"admin\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"isOperation\",\"inputs\":[{\"name\":\"id\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"isOperationDone\",\"inputs\":[{\"name\":\"id\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"isOperationPending\",\"inputs\":[{\"name\":\"id\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"isOperationReady\",\"inputs\":[{\"name\":\"id\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"onERC1155BatchReceived\",\"inputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"\",\"type\":\"uint256[]\",\"internalType\":\"uint256[]\"},{\"name\":\"\",\"type\":\"uint256[]\",\"internalType\":\"uint256[]\"},{\"name\":\"\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes4\",\"internalType\":\"bytes4\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"onERC1155Received\",\"inputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes4\",\"internalType\":\"bytes4\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"onERC721Received\",\"inputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes4\",\"internalType\":\"bytes4\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"renounceRole\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"revokeRole\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"schedule\",\"inputs\":[{\"name\":\"target\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"value\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"data\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"predecessor\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"salt\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"delay\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"scheduleBatch\",\"inputs\":[{\"name\":\"targets\",\"type\":\"address[]\",\"internalType\":\"address[]\"},{\"name\":\"values\",\"type\":\"uint256[]\",\"internalType\":\"uint256[]\"},{\"name\":\"payloads\",\"type\":\"bytes[]\",\"internalType\":\"bytes[]\"},{\"name\":\"predecessor\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"salt\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"delay\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"supportsInterface\",\"inputs\":[{\"name\":\"interfaceId\",\"type\":\"bytes4\",\"internalType\":\"bytes4\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"updateDelay\",\"inputs\":[{\"name\":\"newDelay\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"event\",\"name\":\"CallExecuted\",\"inputs\":[{\"name\":\"id\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"index\",\"type\":\"uint256\",\"indexed\":true,\"internalType\":\"uint256\"},{\"name\":\"target\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"},{\"name\":\"value\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"data\",\"type\":\"bytes\",\"indexed\":false,\"internalType\":\"bytes\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"CallSalt\",\"inputs\":[{\"name\":\"id\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"salt\",\"type\":\"bytes32\",\"indexed\":false,\"internalType\":\"bytes32\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"CallScheduled\",\"inputs\":[{\"name\":\"id\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"index\",\"type\":\"uint256\",\"indexed\":true,\"internalType\":\"uint256\"},{\"name\":\"target\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"},{\"name\":\"value\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"data\",\"type\":\"bytes\",\"indexed\":false,\"internalType\":\"bytes\"},{\"name\":\"predecessor\",\"type\":\"bytes32\",\"indexed\":false,\"internalType\":\"bytes32\"},{\"name\":\"delay\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Cancelled\",\"inputs\":[{\"name\":\"id\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Initialized\",\"inputs\":[{\"name\":\"version\",\"type\":\"uint8\",\"indexed\":false,\"internalType\":\"uint8\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"MinDelayChange\",\"inputs\":[{\"name\":\"oldDuration\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"newDuration\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"RoleAdminChanged\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"previousAdminRole\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"newAdminRole\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"RoleGranted\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"account\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"sender\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"RoleRevoked\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"account\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"sender\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false}]", +} + +// TimelockControllerImplABI is the input ABI used to generate the binding from. +// Deprecated: Use TimelockControllerImplMetaData.ABI instead. +var TimelockControllerImplABI = TimelockControllerImplMetaData.ABI + +// TimelockControllerImpl is an auto generated Go binding around an Ethereum contract. +type TimelockControllerImpl struct { + TimelockControllerImplCaller // Read-only binding to the contract + TimelockControllerImplTransactor // Write-only binding to the contract + TimelockControllerImplFilterer // Log filterer for contract events +} + +// TimelockControllerImplCaller is an auto generated read-only Go binding around an Ethereum contract. +type TimelockControllerImplCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// TimelockControllerImplTransactor is an auto generated write-only Go binding around an Ethereum contract. +type TimelockControllerImplTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// TimelockControllerImplFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type TimelockControllerImplFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// TimelockControllerImplSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type TimelockControllerImplSession struct { + Contract *TimelockControllerImpl // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// TimelockControllerImplCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type TimelockControllerImplCallerSession struct { + Contract *TimelockControllerImplCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// TimelockControllerImplTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type TimelockControllerImplTransactorSession struct { + Contract *TimelockControllerImplTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// TimelockControllerImplRaw is an auto generated low-level Go binding around an Ethereum contract. +type TimelockControllerImplRaw struct { + Contract *TimelockControllerImpl // Generic contract binding to access the raw methods on +} + +// TimelockControllerImplCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type TimelockControllerImplCallerRaw struct { + Contract *TimelockControllerImplCaller // Generic read-only contract binding to access the raw methods on +} + +// TimelockControllerImplTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type TimelockControllerImplTransactorRaw struct { + Contract *TimelockControllerImplTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewTimelockControllerImpl creates a new instance of TimelockControllerImpl, bound to a specific deployed contract. +func NewTimelockControllerImpl(address common.Address, backend bind.ContractBackend) (*TimelockControllerImpl, error) { + contract, err := bindTimelockControllerImpl(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &TimelockControllerImpl{TimelockControllerImplCaller: TimelockControllerImplCaller{contract: contract}, TimelockControllerImplTransactor: TimelockControllerImplTransactor{contract: contract}, TimelockControllerImplFilterer: TimelockControllerImplFilterer{contract: contract}}, nil +} + +// NewTimelockControllerImplCaller creates a new read-only instance of TimelockControllerImpl, bound to a specific deployed contract. +func NewTimelockControllerImplCaller(address common.Address, caller bind.ContractCaller) (*TimelockControllerImplCaller, error) { + contract, err := bindTimelockControllerImpl(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &TimelockControllerImplCaller{contract: contract}, nil +} + +// NewTimelockControllerImplTransactor creates a new write-only instance of TimelockControllerImpl, bound to a specific deployed contract. +func NewTimelockControllerImplTransactor(address common.Address, transactor bind.ContractTransactor) (*TimelockControllerImplTransactor, error) { + contract, err := bindTimelockControllerImpl(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &TimelockControllerImplTransactor{contract: contract}, nil +} + +// NewTimelockControllerImplFilterer creates a new log filterer instance of TimelockControllerImpl, bound to a specific deployed contract. +func NewTimelockControllerImplFilterer(address common.Address, filterer bind.ContractFilterer) (*TimelockControllerImplFilterer, error) { + contract, err := bindTimelockControllerImpl(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &TimelockControllerImplFilterer{contract: contract}, nil +} + +// bindTimelockControllerImpl binds a generic wrapper to an already deployed contract. +func bindTimelockControllerImpl(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := TimelockControllerImplMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_TimelockControllerImpl *TimelockControllerImplRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _TimelockControllerImpl.Contract.TimelockControllerImplCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_TimelockControllerImpl *TimelockControllerImplRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _TimelockControllerImpl.Contract.TimelockControllerImplTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_TimelockControllerImpl *TimelockControllerImplRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _TimelockControllerImpl.Contract.TimelockControllerImplTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_TimelockControllerImpl *TimelockControllerImplCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _TimelockControllerImpl.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_TimelockControllerImpl *TimelockControllerImplTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _TimelockControllerImpl.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_TimelockControllerImpl *TimelockControllerImplTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _TimelockControllerImpl.Contract.contract.Transact(opts, method, params...) +} + +// CANCELLERROLE is a free data retrieval call binding the contract method 0xb08e51c0. +// +// Solidity: function CANCELLER_ROLE() view returns(bytes32) +func (_TimelockControllerImpl *TimelockControllerImplCaller) CANCELLERROLE(opts *bind.CallOpts) ([32]byte, error) { + var out []interface{} + err := _TimelockControllerImpl.contract.Call(opts, &out, "CANCELLER_ROLE") + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// CANCELLERROLE is a free data retrieval call binding the contract method 0xb08e51c0. +// +// Solidity: function CANCELLER_ROLE() view returns(bytes32) +func (_TimelockControllerImpl *TimelockControllerImplSession) CANCELLERROLE() ([32]byte, error) { + return _TimelockControllerImpl.Contract.CANCELLERROLE(&_TimelockControllerImpl.CallOpts) +} + +// CANCELLERROLE is a free data retrieval call binding the contract method 0xb08e51c0. +// +// Solidity: function CANCELLER_ROLE() view returns(bytes32) +func (_TimelockControllerImpl *TimelockControllerImplCallerSession) CANCELLERROLE() ([32]byte, error) { + return _TimelockControllerImpl.Contract.CANCELLERROLE(&_TimelockControllerImpl.CallOpts) +} + +// DEFAULTADMINROLE is a free data retrieval call binding the contract method 0xa217fddf. +// +// Solidity: function DEFAULT_ADMIN_ROLE() view returns(bytes32) +func (_TimelockControllerImpl *TimelockControllerImplCaller) DEFAULTADMINROLE(opts *bind.CallOpts) ([32]byte, error) { + var out []interface{} + err := _TimelockControllerImpl.contract.Call(opts, &out, "DEFAULT_ADMIN_ROLE") + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// DEFAULTADMINROLE is a free data retrieval call binding the contract method 0xa217fddf. +// +// Solidity: function DEFAULT_ADMIN_ROLE() view returns(bytes32) +func (_TimelockControllerImpl *TimelockControllerImplSession) DEFAULTADMINROLE() ([32]byte, error) { + return _TimelockControllerImpl.Contract.DEFAULTADMINROLE(&_TimelockControllerImpl.CallOpts) +} + +// DEFAULTADMINROLE is a free data retrieval call binding the contract method 0xa217fddf. +// +// Solidity: function DEFAULT_ADMIN_ROLE() view returns(bytes32) +func (_TimelockControllerImpl *TimelockControllerImplCallerSession) DEFAULTADMINROLE() ([32]byte, error) { + return _TimelockControllerImpl.Contract.DEFAULTADMINROLE(&_TimelockControllerImpl.CallOpts) +} + +// EXECUTORROLE is a free data retrieval call binding the contract method 0x07bd0265. +// +// Solidity: function EXECUTOR_ROLE() view returns(bytes32) +func (_TimelockControllerImpl *TimelockControllerImplCaller) EXECUTORROLE(opts *bind.CallOpts) ([32]byte, error) { + var out []interface{} + err := _TimelockControllerImpl.contract.Call(opts, &out, "EXECUTOR_ROLE") + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// EXECUTORROLE is a free data retrieval call binding the contract method 0x07bd0265. +// +// Solidity: function EXECUTOR_ROLE() view returns(bytes32) +func (_TimelockControllerImpl *TimelockControllerImplSession) EXECUTORROLE() ([32]byte, error) { + return _TimelockControllerImpl.Contract.EXECUTORROLE(&_TimelockControllerImpl.CallOpts) +} + +// EXECUTORROLE is a free data retrieval call binding the contract method 0x07bd0265. +// +// Solidity: function EXECUTOR_ROLE() view returns(bytes32) +func (_TimelockControllerImpl *TimelockControllerImplCallerSession) EXECUTORROLE() ([32]byte, error) { + return _TimelockControllerImpl.Contract.EXECUTORROLE(&_TimelockControllerImpl.CallOpts) +} + +// PROPOSERROLE is a free data retrieval call binding the contract method 0x8f61f4f5. +// +// Solidity: function PROPOSER_ROLE() view returns(bytes32) +func (_TimelockControllerImpl *TimelockControllerImplCaller) PROPOSERROLE(opts *bind.CallOpts) ([32]byte, error) { + var out []interface{} + err := _TimelockControllerImpl.contract.Call(opts, &out, "PROPOSER_ROLE") + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// PROPOSERROLE is a free data retrieval call binding the contract method 0x8f61f4f5. +// +// Solidity: function PROPOSER_ROLE() view returns(bytes32) +func (_TimelockControllerImpl *TimelockControllerImplSession) PROPOSERROLE() ([32]byte, error) { + return _TimelockControllerImpl.Contract.PROPOSERROLE(&_TimelockControllerImpl.CallOpts) +} + +// PROPOSERROLE is a free data retrieval call binding the contract method 0x8f61f4f5. +// +// Solidity: function PROPOSER_ROLE() view returns(bytes32) +func (_TimelockControllerImpl *TimelockControllerImplCallerSession) PROPOSERROLE() ([32]byte, error) { + return _TimelockControllerImpl.Contract.PROPOSERROLE(&_TimelockControllerImpl.CallOpts) +} + +// TIMELOCKADMINROLE is a free data retrieval call binding the contract method 0x0d3cf6fc. +// +// Solidity: function TIMELOCK_ADMIN_ROLE() view returns(bytes32) +func (_TimelockControllerImpl *TimelockControllerImplCaller) TIMELOCKADMINROLE(opts *bind.CallOpts) ([32]byte, error) { + var out []interface{} + err := _TimelockControllerImpl.contract.Call(opts, &out, "TIMELOCK_ADMIN_ROLE") + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// TIMELOCKADMINROLE is a free data retrieval call binding the contract method 0x0d3cf6fc. +// +// Solidity: function TIMELOCK_ADMIN_ROLE() view returns(bytes32) +func (_TimelockControllerImpl *TimelockControllerImplSession) TIMELOCKADMINROLE() ([32]byte, error) { + return _TimelockControllerImpl.Contract.TIMELOCKADMINROLE(&_TimelockControllerImpl.CallOpts) +} + +// TIMELOCKADMINROLE is a free data retrieval call binding the contract method 0x0d3cf6fc. +// +// Solidity: function TIMELOCK_ADMIN_ROLE() view returns(bytes32) +func (_TimelockControllerImpl *TimelockControllerImplCallerSession) TIMELOCKADMINROLE() ([32]byte, error) { + return _TimelockControllerImpl.Contract.TIMELOCKADMINROLE(&_TimelockControllerImpl.CallOpts) +} + +// GetMinDelay is a free data retrieval call binding the contract method 0xf27a0c92. +// +// Solidity: function getMinDelay() view returns(uint256) +func (_TimelockControllerImpl *TimelockControllerImplCaller) GetMinDelay(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _TimelockControllerImpl.contract.Call(opts, &out, "getMinDelay") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// GetMinDelay is a free data retrieval call binding the contract method 0xf27a0c92. +// +// Solidity: function getMinDelay() view returns(uint256) +func (_TimelockControllerImpl *TimelockControllerImplSession) GetMinDelay() (*big.Int, error) { + return _TimelockControllerImpl.Contract.GetMinDelay(&_TimelockControllerImpl.CallOpts) +} + +// GetMinDelay is a free data retrieval call binding the contract method 0xf27a0c92. +// +// Solidity: function getMinDelay() view returns(uint256) +func (_TimelockControllerImpl *TimelockControllerImplCallerSession) GetMinDelay() (*big.Int, error) { + return _TimelockControllerImpl.Contract.GetMinDelay(&_TimelockControllerImpl.CallOpts) +} + +// GetRoleAdmin is a free data retrieval call binding the contract method 0x248a9ca3. +// +// Solidity: function getRoleAdmin(bytes32 role) view returns(bytes32) +func (_TimelockControllerImpl *TimelockControllerImplCaller) GetRoleAdmin(opts *bind.CallOpts, role [32]byte) ([32]byte, error) { + var out []interface{} + err := _TimelockControllerImpl.contract.Call(opts, &out, "getRoleAdmin", role) + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// GetRoleAdmin is a free data retrieval call binding the contract method 0x248a9ca3. +// +// Solidity: function getRoleAdmin(bytes32 role) view returns(bytes32) +func (_TimelockControllerImpl *TimelockControllerImplSession) GetRoleAdmin(role [32]byte) ([32]byte, error) { + return _TimelockControllerImpl.Contract.GetRoleAdmin(&_TimelockControllerImpl.CallOpts, role) +} + +// GetRoleAdmin is a free data retrieval call binding the contract method 0x248a9ca3. +// +// Solidity: function getRoleAdmin(bytes32 role) view returns(bytes32) +func (_TimelockControllerImpl *TimelockControllerImplCallerSession) GetRoleAdmin(role [32]byte) ([32]byte, error) { + return _TimelockControllerImpl.Contract.GetRoleAdmin(&_TimelockControllerImpl.CallOpts, role) +} + +// GetTimestamp is a free data retrieval call binding the contract method 0xd45c4435. +// +// Solidity: function getTimestamp(bytes32 id) view returns(uint256) +func (_TimelockControllerImpl *TimelockControllerImplCaller) GetTimestamp(opts *bind.CallOpts, id [32]byte) (*big.Int, error) { + var out []interface{} + err := _TimelockControllerImpl.contract.Call(opts, &out, "getTimestamp", id) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// GetTimestamp is a free data retrieval call binding the contract method 0xd45c4435. +// +// Solidity: function getTimestamp(bytes32 id) view returns(uint256) +func (_TimelockControllerImpl *TimelockControllerImplSession) GetTimestamp(id [32]byte) (*big.Int, error) { + return _TimelockControllerImpl.Contract.GetTimestamp(&_TimelockControllerImpl.CallOpts, id) +} + +// GetTimestamp is a free data retrieval call binding the contract method 0xd45c4435. +// +// Solidity: function getTimestamp(bytes32 id) view returns(uint256) +func (_TimelockControllerImpl *TimelockControllerImplCallerSession) GetTimestamp(id [32]byte) (*big.Int, error) { + return _TimelockControllerImpl.Contract.GetTimestamp(&_TimelockControllerImpl.CallOpts, id) +} + +// HasRole is a free data retrieval call binding the contract method 0x91d14854. +// +// Solidity: function hasRole(bytes32 role, address account) view returns(bool) +func (_TimelockControllerImpl *TimelockControllerImplCaller) HasRole(opts *bind.CallOpts, role [32]byte, account common.Address) (bool, error) { + var out []interface{} + err := _TimelockControllerImpl.contract.Call(opts, &out, "hasRole", role, account) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +// HasRole is a free data retrieval call binding the contract method 0x91d14854. +// +// Solidity: function hasRole(bytes32 role, address account) view returns(bool) +func (_TimelockControllerImpl *TimelockControllerImplSession) HasRole(role [32]byte, account common.Address) (bool, error) { + return _TimelockControllerImpl.Contract.HasRole(&_TimelockControllerImpl.CallOpts, role, account) +} + +// HasRole is a free data retrieval call binding the contract method 0x91d14854. +// +// Solidity: function hasRole(bytes32 role, address account) view returns(bool) +func (_TimelockControllerImpl *TimelockControllerImplCallerSession) HasRole(role [32]byte, account common.Address) (bool, error) { + return _TimelockControllerImpl.Contract.HasRole(&_TimelockControllerImpl.CallOpts, role, account) +} + +// HashOperation is a free data retrieval call binding the contract method 0x8065657f. +// +// Solidity: function hashOperation(address target, uint256 value, bytes data, bytes32 predecessor, bytes32 salt) pure returns(bytes32) +func (_TimelockControllerImpl *TimelockControllerImplCaller) HashOperation(opts *bind.CallOpts, target common.Address, value *big.Int, data []byte, predecessor [32]byte, salt [32]byte) ([32]byte, error) { + var out []interface{} + err := _TimelockControllerImpl.contract.Call(opts, &out, "hashOperation", target, value, data, predecessor, salt) + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// HashOperation is a free data retrieval call binding the contract method 0x8065657f. +// +// Solidity: function hashOperation(address target, uint256 value, bytes data, bytes32 predecessor, bytes32 salt) pure returns(bytes32) +func (_TimelockControllerImpl *TimelockControllerImplSession) HashOperation(target common.Address, value *big.Int, data []byte, predecessor [32]byte, salt [32]byte) ([32]byte, error) { + return _TimelockControllerImpl.Contract.HashOperation(&_TimelockControllerImpl.CallOpts, target, value, data, predecessor, salt) +} + +// HashOperation is a free data retrieval call binding the contract method 0x8065657f. +// +// Solidity: function hashOperation(address target, uint256 value, bytes data, bytes32 predecessor, bytes32 salt) pure returns(bytes32) +func (_TimelockControllerImpl *TimelockControllerImplCallerSession) HashOperation(target common.Address, value *big.Int, data []byte, predecessor [32]byte, salt [32]byte) ([32]byte, error) { + return _TimelockControllerImpl.Contract.HashOperation(&_TimelockControllerImpl.CallOpts, target, value, data, predecessor, salt) +} + +// HashOperationBatch is a free data retrieval call binding the contract method 0xb1c5f427. +// +// Solidity: function hashOperationBatch(address[] targets, uint256[] values, bytes[] payloads, bytes32 predecessor, bytes32 salt) pure returns(bytes32) +func (_TimelockControllerImpl *TimelockControllerImplCaller) HashOperationBatch(opts *bind.CallOpts, targets []common.Address, values []*big.Int, payloads [][]byte, predecessor [32]byte, salt [32]byte) ([32]byte, error) { + var out []interface{} + err := _TimelockControllerImpl.contract.Call(opts, &out, "hashOperationBatch", targets, values, payloads, predecessor, salt) + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// HashOperationBatch is a free data retrieval call binding the contract method 0xb1c5f427. +// +// Solidity: function hashOperationBatch(address[] targets, uint256[] values, bytes[] payloads, bytes32 predecessor, bytes32 salt) pure returns(bytes32) +func (_TimelockControllerImpl *TimelockControllerImplSession) HashOperationBatch(targets []common.Address, values []*big.Int, payloads [][]byte, predecessor [32]byte, salt [32]byte) ([32]byte, error) { + return _TimelockControllerImpl.Contract.HashOperationBatch(&_TimelockControllerImpl.CallOpts, targets, values, payloads, predecessor, salt) +} + +// HashOperationBatch is a free data retrieval call binding the contract method 0xb1c5f427. +// +// Solidity: function hashOperationBatch(address[] targets, uint256[] values, bytes[] payloads, bytes32 predecessor, bytes32 salt) pure returns(bytes32) +func (_TimelockControllerImpl *TimelockControllerImplCallerSession) HashOperationBatch(targets []common.Address, values []*big.Int, payloads [][]byte, predecessor [32]byte, salt [32]byte) ([32]byte, error) { + return _TimelockControllerImpl.Contract.HashOperationBatch(&_TimelockControllerImpl.CallOpts, targets, values, payloads, predecessor, salt) +} + +// IsOperation is a free data retrieval call binding the contract method 0x31d50750. +// +// Solidity: function isOperation(bytes32 id) view returns(bool) +func (_TimelockControllerImpl *TimelockControllerImplCaller) IsOperation(opts *bind.CallOpts, id [32]byte) (bool, error) { + var out []interface{} + err := _TimelockControllerImpl.contract.Call(opts, &out, "isOperation", id) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +// IsOperation is a free data retrieval call binding the contract method 0x31d50750. +// +// Solidity: function isOperation(bytes32 id) view returns(bool) +func (_TimelockControllerImpl *TimelockControllerImplSession) IsOperation(id [32]byte) (bool, error) { + return _TimelockControllerImpl.Contract.IsOperation(&_TimelockControllerImpl.CallOpts, id) +} + +// IsOperation is a free data retrieval call binding the contract method 0x31d50750. +// +// Solidity: function isOperation(bytes32 id) view returns(bool) +func (_TimelockControllerImpl *TimelockControllerImplCallerSession) IsOperation(id [32]byte) (bool, error) { + return _TimelockControllerImpl.Contract.IsOperation(&_TimelockControllerImpl.CallOpts, id) +} + +// IsOperationDone is a free data retrieval call binding the contract method 0x2ab0f529. +// +// Solidity: function isOperationDone(bytes32 id) view returns(bool) +func (_TimelockControllerImpl *TimelockControllerImplCaller) IsOperationDone(opts *bind.CallOpts, id [32]byte) (bool, error) { + var out []interface{} + err := _TimelockControllerImpl.contract.Call(opts, &out, "isOperationDone", id) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +// IsOperationDone is a free data retrieval call binding the contract method 0x2ab0f529. +// +// Solidity: function isOperationDone(bytes32 id) view returns(bool) +func (_TimelockControllerImpl *TimelockControllerImplSession) IsOperationDone(id [32]byte) (bool, error) { + return _TimelockControllerImpl.Contract.IsOperationDone(&_TimelockControllerImpl.CallOpts, id) +} + +// IsOperationDone is a free data retrieval call binding the contract method 0x2ab0f529. +// +// Solidity: function isOperationDone(bytes32 id) view returns(bool) +func (_TimelockControllerImpl *TimelockControllerImplCallerSession) IsOperationDone(id [32]byte) (bool, error) { + return _TimelockControllerImpl.Contract.IsOperationDone(&_TimelockControllerImpl.CallOpts, id) +} + +// IsOperationPending is a free data retrieval call binding the contract method 0x584b153e. +// +// Solidity: function isOperationPending(bytes32 id) view returns(bool) +func (_TimelockControllerImpl *TimelockControllerImplCaller) IsOperationPending(opts *bind.CallOpts, id [32]byte) (bool, error) { + var out []interface{} + err := _TimelockControllerImpl.contract.Call(opts, &out, "isOperationPending", id) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +// IsOperationPending is a free data retrieval call binding the contract method 0x584b153e. +// +// Solidity: function isOperationPending(bytes32 id) view returns(bool) +func (_TimelockControllerImpl *TimelockControllerImplSession) IsOperationPending(id [32]byte) (bool, error) { + return _TimelockControllerImpl.Contract.IsOperationPending(&_TimelockControllerImpl.CallOpts, id) +} + +// IsOperationPending is a free data retrieval call binding the contract method 0x584b153e. +// +// Solidity: function isOperationPending(bytes32 id) view returns(bool) +func (_TimelockControllerImpl *TimelockControllerImplCallerSession) IsOperationPending(id [32]byte) (bool, error) { + return _TimelockControllerImpl.Contract.IsOperationPending(&_TimelockControllerImpl.CallOpts, id) +} + +// IsOperationReady is a free data retrieval call binding the contract method 0x13bc9f20. +// +// Solidity: function isOperationReady(bytes32 id) view returns(bool) +func (_TimelockControllerImpl *TimelockControllerImplCaller) IsOperationReady(opts *bind.CallOpts, id [32]byte) (bool, error) { + var out []interface{} + err := _TimelockControllerImpl.contract.Call(opts, &out, "isOperationReady", id) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +// IsOperationReady is a free data retrieval call binding the contract method 0x13bc9f20. +// +// Solidity: function isOperationReady(bytes32 id) view returns(bool) +func (_TimelockControllerImpl *TimelockControllerImplSession) IsOperationReady(id [32]byte) (bool, error) { + return _TimelockControllerImpl.Contract.IsOperationReady(&_TimelockControllerImpl.CallOpts, id) +} + +// IsOperationReady is a free data retrieval call binding the contract method 0x13bc9f20. +// +// Solidity: function isOperationReady(bytes32 id) view returns(bool) +func (_TimelockControllerImpl *TimelockControllerImplCallerSession) IsOperationReady(id [32]byte) (bool, error) { + return _TimelockControllerImpl.Contract.IsOperationReady(&_TimelockControllerImpl.CallOpts, id) +} + +// SupportsInterface is a free data retrieval call binding the contract method 0x01ffc9a7. +// +// Solidity: function supportsInterface(bytes4 interfaceId) view returns(bool) +func (_TimelockControllerImpl *TimelockControllerImplCaller) SupportsInterface(opts *bind.CallOpts, interfaceId [4]byte) (bool, error) { + var out []interface{} + err := _TimelockControllerImpl.contract.Call(opts, &out, "supportsInterface", interfaceId) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +// SupportsInterface is a free data retrieval call binding the contract method 0x01ffc9a7. +// +// Solidity: function supportsInterface(bytes4 interfaceId) view returns(bool) +func (_TimelockControllerImpl *TimelockControllerImplSession) SupportsInterface(interfaceId [4]byte) (bool, error) { + return _TimelockControllerImpl.Contract.SupportsInterface(&_TimelockControllerImpl.CallOpts, interfaceId) +} + +// SupportsInterface is a free data retrieval call binding the contract method 0x01ffc9a7. +// +// Solidity: function supportsInterface(bytes4 interfaceId) view returns(bool) +func (_TimelockControllerImpl *TimelockControllerImplCallerSession) SupportsInterface(interfaceId [4]byte) (bool, error) { + return _TimelockControllerImpl.Contract.SupportsInterface(&_TimelockControllerImpl.CallOpts, interfaceId) +} + +// Cancel is a paid mutator transaction binding the contract method 0xc4d252f5. +// +// Solidity: function cancel(bytes32 id) returns() +func (_TimelockControllerImpl *TimelockControllerImplTransactor) Cancel(opts *bind.TransactOpts, id [32]byte) (*types.Transaction, error) { + return _TimelockControllerImpl.contract.Transact(opts, "cancel", id) +} + +// Cancel is a paid mutator transaction binding the contract method 0xc4d252f5. +// +// Solidity: function cancel(bytes32 id) returns() +func (_TimelockControllerImpl *TimelockControllerImplSession) Cancel(id [32]byte) (*types.Transaction, error) { + return _TimelockControllerImpl.Contract.Cancel(&_TimelockControllerImpl.TransactOpts, id) +} + +// Cancel is a paid mutator transaction binding the contract method 0xc4d252f5. +// +// Solidity: function cancel(bytes32 id) returns() +func (_TimelockControllerImpl *TimelockControllerImplTransactorSession) Cancel(id [32]byte) (*types.Transaction, error) { + return _TimelockControllerImpl.Contract.Cancel(&_TimelockControllerImpl.TransactOpts, id) +} + +// Execute is a paid mutator transaction binding the contract method 0x134008d3. +// +// Solidity: function execute(address target, uint256 value, bytes payload, bytes32 predecessor, bytes32 salt) payable returns() +func (_TimelockControllerImpl *TimelockControllerImplTransactor) Execute(opts *bind.TransactOpts, target common.Address, value *big.Int, payload []byte, predecessor [32]byte, salt [32]byte) (*types.Transaction, error) { + return _TimelockControllerImpl.contract.Transact(opts, "execute", target, value, payload, predecessor, salt) +} + +// Execute is a paid mutator transaction binding the contract method 0x134008d3. +// +// Solidity: function execute(address target, uint256 value, bytes payload, bytes32 predecessor, bytes32 salt) payable returns() +func (_TimelockControllerImpl *TimelockControllerImplSession) Execute(target common.Address, value *big.Int, payload []byte, predecessor [32]byte, salt [32]byte) (*types.Transaction, error) { + return _TimelockControllerImpl.Contract.Execute(&_TimelockControllerImpl.TransactOpts, target, value, payload, predecessor, salt) +} + +// Execute is a paid mutator transaction binding the contract method 0x134008d3. +// +// Solidity: function execute(address target, uint256 value, bytes payload, bytes32 predecessor, bytes32 salt) payable returns() +func (_TimelockControllerImpl *TimelockControllerImplTransactorSession) Execute(target common.Address, value *big.Int, payload []byte, predecessor [32]byte, salt [32]byte) (*types.Transaction, error) { + return _TimelockControllerImpl.Contract.Execute(&_TimelockControllerImpl.TransactOpts, target, value, payload, predecessor, salt) +} + +// ExecuteBatch is a paid mutator transaction binding the contract method 0xe38335e5. +// +// Solidity: function executeBatch(address[] targets, uint256[] values, bytes[] payloads, bytes32 predecessor, bytes32 salt) payable returns() +func (_TimelockControllerImpl *TimelockControllerImplTransactor) ExecuteBatch(opts *bind.TransactOpts, targets []common.Address, values []*big.Int, payloads [][]byte, predecessor [32]byte, salt [32]byte) (*types.Transaction, error) { + return _TimelockControllerImpl.contract.Transact(opts, "executeBatch", targets, values, payloads, predecessor, salt) +} + +// ExecuteBatch is a paid mutator transaction binding the contract method 0xe38335e5. +// +// Solidity: function executeBatch(address[] targets, uint256[] values, bytes[] payloads, bytes32 predecessor, bytes32 salt) payable returns() +func (_TimelockControllerImpl *TimelockControllerImplSession) ExecuteBatch(targets []common.Address, values []*big.Int, payloads [][]byte, predecessor [32]byte, salt [32]byte) (*types.Transaction, error) { + return _TimelockControllerImpl.Contract.ExecuteBatch(&_TimelockControllerImpl.TransactOpts, targets, values, payloads, predecessor, salt) +} + +// ExecuteBatch is a paid mutator transaction binding the contract method 0xe38335e5. +// +// Solidity: function executeBatch(address[] targets, uint256[] values, bytes[] payloads, bytes32 predecessor, bytes32 salt) payable returns() +func (_TimelockControllerImpl *TimelockControllerImplTransactorSession) ExecuteBatch(targets []common.Address, values []*big.Int, payloads [][]byte, predecessor [32]byte, salt [32]byte) (*types.Transaction, error) { + return _TimelockControllerImpl.Contract.ExecuteBatch(&_TimelockControllerImpl.TransactOpts, targets, values, payloads, predecessor, salt) +} + +// GrantRole is a paid mutator transaction binding the contract method 0x2f2ff15d. +// +// Solidity: function grantRole(bytes32 role, address account) returns() +func (_TimelockControllerImpl *TimelockControllerImplTransactor) GrantRole(opts *bind.TransactOpts, role [32]byte, account common.Address) (*types.Transaction, error) { + return _TimelockControllerImpl.contract.Transact(opts, "grantRole", role, account) +} + +// GrantRole is a paid mutator transaction binding the contract method 0x2f2ff15d. +// +// Solidity: function grantRole(bytes32 role, address account) returns() +func (_TimelockControllerImpl *TimelockControllerImplSession) GrantRole(role [32]byte, account common.Address) (*types.Transaction, error) { + return _TimelockControllerImpl.Contract.GrantRole(&_TimelockControllerImpl.TransactOpts, role, account) +} + +// GrantRole is a paid mutator transaction binding the contract method 0x2f2ff15d. +// +// Solidity: function grantRole(bytes32 role, address account) returns() +func (_TimelockControllerImpl *TimelockControllerImplTransactorSession) GrantRole(role [32]byte, account common.Address) (*types.Transaction, error) { + return _TimelockControllerImpl.Contract.GrantRole(&_TimelockControllerImpl.TransactOpts, role, account) +} + +// Initialize is a paid mutator transaction binding the contract method 0xc4c4c7b3. +// +// Solidity: function initialize(uint256 minDelay, address[] proposers, address[] executors, address admin) returns() +func (_TimelockControllerImpl *TimelockControllerImplTransactor) Initialize(opts *bind.TransactOpts, minDelay *big.Int, proposers []common.Address, executors []common.Address, admin common.Address) (*types.Transaction, error) { + return _TimelockControllerImpl.contract.Transact(opts, "initialize", minDelay, proposers, executors, admin) +} + +// Initialize is a paid mutator transaction binding the contract method 0xc4c4c7b3. +// +// Solidity: function initialize(uint256 minDelay, address[] proposers, address[] executors, address admin) returns() +func (_TimelockControllerImpl *TimelockControllerImplSession) Initialize(minDelay *big.Int, proposers []common.Address, executors []common.Address, admin common.Address) (*types.Transaction, error) { + return _TimelockControllerImpl.Contract.Initialize(&_TimelockControllerImpl.TransactOpts, minDelay, proposers, executors, admin) +} + +// Initialize is a paid mutator transaction binding the contract method 0xc4c4c7b3. +// +// Solidity: function initialize(uint256 minDelay, address[] proposers, address[] executors, address admin) returns() +func (_TimelockControllerImpl *TimelockControllerImplTransactorSession) Initialize(minDelay *big.Int, proposers []common.Address, executors []common.Address, admin common.Address) (*types.Transaction, error) { + return _TimelockControllerImpl.Contract.Initialize(&_TimelockControllerImpl.TransactOpts, minDelay, proposers, executors, admin) +} + +// OnERC1155BatchReceived is a paid mutator transaction binding the contract method 0xbc197c81. +// +// Solidity: function onERC1155BatchReceived(address , address , uint256[] , uint256[] , bytes ) returns(bytes4) +func (_TimelockControllerImpl *TimelockControllerImplTransactor) OnERC1155BatchReceived(opts *bind.TransactOpts, arg0 common.Address, arg1 common.Address, arg2 []*big.Int, arg3 []*big.Int, arg4 []byte) (*types.Transaction, error) { + return _TimelockControllerImpl.contract.Transact(opts, "onERC1155BatchReceived", arg0, arg1, arg2, arg3, arg4) +} + +// OnERC1155BatchReceived is a paid mutator transaction binding the contract method 0xbc197c81. +// +// Solidity: function onERC1155BatchReceived(address , address , uint256[] , uint256[] , bytes ) returns(bytes4) +func (_TimelockControllerImpl *TimelockControllerImplSession) OnERC1155BatchReceived(arg0 common.Address, arg1 common.Address, arg2 []*big.Int, arg3 []*big.Int, arg4 []byte) (*types.Transaction, error) { + return _TimelockControllerImpl.Contract.OnERC1155BatchReceived(&_TimelockControllerImpl.TransactOpts, arg0, arg1, arg2, arg3, arg4) +} + +// OnERC1155BatchReceived is a paid mutator transaction binding the contract method 0xbc197c81. +// +// Solidity: function onERC1155BatchReceived(address , address , uint256[] , uint256[] , bytes ) returns(bytes4) +func (_TimelockControllerImpl *TimelockControllerImplTransactorSession) OnERC1155BatchReceived(arg0 common.Address, arg1 common.Address, arg2 []*big.Int, arg3 []*big.Int, arg4 []byte) (*types.Transaction, error) { + return _TimelockControllerImpl.Contract.OnERC1155BatchReceived(&_TimelockControllerImpl.TransactOpts, arg0, arg1, arg2, arg3, arg4) +} + +// OnERC1155Received is a paid mutator transaction binding the contract method 0xf23a6e61. +// +// Solidity: function onERC1155Received(address , address , uint256 , uint256 , bytes ) returns(bytes4) +func (_TimelockControllerImpl *TimelockControllerImplTransactor) OnERC1155Received(opts *bind.TransactOpts, arg0 common.Address, arg1 common.Address, arg2 *big.Int, arg3 *big.Int, arg4 []byte) (*types.Transaction, error) { + return _TimelockControllerImpl.contract.Transact(opts, "onERC1155Received", arg0, arg1, arg2, arg3, arg4) +} + +// OnERC1155Received is a paid mutator transaction binding the contract method 0xf23a6e61. +// +// Solidity: function onERC1155Received(address , address , uint256 , uint256 , bytes ) returns(bytes4) +func (_TimelockControllerImpl *TimelockControllerImplSession) OnERC1155Received(arg0 common.Address, arg1 common.Address, arg2 *big.Int, arg3 *big.Int, arg4 []byte) (*types.Transaction, error) { + return _TimelockControllerImpl.Contract.OnERC1155Received(&_TimelockControllerImpl.TransactOpts, arg0, arg1, arg2, arg3, arg4) +} + +// OnERC1155Received is a paid mutator transaction binding the contract method 0xf23a6e61. +// +// Solidity: function onERC1155Received(address , address , uint256 , uint256 , bytes ) returns(bytes4) +func (_TimelockControllerImpl *TimelockControllerImplTransactorSession) OnERC1155Received(arg0 common.Address, arg1 common.Address, arg2 *big.Int, arg3 *big.Int, arg4 []byte) (*types.Transaction, error) { + return _TimelockControllerImpl.Contract.OnERC1155Received(&_TimelockControllerImpl.TransactOpts, arg0, arg1, arg2, arg3, arg4) +} + +// OnERC721Received is a paid mutator transaction binding the contract method 0x150b7a02. +// +// Solidity: function onERC721Received(address , address , uint256 , bytes ) returns(bytes4) +func (_TimelockControllerImpl *TimelockControllerImplTransactor) OnERC721Received(opts *bind.TransactOpts, arg0 common.Address, arg1 common.Address, arg2 *big.Int, arg3 []byte) (*types.Transaction, error) { + return _TimelockControllerImpl.contract.Transact(opts, "onERC721Received", arg0, arg1, arg2, arg3) +} + +// OnERC721Received is a paid mutator transaction binding the contract method 0x150b7a02. +// +// Solidity: function onERC721Received(address , address , uint256 , bytes ) returns(bytes4) +func (_TimelockControllerImpl *TimelockControllerImplSession) OnERC721Received(arg0 common.Address, arg1 common.Address, arg2 *big.Int, arg3 []byte) (*types.Transaction, error) { + return _TimelockControllerImpl.Contract.OnERC721Received(&_TimelockControllerImpl.TransactOpts, arg0, arg1, arg2, arg3) +} + +// OnERC721Received is a paid mutator transaction binding the contract method 0x150b7a02. +// +// Solidity: function onERC721Received(address , address , uint256 , bytes ) returns(bytes4) +func (_TimelockControllerImpl *TimelockControllerImplTransactorSession) OnERC721Received(arg0 common.Address, arg1 common.Address, arg2 *big.Int, arg3 []byte) (*types.Transaction, error) { + return _TimelockControllerImpl.Contract.OnERC721Received(&_TimelockControllerImpl.TransactOpts, arg0, arg1, arg2, arg3) +} + +// RenounceRole is a paid mutator transaction binding the contract method 0x36568abe. +// +// Solidity: function renounceRole(bytes32 role, address account) returns() +func (_TimelockControllerImpl *TimelockControllerImplTransactor) RenounceRole(opts *bind.TransactOpts, role [32]byte, account common.Address) (*types.Transaction, error) { + return _TimelockControllerImpl.contract.Transact(opts, "renounceRole", role, account) +} + +// RenounceRole is a paid mutator transaction binding the contract method 0x36568abe. +// +// Solidity: function renounceRole(bytes32 role, address account) returns() +func (_TimelockControllerImpl *TimelockControllerImplSession) RenounceRole(role [32]byte, account common.Address) (*types.Transaction, error) { + return _TimelockControllerImpl.Contract.RenounceRole(&_TimelockControllerImpl.TransactOpts, role, account) +} + +// RenounceRole is a paid mutator transaction binding the contract method 0x36568abe. +// +// Solidity: function renounceRole(bytes32 role, address account) returns() +func (_TimelockControllerImpl *TimelockControllerImplTransactorSession) RenounceRole(role [32]byte, account common.Address) (*types.Transaction, error) { + return _TimelockControllerImpl.Contract.RenounceRole(&_TimelockControllerImpl.TransactOpts, role, account) +} + +// RevokeRole is a paid mutator transaction binding the contract method 0xd547741f. +// +// Solidity: function revokeRole(bytes32 role, address account) returns() +func (_TimelockControllerImpl *TimelockControllerImplTransactor) RevokeRole(opts *bind.TransactOpts, role [32]byte, account common.Address) (*types.Transaction, error) { + return _TimelockControllerImpl.contract.Transact(opts, "revokeRole", role, account) +} + +// RevokeRole is a paid mutator transaction binding the contract method 0xd547741f. +// +// Solidity: function revokeRole(bytes32 role, address account) returns() +func (_TimelockControllerImpl *TimelockControllerImplSession) RevokeRole(role [32]byte, account common.Address) (*types.Transaction, error) { + return _TimelockControllerImpl.Contract.RevokeRole(&_TimelockControllerImpl.TransactOpts, role, account) +} + +// RevokeRole is a paid mutator transaction binding the contract method 0xd547741f. +// +// Solidity: function revokeRole(bytes32 role, address account) returns() +func (_TimelockControllerImpl *TimelockControllerImplTransactorSession) RevokeRole(role [32]byte, account common.Address) (*types.Transaction, error) { + return _TimelockControllerImpl.Contract.RevokeRole(&_TimelockControllerImpl.TransactOpts, role, account) +} + +// Schedule is a paid mutator transaction binding the contract method 0x01d5062a. +// +// Solidity: function schedule(address target, uint256 value, bytes data, bytes32 predecessor, bytes32 salt, uint256 delay) returns() +func (_TimelockControllerImpl *TimelockControllerImplTransactor) Schedule(opts *bind.TransactOpts, target common.Address, value *big.Int, data []byte, predecessor [32]byte, salt [32]byte, delay *big.Int) (*types.Transaction, error) { + return _TimelockControllerImpl.contract.Transact(opts, "schedule", target, value, data, predecessor, salt, delay) +} + +// Schedule is a paid mutator transaction binding the contract method 0x01d5062a. +// +// Solidity: function schedule(address target, uint256 value, bytes data, bytes32 predecessor, bytes32 salt, uint256 delay) returns() +func (_TimelockControllerImpl *TimelockControllerImplSession) Schedule(target common.Address, value *big.Int, data []byte, predecessor [32]byte, salt [32]byte, delay *big.Int) (*types.Transaction, error) { + return _TimelockControllerImpl.Contract.Schedule(&_TimelockControllerImpl.TransactOpts, target, value, data, predecessor, salt, delay) +} + +// Schedule is a paid mutator transaction binding the contract method 0x01d5062a. +// +// Solidity: function schedule(address target, uint256 value, bytes data, bytes32 predecessor, bytes32 salt, uint256 delay) returns() +func (_TimelockControllerImpl *TimelockControllerImplTransactorSession) Schedule(target common.Address, value *big.Int, data []byte, predecessor [32]byte, salt [32]byte, delay *big.Int) (*types.Transaction, error) { + return _TimelockControllerImpl.Contract.Schedule(&_TimelockControllerImpl.TransactOpts, target, value, data, predecessor, salt, delay) +} + +// ScheduleBatch is a paid mutator transaction binding the contract method 0x8f2a0bb0. +// +// Solidity: function scheduleBatch(address[] targets, uint256[] values, bytes[] payloads, bytes32 predecessor, bytes32 salt, uint256 delay) returns() +func (_TimelockControllerImpl *TimelockControllerImplTransactor) ScheduleBatch(opts *bind.TransactOpts, targets []common.Address, values []*big.Int, payloads [][]byte, predecessor [32]byte, salt [32]byte, delay *big.Int) (*types.Transaction, error) { + return _TimelockControllerImpl.contract.Transact(opts, "scheduleBatch", targets, values, payloads, predecessor, salt, delay) +} + +// ScheduleBatch is a paid mutator transaction binding the contract method 0x8f2a0bb0. +// +// Solidity: function scheduleBatch(address[] targets, uint256[] values, bytes[] payloads, bytes32 predecessor, bytes32 salt, uint256 delay) returns() +func (_TimelockControllerImpl *TimelockControllerImplSession) ScheduleBatch(targets []common.Address, values []*big.Int, payloads [][]byte, predecessor [32]byte, salt [32]byte, delay *big.Int) (*types.Transaction, error) { + return _TimelockControllerImpl.Contract.ScheduleBatch(&_TimelockControllerImpl.TransactOpts, targets, values, payloads, predecessor, salt, delay) +} + +// ScheduleBatch is a paid mutator transaction binding the contract method 0x8f2a0bb0. +// +// Solidity: function scheduleBatch(address[] targets, uint256[] values, bytes[] payloads, bytes32 predecessor, bytes32 salt, uint256 delay) returns() +func (_TimelockControllerImpl *TimelockControllerImplTransactorSession) ScheduleBatch(targets []common.Address, values []*big.Int, payloads [][]byte, predecessor [32]byte, salt [32]byte, delay *big.Int) (*types.Transaction, error) { + return _TimelockControllerImpl.Contract.ScheduleBatch(&_TimelockControllerImpl.TransactOpts, targets, values, payloads, predecessor, salt, delay) +} + +// UpdateDelay is a paid mutator transaction binding the contract method 0x64d62353. +// +// Solidity: function updateDelay(uint256 newDelay) returns() +func (_TimelockControllerImpl *TimelockControllerImplTransactor) UpdateDelay(opts *bind.TransactOpts, newDelay *big.Int) (*types.Transaction, error) { + return _TimelockControllerImpl.contract.Transact(opts, "updateDelay", newDelay) +} + +// UpdateDelay is a paid mutator transaction binding the contract method 0x64d62353. +// +// Solidity: function updateDelay(uint256 newDelay) returns() +func (_TimelockControllerImpl *TimelockControllerImplSession) UpdateDelay(newDelay *big.Int) (*types.Transaction, error) { + return _TimelockControllerImpl.Contract.UpdateDelay(&_TimelockControllerImpl.TransactOpts, newDelay) +} + +// UpdateDelay is a paid mutator transaction binding the contract method 0x64d62353. +// +// Solidity: function updateDelay(uint256 newDelay) returns() +func (_TimelockControllerImpl *TimelockControllerImplTransactorSession) UpdateDelay(newDelay *big.Int) (*types.Transaction, error) { + return _TimelockControllerImpl.Contract.UpdateDelay(&_TimelockControllerImpl.TransactOpts, newDelay) +} + +// Receive is a paid mutator transaction binding the contract receive function. +// +// Solidity: receive() payable returns() +func (_TimelockControllerImpl *TimelockControllerImplTransactor) Receive(opts *bind.TransactOpts) (*types.Transaction, error) { + return _TimelockControllerImpl.contract.RawTransact(opts, nil) // calldata is disallowed for receive function +} + +// Receive is a paid mutator transaction binding the contract receive function. +// +// Solidity: receive() payable returns() +func (_TimelockControllerImpl *TimelockControllerImplSession) Receive() (*types.Transaction, error) { + return _TimelockControllerImpl.Contract.Receive(&_TimelockControllerImpl.TransactOpts) +} + +// Receive is a paid mutator transaction binding the contract receive function. +// +// Solidity: receive() payable returns() +func (_TimelockControllerImpl *TimelockControllerImplTransactorSession) Receive() (*types.Transaction, error) { + return _TimelockControllerImpl.Contract.Receive(&_TimelockControllerImpl.TransactOpts) +} + +// TimelockControllerImplCallExecutedIterator is returned from FilterCallExecuted and is used to iterate over the raw logs and unpacked data for CallExecuted events raised by the TimelockControllerImpl contract. +type TimelockControllerImplCallExecutedIterator struct { + Event *TimelockControllerImplCallExecuted // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *TimelockControllerImplCallExecutedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(TimelockControllerImplCallExecuted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(TimelockControllerImplCallExecuted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *TimelockControllerImplCallExecutedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TimelockControllerImplCallExecutedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TimelockControllerImplCallExecuted represents a CallExecuted event raised by the TimelockControllerImpl contract. +type TimelockControllerImplCallExecuted struct { + Id [32]byte + Index *big.Int + Target common.Address + Value *big.Int + Data []byte + Raw types.Log // Blockchain specific contextual infos +} + +// FilterCallExecuted is a free log retrieval operation binding the contract event 0xc2617efa69bab66782fa219543714338489c4e9e178271560a91b82c3f612b58. +// +// Solidity: event CallExecuted(bytes32 indexed id, uint256 indexed index, address target, uint256 value, bytes data) +func (_TimelockControllerImpl *TimelockControllerImplFilterer) FilterCallExecuted(opts *bind.FilterOpts, id [][32]byte, index []*big.Int) (*TimelockControllerImplCallExecutedIterator, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + var indexRule []interface{} + for _, indexItem := range index { + indexRule = append(indexRule, indexItem) + } + + logs, sub, err := _TimelockControllerImpl.contract.FilterLogs(opts, "CallExecuted", idRule, indexRule) + if err != nil { + return nil, err + } + return &TimelockControllerImplCallExecutedIterator{contract: _TimelockControllerImpl.contract, event: "CallExecuted", logs: logs, sub: sub}, nil +} + +// WatchCallExecuted is a free log subscription operation binding the contract event 0xc2617efa69bab66782fa219543714338489c4e9e178271560a91b82c3f612b58. +// +// Solidity: event CallExecuted(bytes32 indexed id, uint256 indexed index, address target, uint256 value, bytes data) +func (_TimelockControllerImpl *TimelockControllerImplFilterer) WatchCallExecuted(opts *bind.WatchOpts, sink chan<- *TimelockControllerImplCallExecuted, id [][32]byte, index []*big.Int) (event.Subscription, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + var indexRule []interface{} + for _, indexItem := range index { + indexRule = append(indexRule, indexItem) + } + + logs, sub, err := _TimelockControllerImpl.contract.WatchLogs(opts, "CallExecuted", idRule, indexRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(TimelockControllerImplCallExecuted) + if err := _TimelockControllerImpl.contract.UnpackLog(event, "CallExecuted", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseCallExecuted is a log parse operation binding the contract event 0xc2617efa69bab66782fa219543714338489c4e9e178271560a91b82c3f612b58. +// +// Solidity: event CallExecuted(bytes32 indexed id, uint256 indexed index, address target, uint256 value, bytes data) +func (_TimelockControllerImpl *TimelockControllerImplFilterer) ParseCallExecuted(log types.Log) (*TimelockControllerImplCallExecuted, error) { + event := new(TimelockControllerImplCallExecuted) + if err := _TimelockControllerImpl.contract.UnpackLog(event, "CallExecuted", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// TimelockControllerImplCallSaltIterator is returned from FilterCallSalt and is used to iterate over the raw logs and unpacked data for CallSalt events raised by the TimelockControllerImpl contract. +type TimelockControllerImplCallSaltIterator struct { + Event *TimelockControllerImplCallSalt // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *TimelockControllerImplCallSaltIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(TimelockControllerImplCallSalt) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(TimelockControllerImplCallSalt) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *TimelockControllerImplCallSaltIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TimelockControllerImplCallSaltIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TimelockControllerImplCallSalt represents a CallSalt event raised by the TimelockControllerImpl contract. +type TimelockControllerImplCallSalt struct { + Id [32]byte + Salt [32]byte + Raw types.Log // Blockchain specific contextual infos +} + +// FilterCallSalt is a free log retrieval operation binding the contract event 0x20fda5fd27a1ea7bf5b9567f143ac5470bb059374a27e8f67cb44f946f6d0387. +// +// Solidity: event CallSalt(bytes32 indexed id, bytes32 salt) +func (_TimelockControllerImpl *TimelockControllerImplFilterer) FilterCallSalt(opts *bind.FilterOpts, id [][32]byte) (*TimelockControllerImplCallSaltIterator, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _TimelockControllerImpl.contract.FilterLogs(opts, "CallSalt", idRule) + if err != nil { + return nil, err + } + return &TimelockControllerImplCallSaltIterator{contract: _TimelockControllerImpl.contract, event: "CallSalt", logs: logs, sub: sub}, nil +} + +// WatchCallSalt is a free log subscription operation binding the contract event 0x20fda5fd27a1ea7bf5b9567f143ac5470bb059374a27e8f67cb44f946f6d0387. +// +// Solidity: event CallSalt(bytes32 indexed id, bytes32 salt) +func (_TimelockControllerImpl *TimelockControllerImplFilterer) WatchCallSalt(opts *bind.WatchOpts, sink chan<- *TimelockControllerImplCallSalt, id [][32]byte) (event.Subscription, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _TimelockControllerImpl.contract.WatchLogs(opts, "CallSalt", idRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(TimelockControllerImplCallSalt) + if err := _TimelockControllerImpl.contract.UnpackLog(event, "CallSalt", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseCallSalt is a log parse operation binding the contract event 0x20fda5fd27a1ea7bf5b9567f143ac5470bb059374a27e8f67cb44f946f6d0387. +// +// Solidity: event CallSalt(bytes32 indexed id, bytes32 salt) +func (_TimelockControllerImpl *TimelockControllerImplFilterer) ParseCallSalt(log types.Log) (*TimelockControllerImplCallSalt, error) { + event := new(TimelockControllerImplCallSalt) + if err := _TimelockControllerImpl.contract.UnpackLog(event, "CallSalt", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// TimelockControllerImplCallScheduledIterator is returned from FilterCallScheduled and is used to iterate over the raw logs and unpacked data for CallScheduled events raised by the TimelockControllerImpl contract. +type TimelockControllerImplCallScheduledIterator struct { + Event *TimelockControllerImplCallScheduled // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *TimelockControllerImplCallScheduledIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(TimelockControllerImplCallScheduled) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(TimelockControllerImplCallScheduled) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *TimelockControllerImplCallScheduledIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TimelockControllerImplCallScheduledIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TimelockControllerImplCallScheduled represents a CallScheduled event raised by the TimelockControllerImpl contract. +type TimelockControllerImplCallScheduled struct { + Id [32]byte + Index *big.Int + Target common.Address + Value *big.Int + Data []byte + Predecessor [32]byte + Delay *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterCallScheduled is a free log retrieval operation binding the contract event 0x4cf4410cc57040e44862ef0f45f3dd5a5e02db8eb8add648d4b0e236f1d07dca. +// +// Solidity: event CallScheduled(bytes32 indexed id, uint256 indexed index, address target, uint256 value, bytes data, bytes32 predecessor, uint256 delay) +func (_TimelockControllerImpl *TimelockControllerImplFilterer) FilterCallScheduled(opts *bind.FilterOpts, id [][32]byte, index []*big.Int) (*TimelockControllerImplCallScheduledIterator, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + var indexRule []interface{} + for _, indexItem := range index { + indexRule = append(indexRule, indexItem) + } + + logs, sub, err := _TimelockControllerImpl.contract.FilterLogs(opts, "CallScheduled", idRule, indexRule) + if err != nil { + return nil, err + } + return &TimelockControllerImplCallScheduledIterator{contract: _TimelockControllerImpl.contract, event: "CallScheduled", logs: logs, sub: sub}, nil +} + +// WatchCallScheduled is a free log subscription operation binding the contract event 0x4cf4410cc57040e44862ef0f45f3dd5a5e02db8eb8add648d4b0e236f1d07dca. +// +// Solidity: event CallScheduled(bytes32 indexed id, uint256 indexed index, address target, uint256 value, bytes data, bytes32 predecessor, uint256 delay) +func (_TimelockControllerImpl *TimelockControllerImplFilterer) WatchCallScheduled(opts *bind.WatchOpts, sink chan<- *TimelockControllerImplCallScheduled, id [][32]byte, index []*big.Int) (event.Subscription, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + var indexRule []interface{} + for _, indexItem := range index { + indexRule = append(indexRule, indexItem) + } + + logs, sub, err := _TimelockControllerImpl.contract.WatchLogs(opts, "CallScheduled", idRule, indexRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(TimelockControllerImplCallScheduled) + if err := _TimelockControllerImpl.contract.UnpackLog(event, "CallScheduled", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseCallScheduled is a log parse operation binding the contract event 0x4cf4410cc57040e44862ef0f45f3dd5a5e02db8eb8add648d4b0e236f1d07dca. +// +// Solidity: event CallScheduled(bytes32 indexed id, uint256 indexed index, address target, uint256 value, bytes data, bytes32 predecessor, uint256 delay) +func (_TimelockControllerImpl *TimelockControllerImplFilterer) ParseCallScheduled(log types.Log) (*TimelockControllerImplCallScheduled, error) { + event := new(TimelockControllerImplCallScheduled) + if err := _TimelockControllerImpl.contract.UnpackLog(event, "CallScheduled", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// TimelockControllerImplCancelledIterator is returned from FilterCancelled and is used to iterate over the raw logs and unpacked data for Cancelled events raised by the TimelockControllerImpl contract. +type TimelockControllerImplCancelledIterator struct { + Event *TimelockControllerImplCancelled // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *TimelockControllerImplCancelledIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(TimelockControllerImplCancelled) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(TimelockControllerImplCancelled) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *TimelockControllerImplCancelledIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TimelockControllerImplCancelledIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TimelockControllerImplCancelled represents a Cancelled event raised by the TimelockControllerImpl contract. +type TimelockControllerImplCancelled struct { + Id [32]byte + Raw types.Log // Blockchain specific contextual infos +} + +// FilterCancelled is a free log retrieval operation binding the contract event 0xbaa1eb22f2a492ba1a5fea61b8df4d27c6c8b5f3971e63bb58fa14ff72eedb70. +// +// Solidity: event Cancelled(bytes32 indexed id) +func (_TimelockControllerImpl *TimelockControllerImplFilterer) FilterCancelled(opts *bind.FilterOpts, id [][32]byte) (*TimelockControllerImplCancelledIterator, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _TimelockControllerImpl.contract.FilterLogs(opts, "Cancelled", idRule) + if err != nil { + return nil, err + } + return &TimelockControllerImplCancelledIterator{contract: _TimelockControllerImpl.contract, event: "Cancelled", logs: logs, sub: sub}, nil +} + +// WatchCancelled is a free log subscription operation binding the contract event 0xbaa1eb22f2a492ba1a5fea61b8df4d27c6c8b5f3971e63bb58fa14ff72eedb70. +// +// Solidity: event Cancelled(bytes32 indexed id) +func (_TimelockControllerImpl *TimelockControllerImplFilterer) WatchCancelled(opts *bind.WatchOpts, sink chan<- *TimelockControllerImplCancelled, id [][32]byte) (event.Subscription, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _TimelockControllerImpl.contract.WatchLogs(opts, "Cancelled", idRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(TimelockControllerImplCancelled) + if err := _TimelockControllerImpl.contract.UnpackLog(event, "Cancelled", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseCancelled is a log parse operation binding the contract event 0xbaa1eb22f2a492ba1a5fea61b8df4d27c6c8b5f3971e63bb58fa14ff72eedb70. +// +// Solidity: event Cancelled(bytes32 indexed id) +func (_TimelockControllerImpl *TimelockControllerImplFilterer) ParseCancelled(log types.Log) (*TimelockControllerImplCancelled, error) { + event := new(TimelockControllerImplCancelled) + if err := _TimelockControllerImpl.contract.UnpackLog(event, "Cancelled", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// TimelockControllerImplInitializedIterator is returned from FilterInitialized and is used to iterate over the raw logs and unpacked data for Initialized events raised by the TimelockControllerImpl contract. +type TimelockControllerImplInitializedIterator struct { + Event *TimelockControllerImplInitialized // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *TimelockControllerImplInitializedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(TimelockControllerImplInitialized) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(TimelockControllerImplInitialized) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *TimelockControllerImplInitializedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TimelockControllerImplInitializedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TimelockControllerImplInitialized represents a Initialized event raised by the TimelockControllerImpl contract. +type TimelockControllerImplInitialized struct { + Version uint8 + Raw types.Log // Blockchain specific contextual infos +} + +// FilterInitialized is a free log retrieval operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. +// +// Solidity: event Initialized(uint8 version) +func (_TimelockControllerImpl *TimelockControllerImplFilterer) FilterInitialized(opts *bind.FilterOpts) (*TimelockControllerImplInitializedIterator, error) { + + logs, sub, err := _TimelockControllerImpl.contract.FilterLogs(opts, "Initialized") + if err != nil { + return nil, err + } + return &TimelockControllerImplInitializedIterator{contract: _TimelockControllerImpl.contract, event: "Initialized", logs: logs, sub: sub}, nil +} + +// WatchInitialized is a free log subscription operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. +// +// Solidity: event Initialized(uint8 version) +func (_TimelockControllerImpl *TimelockControllerImplFilterer) WatchInitialized(opts *bind.WatchOpts, sink chan<- *TimelockControllerImplInitialized) (event.Subscription, error) { + + logs, sub, err := _TimelockControllerImpl.contract.WatchLogs(opts, "Initialized") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(TimelockControllerImplInitialized) + if err := _TimelockControllerImpl.contract.UnpackLog(event, "Initialized", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseInitialized is a log parse operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. +// +// Solidity: event Initialized(uint8 version) +func (_TimelockControllerImpl *TimelockControllerImplFilterer) ParseInitialized(log types.Log) (*TimelockControllerImplInitialized, error) { + event := new(TimelockControllerImplInitialized) + if err := _TimelockControllerImpl.contract.UnpackLog(event, "Initialized", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// TimelockControllerImplMinDelayChangeIterator is returned from FilterMinDelayChange and is used to iterate over the raw logs and unpacked data for MinDelayChange events raised by the TimelockControllerImpl contract. +type TimelockControllerImplMinDelayChangeIterator struct { + Event *TimelockControllerImplMinDelayChange // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *TimelockControllerImplMinDelayChangeIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(TimelockControllerImplMinDelayChange) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(TimelockControllerImplMinDelayChange) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *TimelockControllerImplMinDelayChangeIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TimelockControllerImplMinDelayChangeIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TimelockControllerImplMinDelayChange represents a MinDelayChange event raised by the TimelockControllerImpl contract. +type TimelockControllerImplMinDelayChange struct { + OldDuration *big.Int + NewDuration *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterMinDelayChange is a free log retrieval operation binding the contract event 0x11c24f4ead16507c69ac467fbd5e4eed5fb5c699626d2cc6d66421df253886d5. +// +// Solidity: event MinDelayChange(uint256 oldDuration, uint256 newDuration) +func (_TimelockControllerImpl *TimelockControllerImplFilterer) FilterMinDelayChange(opts *bind.FilterOpts) (*TimelockControllerImplMinDelayChangeIterator, error) { + + logs, sub, err := _TimelockControllerImpl.contract.FilterLogs(opts, "MinDelayChange") + if err != nil { + return nil, err + } + return &TimelockControllerImplMinDelayChangeIterator{contract: _TimelockControllerImpl.contract, event: "MinDelayChange", logs: logs, sub: sub}, nil +} + +// WatchMinDelayChange is a free log subscription operation binding the contract event 0x11c24f4ead16507c69ac467fbd5e4eed5fb5c699626d2cc6d66421df253886d5. +// +// Solidity: event MinDelayChange(uint256 oldDuration, uint256 newDuration) +func (_TimelockControllerImpl *TimelockControllerImplFilterer) WatchMinDelayChange(opts *bind.WatchOpts, sink chan<- *TimelockControllerImplMinDelayChange) (event.Subscription, error) { + + logs, sub, err := _TimelockControllerImpl.contract.WatchLogs(opts, "MinDelayChange") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(TimelockControllerImplMinDelayChange) + if err := _TimelockControllerImpl.contract.UnpackLog(event, "MinDelayChange", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseMinDelayChange is a log parse operation binding the contract event 0x11c24f4ead16507c69ac467fbd5e4eed5fb5c699626d2cc6d66421df253886d5. +// +// Solidity: event MinDelayChange(uint256 oldDuration, uint256 newDuration) +func (_TimelockControllerImpl *TimelockControllerImplFilterer) ParseMinDelayChange(log types.Log) (*TimelockControllerImplMinDelayChange, error) { + event := new(TimelockControllerImplMinDelayChange) + if err := _TimelockControllerImpl.contract.UnpackLog(event, "MinDelayChange", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// TimelockControllerImplRoleAdminChangedIterator is returned from FilterRoleAdminChanged and is used to iterate over the raw logs and unpacked data for RoleAdminChanged events raised by the TimelockControllerImpl contract. +type TimelockControllerImplRoleAdminChangedIterator struct { + Event *TimelockControllerImplRoleAdminChanged // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *TimelockControllerImplRoleAdminChangedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(TimelockControllerImplRoleAdminChanged) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(TimelockControllerImplRoleAdminChanged) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *TimelockControllerImplRoleAdminChangedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TimelockControllerImplRoleAdminChangedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TimelockControllerImplRoleAdminChanged represents a RoleAdminChanged event raised by the TimelockControllerImpl contract. +type TimelockControllerImplRoleAdminChanged struct { + Role [32]byte + PreviousAdminRole [32]byte + NewAdminRole [32]byte + Raw types.Log // Blockchain specific contextual infos +} + +// FilterRoleAdminChanged is a free log retrieval operation binding the contract event 0xbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff. +// +// Solidity: event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole) +func (_TimelockControllerImpl *TimelockControllerImplFilterer) FilterRoleAdminChanged(opts *bind.FilterOpts, role [][32]byte, previousAdminRole [][32]byte, newAdminRole [][32]byte) (*TimelockControllerImplRoleAdminChangedIterator, error) { + + var roleRule []interface{} + for _, roleItem := range role { + roleRule = append(roleRule, roleItem) + } + var previousAdminRoleRule []interface{} + for _, previousAdminRoleItem := range previousAdminRole { + previousAdminRoleRule = append(previousAdminRoleRule, previousAdminRoleItem) + } + var newAdminRoleRule []interface{} + for _, newAdminRoleItem := range newAdminRole { + newAdminRoleRule = append(newAdminRoleRule, newAdminRoleItem) + } + + logs, sub, err := _TimelockControllerImpl.contract.FilterLogs(opts, "RoleAdminChanged", roleRule, previousAdminRoleRule, newAdminRoleRule) + if err != nil { + return nil, err + } + return &TimelockControllerImplRoleAdminChangedIterator{contract: _TimelockControllerImpl.contract, event: "RoleAdminChanged", logs: logs, sub: sub}, nil +} + +// WatchRoleAdminChanged is a free log subscription operation binding the contract event 0xbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff. +// +// Solidity: event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole) +func (_TimelockControllerImpl *TimelockControllerImplFilterer) WatchRoleAdminChanged(opts *bind.WatchOpts, sink chan<- *TimelockControllerImplRoleAdminChanged, role [][32]byte, previousAdminRole [][32]byte, newAdminRole [][32]byte) (event.Subscription, error) { + + var roleRule []interface{} + for _, roleItem := range role { + roleRule = append(roleRule, roleItem) + } + var previousAdminRoleRule []interface{} + for _, previousAdminRoleItem := range previousAdminRole { + previousAdminRoleRule = append(previousAdminRoleRule, previousAdminRoleItem) + } + var newAdminRoleRule []interface{} + for _, newAdminRoleItem := range newAdminRole { + newAdminRoleRule = append(newAdminRoleRule, newAdminRoleItem) + } + + logs, sub, err := _TimelockControllerImpl.contract.WatchLogs(opts, "RoleAdminChanged", roleRule, previousAdminRoleRule, newAdminRoleRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(TimelockControllerImplRoleAdminChanged) + if err := _TimelockControllerImpl.contract.UnpackLog(event, "RoleAdminChanged", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseRoleAdminChanged is a log parse operation binding the contract event 0xbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff. +// +// Solidity: event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole) +func (_TimelockControllerImpl *TimelockControllerImplFilterer) ParseRoleAdminChanged(log types.Log) (*TimelockControllerImplRoleAdminChanged, error) { + event := new(TimelockControllerImplRoleAdminChanged) + if err := _TimelockControllerImpl.contract.UnpackLog(event, "RoleAdminChanged", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// TimelockControllerImplRoleGrantedIterator is returned from FilterRoleGranted and is used to iterate over the raw logs and unpacked data for RoleGranted events raised by the TimelockControllerImpl contract. +type TimelockControllerImplRoleGrantedIterator struct { + Event *TimelockControllerImplRoleGranted // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *TimelockControllerImplRoleGrantedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(TimelockControllerImplRoleGranted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(TimelockControllerImplRoleGranted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *TimelockControllerImplRoleGrantedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TimelockControllerImplRoleGrantedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TimelockControllerImplRoleGranted represents a RoleGranted event raised by the TimelockControllerImpl contract. +type TimelockControllerImplRoleGranted struct { + Role [32]byte + Account common.Address + Sender common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterRoleGranted is a free log retrieval operation binding the contract event 0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d. +// +// Solidity: event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender) +func (_TimelockControllerImpl *TimelockControllerImplFilterer) FilterRoleGranted(opts *bind.FilterOpts, role [][32]byte, account []common.Address, sender []common.Address) (*TimelockControllerImplRoleGrantedIterator, error) { + + var roleRule []interface{} + for _, roleItem := range role { + roleRule = append(roleRule, roleItem) + } + var accountRule []interface{} + for _, accountItem := range account { + accountRule = append(accountRule, accountItem) + } + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _TimelockControllerImpl.contract.FilterLogs(opts, "RoleGranted", roleRule, accountRule, senderRule) + if err != nil { + return nil, err + } + return &TimelockControllerImplRoleGrantedIterator{contract: _TimelockControllerImpl.contract, event: "RoleGranted", logs: logs, sub: sub}, nil +} + +// WatchRoleGranted is a free log subscription operation binding the contract event 0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d. +// +// Solidity: event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender) +func (_TimelockControllerImpl *TimelockControllerImplFilterer) WatchRoleGranted(opts *bind.WatchOpts, sink chan<- *TimelockControllerImplRoleGranted, role [][32]byte, account []common.Address, sender []common.Address) (event.Subscription, error) { + + var roleRule []interface{} + for _, roleItem := range role { + roleRule = append(roleRule, roleItem) + } + var accountRule []interface{} + for _, accountItem := range account { + accountRule = append(accountRule, accountItem) + } + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _TimelockControllerImpl.contract.WatchLogs(opts, "RoleGranted", roleRule, accountRule, senderRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(TimelockControllerImplRoleGranted) + if err := _TimelockControllerImpl.contract.UnpackLog(event, "RoleGranted", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseRoleGranted is a log parse operation binding the contract event 0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d. +// +// Solidity: event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender) +func (_TimelockControllerImpl *TimelockControllerImplFilterer) ParseRoleGranted(log types.Log) (*TimelockControllerImplRoleGranted, error) { + event := new(TimelockControllerImplRoleGranted) + if err := _TimelockControllerImpl.contract.UnpackLog(event, "RoleGranted", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// TimelockControllerImplRoleRevokedIterator is returned from FilterRoleRevoked and is used to iterate over the raw logs and unpacked data for RoleRevoked events raised by the TimelockControllerImpl contract. +type TimelockControllerImplRoleRevokedIterator struct { + Event *TimelockControllerImplRoleRevoked // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *TimelockControllerImplRoleRevokedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(TimelockControllerImplRoleRevoked) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(TimelockControllerImplRoleRevoked) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *TimelockControllerImplRoleRevokedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TimelockControllerImplRoleRevokedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TimelockControllerImplRoleRevoked represents a RoleRevoked event raised by the TimelockControllerImpl contract. +type TimelockControllerImplRoleRevoked struct { + Role [32]byte + Account common.Address + Sender common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterRoleRevoked is a free log retrieval operation binding the contract event 0xf6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b. +// +// Solidity: event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender) +func (_TimelockControllerImpl *TimelockControllerImplFilterer) FilterRoleRevoked(opts *bind.FilterOpts, role [][32]byte, account []common.Address, sender []common.Address) (*TimelockControllerImplRoleRevokedIterator, error) { + + var roleRule []interface{} + for _, roleItem := range role { + roleRule = append(roleRule, roleItem) + } + var accountRule []interface{} + for _, accountItem := range account { + accountRule = append(accountRule, accountItem) + } + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _TimelockControllerImpl.contract.FilterLogs(opts, "RoleRevoked", roleRule, accountRule, senderRule) + if err != nil { + return nil, err + } + return &TimelockControllerImplRoleRevokedIterator{contract: _TimelockControllerImpl.contract, event: "RoleRevoked", logs: logs, sub: sub}, nil +} + +// WatchRoleRevoked is a free log subscription operation binding the contract event 0xf6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b. +// +// Solidity: event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender) +func (_TimelockControllerImpl *TimelockControllerImplFilterer) WatchRoleRevoked(opts *bind.WatchOpts, sink chan<- *TimelockControllerImplRoleRevoked, role [][32]byte, account []common.Address, sender []common.Address) (event.Subscription, error) { + + var roleRule []interface{} + for _, roleItem := range role { + roleRule = append(roleRule, roleItem) + } + var accountRule []interface{} + for _, accountItem := range account { + accountRule = append(accountRule, accountItem) + } + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _TimelockControllerImpl.contract.WatchLogs(opts, "RoleRevoked", roleRule, accountRule, senderRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(TimelockControllerImplRoleRevoked) + if err := _TimelockControllerImpl.contract.UnpackLog(event, "RoleRevoked", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseRoleRevoked is a log parse operation binding the contract event 0xf6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b. +// +// Solidity: event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender) +func (_TimelockControllerImpl *TimelockControllerImplFilterer) ParseRoleRevoked(log types.Log) (*TimelockControllerImplRoleRevoked, error) { + event := new(TimelockControllerImplRoleRevoked) + if err := _TimelockControllerImpl.contract.UnpackLog(event, "RoleRevoked", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} diff --git a/pkg/bindings/v2/AppController/binding.go b/pkg/bindings/v2/AppController/binding.go index dd43008..842174a 100644 --- a/pkg/bindings/v2/AppController/binding.go +++ b/pkg/bindings/v2/AppController/binding.go @@ -26,10 +26,24 @@ var ( // IAppControllerAppConfig is an auto generated low-level Go binding around an user-defined struct. type IAppControllerAppConfig struct { - Creator common.Address + Owner common.Address OperatorSetId uint32 LatestReleaseBlockNumber uint32 Status uint8 + Timelocked bool +} + +// IAppControllerAppRoles is an auto generated low-level Go binding around an user-defined struct. +type IAppControllerAppRoles struct { + App common.Address + IsOwner bool + Roles []uint8 +} + +// IAppControllerPendingUpgrade is an auto generated low-level Go binding around an user-defined struct. +type IAppControllerPendingUpgrade struct { + ReleaseHash [32]byte + ReadyAt *big.Int } // IAppControllerRelease is an auto generated low-level Go binding around an user-defined struct. @@ -53,7 +67,7 @@ type IReleaseManagerTypesRelease struct { // AppControllerMetaData contains all meta data concerning the AppController contract. var AppControllerMetaData = bind.MetaData{ - ABI: "[{\"type\":\"constructor\",\"inputs\":[{\"name\":\"_version\",\"type\":\"string\",\"internalType\":\"string\"},{\"name\":\"_permissionController\",\"type\":\"address\",\"internalType\":\"contractIPermissionController\"},{\"name\":\"_releaseManager\",\"type\":\"address\",\"internalType\":\"contractIReleaseManager\"},{\"name\":\"_computeAVSRegistrar\",\"type\":\"address\",\"internalType\":\"contractIComputeAVSRegistrar\"},{\"name\":\"_computeOperator\",\"type\":\"address\",\"internalType\":\"contractIComputeOperator\"},{\"name\":\"_appBeacon\",\"type\":\"address\",\"internalType\":\"contractIBeacon\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"API_PERMISSION_TYPEHASH\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"appBeacon\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIBeacon\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"calculateApiPermissionDigestHash\",\"inputs\":[{\"name\":\"permission\",\"type\":\"bytes4\",\"internalType\":\"bytes4\"},{\"name\":\"expiry\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"calculateAppId\",\"inputs\":[{\"name\":\"deployer\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"salt\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"computeAVSRegistrar\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIComputeAVSRegistrar\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"computeOperator\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIComputeOperator\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"createApp\",\"inputs\":[{\"name\":\"salt\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"release\",\"type\":\"tuple\",\"internalType\":\"structIAppController.Release\",\"components\":[{\"name\":\"rmsRelease\",\"type\":\"tuple\",\"internalType\":\"structIReleaseManagerTypes.Release\",\"components\":[{\"name\":\"artifacts\",\"type\":\"tuple[]\",\"internalType\":\"structIReleaseManagerTypes.Artifact[]\",\"components\":[{\"name\":\"digest\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"registry\",\"type\":\"string\",\"internalType\":\"string\"}]},{\"name\":\"upgradeByTime\",\"type\":\"uint32\",\"internalType\":\"uint32\"}]},{\"name\":\"publicEnv\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"encryptedEnv\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]}],\"outputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"createAppWithIsolatedBilling\",\"inputs\":[{\"name\":\"salt\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"release\",\"type\":\"tuple\",\"internalType\":\"structIAppController.Release\",\"components\":[{\"name\":\"rmsRelease\",\"type\":\"tuple\",\"internalType\":\"structIReleaseManagerTypes.Release\",\"components\":[{\"name\":\"artifacts\",\"type\":\"tuple[]\",\"internalType\":\"structIReleaseManagerTypes.Artifact[]\",\"components\":[{\"name\":\"digest\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"registry\",\"type\":\"string\",\"internalType\":\"string\"}]},{\"name\":\"upgradeByTime\",\"type\":\"uint32\",\"internalType\":\"uint32\"}]},{\"name\":\"publicEnv\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"encryptedEnv\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]}],\"outputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"domainSeparator\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getActiveAppCount\",\"inputs\":[{\"name\":\"user\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getAppCreator\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getAppLatestReleaseBlockNumber\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getAppOperatorSetId\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getAppStatus\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint8\",\"internalType\":\"enumIAppController.AppStatus\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getApps\",\"inputs\":[{\"name\":\"offset\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"limit\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"apps\",\"type\":\"address[]\",\"internalType\":\"contractIApp[]\"},{\"name\":\"appConfigsMem\",\"type\":\"tuple[]\",\"internalType\":\"structIAppController.AppConfig[]\",\"components\":[{\"name\":\"creator\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"operatorSetId\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"latestReleaseBlockNumber\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"status\",\"type\":\"uint8\",\"internalType\":\"enumIAppController.AppStatus\"}]}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getAppsByBillingAccount\",\"inputs\":[{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"offset\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"limit\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"apps\",\"type\":\"address[]\",\"internalType\":\"contractIApp[]\"},{\"name\":\"appConfigsMem\",\"type\":\"tuple[]\",\"internalType\":\"structIAppController.AppConfig[]\",\"components\":[{\"name\":\"creator\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"operatorSetId\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"latestReleaseBlockNumber\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"status\",\"type\":\"uint8\",\"internalType\":\"enumIAppController.AppStatus\"}]}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getAppsByCreator\",\"inputs\":[{\"name\":\"creator\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"offset\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"limit\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"apps\",\"type\":\"address[]\",\"internalType\":\"contractIApp[]\"},{\"name\":\"appConfigsMem\",\"type\":\"tuple[]\",\"internalType\":\"structIAppController.AppConfig[]\",\"components\":[{\"name\":\"creator\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"operatorSetId\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"latestReleaseBlockNumber\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"status\",\"type\":\"uint8\",\"internalType\":\"enumIAppController.AppStatus\"}]}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getAppsByDeveloper\",\"inputs\":[{\"name\":\"developer\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"offset\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"limit\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"apps\",\"type\":\"address[]\",\"internalType\":\"contractIApp[]\"},{\"name\":\"appConfigsMem\",\"type\":\"tuple[]\",\"internalType\":\"structIAppController.AppConfig[]\",\"components\":[{\"name\":\"creator\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"operatorSetId\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"latestReleaseBlockNumber\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"status\",\"type\":\"uint8\",\"internalType\":\"enumIAppController.AppStatus\"}]}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getBillingAccount\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getBillingType\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint8\",\"internalType\":\"enumIAppController.BillingType\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getMaxActiveAppsPerUser\",\"inputs\":[{\"name\":\"user\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"globalActiveAppCount\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"initialize\",\"inputs\":[{\"name\":\"admin\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"maxGlobalActiveApps\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"permissionController\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIPermissionController\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"releaseManager\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIReleaseManager\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"setMaxActiveAppsPerUser\",\"inputs\":[{\"name\":\"user\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"limit\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"setMaxGlobalActiveApps\",\"inputs\":[{\"name\":\"limit\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"startApp\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"stopApp\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"suspend\",\"inputs\":[{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"apps\",\"type\":\"address[]\",\"internalType\":\"contractIApp[]\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"terminateApp\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"terminateAppByAdmin\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"updateAppMetadataURI\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"},{\"name\":\"metadataURI\",\"type\":\"string\",\"internalType\":\"string\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"upgradeApp\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"},{\"name\":\"release\",\"type\":\"tuple\",\"internalType\":\"structIAppController.Release\",\"components\":[{\"name\":\"rmsRelease\",\"type\":\"tuple\",\"internalType\":\"structIReleaseManagerTypes.Release\",\"components\":[{\"name\":\"artifacts\",\"type\":\"tuple[]\",\"internalType\":\"structIReleaseManagerTypes.Artifact[]\",\"components\":[{\"name\":\"digest\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"registry\",\"type\":\"string\",\"internalType\":\"string\"}]},{\"name\":\"upgradeByTime\",\"type\":\"uint32\",\"internalType\":\"uint32\"}]},{\"name\":\"publicEnv\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"encryptedEnv\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"version\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"string\",\"internalType\":\"string\"}],\"stateMutability\":\"view\"},{\"type\":\"event\",\"name\":\"AppCreated\",\"inputs\":[{\"name\":\"creator\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"app\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"contractIApp\"},{\"name\":\"operatorSetId\",\"type\":\"uint32\",\"indexed\":false,\"internalType\":\"uint32\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"AppMetadataURIUpdated\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"contractIApp\"},{\"name\":\"metadataURI\",\"type\":\"string\",\"indexed\":false,\"internalType\":\"string\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"AppStarted\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"contractIApp\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"AppStopped\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"contractIApp\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"AppSuspended\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"contractIApp\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"AppTerminated\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"contractIApp\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"AppTerminatedByAdmin\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"contractIApp\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"AppUpgraded\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"contractIApp\"},{\"name\":\"rmsReleaseId\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"release\",\"type\":\"tuple\",\"indexed\":false,\"internalType\":\"structIAppController.Release\",\"components\":[{\"name\":\"rmsRelease\",\"type\":\"tuple\",\"internalType\":\"structIReleaseManagerTypes.Release\",\"components\":[{\"name\":\"artifacts\",\"type\":\"tuple[]\",\"internalType\":\"structIReleaseManagerTypes.Artifact[]\",\"components\":[{\"name\":\"digest\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"registry\",\"type\":\"string\",\"internalType\":\"string\"}]},{\"name\":\"upgradeByTime\",\"type\":\"uint32\",\"internalType\":\"uint32\"}]},{\"name\":\"publicEnv\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"encryptedEnv\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"GlobalMaxActiveAppsSet\",\"inputs\":[{\"name\":\"limit\",\"type\":\"uint32\",\"indexed\":false,\"internalType\":\"uint32\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Initialized\",\"inputs\":[{\"name\":\"version\",\"type\":\"uint8\",\"indexed\":false,\"internalType\":\"uint8\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"MaxActiveAppsSet\",\"inputs\":[{\"name\":\"user\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"limit\",\"type\":\"uint32\",\"indexed\":false,\"internalType\":\"uint32\"}],\"anonymous\":false},{\"type\":\"error\",\"name\":\"AccountHasActiveApps\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"AppAlreadyExists\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"AppDoesNotExist\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"GlobalMaxActiveAppsExceeded\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidAppStatus\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidPermissions\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidReleaseMetadataURI\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidShortString\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidSignature\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"MaxActiveAppsExceeded\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"MoreThanOneArtifact\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"SignatureExpired\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"StringTooLong\",\"inputs\":[{\"name\":\"str\",\"type\":\"string\",\"internalType\":\"string\"}]}]", + ABI: "[{\"type\":\"constructor\",\"inputs\":[{\"name\":\"_version\",\"type\":\"string\",\"internalType\":\"string\"},{\"name\":\"_permissionController\",\"type\":\"address\",\"internalType\":\"contractIPermissionController\"},{\"name\":\"_releaseManager\",\"type\":\"address\",\"internalType\":\"contractIReleaseManager\"},{\"name\":\"_computeAVSRegistrar\",\"type\":\"address\",\"internalType\":\"contractIComputeAVSRegistrar\"},{\"name\":\"_computeOperator\",\"type\":\"address\",\"internalType\":\"contractIComputeOperator\"},{\"name\":\"_appBeacon\",\"type\":\"address\",\"internalType\":\"contractIBeacon\"},{\"name\":\"_safeTimelockFactory\",\"type\":\"address\",\"internalType\":\"contractISafeTimelockFactory\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"API_PERMISSION_TYPEHASH\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"DEFAULT_ADMIN_ROLE\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"appBeacon\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIBeacon\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"calculateApiPermissionDigestHash\",\"inputs\":[{\"name\":\"permission\",\"type\":\"bytes4\",\"internalType\":\"bytes4\"},{\"name\":\"expiry\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"calculateAppId\",\"inputs\":[{\"name\":\"deployer\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"salt\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"cancelUpgrade\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"computeAVSRegistrar\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIComputeAVSRegistrar\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"computeOperator\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIComputeOperator\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"createApp\",\"inputs\":[{\"name\":\"salt\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"release\",\"type\":\"tuple\",\"internalType\":\"structIAppController.Release\",\"components\":[{\"name\":\"rmsRelease\",\"type\":\"tuple\",\"internalType\":\"structIReleaseManagerTypes.Release\",\"components\":[{\"name\":\"artifacts\",\"type\":\"tuple[]\",\"internalType\":\"structIReleaseManagerTypes.Artifact[]\",\"components\":[{\"name\":\"digest\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"registry\",\"type\":\"string\",\"internalType\":\"string\"}]},{\"name\":\"upgradeByTime\",\"type\":\"uint32\",\"internalType\":\"uint32\"}]},{\"name\":\"publicEnv\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"encryptedEnv\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]}],\"outputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"createAppForTeam\",\"inputs\":[{\"name\":\"team\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"salt\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"release\",\"type\":\"tuple\",\"internalType\":\"structIAppController.Release\",\"components\":[{\"name\":\"rmsRelease\",\"type\":\"tuple\",\"internalType\":\"structIReleaseManagerTypes.Release\",\"components\":[{\"name\":\"artifacts\",\"type\":\"tuple[]\",\"internalType\":\"structIReleaseManagerTypes.Artifact[]\",\"components\":[{\"name\":\"digest\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"registry\",\"type\":\"string\",\"internalType\":\"string\"}]},{\"name\":\"upgradeByTime\",\"type\":\"uint32\",\"internalType\":\"uint32\"}]},{\"name\":\"publicEnv\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"encryptedEnv\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]}],\"outputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"domainSeparator\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"executeUpgrade\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"},{\"name\":\"release\",\"type\":\"tuple\",\"internalType\":\"structIAppController.Release\",\"components\":[{\"name\":\"rmsRelease\",\"type\":\"tuple\",\"internalType\":\"structIReleaseManagerTypes.Release\",\"components\":[{\"name\":\"artifacts\",\"type\":\"tuple[]\",\"internalType\":\"structIReleaseManagerTypes.Artifact[]\",\"components\":[{\"name\":\"digest\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"registry\",\"type\":\"string\",\"internalType\":\"string\"}]},{\"name\":\"upgradeByTime\",\"type\":\"uint32\",\"internalType\":\"uint32\"}]},{\"name\":\"publicEnv\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"encryptedEnv\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"getActiveAppCount\",\"inputs\":[{\"name\":\"user\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getAppLatestReleaseBlockNumber\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getAppOperatorSetId\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getAppOwner\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getAppStatus\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint8\",\"internalType\":\"enumIAppController.AppStatus\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getAppTimelocked\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getApps\",\"inputs\":[{\"name\":\"offset\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"limit\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"apps\",\"type\":\"address[]\",\"internalType\":\"contractIApp[]\"},{\"name\":\"appConfigsMem\",\"type\":\"tuple[]\",\"internalType\":\"structIAppController.AppConfig[]\",\"components\":[{\"name\":\"owner\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"operatorSetId\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"latestReleaseBlockNumber\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"status\",\"type\":\"uint8\",\"internalType\":\"enumIAppController.AppStatus\"},{\"name\":\"timelocked\",\"type\":\"bool\",\"internalType\":\"bool\"}]}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getAppsByCreator\",\"inputs\":[{\"name\":\"creator\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"offset\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"limit\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"apps\",\"type\":\"address[]\",\"internalType\":\"contractIApp[]\"},{\"name\":\"appConfigsMem\",\"type\":\"tuple[]\",\"internalType\":\"structIAppController.AppConfig[]\",\"components\":[{\"name\":\"owner\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"operatorSetId\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"latestReleaseBlockNumber\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"status\",\"type\":\"uint8\",\"internalType\":\"enumIAppController.AppStatus\"},{\"name\":\"timelocked\",\"type\":\"bool\",\"internalType\":\"bool\"}]}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getAppsByDeveloper\",\"inputs\":[{\"name\":\"developer\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"offset\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"limit\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"apps\",\"type\":\"address[]\",\"internalType\":\"contractIApp[]\"},{\"name\":\"appConfigsMem\",\"type\":\"tuple[]\",\"internalType\":\"structIAppController.AppConfig[]\",\"components\":[{\"name\":\"owner\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"operatorSetId\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"latestReleaseBlockNumber\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"status\",\"type\":\"uint8\",\"internalType\":\"enumIAppController.AppStatus\"},{\"name\":\"timelocked\",\"type\":\"bool\",\"internalType\":\"bool\"}]}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getAppsForAccount\",\"inputs\":[{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"offset\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"limit\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"appRoles\",\"type\":\"tuple[]\",\"internalType\":\"structIAppController.AppRoles[]\",\"components\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"},{\"name\":\"isOwner\",\"type\":\"bool\",\"internalType\":\"bool\"},{\"name\":\"roles\",\"type\":\"uint8[]\",\"internalType\":\"enumIAppController.TeamRole[]\"}]}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getMaxActiveAppsPerUser\",\"inputs\":[{\"name\":\"user\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getPendingUpgrade\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"outputs\":[{\"name\":\"\",\"type\":\"tuple\",\"internalType\":\"structIAppController.PendingUpgrade\",\"components\":[{\"name\":\"releaseHash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"readyAt\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getRoleAdmin\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getRoleMember\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"index\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getRoleMemberCount\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getTeamRoleMember\",\"inputs\":[{\"name\":\"team\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"role\",\"type\":\"uint8\",\"internalType\":\"enumIAppController.TeamRole\"},{\"name\":\"index\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getTeamRoleMemberCount\",\"inputs\":[{\"name\":\"team\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"role\",\"type\":\"uint8\",\"internalType\":\"enumIAppController.TeamRole\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getTeamRoleMembers\",\"inputs\":[{\"name\":\"team\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"role\",\"type\":\"uint8\",\"internalType\":\"enumIAppController.TeamRole\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address[]\",\"internalType\":\"address[]\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"globalActiveAppCount\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"grantRole\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"grantTeamRole\",\"inputs\":[{\"name\":\"team\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"role\",\"type\":\"uint8\",\"internalType\":\"enumIAppController.TeamRole\"},{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"hasRole\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"hasTeamRole\",\"inputs\":[{\"name\":\"team\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"role\",\"type\":\"uint8\",\"internalType\":\"enumIAppController.TeamRole\"},{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"initialize\",\"inputs\":[{\"name\":\"admin\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"maxGlobalActiveApps\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"migrateAdmins\",\"inputs\":[{\"name\":\"apps\",\"type\":\"address[]\",\"internalType\":\"contractIApp[]\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"permissionController\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIPermissionController\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"releaseManager\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIReleaseManager\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"renounceRole\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"renounceTeamRole\",\"inputs\":[{\"name\":\"team\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"role\",\"type\":\"uint8\",\"internalType\":\"enumIAppController.TeamRole\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"revokeRole\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"revokeTeamRole\",\"inputs\":[{\"name\":\"team\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"role\",\"type\":\"uint8\",\"internalType\":\"enumIAppController.TeamRole\"},{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"safeTimelockFactory\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractISafeTimelockFactory\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"scheduleUpgrade\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"},{\"name\":\"release\",\"type\":\"tuple\",\"internalType\":\"structIAppController.Release\",\"components\":[{\"name\":\"rmsRelease\",\"type\":\"tuple\",\"internalType\":\"structIReleaseManagerTypes.Release\",\"components\":[{\"name\":\"artifacts\",\"type\":\"tuple[]\",\"internalType\":\"structIReleaseManagerTypes.Artifact[]\",\"components\":[{\"name\":\"digest\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"registry\",\"type\":\"string\",\"internalType\":\"string\"}]},{\"name\":\"upgradeByTime\",\"type\":\"uint32\",\"internalType\":\"uint32\"}]},{\"name\":\"publicEnv\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"encryptedEnv\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]},{\"name\":\"delay\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"setMaxActiveAppsPerUser\",\"inputs\":[{\"name\":\"user\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"limit\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"setMaxGlobalActiveApps\",\"inputs\":[{\"name\":\"limit\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"startApp\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"stopApp\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"supportsInterface\",\"inputs\":[{\"name\":\"interfaceId\",\"type\":\"bytes4\",\"internalType\":\"bytes4\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"suspend\",\"inputs\":[{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"apps\",\"type\":\"address[]\",\"internalType\":\"contractIApp[]\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"terminateApp\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"terminateAppByAdmin\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"transferOwnership\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"},{\"name\":\"newOwner\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"updateAppMetadataURI\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"},{\"name\":\"metadataURI\",\"type\":\"string\",\"internalType\":\"string\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"upgradeApp\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"},{\"name\":\"release\",\"type\":\"tuple\",\"internalType\":\"structIAppController.Release\",\"components\":[{\"name\":\"rmsRelease\",\"type\":\"tuple\",\"internalType\":\"structIReleaseManagerTypes.Release\",\"components\":[{\"name\":\"artifacts\",\"type\":\"tuple[]\",\"internalType\":\"structIReleaseManagerTypes.Artifact[]\",\"components\":[{\"name\":\"digest\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"registry\",\"type\":\"string\",\"internalType\":\"string\"}]},{\"name\":\"upgradeByTime\",\"type\":\"uint32\",\"internalType\":\"uint32\"}]},{\"name\":\"publicEnv\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"encryptedEnv\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"version\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"string\",\"internalType\":\"string\"}],\"stateMutability\":\"view\"},{\"type\":\"event\",\"name\":\"AppCreated\",\"inputs\":[{\"name\":\"owner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"app\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"contractIApp\"},{\"name\":\"operatorSetId\",\"type\":\"uint32\",\"indexed\":false,\"internalType\":\"uint32\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"AppMetadataURIUpdated\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"contractIApp\"},{\"name\":\"metadataURI\",\"type\":\"string\",\"indexed\":false,\"internalType\":\"string\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"AppOwnershipTransferred\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"contractIApp\"},{\"name\":\"previousOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"newOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"AppStarted\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"contractIApp\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"AppStopped\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"contractIApp\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"AppSuspended\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"contractIApp\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"AppTerminated\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"contractIApp\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"AppTerminatedByAdmin\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"contractIApp\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"AppUpgradeCancelled\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"contractIApp\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"AppUpgradeScheduled\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"contractIApp\"},{\"name\":\"readyAt\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"release\",\"type\":\"tuple\",\"indexed\":false,\"internalType\":\"structIAppController.Release\",\"components\":[{\"name\":\"rmsRelease\",\"type\":\"tuple\",\"internalType\":\"structIReleaseManagerTypes.Release\",\"components\":[{\"name\":\"artifacts\",\"type\":\"tuple[]\",\"internalType\":\"structIReleaseManagerTypes.Artifact[]\",\"components\":[{\"name\":\"digest\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"registry\",\"type\":\"string\",\"internalType\":\"string\"}]},{\"name\":\"upgradeByTime\",\"type\":\"uint32\",\"internalType\":\"uint32\"}]},{\"name\":\"publicEnv\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"encryptedEnv\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"AppUpgraded\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"contractIApp\"},{\"name\":\"rmsReleaseId\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"release\",\"type\":\"tuple\",\"indexed\":false,\"internalType\":\"structIAppController.Release\",\"components\":[{\"name\":\"rmsRelease\",\"type\":\"tuple\",\"internalType\":\"structIReleaseManagerTypes.Release\",\"components\":[{\"name\":\"artifacts\",\"type\":\"tuple[]\",\"internalType\":\"structIReleaseManagerTypes.Artifact[]\",\"components\":[{\"name\":\"digest\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"registry\",\"type\":\"string\",\"internalType\":\"string\"}]},{\"name\":\"upgradeByTime\",\"type\":\"uint32\",\"internalType\":\"uint32\"}]},{\"name\":\"publicEnv\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"encryptedEnv\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"GlobalMaxActiveAppsSet\",\"inputs\":[{\"name\":\"limit\",\"type\":\"uint32\",\"indexed\":false,\"internalType\":\"uint32\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Initialized\",\"inputs\":[{\"name\":\"version\",\"type\":\"uint8\",\"indexed\":false,\"internalType\":\"uint8\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"MaxActiveAppsSet\",\"inputs\":[{\"name\":\"user\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"limit\",\"type\":\"uint32\",\"indexed\":false,\"internalType\":\"uint32\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"RoleAdminChanged\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"previousAdminRole\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"newAdminRole\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"RoleGranted\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"account\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"sender\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"RoleRevoked\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"account\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"sender\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"error\",\"name\":\"AccountHasActiveApps\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"AppAlreadyExists\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"AppDoesNotExist\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"CannotRevokeLastAdmin\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"GlobalMaxActiveAppsExceeded\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidAppStatus\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidPermissions\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidReleaseMetadataURI\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidShortString\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidSignature\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"MaxActiveAppsExceeded\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"MoreThanOneArtifact\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"NoScheduledUpgrade\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"NotTimelocked\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"ReleaseMismatch\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"SignatureExpired\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"StringTooLong\",\"inputs\":[{\"name\":\"str\",\"type\":\"string\",\"internalType\":\"string\"}]},{\"type\":\"error\",\"name\":\"TimelockRequired\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"UpgradeNotReady\",\"inputs\":[]}]", ID: "AppController", } @@ -80,9 +94,9 @@ func (c *AppController) Instance(backend bind.ContractBackend, addr common.Addre // PackConstructor is the Go binding used to pack the parameters required for // contract deployment. // -// Solidity: constructor(string _version, address _permissionController, address _releaseManager, address _computeAVSRegistrar, address _computeOperator, address _appBeacon) returns() -func (appController *AppController) PackConstructor(_version string, _permissionController common.Address, _releaseManager common.Address, _computeAVSRegistrar common.Address, _computeOperator common.Address, _appBeacon common.Address) []byte { - enc, err := appController.abi.Pack("", _version, _permissionController, _releaseManager, _computeAVSRegistrar, _computeOperator, _appBeacon) +// Solidity: constructor(string _version, address _permissionController, address _releaseManager, address _computeAVSRegistrar, address _computeOperator, address _appBeacon, address _safeTimelockFactory) returns() +func (appController *AppController) PackConstructor(_version string, _permissionController common.Address, _releaseManager common.Address, _computeAVSRegistrar common.Address, _computeOperator common.Address, _appBeacon common.Address, _safeTimelockFactory common.Address) []byte { + enc, err := appController.abi.Pack("", _version, _permissionController, _releaseManager, _computeAVSRegistrar, _computeOperator, _appBeacon, _safeTimelockFactory) if err != nil { panic(err) } @@ -124,6 +138,41 @@ func (appController *AppController) UnpackAPIPERMISSIONTYPEHASH(data []byte) ([3 return out0, nil } +// PackDEFAULTADMINROLE is the Go binding used to pack the parameters required for calling +// the contract method with ID 0xa217fddf. This method will panic if any +// invalid/nil inputs are passed. +// +// Solidity: function DEFAULT_ADMIN_ROLE() view returns(bytes32) +func (appController *AppController) PackDEFAULTADMINROLE() []byte { + enc, err := appController.abi.Pack("DEFAULT_ADMIN_ROLE") + if err != nil { + panic(err) + } + return enc +} + +// TryPackDEFAULTADMINROLE is the Go binding used to pack the parameters required for calling +// the contract method with ID 0xa217fddf. This method will return an error +// if any inputs are invalid/nil. +// +// Solidity: function DEFAULT_ADMIN_ROLE() view returns(bytes32) +func (appController *AppController) TryPackDEFAULTADMINROLE() ([]byte, error) { + return appController.abi.Pack("DEFAULT_ADMIN_ROLE") +} + +// UnpackDEFAULTADMINROLE is the Go binding that unpacks the parameters returned +// from invoking the contract method with ID 0xa217fddf. +// +// Solidity: function DEFAULT_ADMIN_ROLE() view returns(bytes32) +func (appController *AppController) UnpackDEFAULTADMINROLE(data []byte) ([32]byte, error) { + out, err := appController.abi.Unpack("DEFAULT_ADMIN_ROLE", data) + if err != nil { + return *new([32]byte), err + } + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + return out0, nil +} + // PackAppBeacon is the Go binding used to pack the parameters required for calling // the contract method with ID 0x8a52d0b5. This method will panic if any // invalid/nil inputs are passed. @@ -229,6 +278,28 @@ func (appController *AppController) UnpackCalculateAppId(data []byte) (common.Ad return out0, nil } +// PackCancelUpgrade is the Go binding used to pack the parameters required for calling +// the contract method with ID 0xc44fb8ec. This method will panic if any +// invalid/nil inputs are passed. +// +// Solidity: function cancelUpgrade(address app) returns() +func (appController *AppController) PackCancelUpgrade(app common.Address) []byte { + enc, err := appController.abi.Pack("cancelUpgrade", app) + if err != nil { + panic(err) + } + return enc +} + +// TryPackCancelUpgrade is the Go binding used to pack the parameters required for calling +// the contract method with ID 0xc44fb8ec. This method will return an error +// if any inputs are invalid/nil. +// +// Solidity: function cancelUpgrade(address app) returns() +func (appController *AppController) TryPackCancelUpgrade(app common.Address) ([]byte, error) { + return appController.abi.Pack("cancelUpgrade", app) +} + // PackComputeAVSRegistrar is the Go binding used to pack the parameters required for calling // the contract method with ID 0xef6d92c6. This method will panic if any // invalid/nil inputs are passed. @@ -334,34 +405,34 @@ func (appController *AppController) UnpackCreateApp(data []byte) (common.Address return out0, nil } -// PackCreateAppWithIsolatedBilling is the Go binding used to pack the parameters required for calling -// the contract method with ID 0x559cf359. This method will panic if any +// PackCreateAppForTeam is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x688c3ec3. This method will panic if any // invalid/nil inputs are passed. // -// Solidity: function createAppWithIsolatedBilling(bytes32 salt, (((bytes32,string)[],uint32),bytes,bytes) release) returns(address app) -func (appController *AppController) PackCreateAppWithIsolatedBilling(salt [32]byte, release IAppControllerRelease) []byte { - enc, err := appController.abi.Pack("createAppWithIsolatedBilling", salt, release) +// Solidity: function createAppForTeam(address team, bytes32 salt, (((bytes32,string)[],uint32),bytes,bytes) release) returns(address app) +func (appController *AppController) PackCreateAppForTeam(team common.Address, salt [32]byte, release IAppControllerRelease) []byte { + enc, err := appController.abi.Pack("createAppForTeam", team, salt, release) if err != nil { panic(err) } return enc } -// TryPackCreateAppWithIsolatedBilling is the Go binding used to pack the parameters required for calling -// the contract method with ID 0x559cf359. This method will return an error +// TryPackCreateAppForTeam is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x688c3ec3. This method will return an error // if any inputs are invalid/nil. // -// Solidity: function createAppWithIsolatedBilling(bytes32 salt, (((bytes32,string)[],uint32),bytes,bytes) release) returns(address app) -func (appController *AppController) TryPackCreateAppWithIsolatedBilling(salt [32]byte, release IAppControllerRelease) ([]byte, error) { - return appController.abi.Pack("createAppWithIsolatedBilling", salt, release) +// Solidity: function createAppForTeam(address team, bytes32 salt, (((bytes32,string)[],uint32),bytes,bytes) release) returns(address app) +func (appController *AppController) TryPackCreateAppForTeam(team common.Address, salt [32]byte, release IAppControllerRelease) ([]byte, error) { + return appController.abi.Pack("createAppForTeam", team, salt, release) } -// UnpackCreateAppWithIsolatedBilling is the Go binding that unpacks the parameters returned -// from invoking the contract method with ID 0x559cf359. +// UnpackCreateAppForTeam is the Go binding that unpacks the parameters returned +// from invoking the contract method with ID 0x688c3ec3. // -// Solidity: function createAppWithIsolatedBilling(bytes32 salt, (((bytes32,string)[],uint32),bytes,bytes) release) returns(address app) -func (appController *AppController) UnpackCreateAppWithIsolatedBilling(data []byte) (common.Address, error) { - out, err := appController.abi.Unpack("createAppWithIsolatedBilling", data) +// Solidity: function createAppForTeam(address team, bytes32 salt, (((bytes32,string)[],uint32),bytes,bytes) release) returns(address app) +func (appController *AppController) UnpackCreateAppForTeam(data []byte) (common.Address, error) { + out, err := appController.abi.Unpack("createAppForTeam", data) if err != nil { return *new(common.Address), err } @@ -404,73 +475,73 @@ func (appController *AppController) UnpackDomainSeparator(data []byte) ([32]byte return out0, nil } -// PackGetActiveAppCount is the Go binding used to pack the parameters required for calling -// the contract method with ID 0x0c2199fb. This method will panic if any +// PackExecuteUpgrade is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x57d1a51b. This method will panic if any // invalid/nil inputs are passed. // -// Solidity: function getActiveAppCount(address user) view returns(uint32) -func (appController *AppController) PackGetActiveAppCount(user common.Address) []byte { - enc, err := appController.abi.Pack("getActiveAppCount", user) +// Solidity: function executeUpgrade(address app, (((bytes32,string)[],uint32),bytes,bytes) release) returns(uint256) +func (appController *AppController) PackExecuteUpgrade(app common.Address, release IAppControllerRelease) []byte { + enc, err := appController.abi.Pack("executeUpgrade", app, release) if err != nil { panic(err) } return enc } -// TryPackGetActiveAppCount is the Go binding used to pack the parameters required for calling -// the contract method with ID 0x0c2199fb. This method will return an error +// TryPackExecuteUpgrade is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x57d1a51b. This method will return an error // if any inputs are invalid/nil. // -// Solidity: function getActiveAppCount(address user) view returns(uint32) -func (appController *AppController) TryPackGetActiveAppCount(user common.Address) ([]byte, error) { - return appController.abi.Pack("getActiveAppCount", user) +// Solidity: function executeUpgrade(address app, (((bytes32,string)[],uint32),bytes,bytes) release) returns(uint256) +func (appController *AppController) TryPackExecuteUpgrade(app common.Address, release IAppControllerRelease) ([]byte, error) { + return appController.abi.Pack("executeUpgrade", app, release) } -// UnpackGetActiveAppCount is the Go binding that unpacks the parameters returned -// from invoking the contract method with ID 0x0c2199fb. +// UnpackExecuteUpgrade is the Go binding that unpacks the parameters returned +// from invoking the contract method with ID 0x57d1a51b. // -// Solidity: function getActiveAppCount(address user) view returns(uint32) -func (appController *AppController) UnpackGetActiveAppCount(data []byte) (uint32, error) { - out, err := appController.abi.Unpack("getActiveAppCount", data) +// Solidity: function executeUpgrade(address app, (((bytes32,string)[],uint32),bytes,bytes) release) returns(uint256) +func (appController *AppController) UnpackExecuteUpgrade(data []byte) (*big.Int, error) { + out, err := appController.abi.Unpack("executeUpgrade", data) if err != nil { - return *new(uint32), err + return new(big.Int), err } - out0 := *abi.ConvertType(out[0], new(uint32)).(*uint32) + out0 := abi.ConvertType(out[0], new(big.Int)).(*big.Int) return out0, nil } -// PackGetAppCreator is the Go binding used to pack the parameters required for calling -// the contract method with ID 0x67962d48. This method will panic if any +// PackGetActiveAppCount is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x0c2199fb. This method will panic if any // invalid/nil inputs are passed. // -// Solidity: function getAppCreator(address app) view returns(address) -func (appController *AppController) PackGetAppCreator(app common.Address) []byte { - enc, err := appController.abi.Pack("getAppCreator", app) +// Solidity: function getActiveAppCount(address user) view returns(uint32) +func (appController *AppController) PackGetActiveAppCount(user common.Address) []byte { + enc, err := appController.abi.Pack("getActiveAppCount", user) if err != nil { panic(err) } return enc } -// TryPackGetAppCreator is the Go binding used to pack the parameters required for calling -// the contract method with ID 0x67962d48. This method will return an error +// TryPackGetActiveAppCount is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x0c2199fb. This method will return an error // if any inputs are invalid/nil. // -// Solidity: function getAppCreator(address app) view returns(address) -func (appController *AppController) TryPackGetAppCreator(app common.Address) ([]byte, error) { - return appController.abi.Pack("getAppCreator", app) +// Solidity: function getActiveAppCount(address user) view returns(uint32) +func (appController *AppController) TryPackGetActiveAppCount(user common.Address) ([]byte, error) { + return appController.abi.Pack("getActiveAppCount", user) } -// UnpackGetAppCreator is the Go binding that unpacks the parameters returned -// from invoking the contract method with ID 0x67962d48. +// UnpackGetActiveAppCount is the Go binding that unpacks the parameters returned +// from invoking the contract method with ID 0x0c2199fb. // -// Solidity: function getAppCreator(address app) view returns(address) -func (appController *AppController) UnpackGetAppCreator(data []byte) (common.Address, error) { - out, err := appController.abi.Unpack("getAppCreator", data) +// Solidity: function getActiveAppCount(address user) view returns(uint32) +func (appController *AppController) UnpackGetActiveAppCount(data []byte) (uint32, error) { + out, err := appController.abi.Unpack("getActiveAppCount", data) if err != nil { - return *new(common.Address), err + return *new(uint32), err } - out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + out0 := *abi.ConvertType(out[0], new(uint32)).(*uint32) return out0, nil } @@ -544,6 +615,41 @@ func (appController *AppController) UnpackGetAppOperatorSetId(data []byte) (uint return out0, nil } +// PackGetAppOwner is the Go binding used to pack the parameters required for calling +// the contract method with ID 0xffb42b51. This method will panic if any +// invalid/nil inputs are passed. +// +// Solidity: function getAppOwner(address app) view returns(address) +func (appController *AppController) PackGetAppOwner(app common.Address) []byte { + enc, err := appController.abi.Pack("getAppOwner", app) + if err != nil { + panic(err) + } + return enc +} + +// TryPackGetAppOwner is the Go binding used to pack the parameters required for calling +// the contract method with ID 0xffb42b51. This method will return an error +// if any inputs are invalid/nil. +// +// Solidity: function getAppOwner(address app) view returns(address) +func (appController *AppController) TryPackGetAppOwner(app common.Address) ([]byte, error) { + return appController.abi.Pack("getAppOwner", app) +} + +// UnpackGetAppOwner is the Go binding that unpacks the parameters returned +// from invoking the contract method with ID 0xffb42b51. +// +// Solidity: function getAppOwner(address app) view returns(address) +func (appController *AppController) UnpackGetAppOwner(data []byte) (common.Address, error) { + out, err := appController.abi.Unpack("getAppOwner", data) + if err != nil { + return *new(common.Address), err + } + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + return out0, nil +} + // PackGetAppStatus is the Go binding used to pack the parameters required for calling // the contract method with ID 0xd5aae178. This method will panic if any // invalid/nil inputs are passed. @@ -579,86 +685,77 @@ func (appController *AppController) UnpackGetAppStatus(data []byte) (uint8, erro return out0, nil } -// PackGetApps is the Go binding used to pack the parameters required for calling -// the contract method with ID 0xa37e7e44. This method will panic if any +// PackGetAppTimelocked is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x508ac1d6. This method will panic if any // invalid/nil inputs are passed. // -// Solidity: function getApps(uint256 offset, uint256 limit) view returns(address[] apps, (address,uint32,uint32,uint8)[] appConfigsMem) -func (appController *AppController) PackGetApps(offset *big.Int, limit *big.Int) []byte { - enc, err := appController.abi.Pack("getApps", offset, limit) +// Solidity: function getAppTimelocked(address app) view returns(bool) +func (appController *AppController) PackGetAppTimelocked(app common.Address) []byte { + enc, err := appController.abi.Pack("getAppTimelocked", app) if err != nil { panic(err) } return enc } -// TryPackGetApps is the Go binding used to pack the parameters required for calling -// the contract method with ID 0xa37e7e44. This method will return an error +// TryPackGetAppTimelocked is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x508ac1d6. This method will return an error // if any inputs are invalid/nil. // -// Solidity: function getApps(uint256 offset, uint256 limit) view returns(address[] apps, (address,uint32,uint32,uint8)[] appConfigsMem) -func (appController *AppController) TryPackGetApps(offset *big.Int, limit *big.Int) ([]byte, error) { - return appController.abi.Pack("getApps", offset, limit) -} - -// GetAppsOutput serves as a container for the return parameters of contract -// method GetApps. -type GetAppsOutput struct { - Apps []common.Address - AppConfigsMem []IAppControllerAppConfig +// Solidity: function getAppTimelocked(address app) view returns(bool) +func (appController *AppController) TryPackGetAppTimelocked(app common.Address) ([]byte, error) { + return appController.abi.Pack("getAppTimelocked", app) } -// UnpackGetApps is the Go binding that unpacks the parameters returned -// from invoking the contract method with ID 0xa37e7e44. +// UnpackGetAppTimelocked is the Go binding that unpacks the parameters returned +// from invoking the contract method with ID 0x508ac1d6. // -// Solidity: function getApps(uint256 offset, uint256 limit) view returns(address[] apps, (address,uint32,uint32,uint8)[] appConfigsMem) -func (appController *AppController) UnpackGetApps(data []byte) (GetAppsOutput, error) { - out, err := appController.abi.Unpack("getApps", data) - outstruct := new(GetAppsOutput) +// Solidity: function getAppTimelocked(address app) view returns(bool) +func (appController *AppController) UnpackGetAppTimelocked(data []byte) (bool, error) { + out, err := appController.abi.Unpack("getAppTimelocked", data) if err != nil { - return *outstruct, err + return *new(bool), err } - outstruct.Apps = *abi.ConvertType(out[0], new([]common.Address)).(*[]common.Address) - outstruct.AppConfigsMem = *abi.ConvertType(out[1], new([]IAppControllerAppConfig)).(*[]IAppControllerAppConfig) - return *outstruct, nil + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + return out0, nil } -// PackGetAppsByBillingAccount is the Go binding used to pack the parameters required for calling -// the contract method with ID 0xdbb1c4e1. This method will panic if any +// PackGetApps is the Go binding used to pack the parameters required for calling +// the contract method with ID 0xa37e7e44. This method will panic if any // invalid/nil inputs are passed. // -// Solidity: function getAppsByBillingAccount(address account, uint256 offset, uint256 limit) view returns(address[] apps, (address,uint32,uint32,uint8)[] appConfigsMem) -func (appController *AppController) PackGetAppsByBillingAccount(account common.Address, offset *big.Int, limit *big.Int) []byte { - enc, err := appController.abi.Pack("getAppsByBillingAccount", account, offset, limit) +// Solidity: function getApps(uint256 offset, uint256 limit) view returns(address[] apps, (address,uint32,uint32,uint8,bool)[] appConfigsMem) +func (appController *AppController) PackGetApps(offset *big.Int, limit *big.Int) []byte { + enc, err := appController.abi.Pack("getApps", offset, limit) if err != nil { panic(err) } return enc } -// TryPackGetAppsByBillingAccount is the Go binding used to pack the parameters required for calling -// the contract method with ID 0xdbb1c4e1. This method will return an error +// TryPackGetApps is the Go binding used to pack the parameters required for calling +// the contract method with ID 0xa37e7e44. This method will return an error // if any inputs are invalid/nil. // -// Solidity: function getAppsByBillingAccount(address account, uint256 offset, uint256 limit) view returns(address[] apps, (address,uint32,uint32,uint8)[] appConfigsMem) -func (appController *AppController) TryPackGetAppsByBillingAccount(account common.Address, offset *big.Int, limit *big.Int) ([]byte, error) { - return appController.abi.Pack("getAppsByBillingAccount", account, offset, limit) +// Solidity: function getApps(uint256 offset, uint256 limit) view returns(address[] apps, (address,uint32,uint32,uint8,bool)[] appConfigsMem) +func (appController *AppController) TryPackGetApps(offset *big.Int, limit *big.Int) ([]byte, error) { + return appController.abi.Pack("getApps", offset, limit) } -// GetAppsByBillingAccountOutput serves as a container for the return parameters of contract -// method GetAppsByBillingAccount. -type GetAppsByBillingAccountOutput struct { +// GetAppsOutput serves as a container for the return parameters of contract +// method GetApps. +type GetAppsOutput struct { Apps []common.Address AppConfigsMem []IAppControllerAppConfig } -// UnpackGetAppsByBillingAccount is the Go binding that unpacks the parameters returned -// from invoking the contract method with ID 0xdbb1c4e1. +// UnpackGetApps is the Go binding that unpacks the parameters returned +// from invoking the contract method with ID 0xa37e7e44. // -// Solidity: function getAppsByBillingAccount(address account, uint256 offset, uint256 limit) view returns(address[] apps, (address,uint32,uint32,uint8)[] appConfigsMem) -func (appController *AppController) UnpackGetAppsByBillingAccount(data []byte) (GetAppsByBillingAccountOutput, error) { - out, err := appController.abi.Unpack("getAppsByBillingAccount", data) - outstruct := new(GetAppsByBillingAccountOutput) +// Solidity: function getApps(uint256 offset, uint256 limit) view returns(address[] apps, (address,uint32,uint32,uint8,bool)[] appConfigsMem) +func (appController *AppController) UnpackGetApps(data []byte) (GetAppsOutput, error) { + out, err := appController.abi.Unpack("getApps", data) + outstruct := new(GetAppsOutput) if err != nil { return *outstruct, err } @@ -671,7 +768,7 @@ func (appController *AppController) UnpackGetAppsByBillingAccount(data []byte) ( // the contract method with ID 0x8099ef2e. This method will panic if any // invalid/nil inputs are passed. // -// Solidity: function getAppsByCreator(address creator, uint256 offset, uint256 limit) view returns(address[] apps, (address,uint32,uint32,uint8)[] appConfigsMem) +// Solidity: function getAppsByCreator(address creator, uint256 offset, uint256 limit) view returns(address[] apps, (address,uint32,uint32,uint8,bool)[] appConfigsMem) func (appController *AppController) PackGetAppsByCreator(creator common.Address, offset *big.Int, limit *big.Int) []byte { enc, err := appController.abi.Pack("getAppsByCreator", creator, offset, limit) if err != nil { @@ -684,7 +781,7 @@ func (appController *AppController) PackGetAppsByCreator(creator common.Address, // the contract method with ID 0x8099ef2e. This method will return an error // if any inputs are invalid/nil. // -// Solidity: function getAppsByCreator(address creator, uint256 offset, uint256 limit) view returns(address[] apps, (address,uint32,uint32,uint8)[] appConfigsMem) +// Solidity: function getAppsByCreator(address creator, uint256 offset, uint256 limit) view returns(address[] apps, (address,uint32,uint32,uint8,bool)[] appConfigsMem) func (appController *AppController) TryPackGetAppsByCreator(creator common.Address, offset *big.Int, limit *big.Int) ([]byte, error) { return appController.abi.Pack("getAppsByCreator", creator, offset, limit) } @@ -699,7 +796,7 @@ type GetAppsByCreatorOutput struct { // UnpackGetAppsByCreator is the Go binding that unpacks the parameters returned // from invoking the contract method with ID 0x8099ef2e. // -// Solidity: function getAppsByCreator(address creator, uint256 offset, uint256 limit) view returns(address[] apps, (address,uint32,uint32,uint8)[] appConfigsMem) +// Solidity: function getAppsByCreator(address creator, uint256 offset, uint256 limit) view returns(address[] apps, (address,uint32,uint32,uint8,bool)[] appConfigsMem) func (appController *AppController) UnpackGetAppsByCreator(data []byte) (GetAppsByCreatorOutput, error) { out, err := appController.abi.Unpack("getAppsByCreator", data) outstruct := new(GetAppsByCreatorOutput) @@ -715,7 +812,7 @@ func (appController *AppController) UnpackGetAppsByCreator(data []byte) (GetApps // the contract method with ID 0xf36618ac. This method will panic if any // invalid/nil inputs are passed. // -// Solidity: function getAppsByDeveloper(address developer, uint256 offset, uint256 limit) view returns(address[] apps, (address,uint32,uint32,uint8)[] appConfigsMem) +// Solidity: function getAppsByDeveloper(address developer, uint256 offset, uint256 limit) view returns(address[] apps, (address,uint32,uint32,uint8,bool)[] appConfigsMem) func (appController *AppController) PackGetAppsByDeveloper(developer common.Address, offset *big.Int, limit *big.Int) []byte { enc, err := appController.abi.Pack("getAppsByDeveloper", developer, offset, limit) if err != nil { @@ -728,7 +825,7 @@ func (appController *AppController) PackGetAppsByDeveloper(developer common.Addr // the contract method with ID 0xf36618ac. This method will return an error // if any inputs are invalid/nil. // -// Solidity: function getAppsByDeveloper(address developer, uint256 offset, uint256 limit) view returns(address[] apps, (address,uint32,uint32,uint8)[] appConfigsMem) +// Solidity: function getAppsByDeveloper(address developer, uint256 offset, uint256 limit) view returns(address[] apps, (address,uint32,uint32,uint8,bool)[] appConfigsMem) func (appController *AppController) TryPackGetAppsByDeveloper(developer common.Address, offset *big.Int, limit *big.Int) ([]byte, error) { return appController.abi.Pack("getAppsByDeveloper", developer, offset, limit) } @@ -743,7 +840,7 @@ type GetAppsByDeveloperOutput struct { // UnpackGetAppsByDeveloper is the Go binding that unpacks the parameters returned // from invoking the contract method with ID 0xf36618ac. // -// Solidity: function getAppsByDeveloper(address developer, uint256 offset, uint256 limit) view returns(address[] apps, (address,uint32,uint32,uint8)[] appConfigsMem) +// Solidity: function getAppsByDeveloper(address developer, uint256 offset, uint256 limit) view returns(address[] apps, (address,uint32,uint32,uint8,bool)[] appConfigsMem) func (appController *AppController) UnpackGetAppsByDeveloper(data []byte) (GetAppsByDeveloperOutput, error) { out, err := appController.abi.Unpack("getAppsByDeveloper", data) outstruct := new(GetAppsByDeveloperOutput) @@ -755,73 +852,38 @@ func (appController *AppController) UnpackGetAppsByDeveloper(data []byte) (GetAp return *outstruct, nil } -// PackGetBillingAccount is the Go binding used to pack the parameters required for calling -// the contract method with ID 0x3e032115. This method will panic if any -// invalid/nil inputs are passed. -// -// Solidity: function getBillingAccount(address app) view returns(address) -func (appController *AppController) PackGetBillingAccount(app common.Address) []byte { - enc, err := appController.abi.Pack("getBillingAccount", app) - if err != nil { - panic(err) - } - return enc -} - -// TryPackGetBillingAccount is the Go binding used to pack the parameters required for calling -// the contract method with ID 0x3e032115. This method will return an error -// if any inputs are invalid/nil. -// -// Solidity: function getBillingAccount(address app) view returns(address) -func (appController *AppController) TryPackGetBillingAccount(app common.Address) ([]byte, error) { - return appController.abi.Pack("getBillingAccount", app) -} - -// UnpackGetBillingAccount is the Go binding that unpacks the parameters returned -// from invoking the contract method with ID 0x3e032115. -// -// Solidity: function getBillingAccount(address app) view returns(address) -func (appController *AppController) UnpackGetBillingAccount(data []byte) (common.Address, error) { - out, err := appController.abi.Unpack("getBillingAccount", data) - if err != nil { - return *new(common.Address), err - } - out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) - return out0, nil -} - -// PackGetBillingType is the Go binding used to pack the parameters required for calling -// the contract method with ID 0x85e9babb. This method will panic if any +// PackGetAppsForAccount is the Go binding used to pack the parameters required for calling +// the contract method with ID 0xf61b3a25. This method will panic if any // invalid/nil inputs are passed. // -// Solidity: function getBillingType(address app) view returns(uint8) -func (appController *AppController) PackGetBillingType(app common.Address) []byte { - enc, err := appController.abi.Pack("getBillingType", app) +// Solidity: function getAppsForAccount(address account, uint256 offset, uint256 limit) view returns((address,bool,uint8[])[] appRoles) +func (appController *AppController) PackGetAppsForAccount(account common.Address, offset *big.Int, limit *big.Int) []byte { + enc, err := appController.abi.Pack("getAppsForAccount", account, offset, limit) if err != nil { panic(err) } return enc } -// TryPackGetBillingType is the Go binding used to pack the parameters required for calling -// the contract method with ID 0x85e9babb. This method will return an error +// TryPackGetAppsForAccount is the Go binding used to pack the parameters required for calling +// the contract method with ID 0xf61b3a25. This method will return an error // if any inputs are invalid/nil. // -// Solidity: function getBillingType(address app) view returns(uint8) -func (appController *AppController) TryPackGetBillingType(app common.Address) ([]byte, error) { - return appController.abi.Pack("getBillingType", app) +// Solidity: function getAppsForAccount(address account, uint256 offset, uint256 limit) view returns((address,bool,uint8[])[] appRoles) +func (appController *AppController) TryPackGetAppsForAccount(account common.Address, offset *big.Int, limit *big.Int) ([]byte, error) { + return appController.abi.Pack("getAppsForAccount", account, offset, limit) } -// UnpackGetBillingType is the Go binding that unpacks the parameters returned -// from invoking the contract method with ID 0x85e9babb. +// UnpackGetAppsForAccount is the Go binding that unpacks the parameters returned +// from invoking the contract method with ID 0xf61b3a25. // -// Solidity: function getBillingType(address app) view returns(uint8) -func (appController *AppController) UnpackGetBillingType(data []byte) (uint8, error) { - out, err := appController.abi.Unpack("getBillingType", data) +// Solidity: function getAppsForAccount(address account, uint256 offset, uint256 limit) view returns((address,bool,uint8[])[] appRoles) +func (appController *AppController) UnpackGetAppsForAccount(data []byte) ([]IAppControllerAppRoles, error) { + out, err := appController.abi.Unpack("getAppsForAccount", data) if err != nil { - return *new(uint8), err + return *new([]IAppControllerAppRoles), err } - out0 := *abi.ConvertType(out[0], new(uint8)).(*uint8) + out0 := *abi.ConvertType(out[0], new([]IAppControllerAppRoles)).(*[]IAppControllerAppRoles) return out0, nil } @@ -860,161 +922,174 @@ func (appController *AppController) UnpackGetMaxActiveAppsPerUser(data []byte) ( return out0, nil } -// PackGlobalActiveAppCount is the Go binding used to pack the parameters required for calling -// the contract method with ID 0xa8aa2bd3. This method will panic if any +// PackGetPendingUpgrade is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x57ececcd. This method will panic if any // invalid/nil inputs are passed. // -// Solidity: function globalActiveAppCount() view returns(uint32) -func (appController *AppController) PackGlobalActiveAppCount() []byte { - enc, err := appController.abi.Pack("globalActiveAppCount") +// Solidity: function getPendingUpgrade(address app) view returns((bytes32,uint256)) +func (appController *AppController) PackGetPendingUpgrade(app common.Address) []byte { + enc, err := appController.abi.Pack("getPendingUpgrade", app) if err != nil { panic(err) } return enc } -// TryPackGlobalActiveAppCount is the Go binding used to pack the parameters required for calling -// the contract method with ID 0xa8aa2bd3. This method will return an error +// TryPackGetPendingUpgrade is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x57ececcd. This method will return an error // if any inputs are invalid/nil. // -// Solidity: function globalActiveAppCount() view returns(uint32) -func (appController *AppController) TryPackGlobalActiveAppCount() ([]byte, error) { - return appController.abi.Pack("globalActiveAppCount") +// Solidity: function getPendingUpgrade(address app) view returns((bytes32,uint256)) +func (appController *AppController) TryPackGetPendingUpgrade(app common.Address) ([]byte, error) { + return appController.abi.Pack("getPendingUpgrade", app) } -// UnpackGlobalActiveAppCount is the Go binding that unpacks the parameters returned -// from invoking the contract method with ID 0xa8aa2bd3. +// UnpackGetPendingUpgrade is the Go binding that unpacks the parameters returned +// from invoking the contract method with ID 0x57ececcd. // -// Solidity: function globalActiveAppCount() view returns(uint32) -func (appController *AppController) UnpackGlobalActiveAppCount(data []byte) (uint32, error) { - out, err := appController.abi.Unpack("globalActiveAppCount", data) +// Solidity: function getPendingUpgrade(address app) view returns((bytes32,uint256)) +func (appController *AppController) UnpackGetPendingUpgrade(data []byte) (IAppControllerPendingUpgrade, error) { + out, err := appController.abi.Unpack("getPendingUpgrade", data) if err != nil { - return *new(uint32), err + return *new(IAppControllerPendingUpgrade), err } - out0 := *abi.ConvertType(out[0], new(uint32)).(*uint32) + out0 := *abi.ConvertType(out[0], new(IAppControllerPendingUpgrade)).(*IAppControllerPendingUpgrade) return out0, nil } -// PackInitialize is the Go binding used to pack the parameters required for calling -// the contract method with ID 0xc4d66de8. This method will panic if any +// PackGetRoleAdmin is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x248a9ca3. This method will panic if any // invalid/nil inputs are passed. // -// Solidity: function initialize(address admin) returns() -func (appController *AppController) PackInitialize(admin common.Address) []byte { - enc, err := appController.abi.Pack("initialize", admin) +// Solidity: function getRoleAdmin(bytes32 role) view returns(bytes32) +func (appController *AppController) PackGetRoleAdmin(role [32]byte) []byte { + enc, err := appController.abi.Pack("getRoleAdmin", role) if err != nil { panic(err) } return enc } -// TryPackInitialize is the Go binding used to pack the parameters required for calling -// the contract method with ID 0xc4d66de8. This method will return an error +// TryPackGetRoleAdmin is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x248a9ca3. This method will return an error // if any inputs are invalid/nil. // -// Solidity: function initialize(address admin) returns() -func (appController *AppController) TryPackInitialize(admin common.Address) ([]byte, error) { - return appController.abi.Pack("initialize", admin) +// Solidity: function getRoleAdmin(bytes32 role) view returns(bytes32) +func (appController *AppController) TryPackGetRoleAdmin(role [32]byte) ([]byte, error) { + return appController.abi.Pack("getRoleAdmin", role) } -// PackMaxGlobalActiveApps is the Go binding used to pack the parameters required for calling -// the contract method with ID 0xa46530a2. This method will panic if any +// UnpackGetRoleAdmin is the Go binding that unpacks the parameters returned +// from invoking the contract method with ID 0x248a9ca3. +// +// Solidity: function getRoleAdmin(bytes32 role) view returns(bytes32) +func (appController *AppController) UnpackGetRoleAdmin(data []byte) ([32]byte, error) { + out, err := appController.abi.Unpack("getRoleAdmin", data) + if err != nil { + return *new([32]byte), err + } + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + return out0, nil +} + +// PackGetRoleMember is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x9010d07c. This method will panic if any // invalid/nil inputs are passed. // -// Solidity: function maxGlobalActiveApps() view returns(uint32) -func (appController *AppController) PackMaxGlobalActiveApps() []byte { - enc, err := appController.abi.Pack("maxGlobalActiveApps") +// Solidity: function getRoleMember(bytes32 role, uint256 index) view returns(address) +func (appController *AppController) PackGetRoleMember(role [32]byte, index *big.Int) []byte { + enc, err := appController.abi.Pack("getRoleMember", role, index) if err != nil { panic(err) } return enc } -// TryPackMaxGlobalActiveApps is the Go binding used to pack the parameters required for calling -// the contract method with ID 0xa46530a2. This method will return an error +// TryPackGetRoleMember is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x9010d07c. This method will return an error // if any inputs are invalid/nil. // -// Solidity: function maxGlobalActiveApps() view returns(uint32) -func (appController *AppController) TryPackMaxGlobalActiveApps() ([]byte, error) { - return appController.abi.Pack("maxGlobalActiveApps") +// Solidity: function getRoleMember(bytes32 role, uint256 index) view returns(address) +func (appController *AppController) TryPackGetRoleMember(role [32]byte, index *big.Int) ([]byte, error) { + return appController.abi.Pack("getRoleMember", role, index) } -// UnpackMaxGlobalActiveApps is the Go binding that unpacks the parameters returned -// from invoking the contract method with ID 0xa46530a2. +// UnpackGetRoleMember is the Go binding that unpacks the parameters returned +// from invoking the contract method with ID 0x9010d07c. // -// Solidity: function maxGlobalActiveApps() view returns(uint32) -func (appController *AppController) UnpackMaxGlobalActiveApps(data []byte) (uint32, error) { - out, err := appController.abi.Unpack("maxGlobalActiveApps", data) +// Solidity: function getRoleMember(bytes32 role, uint256 index) view returns(address) +func (appController *AppController) UnpackGetRoleMember(data []byte) (common.Address, error) { + out, err := appController.abi.Unpack("getRoleMember", data) if err != nil { - return *new(uint32), err + return *new(common.Address), err } - out0 := *abi.ConvertType(out[0], new(uint32)).(*uint32) + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) return out0, nil } -// PackPermissionController is the Go binding used to pack the parameters required for calling -// the contract method with ID 0x4657e26a. This method will panic if any +// PackGetRoleMemberCount is the Go binding used to pack the parameters required for calling +// the contract method with ID 0xca15c873. This method will panic if any // invalid/nil inputs are passed. // -// Solidity: function permissionController() view returns(address) -func (appController *AppController) PackPermissionController() []byte { - enc, err := appController.abi.Pack("permissionController") +// Solidity: function getRoleMemberCount(bytes32 role) view returns(uint256) +func (appController *AppController) PackGetRoleMemberCount(role [32]byte) []byte { + enc, err := appController.abi.Pack("getRoleMemberCount", role) if err != nil { panic(err) } return enc } -// TryPackPermissionController is the Go binding used to pack the parameters required for calling -// the contract method with ID 0x4657e26a. This method will return an error +// TryPackGetRoleMemberCount is the Go binding used to pack the parameters required for calling +// the contract method with ID 0xca15c873. This method will return an error // if any inputs are invalid/nil. // -// Solidity: function permissionController() view returns(address) -func (appController *AppController) TryPackPermissionController() ([]byte, error) { - return appController.abi.Pack("permissionController") +// Solidity: function getRoleMemberCount(bytes32 role) view returns(uint256) +func (appController *AppController) TryPackGetRoleMemberCount(role [32]byte) ([]byte, error) { + return appController.abi.Pack("getRoleMemberCount", role) } -// UnpackPermissionController is the Go binding that unpacks the parameters returned -// from invoking the contract method with ID 0x4657e26a. +// UnpackGetRoleMemberCount is the Go binding that unpacks the parameters returned +// from invoking the contract method with ID 0xca15c873. // -// Solidity: function permissionController() view returns(address) -func (appController *AppController) UnpackPermissionController(data []byte) (common.Address, error) { - out, err := appController.abi.Unpack("permissionController", data) +// Solidity: function getRoleMemberCount(bytes32 role) view returns(uint256) +func (appController *AppController) UnpackGetRoleMemberCount(data []byte) (*big.Int, error) { + out, err := appController.abi.Unpack("getRoleMemberCount", data) if err != nil { - return *new(common.Address), err + return new(big.Int), err } - out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + out0 := abi.ConvertType(out[0], new(big.Int)).(*big.Int) return out0, nil } -// PackReleaseManager is the Go binding used to pack the parameters required for calling -// the contract method with ID 0x0d78573e. This method will panic if any +// PackGetTeamRoleMember is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x1d349e61. This method will panic if any // invalid/nil inputs are passed. // -// Solidity: function releaseManager() view returns(address) -func (appController *AppController) PackReleaseManager() []byte { - enc, err := appController.abi.Pack("releaseManager") +// Solidity: function getTeamRoleMember(address team, uint8 role, uint256 index) view returns(address) +func (appController *AppController) PackGetTeamRoleMember(team common.Address, role uint8, index *big.Int) []byte { + enc, err := appController.abi.Pack("getTeamRoleMember", team, role, index) if err != nil { panic(err) } return enc } -// TryPackReleaseManager is the Go binding used to pack the parameters required for calling -// the contract method with ID 0x0d78573e. This method will return an error +// TryPackGetTeamRoleMember is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x1d349e61. This method will return an error // if any inputs are invalid/nil. // -// Solidity: function releaseManager() view returns(address) -func (appController *AppController) TryPackReleaseManager() ([]byte, error) { - return appController.abi.Pack("releaseManager") +// Solidity: function getTeamRoleMember(address team, uint8 role, uint256 index) view returns(address) +func (appController *AppController) TryPackGetTeamRoleMember(team common.Address, role uint8, index *big.Int) ([]byte, error) { + return appController.abi.Pack("getTeamRoleMember", team, role, index) } -// UnpackReleaseManager is the Go binding that unpacks the parameters returned -// from invoking the contract method with ID 0x0d78573e. +// UnpackGetTeamRoleMember is the Go binding that unpacks the parameters returned +// from invoking the contract method with ID 0x1d349e61. // -// Solidity: function releaseManager() view returns(address) -func (appController *AppController) UnpackReleaseManager(data []byte) (common.Address, error) { - out, err := appController.abi.Unpack("releaseManager", data) +// Solidity: function getTeamRoleMember(address team, uint8 role, uint256 index) view returns(address) +func (appController *AppController) UnpackGetTeamRoleMember(data []byte) (common.Address, error) { + out, err := appController.abi.Unpack("getTeamRoleMember", data) if err != nil { return *new(common.Address), err } @@ -1022,29 +1097,542 @@ func (appController *AppController) UnpackReleaseManager(data []byte) (common.Ad return out0, nil } -// PackSetMaxActiveAppsPerUser is the Go binding used to pack the parameters required for calling -// the contract method with ID 0xd49fec2b. This method will panic if any +// PackGetTeamRoleMemberCount is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x3c98ff65. This method will panic if any // invalid/nil inputs are passed. // -// Solidity: function setMaxActiveAppsPerUser(address user, uint32 limit) returns() -func (appController *AppController) PackSetMaxActiveAppsPerUser(user common.Address, limit uint32) []byte { - enc, err := appController.abi.Pack("setMaxActiveAppsPerUser", user, limit) +// Solidity: function getTeamRoleMemberCount(address team, uint8 role) view returns(uint256) +func (appController *AppController) PackGetTeamRoleMemberCount(team common.Address, role uint8) []byte { + enc, err := appController.abi.Pack("getTeamRoleMemberCount", team, role) if err != nil { panic(err) } return enc } -// TryPackSetMaxActiveAppsPerUser is the Go binding used to pack the parameters required for calling -// the contract method with ID 0xd49fec2b. This method will return an error +// TryPackGetTeamRoleMemberCount is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x3c98ff65. This method will return an error // if any inputs are invalid/nil. // -// Solidity: function setMaxActiveAppsPerUser(address user, uint32 limit) returns() -func (appController *AppController) TryPackSetMaxActiveAppsPerUser(user common.Address, limit uint32) ([]byte, error) { - return appController.abi.Pack("setMaxActiveAppsPerUser", user, limit) +// Solidity: function getTeamRoleMemberCount(address team, uint8 role) view returns(uint256) +func (appController *AppController) TryPackGetTeamRoleMemberCount(team common.Address, role uint8) ([]byte, error) { + return appController.abi.Pack("getTeamRoleMemberCount", team, role) } -// PackSetMaxGlobalActiveApps is the Go binding used to pack the parameters required for calling +// UnpackGetTeamRoleMemberCount is the Go binding that unpacks the parameters returned +// from invoking the contract method with ID 0x3c98ff65. +// +// Solidity: function getTeamRoleMemberCount(address team, uint8 role) view returns(uint256) +func (appController *AppController) UnpackGetTeamRoleMemberCount(data []byte) (*big.Int, error) { + out, err := appController.abi.Unpack("getTeamRoleMemberCount", data) + if err != nil { + return new(big.Int), err + } + out0 := abi.ConvertType(out[0], new(big.Int)).(*big.Int) + return out0, nil +} + +// PackGetTeamRoleMembers is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x60257ae6. This method will panic if any +// invalid/nil inputs are passed. +// +// Solidity: function getTeamRoleMembers(address team, uint8 role) view returns(address[]) +func (appController *AppController) PackGetTeamRoleMembers(team common.Address, role uint8) []byte { + enc, err := appController.abi.Pack("getTeamRoleMembers", team, role) + if err != nil { + panic(err) + } + return enc +} + +// TryPackGetTeamRoleMembers is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x60257ae6. This method will return an error +// if any inputs are invalid/nil. +// +// Solidity: function getTeamRoleMembers(address team, uint8 role) view returns(address[]) +func (appController *AppController) TryPackGetTeamRoleMembers(team common.Address, role uint8) ([]byte, error) { + return appController.abi.Pack("getTeamRoleMembers", team, role) +} + +// UnpackGetTeamRoleMembers is the Go binding that unpacks the parameters returned +// from invoking the contract method with ID 0x60257ae6. +// +// Solidity: function getTeamRoleMembers(address team, uint8 role) view returns(address[]) +func (appController *AppController) UnpackGetTeamRoleMembers(data []byte) ([]common.Address, error) { + out, err := appController.abi.Unpack("getTeamRoleMembers", data) + if err != nil { + return *new([]common.Address), err + } + out0 := *abi.ConvertType(out[0], new([]common.Address)).(*[]common.Address) + return out0, nil +} + +// PackGlobalActiveAppCount is the Go binding used to pack the parameters required for calling +// the contract method with ID 0xa8aa2bd3. This method will panic if any +// invalid/nil inputs are passed. +// +// Solidity: function globalActiveAppCount() view returns(uint32) +func (appController *AppController) PackGlobalActiveAppCount() []byte { + enc, err := appController.abi.Pack("globalActiveAppCount") + if err != nil { + panic(err) + } + return enc +} + +// TryPackGlobalActiveAppCount is the Go binding used to pack the parameters required for calling +// the contract method with ID 0xa8aa2bd3. This method will return an error +// if any inputs are invalid/nil. +// +// Solidity: function globalActiveAppCount() view returns(uint32) +func (appController *AppController) TryPackGlobalActiveAppCount() ([]byte, error) { + return appController.abi.Pack("globalActiveAppCount") +} + +// UnpackGlobalActiveAppCount is the Go binding that unpacks the parameters returned +// from invoking the contract method with ID 0xa8aa2bd3. +// +// Solidity: function globalActiveAppCount() view returns(uint32) +func (appController *AppController) UnpackGlobalActiveAppCount(data []byte) (uint32, error) { + out, err := appController.abi.Unpack("globalActiveAppCount", data) + if err != nil { + return *new(uint32), err + } + out0 := *abi.ConvertType(out[0], new(uint32)).(*uint32) + return out0, nil +} + +// PackGrantRole is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x2f2ff15d. This method will panic if any +// invalid/nil inputs are passed. +// +// Solidity: function grantRole(bytes32 role, address account) returns() +func (appController *AppController) PackGrantRole(role [32]byte, account common.Address) []byte { + enc, err := appController.abi.Pack("grantRole", role, account) + if err != nil { + panic(err) + } + return enc +} + +// TryPackGrantRole is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x2f2ff15d. This method will return an error +// if any inputs are invalid/nil. +// +// Solidity: function grantRole(bytes32 role, address account) returns() +func (appController *AppController) TryPackGrantRole(role [32]byte, account common.Address) ([]byte, error) { + return appController.abi.Pack("grantRole", role, account) +} + +// PackGrantTeamRole is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x58f2c536. This method will panic if any +// invalid/nil inputs are passed. +// +// Solidity: function grantTeamRole(address team, uint8 role, address account) returns() +func (appController *AppController) PackGrantTeamRole(team common.Address, role uint8, account common.Address) []byte { + enc, err := appController.abi.Pack("grantTeamRole", team, role, account) + if err != nil { + panic(err) + } + return enc +} + +// TryPackGrantTeamRole is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x58f2c536. This method will return an error +// if any inputs are invalid/nil. +// +// Solidity: function grantTeamRole(address team, uint8 role, address account) returns() +func (appController *AppController) TryPackGrantTeamRole(team common.Address, role uint8, account common.Address) ([]byte, error) { + return appController.abi.Pack("grantTeamRole", team, role, account) +} + +// PackHasRole is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x91d14854. This method will panic if any +// invalid/nil inputs are passed. +// +// Solidity: function hasRole(bytes32 role, address account) view returns(bool) +func (appController *AppController) PackHasRole(role [32]byte, account common.Address) []byte { + enc, err := appController.abi.Pack("hasRole", role, account) + if err != nil { + panic(err) + } + return enc +} + +// TryPackHasRole is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x91d14854. This method will return an error +// if any inputs are invalid/nil. +// +// Solidity: function hasRole(bytes32 role, address account) view returns(bool) +func (appController *AppController) TryPackHasRole(role [32]byte, account common.Address) ([]byte, error) { + return appController.abi.Pack("hasRole", role, account) +} + +// UnpackHasRole is the Go binding that unpacks the parameters returned +// from invoking the contract method with ID 0x91d14854. +// +// Solidity: function hasRole(bytes32 role, address account) view returns(bool) +func (appController *AppController) UnpackHasRole(data []byte) (bool, error) { + out, err := appController.abi.Unpack("hasRole", data) + if err != nil { + return *new(bool), err + } + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + return out0, nil +} + +// PackHasTeamRole is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x54bfb170. This method will panic if any +// invalid/nil inputs are passed. +// +// Solidity: function hasTeamRole(address team, uint8 role, address account) view returns(bool) +func (appController *AppController) PackHasTeamRole(team common.Address, role uint8, account common.Address) []byte { + enc, err := appController.abi.Pack("hasTeamRole", team, role, account) + if err != nil { + panic(err) + } + return enc +} + +// TryPackHasTeamRole is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x54bfb170. This method will return an error +// if any inputs are invalid/nil. +// +// Solidity: function hasTeamRole(address team, uint8 role, address account) view returns(bool) +func (appController *AppController) TryPackHasTeamRole(team common.Address, role uint8, account common.Address) ([]byte, error) { + return appController.abi.Pack("hasTeamRole", team, role, account) +} + +// UnpackHasTeamRole is the Go binding that unpacks the parameters returned +// from invoking the contract method with ID 0x54bfb170. +// +// Solidity: function hasTeamRole(address team, uint8 role, address account) view returns(bool) +func (appController *AppController) UnpackHasTeamRole(data []byte) (bool, error) { + out, err := appController.abi.Unpack("hasTeamRole", data) + if err != nil { + return *new(bool), err + } + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + return out0, nil +} + +// PackInitialize is the Go binding used to pack the parameters required for calling +// the contract method with ID 0xc4d66de8. This method will panic if any +// invalid/nil inputs are passed. +// +// Solidity: function initialize(address admin) returns() +func (appController *AppController) PackInitialize(admin common.Address) []byte { + enc, err := appController.abi.Pack("initialize", admin) + if err != nil { + panic(err) + } + return enc +} + +// TryPackInitialize is the Go binding used to pack the parameters required for calling +// the contract method with ID 0xc4d66de8. This method will return an error +// if any inputs are invalid/nil. +// +// Solidity: function initialize(address admin) returns() +func (appController *AppController) TryPackInitialize(admin common.Address) ([]byte, error) { + return appController.abi.Pack("initialize", admin) +} + +// PackMaxGlobalActiveApps is the Go binding used to pack the parameters required for calling +// the contract method with ID 0xa46530a2. This method will panic if any +// invalid/nil inputs are passed. +// +// Solidity: function maxGlobalActiveApps() view returns(uint32) +func (appController *AppController) PackMaxGlobalActiveApps() []byte { + enc, err := appController.abi.Pack("maxGlobalActiveApps") + if err != nil { + panic(err) + } + return enc +} + +// TryPackMaxGlobalActiveApps is the Go binding used to pack the parameters required for calling +// the contract method with ID 0xa46530a2. This method will return an error +// if any inputs are invalid/nil. +// +// Solidity: function maxGlobalActiveApps() view returns(uint32) +func (appController *AppController) TryPackMaxGlobalActiveApps() ([]byte, error) { + return appController.abi.Pack("maxGlobalActiveApps") +} + +// UnpackMaxGlobalActiveApps is the Go binding that unpacks the parameters returned +// from invoking the contract method with ID 0xa46530a2. +// +// Solidity: function maxGlobalActiveApps() view returns(uint32) +func (appController *AppController) UnpackMaxGlobalActiveApps(data []byte) (uint32, error) { + out, err := appController.abi.Unpack("maxGlobalActiveApps", data) + if err != nil { + return *new(uint32), err + } + out0 := *abi.ConvertType(out[0], new(uint32)).(*uint32) + return out0, nil +} + +// PackMigrateAdmins is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x00b73d4c. This method will panic if any +// invalid/nil inputs are passed. +// +// Solidity: function migrateAdmins(address[] apps) returns() +func (appController *AppController) PackMigrateAdmins(apps []common.Address) []byte { + enc, err := appController.abi.Pack("migrateAdmins", apps) + if err != nil { + panic(err) + } + return enc +} + +// TryPackMigrateAdmins is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x00b73d4c. This method will return an error +// if any inputs are invalid/nil. +// +// Solidity: function migrateAdmins(address[] apps) returns() +func (appController *AppController) TryPackMigrateAdmins(apps []common.Address) ([]byte, error) { + return appController.abi.Pack("migrateAdmins", apps) +} + +// PackPermissionController is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x4657e26a. This method will panic if any +// invalid/nil inputs are passed. +// +// Solidity: function permissionController() view returns(address) +func (appController *AppController) PackPermissionController() []byte { + enc, err := appController.abi.Pack("permissionController") + if err != nil { + panic(err) + } + return enc +} + +// TryPackPermissionController is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x4657e26a. This method will return an error +// if any inputs are invalid/nil. +// +// Solidity: function permissionController() view returns(address) +func (appController *AppController) TryPackPermissionController() ([]byte, error) { + return appController.abi.Pack("permissionController") +} + +// UnpackPermissionController is the Go binding that unpacks the parameters returned +// from invoking the contract method with ID 0x4657e26a. +// +// Solidity: function permissionController() view returns(address) +func (appController *AppController) UnpackPermissionController(data []byte) (common.Address, error) { + out, err := appController.abi.Unpack("permissionController", data) + if err != nil { + return *new(common.Address), err + } + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + return out0, nil +} + +// PackReleaseManager is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x0d78573e. This method will panic if any +// invalid/nil inputs are passed. +// +// Solidity: function releaseManager() view returns(address) +func (appController *AppController) PackReleaseManager() []byte { + enc, err := appController.abi.Pack("releaseManager") + if err != nil { + panic(err) + } + return enc +} + +// TryPackReleaseManager is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x0d78573e. This method will return an error +// if any inputs are invalid/nil. +// +// Solidity: function releaseManager() view returns(address) +func (appController *AppController) TryPackReleaseManager() ([]byte, error) { + return appController.abi.Pack("releaseManager") +} + +// UnpackReleaseManager is the Go binding that unpacks the parameters returned +// from invoking the contract method with ID 0x0d78573e. +// +// Solidity: function releaseManager() view returns(address) +func (appController *AppController) UnpackReleaseManager(data []byte) (common.Address, error) { + out, err := appController.abi.Unpack("releaseManager", data) + if err != nil { + return *new(common.Address), err + } + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + return out0, nil +} + +// PackRenounceRole is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x36568abe. This method will panic if any +// invalid/nil inputs are passed. +// +// Solidity: function renounceRole(bytes32 role, address account) returns() +func (appController *AppController) PackRenounceRole(role [32]byte, account common.Address) []byte { + enc, err := appController.abi.Pack("renounceRole", role, account) + if err != nil { + panic(err) + } + return enc +} + +// TryPackRenounceRole is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x36568abe. This method will return an error +// if any inputs are invalid/nil. +// +// Solidity: function renounceRole(bytes32 role, address account) returns() +func (appController *AppController) TryPackRenounceRole(role [32]byte, account common.Address) ([]byte, error) { + return appController.abi.Pack("renounceRole", role, account) +} + +// PackRenounceTeamRole is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x17f4c90b. This method will panic if any +// invalid/nil inputs are passed. +// +// Solidity: function renounceTeamRole(address team, uint8 role) returns() +func (appController *AppController) PackRenounceTeamRole(team common.Address, role uint8) []byte { + enc, err := appController.abi.Pack("renounceTeamRole", team, role) + if err != nil { + panic(err) + } + return enc +} + +// TryPackRenounceTeamRole is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x17f4c90b. This method will return an error +// if any inputs are invalid/nil. +// +// Solidity: function renounceTeamRole(address team, uint8 role) returns() +func (appController *AppController) TryPackRenounceTeamRole(team common.Address, role uint8) ([]byte, error) { + return appController.abi.Pack("renounceTeamRole", team, role) +} + +// PackRevokeRole is the Go binding used to pack the parameters required for calling +// the contract method with ID 0xd547741f. This method will panic if any +// invalid/nil inputs are passed. +// +// Solidity: function revokeRole(bytes32 role, address account) returns() +func (appController *AppController) PackRevokeRole(role [32]byte, account common.Address) []byte { + enc, err := appController.abi.Pack("revokeRole", role, account) + if err != nil { + panic(err) + } + return enc +} + +// TryPackRevokeRole is the Go binding used to pack the parameters required for calling +// the contract method with ID 0xd547741f. This method will return an error +// if any inputs are invalid/nil. +// +// Solidity: function revokeRole(bytes32 role, address account) returns() +func (appController *AppController) TryPackRevokeRole(role [32]byte, account common.Address) ([]byte, error) { + return appController.abi.Pack("revokeRole", role, account) +} + +// PackRevokeTeamRole is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x11b652e2. This method will panic if any +// invalid/nil inputs are passed. +// +// Solidity: function revokeTeamRole(address team, uint8 role, address account) returns() +func (appController *AppController) PackRevokeTeamRole(team common.Address, role uint8, account common.Address) []byte { + enc, err := appController.abi.Pack("revokeTeamRole", team, role, account) + if err != nil { + panic(err) + } + return enc +} + +// TryPackRevokeTeamRole is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x11b652e2. This method will return an error +// if any inputs are invalid/nil. +// +// Solidity: function revokeTeamRole(address team, uint8 role, address account) returns() +func (appController *AppController) TryPackRevokeTeamRole(team common.Address, role uint8, account common.Address) ([]byte, error) { + return appController.abi.Pack("revokeTeamRole", team, role, account) +} + +// PackSafeTimelockFactory is the Go binding used to pack the parameters required for calling +// the contract method with ID 0xa03d2a81. This method will panic if any +// invalid/nil inputs are passed. +// +// Solidity: function safeTimelockFactory() view returns(address) +func (appController *AppController) PackSafeTimelockFactory() []byte { + enc, err := appController.abi.Pack("safeTimelockFactory") + if err != nil { + panic(err) + } + return enc +} + +// TryPackSafeTimelockFactory is the Go binding used to pack the parameters required for calling +// the contract method with ID 0xa03d2a81. This method will return an error +// if any inputs are invalid/nil. +// +// Solidity: function safeTimelockFactory() view returns(address) +func (appController *AppController) TryPackSafeTimelockFactory() ([]byte, error) { + return appController.abi.Pack("safeTimelockFactory") +} + +// UnpackSafeTimelockFactory is the Go binding that unpacks the parameters returned +// from invoking the contract method with ID 0xa03d2a81. +// +// Solidity: function safeTimelockFactory() view returns(address) +func (appController *AppController) UnpackSafeTimelockFactory(data []byte) (common.Address, error) { + out, err := appController.abi.Unpack("safeTimelockFactory", data) + if err != nil { + return *new(common.Address), err + } + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + return out0, nil +} + +// PackScheduleUpgrade is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x890b78c4. This method will panic if any +// invalid/nil inputs are passed. +// +// Solidity: function scheduleUpgrade(address app, (((bytes32,string)[],uint32),bytes,bytes) release, uint256 delay) returns() +func (appController *AppController) PackScheduleUpgrade(app common.Address, release IAppControllerRelease, delay *big.Int) []byte { + enc, err := appController.abi.Pack("scheduleUpgrade", app, release, delay) + if err != nil { + panic(err) + } + return enc +} + +// TryPackScheduleUpgrade is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x890b78c4. This method will return an error +// if any inputs are invalid/nil. +// +// Solidity: function scheduleUpgrade(address app, (((bytes32,string)[],uint32),bytes,bytes) release, uint256 delay) returns() +func (appController *AppController) TryPackScheduleUpgrade(app common.Address, release IAppControllerRelease, delay *big.Int) ([]byte, error) { + return appController.abi.Pack("scheduleUpgrade", app, release, delay) +} + +// PackSetMaxActiveAppsPerUser is the Go binding used to pack the parameters required for calling +// the contract method with ID 0xd49fec2b. This method will panic if any +// invalid/nil inputs are passed. +// +// Solidity: function setMaxActiveAppsPerUser(address user, uint32 limit) returns() +func (appController *AppController) PackSetMaxActiveAppsPerUser(user common.Address, limit uint32) []byte { + enc, err := appController.abi.Pack("setMaxActiveAppsPerUser", user, limit) + if err != nil { + panic(err) + } + return enc +} + +// TryPackSetMaxActiveAppsPerUser is the Go binding used to pack the parameters required for calling +// the contract method with ID 0xd49fec2b. This method will return an error +// if any inputs are invalid/nil. +// +// Solidity: function setMaxActiveAppsPerUser(address user, uint32 limit) returns() +func (appController *AppController) TryPackSetMaxActiveAppsPerUser(user common.Address, limit uint32) ([]byte, error) { + return appController.abi.Pack("setMaxActiveAppsPerUser", user, limit) +} + +// PackSetMaxGlobalActiveApps is the Go binding used to pack the parameters required for calling // the contract method with ID 0xb438c141. This method will panic if any // invalid/nil inputs are passed. // @@ -1110,6 +1698,41 @@ func (appController *AppController) TryPackStopApp(app common.Address) ([]byte, return appController.abi.Pack("stopApp", app) } +// PackSupportsInterface is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x01ffc9a7. This method will panic if any +// invalid/nil inputs are passed. +// +// Solidity: function supportsInterface(bytes4 interfaceId) view returns(bool) +func (appController *AppController) PackSupportsInterface(interfaceId [4]byte) []byte { + enc, err := appController.abi.Pack("supportsInterface", interfaceId) + if err != nil { + panic(err) + } + return enc +} + +// TryPackSupportsInterface is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x01ffc9a7. This method will return an error +// if any inputs are invalid/nil. +// +// Solidity: function supportsInterface(bytes4 interfaceId) view returns(bool) +func (appController *AppController) TryPackSupportsInterface(interfaceId [4]byte) ([]byte, error) { + return appController.abi.Pack("supportsInterface", interfaceId) +} + +// UnpackSupportsInterface is the Go binding that unpacks the parameters returned +// from invoking the contract method with ID 0x01ffc9a7. +// +// Solidity: function supportsInterface(bytes4 interfaceId) view returns(bool) +func (appController *AppController) UnpackSupportsInterface(data []byte) (bool, error) { + out, err := appController.abi.Unpack("supportsInterface", data) + if err != nil { + return *new(bool), err + } + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + return out0, nil +} + // PackSuspend is the Go binding used to pack the parameters required for calling // the contract method with ID 0xcb1e6ff7. This method will panic if any // invalid/nil inputs are passed. @@ -1176,6 +1799,28 @@ func (appController *AppController) TryPackTerminateAppByAdmin(app common.Addres return appController.abi.Pack("terminateAppByAdmin", app) } +// PackTransferOwnership is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x6d435421. This method will panic if any +// invalid/nil inputs are passed. +// +// Solidity: function transferOwnership(address app, address newOwner) returns() +func (appController *AppController) PackTransferOwnership(app common.Address, newOwner common.Address) []byte { + enc, err := appController.abi.Pack("transferOwnership", app, newOwner) + if err != nil { + panic(err) + } + return enc +} + +// TryPackTransferOwnership is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x6d435421. This method will return an error +// if any inputs are invalid/nil. +// +// Solidity: function transferOwnership(address app, address newOwner) returns() +func (appController *AppController) TryPackTransferOwnership(app common.Address, newOwner common.Address) ([]byte, error) { + return appController.abi.Pack("transferOwnership", app, newOwner) +} + // PackUpdateAppMetadataURI is the Go binding used to pack the parameters required for calling // the contract method with ID 0x65aa9a65. This method will panic if any // invalid/nil inputs are passed. @@ -1270,7 +1915,7 @@ func (appController *AppController) UnpackVersion(data []byte) (string, error) { // AppControllerAppCreated represents a AppCreated event raised by the AppController contract. type AppControllerAppCreated struct { - Creator common.Address + Owner common.Address App common.Address OperatorSetId uint32 Raw *types.Log // Blockchain specific contextual infos @@ -1286,13 +1931,55 @@ func (AppControllerAppCreated) ContractEventName() string { // UnpackAppCreatedEvent is the Go binding that unpacks the event data emitted // by contract. // -// Solidity: event AppCreated(address indexed creator, address indexed app, uint32 operatorSetId) -func (appController *AppController) UnpackAppCreatedEvent(log *types.Log) (*AppControllerAppCreated, error) { - event := "AppCreated" +// Solidity: event AppCreated(address indexed owner, address indexed app, uint32 operatorSetId) +func (appController *AppController) UnpackAppCreatedEvent(log *types.Log) (*AppControllerAppCreated, error) { + event := "AppCreated" + if len(log.Topics) == 0 || log.Topics[0] != appController.abi.Events[event].ID { + return nil, errors.New("event signature mismatch") + } + out := new(AppControllerAppCreated) + if len(log.Data) > 0 { + if err := appController.abi.UnpackIntoInterface(out, event, log.Data); err != nil { + return nil, err + } + } + var indexed abi.Arguments + for _, arg := range appController.abi.Events[event].Inputs { + if arg.Indexed { + indexed = append(indexed, arg) + } + } + if err := abi.ParseTopics(out, indexed, log.Topics[1:]); err != nil { + return nil, err + } + out.Raw = log + return out, nil +} + +// AppControllerAppMetadataURIUpdated represents a AppMetadataURIUpdated event raised by the AppController contract. +type AppControllerAppMetadataURIUpdated struct { + App common.Address + MetadataURI string + Raw *types.Log // Blockchain specific contextual infos +} + +const AppControllerAppMetadataURIUpdatedEventName = "AppMetadataURIUpdated" + +// ContractEventName returns the user-defined event name. +func (AppControllerAppMetadataURIUpdated) ContractEventName() string { + return AppControllerAppMetadataURIUpdatedEventName +} + +// UnpackAppMetadataURIUpdatedEvent is the Go binding that unpacks the event data emitted +// by contract. +// +// Solidity: event AppMetadataURIUpdated(address indexed app, string metadataURI) +func (appController *AppController) UnpackAppMetadataURIUpdatedEvent(log *types.Log) (*AppControllerAppMetadataURIUpdated, error) { + event := "AppMetadataURIUpdated" if len(log.Topics) == 0 || log.Topics[0] != appController.abi.Events[event].ID { return nil, errors.New("event signature mismatch") } - out := new(AppControllerAppCreated) + out := new(AppControllerAppMetadataURIUpdated) if len(log.Data) > 0 { if err := appController.abi.UnpackIntoInterface(out, event, log.Data); err != nil { return nil, err @@ -1311,30 +1998,31 @@ func (appController *AppController) UnpackAppCreatedEvent(log *types.Log) (*AppC return out, nil } -// AppControllerAppMetadataURIUpdated represents a AppMetadataURIUpdated event raised by the AppController contract. -type AppControllerAppMetadataURIUpdated struct { - App common.Address - MetadataURI string - Raw *types.Log // Blockchain specific contextual infos +// AppControllerAppOwnershipTransferred represents a AppOwnershipTransferred event raised by the AppController contract. +type AppControllerAppOwnershipTransferred struct { + App common.Address + PreviousOwner common.Address + NewOwner common.Address + Raw *types.Log // Blockchain specific contextual infos } -const AppControllerAppMetadataURIUpdatedEventName = "AppMetadataURIUpdated" +const AppControllerAppOwnershipTransferredEventName = "AppOwnershipTransferred" // ContractEventName returns the user-defined event name. -func (AppControllerAppMetadataURIUpdated) ContractEventName() string { - return AppControllerAppMetadataURIUpdatedEventName +func (AppControllerAppOwnershipTransferred) ContractEventName() string { + return AppControllerAppOwnershipTransferredEventName } -// UnpackAppMetadataURIUpdatedEvent is the Go binding that unpacks the event data emitted +// UnpackAppOwnershipTransferredEvent is the Go binding that unpacks the event data emitted // by contract. // -// Solidity: event AppMetadataURIUpdated(address indexed app, string metadataURI) -func (appController *AppController) UnpackAppMetadataURIUpdatedEvent(log *types.Log) (*AppControllerAppMetadataURIUpdated, error) { - event := "AppMetadataURIUpdated" +// Solidity: event AppOwnershipTransferred(address indexed app, address indexed previousOwner, address indexed newOwner) +func (appController *AppController) UnpackAppOwnershipTransferredEvent(log *types.Log) (*AppControllerAppOwnershipTransferred, error) { + event := "AppOwnershipTransferred" if len(log.Topics) == 0 || log.Topics[0] != appController.abi.Events[event].ID { return nil, errors.New("event signature mismatch") } - out := new(AppControllerAppMetadataURIUpdated) + out := new(AppControllerAppOwnershipTransferred) if len(log.Data) > 0 { if err := appController.abi.UnpackIntoInterface(out, event, log.Data); err != nil { return nil, err @@ -1558,6 +2246,90 @@ func (appController *AppController) UnpackAppTerminatedByAdminEvent(log *types.L return out, nil } +// AppControllerAppUpgradeCancelled represents a AppUpgradeCancelled event raised by the AppController contract. +type AppControllerAppUpgradeCancelled struct { + App common.Address + Raw *types.Log // Blockchain specific contextual infos +} + +const AppControllerAppUpgradeCancelledEventName = "AppUpgradeCancelled" + +// ContractEventName returns the user-defined event name. +func (AppControllerAppUpgradeCancelled) ContractEventName() string { + return AppControllerAppUpgradeCancelledEventName +} + +// UnpackAppUpgradeCancelledEvent is the Go binding that unpacks the event data emitted +// by contract. +// +// Solidity: event AppUpgradeCancelled(address indexed app) +func (appController *AppController) UnpackAppUpgradeCancelledEvent(log *types.Log) (*AppControllerAppUpgradeCancelled, error) { + event := "AppUpgradeCancelled" + if len(log.Topics) == 0 || log.Topics[0] != appController.abi.Events[event].ID { + return nil, errors.New("event signature mismatch") + } + out := new(AppControllerAppUpgradeCancelled) + if len(log.Data) > 0 { + if err := appController.abi.UnpackIntoInterface(out, event, log.Data); err != nil { + return nil, err + } + } + var indexed abi.Arguments + for _, arg := range appController.abi.Events[event].Inputs { + if arg.Indexed { + indexed = append(indexed, arg) + } + } + if err := abi.ParseTopics(out, indexed, log.Topics[1:]); err != nil { + return nil, err + } + out.Raw = log + return out, nil +} + +// AppControllerAppUpgradeScheduled represents a AppUpgradeScheduled event raised by the AppController contract. +type AppControllerAppUpgradeScheduled struct { + App common.Address + ReadyAt *big.Int + Release IAppControllerRelease + Raw *types.Log // Blockchain specific contextual infos +} + +const AppControllerAppUpgradeScheduledEventName = "AppUpgradeScheduled" + +// ContractEventName returns the user-defined event name. +func (AppControllerAppUpgradeScheduled) ContractEventName() string { + return AppControllerAppUpgradeScheduledEventName +} + +// UnpackAppUpgradeScheduledEvent is the Go binding that unpacks the event data emitted +// by contract. +// +// Solidity: event AppUpgradeScheduled(address indexed app, uint256 readyAt, (((bytes32,string)[],uint32),bytes,bytes) release) +func (appController *AppController) UnpackAppUpgradeScheduledEvent(log *types.Log) (*AppControllerAppUpgradeScheduled, error) { + event := "AppUpgradeScheduled" + if len(log.Topics) == 0 || log.Topics[0] != appController.abi.Events[event].ID { + return nil, errors.New("event signature mismatch") + } + out := new(AppControllerAppUpgradeScheduled) + if len(log.Data) > 0 { + if err := appController.abi.UnpackIntoInterface(out, event, log.Data); err != nil { + return nil, err + } + } + var indexed abi.Arguments + for _, arg := range appController.abi.Events[event].Inputs { + if arg.Indexed { + indexed = append(indexed, arg) + } + } + if err := abi.ParseTopics(out, indexed, log.Topics[1:]); err != nil { + return nil, err + } + out.Raw = log + return out, nil +} + // AppControllerAppUpgraded represents a AppUpgraded event raised by the AppController contract. type AppControllerAppUpgraded struct { App common.Address @@ -1725,6 +2497,135 @@ func (appController *AppController) UnpackMaxActiveAppsSetEvent(log *types.Log) return out, nil } +// AppControllerRoleAdminChanged represents a RoleAdminChanged event raised by the AppController contract. +type AppControllerRoleAdminChanged struct { + Role [32]byte + PreviousAdminRole [32]byte + NewAdminRole [32]byte + Raw *types.Log // Blockchain specific contextual infos +} + +const AppControllerRoleAdminChangedEventName = "RoleAdminChanged" + +// ContractEventName returns the user-defined event name. +func (AppControllerRoleAdminChanged) ContractEventName() string { + return AppControllerRoleAdminChangedEventName +} + +// UnpackRoleAdminChangedEvent is the Go binding that unpacks the event data emitted +// by contract. +// +// Solidity: event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole) +func (appController *AppController) UnpackRoleAdminChangedEvent(log *types.Log) (*AppControllerRoleAdminChanged, error) { + event := "RoleAdminChanged" + if len(log.Topics) == 0 || log.Topics[0] != appController.abi.Events[event].ID { + return nil, errors.New("event signature mismatch") + } + out := new(AppControllerRoleAdminChanged) + if len(log.Data) > 0 { + if err := appController.abi.UnpackIntoInterface(out, event, log.Data); err != nil { + return nil, err + } + } + var indexed abi.Arguments + for _, arg := range appController.abi.Events[event].Inputs { + if arg.Indexed { + indexed = append(indexed, arg) + } + } + if err := abi.ParseTopics(out, indexed, log.Topics[1:]); err != nil { + return nil, err + } + out.Raw = log + return out, nil +} + +// AppControllerRoleGranted represents a RoleGranted event raised by the AppController contract. +type AppControllerRoleGranted struct { + Role [32]byte + Account common.Address + Sender common.Address + Raw *types.Log // Blockchain specific contextual infos +} + +const AppControllerRoleGrantedEventName = "RoleGranted" + +// ContractEventName returns the user-defined event name. +func (AppControllerRoleGranted) ContractEventName() string { + return AppControllerRoleGrantedEventName +} + +// UnpackRoleGrantedEvent is the Go binding that unpacks the event data emitted +// by contract. +// +// Solidity: event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender) +func (appController *AppController) UnpackRoleGrantedEvent(log *types.Log) (*AppControllerRoleGranted, error) { + event := "RoleGranted" + if len(log.Topics) == 0 || log.Topics[0] != appController.abi.Events[event].ID { + return nil, errors.New("event signature mismatch") + } + out := new(AppControllerRoleGranted) + if len(log.Data) > 0 { + if err := appController.abi.UnpackIntoInterface(out, event, log.Data); err != nil { + return nil, err + } + } + var indexed abi.Arguments + for _, arg := range appController.abi.Events[event].Inputs { + if arg.Indexed { + indexed = append(indexed, arg) + } + } + if err := abi.ParseTopics(out, indexed, log.Topics[1:]); err != nil { + return nil, err + } + out.Raw = log + return out, nil +} + +// AppControllerRoleRevoked represents a RoleRevoked event raised by the AppController contract. +type AppControllerRoleRevoked struct { + Role [32]byte + Account common.Address + Sender common.Address + Raw *types.Log // Blockchain specific contextual infos +} + +const AppControllerRoleRevokedEventName = "RoleRevoked" + +// ContractEventName returns the user-defined event name. +func (AppControllerRoleRevoked) ContractEventName() string { + return AppControllerRoleRevokedEventName +} + +// UnpackRoleRevokedEvent is the Go binding that unpacks the event data emitted +// by contract. +// +// Solidity: event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender) +func (appController *AppController) UnpackRoleRevokedEvent(log *types.Log) (*AppControllerRoleRevoked, error) { + event := "RoleRevoked" + if len(log.Topics) == 0 || log.Topics[0] != appController.abi.Events[event].ID { + return nil, errors.New("event signature mismatch") + } + out := new(AppControllerRoleRevoked) + if len(log.Data) > 0 { + if err := appController.abi.UnpackIntoInterface(out, event, log.Data); err != nil { + return nil, err + } + } + var indexed abi.Arguments + for _, arg := range appController.abi.Events[event].Inputs { + if arg.Indexed { + indexed = append(indexed, arg) + } + } + if err := abi.ParseTopics(out, indexed, log.Topics[1:]); err != nil { + return nil, err + } + out.Raw = log + return out, nil +} + // UnpackError attempts to decode the provided error data using user-defined // error definitions. func (appController *AppController) UnpackError(raw []byte) (any, error) { @@ -1737,6 +2638,9 @@ func (appController *AppController) UnpackError(raw []byte) (any, error) { if bytes.Equal(raw[:4], appController.abi.Errors["AppDoesNotExist"].ID.Bytes()[:4]) { return appController.UnpackAppDoesNotExistError(raw[4:]) } + if bytes.Equal(raw[:4], appController.abi.Errors["CannotRevokeLastAdmin"].ID.Bytes()[:4]) { + return appController.UnpackCannotRevokeLastAdminError(raw[4:]) + } if bytes.Equal(raw[:4], appController.abi.Errors["GlobalMaxActiveAppsExceeded"].ID.Bytes()[:4]) { return appController.UnpackGlobalMaxActiveAppsExceededError(raw[4:]) } @@ -1761,12 +2665,27 @@ func (appController *AppController) UnpackError(raw []byte) (any, error) { if bytes.Equal(raw[:4], appController.abi.Errors["MoreThanOneArtifact"].ID.Bytes()[:4]) { return appController.UnpackMoreThanOneArtifactError(raw[4:]) } + if bytes.Equal(raw[:4], appController.abi.Errors["NoScheduledUpgrade"].ID.Bytes()[:4]) { + return appController.UnpackNoScheduledUpgradeError(raw[4:]) + } + if bytes.Equal(raw[:4], appController.abi.Errors["NotTimelocked"].ID.Bytes()[:4]) { + return appController.UnpackNotTimelockedError(raw[4:]) + } + if bytes.Equal(raw[:4], appController.abi.Errors["ReleaseMismatch"].ID.Bytes()[:4]) { + return appController.UnpackReleaseMismatchError(raw[4:]) + } if bytes.Equal(raw[:4], appController.abi.Errors["SignatureExpired"].ID.Bytes()[:4]) { return appController.UnpackSignatureExpiredError(raw[4:]) } if bytes.Equal(raw[:4], appController.abi.Errors["StringTooLong"].ID.Bytes()[:4]) { return appController.UnpackStringTooLongError(raw[4:]) } + if bytes.Equal(raw[:4], appController.abi.Errors["TimelockRequired"].ID.Bytes()[:4]) { + return appController.UnpackTimelockRequiredError(raw[4:]) + } + if bytes.Equal(raw[:4], appController.abi.Errors["UpgradeNotReady"].ID.Bytes()[:4]) { + return appController.UnpackUpgradeNotReadyError(raw[4:]) + } return nil, errors.New("Unknown error") } @@ -1839,6 +2758,29 @@ func (appController *AppController) UnpackAppDoesNotExistError(raw []byte) (*App return out, nil } +// AppControllerCannotRevokeLastAdmin represents a CannotRevokeLastAdmin error raised by the AppController contract. +type AppControllerCannotRevokeLastAdmin struct { +} + +// ErrorID returns the hash of canonical representation of the error's signature. +// +// Solidity: error CannotRevokeLastAdmin() +func AppControllerCannotRevokeLastAdminErrorID() common.Hash { + return common.HexToHash("0x7b3c5626cbfd5fdcf52b63e673866e76bff45fc309aa6b0de7826cd85e9ec325") +} + +// UnpackCannotRevokeLastAdminError is the Go binding used to decode the provided +// error data into the corresponding Go error struct. +// +// Solidity: error CannotRevokeLastAdmin() +func (appController *AppController) UnpackCannotRevokeLastAdminError(raw []byte) (*AppControllerCannotRevokeLastAdmin, error) { + out := new(AppControllerCannotRevokeLastAdmin) + if err := appController.abi.UnpackIntoInterface(out, "CannotRevokeLastAdmin", raw); err != nil { + return nil, err + } + return out, nil +} + // AppControllerGlobalMaxActiveAppsExceeded represents a GlobalMaxActiveAppsExceeded error raised by the AppController contract. type AppControllerGlobalMaxActiveAppsExceeded struct { } @@ -2023,6 +2965,75 @@ func (appController *AppController) UnpackMoreThanOneArtifactError(raw []byte) ( return out, nil } +// AppControllerNoScheduledUpgrade represents a NoScheduledUpgrade error raised by the AppController contract. +type AppControllerNoScheduledUpgrade struct { +} + +// ErrorID returns the hash of canonical representation of the error's signature. +// +// Solidity: error NoScheduledUpgrade() +func AppControllerNoScheduledUpgradeErrorID() common.Hash { + return common.HexToHash("0xf120d0577a0f198a031035e639c713acc3097f93edd4a78271b856a126688a45") +} + +// UnpackNoScheduledUpgradeError is the Go binding used to decode the provided +// error data into the corresponding Go error struct. +// +// Solidity: error NoScheduledUpgrade() +func (appController *AppController) UnpackNoScheduledUpgradeError(raw []byte) (*AppControllerNoScheduledUpgrade, error) { + out := new(AppControllerNoScheduledUpgrade) + if err := appController.abi.UnpackIntoInterface(out, "NoScheduledUpgrade", raw); err != nil { + return nil, err + } + return out, nil +} + +// AppControllerNotTimelocked represents a NotTimelocked error raised by the AppController contract. +type AppControllerNotTimelocked struct { +} + +// ErrorID returns the hash of canonical representation of the error's signature. +// +// Solidity: error NotTimelocked() +func AppControllerNotTimelockedErrorID() common.Hash { + return common.HexToHash("0xb48b74db2c828a88a77710e47b80a5e7906b02e8be9cba32ca36252d00e2df7b") +} + +// UnpackNotTimelockedError is the Go binding used to decode the provided +// error data into the corresponding Go error struct. +// +// Solidity: error NotTimelocked() +func (appController *AppController) UnpackNotTimelockedError(raw []byte) (*AppControllerNotTimelocked, error) { + out := new(AppControllerNotTimelocked) + if err := appController.abi.UnpackIntoInterface(out, "NotTimelocked", raw); err != nil { + return nil, err + } + return out, nil +} + +// AppControllerReleaseMismatch represents a ReleaseMismatch error raised by the AppController contract. +type AppControllerReleaseMismatch struct { +} + +// ErrorID returns the hash of canonical representation of the error's signature. +// +// Solidity: error ReleaseMismatch() +func AppControllerReleaseMismatchErrorID() common.Hash { + return common.HexToHash("0x7e12f55f1c6d381c7259212a0db1adb04659234404021ffa440ec07c33c43269") +} + +// UnpackReleaseMismatchError is the Go binding used to decode the provided +// error data into the corresponding Go error struct. +// +// Solidity: error ReleaseMismatch() +func (appController *AppController) UnpackReleaseMismatchError(raw []byte) (*AppControllerReleaseMismatch, error) { + out := new(AppControllerReleaseMismatch) + if err := appController.abi.UnpackIntoInterface(out, "ReleaseMismatch", raw); err != nil { + return nil, err + } + return out, nil +} + // AppControllerSignatureExpired represents a SignatureExpired error raised by the AppController contract. type AppControllerSignatureExpired struct { } @@ -2069,3 +3080,49 @@ func (appController *AppController) UnpackStringTooLongError(raw []byte) (*AppCo } return out, nil } + +// AppControllerTimelockRequired represents a TimelockRequired error raised by the AppController contract. +type AppControllerTimelockRequired struct { +} + +// ErrorID returns the hash of canonical representation of the error's signature. +// +// Solidity: error TimelockRequired() +func AppControllerTimelockRequiredErrorID() common.Hash { + return common.HexToHash("0x99f26d5ba7d7b6eab4548ad1e80ab2f619d640fccce0209554cf0266178e110b") +} + +// UnpackTimelockRequiredError is the Go binding used to decode the provided +// error data into the corresponding Go error struct. +// +// Solidity: error TimelockRequired() +func (appController *AppController) UnpackTimelockRequiredError(raw []byte) (*AppControllerTimelockRequired, error) { + out := new(AppControllerTimelockRequired) + if err := appController.abi.UnpackIntoInterface(out, "TimelockRequired", raw); err != nil { + return nil, err + } + return out, nil +} + +// AppControllerUpgradeNotReady represents a UpgradeNotReady error raised by the AppController contract. +type AppControllerUpgradeNotReady struct { +} + +// ErrorID returns the hash of canonical representation of the error's signature. +// +// Solidity: error UpgradeNotReady() +func AppControllerUpgradeNotReadyErrorID() common.Hash { + return common.HexToHash("0x1bada80216aface91d6a430ccf87bb5350f653443d8c6fadbd883d765d28e31f") +} + +// UnpackUpgradeNotReadyError is the Go binding used to decode the provided +// error data into the corresponding Go error struct. +// +// Solidity: error UpgradeNotReady() +func (appController *AppController) UnpackUpgradeNotReadyError(raw []byte) (*AppControllerUpgradeNotReady, error) { + out := new(AppControllerUpgradeNotReady) + if err := appController.abi.UnpackIntoInterface(out, "UpgradeNotReady", raw); err != nil { + return nil, err + } + return out, nil +} diff --git a/pkg/bindings/v2/SafeTimelockFactory/binding.go b/pkg/bindings/v2/SafeTimelockFactory/binding.go new file mode 100644 index 0000000..6558f9d --- /dev/null +++ b/pkg/bindings/v2/SafeTimelockFactory/binding.go @@ -0,0 +1,690 @@ +// Code generated via abigen V2 - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package SafeTimelockFactory + +import ( + "bytes" + "errors" + "math/big" + + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind/v2" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = bytes.Equal + _ = errors.New + _ = big.NewInt + _ = common.Big1 + _ = types.BloomLookup + _ = abi.ConvertType +) + +// ISafeTimelockFactorySafeConfig is an auto generated low-level Go binding around an user-defined struct. +type ISafeTimelockFactorySafeConfig struct { + Owners []common.Address + Threshold *big.Int +} + +// ISafeTimelockFactoryTimelockConfig is an auto generated low-level Go binding around an user-defined struct. +type ISafeTimelockFactoryTimelockConfig struct { + MinDelay *big.Int + Proposers []common.Address + Executors []common.Address +} + +// SafeTimelockFactoryMetaData contains all meta data concerning the SafeTimelockFactory contract. +var SafeTimelockFactoryMetaData = bind.MetaData{ + ABI: "[{\"type\":\"constructor\",\"inputs\":[{\"name\":\"_safeSingleton\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_safeProxyFactory\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_safeFallbackHandler\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_timelockImplementation\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"calculateSafeAddress\",\"inputs\":[{\"name\":\"deployer\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"config\",\"type\":\"tuple\",\"internalType\":\"structISafeTimelockFactory.SafeConfig\",\"components\":[{\"name\":\"owners\",\"type\":\"address[]\",\"internalType\":\"address[]\"},{\"name\":\"threshold\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]},{\"name\":\"salt\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"calculateTimelockAddress\",\"inputs\":[{\"name\":\"deployer\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"salt\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"deploySafe\",\"inputs\":[{\"name\":\"config\",\"type\":\"tuple\",\"internalType\":\"structISafeTimelockFactory.SafeConfig\",\"components\":[{\"name\":\"owners\",\"type\":\"address[]\",\"internalType\":\"address[]\"},{\"name\":\"threshold\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]},{\"name\":\"salt\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"safe\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"deployTimelock\",\"inputs\":[{\"name\":\"config\",\"type\":\"tuple\",\"internalType\":\"structISafeTimelockFactory.TimelockConfig\",\"components\":[{\"name\":\"minDelay\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"proposers\",\"type\":\"address[]\",\"internalType\":\"address[]\"},{\"name\":\"executors\",\"type\":\"address[]\",\"internalType\":\"address[]\"}]},{\"name\":\"salt\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"timelock\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"initialize\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"isSafe\",\"inputs\":[{\"name\":\"safe\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"isTimelock\",\"inputs\":[{\"name\":\"timelock\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"safeFallbackHandler\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"safeProxyFactory\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"safeSingleton\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"timelockImplementation\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"event\",\"name\":\"Initialized\",\"inputs\":[{\"name\":\"version\",\"type\":\"uint8\",\"indexed\":false,\"internalType\":\"uint8\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"SafeDeployed\",\"inputs\":[{\"name\":\"deployer\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"safe\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"owners\",\"type\":\"address[]\",\"indexed\":false,\"internalType\":\"address[]\"},{\"name\":\"threshold\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"salt\",\"type\":\"bytes32\",\"indexed\":false,\"internalType\":\"bytes32\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"TimelockDeployed\",\"inputs\":[{\"name\":\"deployer\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"timelock\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"minDelay\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"proposers\",\"type\":\"address[]\",\"indexed\":false,\"internalType\":\"address[]\"},{\"name\":\"executors\",\"type\":\"address[]\",\"indexed\":false,\"internalType\":\"address[]\"},{\"name\":\"salt\",\"type\":\"bytes32\",\"indexed\":false,\"internalType\":\"bytes32\"}],\"anonymous\":false},{\"type\":\"error\",\"name\":\"NoExecutors\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"NoProposers\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"ZeroAddressExecutor\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"ZeroAddressProposer\",\"inputs\":[]}]", + ID: "SafeTimelockFactory", +} + +// SafeTimelockFactory is an auto generated Go binding around an Ethereum contract. +type SafeTimelockFactory struct { + abi abi.ABI +} + +// NewSafeTimelockFactory creates a new instance of SafeTimelockFactory. +func NewSafeTimelockFactory() *SafeTimelockFactory { + parsed, err := SafeTimelockFactoryMetaData.ParseABI() + if err != nil { + panic(errors.New("invalid ABI: " + err.Error())) + } + return &SafeTimelockFactory{abi: *parsed} +} + +// Instance creates a wrapper for a deployed contract instance at the given address. +// Use this to create the instance object passed to abigen v2 library functions Call, Transact, etc. +func (c *SafeTimelockFactory) Instance(backend bind.ContractBackend, addr common.Address) *bind.BoundContract { + return bind.NewBoundContract(addr, c.abi, backend, backend, backend) +} + +// PackConstructor is the Go binding used to pack the parameters required for +// contract deployment. +// +// Solidity: constructor(address _safeSingleton, address _safeProxyFactory, address _safeFallbackHandler, address _timelockImplementation) returns() +func (safeTimelockFactory *SafeTimelockFactory) PackConstructor(_safeSingleton common.Address, _safeProxyFactory common.Address, _safeFallbackHandler common.Address, _timelockImplementation common.Address) []byte { + enc, err := safeTimelockFactory.abi.Pack("", _safeSingleton, _safeProxyFactory, _safeFallbackHandler, _timelockImplementation) + if err != nil { + panic(err) + } + return enc +} + +// PackCalculateSafeAddress is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x68282cf3. This method will panic if any +// invalid/nil inputs are passed. +// +// Solidity: function calculateSafeAddress(address deployer, (address[],uint256) config, bytes32 salt) view returns(address) +func (safeTimelockFactory *SafeTimelockFactory) PackCalculateSafeAddress(deployer common.Address, config ISafeTimelockFactorySafeConfig, salt [32]byte) []byte { + enc, err := safeTimelockFactory.abi.Pack("calculateSafeAddress", deployer, config, salt) + if err != nil { + panic(err) + } + return enc +} + +// TryPackCalculateSafeAddress is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x68282cf3. This method will return an error +// if any inputs are invalid/nil. +// +// Solidity: function calculateSafeAddress(address deployer, (address[],uint256) config, bytes32 salt) view returns(address) +func (safeTimelockFactory *SafeTimelockFactory) TryPackCalculateSafeAddress(deployer common.Address, config ISafeTimelockFactorySafeConfig, salt [32]byte) ([]byte, error) { + return safeTimelockFactory.abi.Pack("calculateSafeAddress", deployer, config, salt) +} + +// UnpackCalculateSafeAddress is the Go binding that unpacks the parameters returned +// from invoking the contract method with ID 0x68282cf3. +// +// Solidity: function calculateSafeAddress(address deployer, (address[],uint256) config, bytes32 salt) view returns(address) +func (safeTimelockFactory *SafeTimelockFactory) UnpackCalculateSafeAddress(data []byte) (common.Address, error) { + out, err := safeTimelockFactory.abi.Unpack("calculateSafeAddress", data) + if err != nil { + return *new(common.Address), err + } + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + return out0, nil +} + +// PackCalculateTimelockAddress is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x0e5ceba7. This method will panic if any +// invalid/nil inputs are passed. +// +// Solidity: function calculateTimelockAddress(address deployer, bytes32 salt) view returns(address) +func (safeTimelockFactory *SafeTimelockFactory) PackCalculateTimelockAddress(deployer common.Address, salt [32]byte) []byte { + enc, err := safeTimelockFactory.abi.Pack("calculateTimelockAddress", deployer, salt) + if err != nil { + panic(err) + } + return enc +} + +// TryPackCalculateTimelockAddress is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x0e5ceba7. This method will return an error +// if any inputs are invalid/nil. +// +// Solidity: function calculateTimelockAddress(address deployer, bytes32 salt) view returns(address) +func (safeTimelockFactory *SafeTimelockFactory) TryPackCalculateTimelockAddress(deployer common.Address, salt [32]byte) ([]byte, error) { + return safeTimelockFactory.abi.Pack("calculateTimelockAddress", deployer, salt) +} + +// UnpackCalculateTimelockAddress is the Go binding that unpacks the parameters returned +// from invoking the contract method with ID 0x0e5ceba7. +// +// Solidity: function calculateTimelockAddress(address deployer, bytes32 salt) view returns(address) +func (safeTimelockFactory *SafeTimelockFactory) UnpackCalculateTimelockAddress(data []byte) (common.Address, error) { + out, err := safeTimelockFactory.abi.Unpack("calculateTimelockAddress", data) + if err != nil { + return *new(common.Address), err + } + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + return out0, nil +} + +// PackDeploySafe is the Go binding used to pack the parameters required for calling +// the contract method with ID 0xd15a64ce. This method will panic if any +// invalid/nil inputs are passed. +// +// Solidity: function deploySafe((address[],uint256) config, bytes32 salt) returns(address safe) +func (safeTimelockFactory *SafeTimelockFactory) PackDeploySafe(config ISafeTimelockFactorySafeConfig, salt [32]byte) []byte { + enc, err := safeTimelockFactory.abi.Pack("deploySafe", config, salt) + if err != nil { + panic(err) + } + return enc +} + +// TryPackDeploySafe is the Go binding used to pack the parameters required for calling +// the contract method with ID 0xd15a64ce. This method will return an error +// if any inputs are invalid/nil. +// +// Solidity: function deploySafe((address[],uint256) config, bytes32 salt) returns(address safe) +func (safeTimelockFactory *SafeTimelockFactory) TryPackDeploySafe(config ISafeTimelockFactorySafeConfig, salt [32]byte) ([]byte, error) { + return safeTimelockFactory.abi.Pack("deploySafe", config, salt) +} + +// UnpackDeploySafe is the Go binding that unpacks the parameters returned +// from invoking the contract method with ID 0xd15a64ce. +// +// Solidity: function deploySafe((address[],uint256) config, bytes32 salt) returns(address safe) +func (safeTimelockFactory *SafeTimelockFactory) UnpackDeploySafe(data []byte) (common.Address, error) { + out, err := safeTimelockFactory.abi.Unpack("deploySafe", data) + if err != nil { + return *new(common.Address), err + } + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + return out0, nil +} + +// PackDeployTimelock is the Go binding used to pack the parameters required for calling +// the contract method with ID 0xb7638897. This method will panic if any +// invalid/nil inputs are passed. +// +// Solidity: function deployTimelock((uint256,address[],address[]) config, bytes32 salt) returns(address timelock) +func (safeTimelockFactory *SafeTimelockFactory) PackDeployTimelock(config ISafeTimelockFactoryTimelockConfig, salt [32]byte) []byte { + enc, err := safeTimelockFactory.abi.Pack("deployTimelock", config, salt) + if err != nil { + panic(err) + } + return enc +} + +// TryPackDeployTimelock is the Go binding used to pack the parameters required for calling +// the contract method with ID 0xb7638897. This method will return an error +// if any inputs are invalid/nil. +// +// Solidity: function deployTimelock((uint256,address[],address[]) config, bytes32 salt) returns(address timelock) +func (safeTimelockFactory *SafeTimelockFactory) TryPackDeployTimelock(config ISafeTimelockFactoryTimelockConfig, salt [32]byte) ([]byte, error) { + return safeTimelockFactory.abi.Pack("deployTimelock", config, salt) +} + +// UnpackDeployTimelock is the Go binding that unpacks the parameters returned +// from invoking the contract method with ID 0xb7638897. +// +// Solidity: function deployTimelock((uint256,address[],address[]) config, bytes32 salt) returns(address timelock) +func (safeTimelockFactory *SafeTimelockFactory) UnpackDeployTimelock(data []byte) (common.Address, error) { + out, err := safeTimelockFactory.abi.Unpack("deployTimelock", data) + if err != nil { + return *new(common.Address), err + } + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + return out0, nil +} + +// PackInitialize is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x8129fc1c. This method will panic if any +// invalid/nil inputs are passed. +// +// Solidity: function initialize() returns() +func (safeTimelockFactory *SafeTimelockFactory) PackInitialize() []byte { + enc, err := safeTimelockFactory.abi.Pack("initialize") + if err != nil { + panic(err) + } + return enc +} + +// TryPackInitialize is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x8129fc1c. This method will return an error +// if any inputs are invalid/nil. +// +// Solidity: function initialize() returns() +func (safeTimelockFactory *SafeTimelockFactory) TryPackInitialize() ([]byte, error) { + return safeTimelockFactory.abi.Pack("initialize") +} + +// PackIsSafe is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x769a28ac. This method will panic if any +// invalid/nil inputs are passed. +// +// Solidity: function isSafe(address safe) view returns(bool) +func (safeTimelockFactory *SafeTimelockFactory) PackIsSafe(safe common.Address) []byte { + enc, err := safeTimelockFactory.abi.Pack("isSafe", safe) + if err != nil { + panic(err) + } + return enc +} + +// TryPackIsSafe is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x769a28ac. This method will return an error +// if any inputs are invalid/nil. +// +// Solidity: function isSafe(address safe) view returns(bool) +func (safeTimelockFactory *SafeTimelockFactory) TryPackIsSafe(safe common.Address) ([]byte, error) { + return safeTimelockFactory.abi.Pack("isSafe", safe) +} + +// UnpackIsSafe is the Go binding that unpacks the parameters returned +// from invoking the contract method with ID 0x769a28ac. +// +// Solidity: function isSafe(address safe) view returns(bool) +func (safeTimelockFactory *SafeTimelockFactory) UnpackIsSafe(data []byte) (bool, error) { + out, err := safeTimelockFactory.abi.Unpack("isSafe", data) + if err != nil { + return *new(bool), err + } + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + return out0, nil +} + +// PackIsTimelock is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x9e93963c. This method will panic if any +// invalid/nil inputs are passed. +// +// Solidity: function isTimelock(address timelock) view returns(bool) +func (safeTimelockFactory *SafeTimelockFactory) PackIsTimelock(timelock common.Address) []byte { + enc, err := safeTimelockFactory.abi.Pack("isTimelock", timelock) + if err != nil { + panic(err) + } + return enc +} + +// TryPackIsTimelock is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x9e93963c. This method will return an error +// if any inputs are invalid/nil. +// +// Solidity: function isTimelock(address timelock) view returns(bool) +func (safeTimelockFactory *SafeTimelockFactory) TryPackIsTimelock(timelock common.Address) ([]byte, error) { + return safeTimelockFactory.abi.Pack("isTimelock", timelock) +} + +// UnpackIsTimelock is the Go binding that unpacks the parameters returned +// from invoking the contract method with ID 0x9e93963c. +// +// Solidity: function isTimelock(address timelock) view returns(bool) +func (safeTimelockFactory *SafeTimelockFactory) UnpackIsTimelock(data []byte) (bool, error) { + out, err := safeTimelockFactory.abi.Unpack("isTimelock", data) + if err != nil { + return *new(bool), err + } + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + return out0, nil +} + +// PackSafeFallbackHandler is the Go binding used to pack the parameters required for calling +// the contract method with ID 0xa03bad5a. This method will panic if any +// invalid/nil inputs are passed. +// +// Solidity: function safeFallbackHandler() view returns(address) +func (safeTimelockFactory *SafeTimelockFactory) PackSafeFallbackHandler() []byte { + enc, err := safeTimelockFactory.abi.Pack("safeFallbackHandler") + if err != nil { + panic(err) + } + return enc +} + +// TryPackSafeFallbackHandler is the Go binding used to pack the parameters required for calling +// the contract method with ID 0xa03bad5a. This method will return an error +// if any inputs are invalid/nil. +// +// Solidity: function safeFallbackHandler() view returns(address) +func (safeTimelockFactory *SafeTimelockFactory) TryPackSafeFallbackHandler() ([]byte, error) { + return safeTimelockFactory.abi.Pack("safeFallbackHandler") +} + +// UnpackSafeFallbackHandler is the Go binding that unpacks the parameters returned +// from invoking the contract method with ID 0xa03bad5a. +// +// Solidity: function safeFallbackHandler() view returns(address) +func (safeTimelockFactory *SafeTimelockFactory) UnpackSafeFallbackHandler(data []byte) (common.Address, error) { + out, err := safeTimelockFactory.abi.Unpack("safeFallbackHandler", data) + if err != nil { + return *new(common.Address), err + } + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + return out0, nil +} + +// PackSafeProxyFactory is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x19964501. This method will panic if any +// invalid/nil inputs are passed. +// +// Solidity: function safeProxyFactory() view returns(address) +func (safeTimelockFactory *SafeTimelockFactory) PackSafeProxyFactory() []byte { + enc, err := safeTimelockFactory.abi.Pack("safeProxyFactory") + if err != nil { + panic(err) + } + return enc +} + +// TryPackSafeProxyFactory is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x19964501. This method will return an error +// if any inputs are invalid/nil. +// +// Solidity: function safeProxyFactory() view returns(address) +func (safeTimelockFactory *SafeTimelockFactory) TryPackSafeProxyFactory() ([]byte, error) { + return safeTimelockFactory.abi.Pack("safeProxyFactory") +} + +// UnpackSafeProxyFactory is the Go binding that unpacks the parameters returned +// from invoking the contract method with ID 0x19964501. +// +// Solidity: function safeProxyFactory() view returns(address) +func (safeTimelockFactory *SafeTimelockFactory) UnpackSafeProxyFactory(data []byte) (common.Address, error) { + out, err := safeTimelockFactory.abi.Unpack("safeProxyFactory", data) + if err != nil { + return *new(common.Address), err + } + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + return out0, nil +} + +// PackSafeSingleton is the Go binding used to pack the parameters required for calling +// the contract method with ID 0xac7d146b. This method will panic if any +// invalid/nil inputs are passed. +// +// Solidity: function safeSingleton() view returns(address) +func (safeTimelockFactory *SafeTimelockFactory) PackSafeSingleton() []byte { + enc, err := safeTimelockFactory.abi.Pack("safeSingleton") + if err != nil { + panic(err) + } + return enc +} + +// TryPackSafeSingleton is the Go binding used to pack the parameters required for calling +// the contract method with ID 0xac7d146b. This method will return an error +// if any inputs are invalid/nil. +// +// Solidity: function safeSingleton() view returns(address) +func (safeTimelockFactory *SafeTimelockFactory) TryPackSafeSingleton() ([]byte, error) { + return safeTimelockFactory.abi.Pack("safeSingleton") +} + +// UnpackSafeSingleton is the Go binding that unpacks the parameters returned +// from invoking the contract method with ID 0xac7d146b. +// +// Solidity: function safeSingleton() view returns(address) +func (safeTimelockFactory *SafeTimelockFactory) UnpackSafeSingleton(data []byte) (common.Address, error) { + out, err := safeTimelockFactory.abi.Unpack("safeSingleton", data) + if err != nil { + return *new(common.Address), err + } + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + return out0, nil +} + +// PackTimelockImplementation is the Go binding used to pack the parameters required for calling +// the contract method with ID 0xc5e8f3e5. This method will panic if any +// invalid/nil inputs are passed. +// +// Solidity: function timelockImplementation() view returns(address) +func (safeTimelockFactory *SafeTimelockFactory) PackTimelockImplementation() []byte { + enc, err := safeTimelockFactory.abi.Pack("timelockImplementation") + if err != nil { + panic(err) + } + return enc +} + +// TryPackTimelockImplementation is the Go binding used to pack the parameters required for calling +// the contract method with ID 0xc5e8f3e5. This method will return an error +// if any inputs are invalid/nil. +// +// Solidity: function timelockImplementation() view returns(address) +func (safeTimelockFactory *SafeTimelockFactory) TryPackTimelockImplementation() ([]byte, error) { + return safeTimelockFactory.abi.Pack("timelockImplementation") +} + +// UnpackTimelockImplementation is the Go binding that unpacks the parameters returned +// from invoking the contract method with ID 0xc5e8f3e5. +// +// Solidity: function timelockImplementation() view returns(address) +func (safeTimelockFactory *SafeTimelockFactory) UnpackTimelockImplementation(data []byte) (common.Address, error) { + out, err := safeTimelockFactory.abi.Unpack("timelockImplementation", data) + if err != nil { + return *new(common.Address), err + } + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + return out0, nil +} + +// SafeTimelockFactoryInitialized represents a Initialized event raised by the SafeTimelockFactory contract. +type SafeTimelockFactoryInitialized struct { + Version uint8 + Raw *types.Log // Blockchain specific contextual infos +} + +const SafeTimelockFactoryInitializedEventName = "Initialized" + +// ContractEventName returns the user-defined event name. +func (SafeTimelockFactoryInitialized) ContractEventName() string { + return SafeTimelockFactoryInitializedEventName +} + +// UnpackInitializedEvent is the Go binding that unpacks the event data emitted +// by contract. +// +// Solidity: event Initialized(uint8 version) +func (safeTimelockFactory *SafeTimelockFactory) UnpackInitializedEvent(log *types.Log) (*SafeTimelockFactoryInitialized, error) { + event := "Initialized" + if len(log.Topics) == 0 || log.Topics[0] != safeTimelockFactory.abi.Events[event].ID { + return nil, errors.New("event signature mismatch") + } + out := new(SafeTimelockFactoryInitialized) + if len(log.Data) > 0 { + if err := safeTimelockFactory.abi.UnpackIntoInterface(out, event, log.Data); err != nil { + return nil, err + } + } + var indexed abi.Arguments + for _, arg := range safeTimelockFactory.abi.Events[event].Inputs { + if arg.Indexed { + indexed = append(indexed, arg) + } + } + if err := abi.ParseTopics(out, indexed, log.Topics[1:]); err != nil { + return nil, err + } + out.Raw = log + return out, nil +} + +// SafeTimelockFactorySafeDeployed represents a SafeDeployed event raised by the SafeTimelockFactory contract. +type SafeTimelockFactorySafeDeployed struct { + Deployer common.Address + Safe common.Address + Owners []common.Address + Threshold *big.Int + Salt [32]byte + Raw *types.Log // Blockchain specific contextual infos +} + +const SafeTimelockFactorySafeDeployedEventName = "SafeDeployed" + +// ContractEventName returns the user-defined event name. +func (SafeTimelockFactorySafeDeployed) ContractEventName() string { + return SafeTimelockFactorySafeDeployedEventName +} + +// UnpackSafeDeployedEvent is the Go binding that unpacks the event data emitted +// by contract. +// +// Solidity: event SafeDeployed(address indexed deployer, address indexed safe, address[] owners, uint256 threshold, bytes32 salt) +func (safeTimelockFactory *SafeTimelockFactory) UnpackSafeDeployedEvent(log *types.Log) (*SafeTimelockFactorySafeDeployed, error) { + event := "SafeDeployed" + if len(log.Topics) == 0 || log.Topics[0] != safeTimelockFactory.abi.Events[event].ID { + return nil, errors.New("event signature mismatch") + } + out := new(SafeTimelockFactorySafeDeployed) + if len(log.Data) > 0 { + if err := safeTimelockFactory.abi.UnpackIntoInterface(out, event, log.Data); err != nil { + return nil, err + } + } + var indexed abi.Arguments + for _, arg := range safeTimelockFactory.abi.Events[event].Inputs { + if arg.Indexed { + indexed = append(indexed, arg) + } + } + if err := abi.ParseTopics(out, indexed, log.Topics[1:]); err != nil { + return nil, err + } + out.Raw = log + return out, nil +} + +// SafeTimelockFactoryTimelockDeployed represents a TimelockDeployed event raised by the SafeTimelockFactory contract. +type SafeTimelockFactoryTimelockDeployed struct { + Deployer common.Address + Timelock common.Address + MinDelay *big.Int + Proposers []common.Address + Executors []common.Address + Salt [32]byte + Raw *types.Log // Blockchain specific contextual infos +} + +const SafeTimelockFactoryTimelockDeployedEventName = "TimelockDeployed" + +// ContractEventName returns the user-defined event name. +func (SafeTimelockFactoryTimelockDeployed) ContractEventName() string { + return SafeTimelockFactoryTimelockDeployedEventName +} + +// UnpackTimelockDeployedEvent is the Go binding that unpacks the event data emitted +// by contract. +// +// Solidity: event TimelockDeployed(address indexed deployer, address indexed timelock, uint256 minDelay, address[] proposers, address[] executors, bytes32 salt) +func (safeTimelockFactory *SafeTimelockFactory) UnpackTimelockDeployedEvent(log *types.Log) (*SafeTimelockFactoryTimelockDeployed, error) { + event := "TimelockDeployed" + if len(log.Topics) == 0 || log.Topics[0] != safeTimelockFactory.abi.Events[event].ID { + return nil, errors.New("event signature mismatch") + } + out := new(SafeTimelockFactoryTimelockDeployed) + if len(log.Data) > 0 { + if err := safeTimelockFactory.abi.UnpackIntoInterface(out, event, log.Data); err != nil { + return nil, err + } + } + var indexed abi.Arguments + for _, arg := range safeTimelockFactory.abi.Events[event].Inputs { + if arg.Indexed { + indexed = append(indexed, arg) + } + } + if err := abi.ParseTopics(out, indexed, log.Topics[1:]); err != nil { + return nil, err + } + out.Raw = log + return out, nil +} + +// UnpackError attempts to decode the provided error data using user-defined +// error definitions. +func (safeTimelockFactory *SafeTimelockFactory) UnpackError(raw []byte) (any, error) { + if bytes.Equal(raw[:4], safeTimelockFactory.abi.Errors["NoExecutors"].ID.Bytes()[:4]) { + return safeTimelockFactory.UnpackNoExecutorsError(raw[4:]) + } + if bytes.Equal(raw[:4], safeTimelockFactory.abi.Errors["NoProposers"].ID.Bytes()[:4]) { + return safeTimelockFactory.UnpackNoProposersError(raw[4:]) + } + if bytes.Equal(raw[:4], safeTimelockFactory.abi.Errors["ZeroAddressExecutor"].ID.Bytes()[:4]) { + return safeTimelockFactory.UnpackZeroAddressExecutorError(raw[4:]) + } + if bytes.Equal(raw[:4], safeTimelockFactory.abi.Errors["ZeroAddressProposer"].ID.Bytes()[:4]) { + return safeTimelockFactory.UnpackZeroAddressProposerError(raw[4:]) + } + return nil, errors.New("Unknown error") +} + +// SafeTimelockFactoryNoExecutors represents a NoExecutors error raised by the SafeTimelockFactory contract. +type SafeTimelockFactoryNoExecutors struct { +} + +// ErrorID returns the hash of canonical representation of the error's signature. +// +// Solidity: error NoExecutors() +func SafeTimelockFactoryNoExecutorsErrorID() common.Hash { + return common.HexToHash("0xebad7a3917673636faa3bf87473642d74ec4970df627b81fb966aa4512d4ff9e") +} + +// UnpackNoExecutorsError is the Go binding used to decode the provided +// error data into the corresponding Go error struct. +// +// Solidity: error NoExecutors() +func (safeTimelockFactory *SafeTimelockFactory) UnpackNoExecutorsError(raw []byte) (*SafeTimelockFactoryNoExecutors, error) { + out := new(SafeTimelockFactoryNoExecutors) + if err := safeTimelockFactory.abi.UnpackIntoInterface(out, "NoExecutors", raw); err != nil { + return nil, err + } + return out, nil +} + +// SafeTimelockFactoryNoProposers represents a NoProposers error raised by the SafeTimelockFactory contract. +type SafeTimelockFactoryNoProposers struct { +} + +// ErrorID returns the hash of canonical representation of the error's signature. +// +// Solidity: error NoProposers() +func SafeTimelockFactoryNoProposersErrorID() common.Hash { + return common.HexToHash("0x80ffbcc335a5e874626ebd60b239200cd2bbff73591ae555058a6f678f2f6e01") +} + +// UnpackNoProposersError is the Go binding used to decode the provided +// error data into the corresponding Go error struct. +// +// Solidity: error NoProposers() +func (safeTimelockFactory *SafeTimelockFactory) UnpackNoProposersError(raw []byte) (*SafeTimelockFactoryNoProposers, error) { + out := new(SafeTimelockFactoryNoProposers) + if err := safeTimelockFactory.abi.UnpackIntoInterface(out, "NoProposers", raw); err != nil { + return nil, err + } + return out, nil +} + +// SafeTimelockFactoryZeroAddressExecutor represents a ZeroAddressExecutor error raised by the SafeTimelockFactory contract. +type SafeTimelockFactoryZeroAddressExecutor struct { +} + +// ErrorID returns the hash of canonical representation of the error's signature. +// +// Solidity: error ZeroAddressExecutor() +func SafeTimelockFactoryZeroAddressExecutorErrorID() common.Hash { + return common.HexToHash("0xfd1d5901a90fb747931b09fbcdd82984a0ab6a26f1a8a75e416ce9251d56e708") +} + +// UnpackZeroAddressExecutorError is the Go binding used to decode the provided +// error data into the corresponding Go error struct. +// +// Solidity: error ZeroAddressExecutor() +func (safeTimelockFactory *SafeTimelockFactory) UnpackZeroAddressExecutorError(raw []byte) (*SafeTimelockFactoryZeroAddressExecutor, error) { + out := new(SafeTimelockFactoryZeroAddressExecutor) + if err := safeTimelockFactory.abi.UnpackIntoInterface(out, "ZeroAddressExecutor", raw); err != nil { + return nil, err + } + return out, nil +} + +// SafeTimelockFactoryZeroAddressProposer represents a ZeroAddressProposer error raised by the SafeTimelockFactory contract. +type SafeTimelockFactoryZeroAddressProposer struct { +} + +// ErrorID returns the hash of canonical representation of the error's signature. +// +// Solidity: error ZeroAddressProposer() +func SafeTimelockFactoryZeroAddressProposerErrorID() common.Hash { + return common.HexToHash("0x765e2e8cd4c853dae1bb4c199ca3822bdfd4b513e6602f7132b09a8a5e701714") +} + +// UnpackZeroAddressProposerError is the Go binding used to decode the provided +// error data into the corresponding Go error struct. +// +// Solidity: error ZeroAddressProposer() +func (safeTimelockFactory *SafeTimelockFactory) UnpackZeroAddressProposerError(raw []byte) (*SafeTimelockFactoryZeroAddressProposer, error) { + out := new(SafeTimelockFactoryZeroAddressProposer) + if err := safeTimelockFactory.abi.UnpackIntoInterface(out, "ZeroAddressProposer", raw); err != nil { + return nil, err + } + return out, nil +} diff --git a/pkg/bindings/v2/TimelockControllerImpl/binding.go b/pkg/bindings/v2/TimelockControllerImpl/binding.go new file mode 100644 index 0000000..6e4caf6 --- /dev/null +++ b/pkg/bindings/v2/TimelockControllerImpl/binding.go @@ -0,0 +1,1323 @@ +// Code generated via abigen V2 - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package TimelockControllerImpl + +import ( + "bytes" + "errors" + "math/big" + + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind/v2" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = bytes.Equal + _ = errors.New + _ = big.NewInt + _ = common.Big1 + _ = types.BloomLookup + _ = abi.ConvertType +) + +// TimelockControllerImplMetaData contains all meta data concerning the TimelockControllerImpl contract. +var TimelockControllerImplMetaData = bind.MetaData{ + ABI: "[{\"type\":\"constructor\",\"inputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"receive\",\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"CANCELLER_ROLE\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"DEFAULT_ADMIN_ROLE\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"EXECUTOR_ROLE\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"PROPOSER_ROLE\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"TIMELOCK_ADMIN_ROLE\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"cancel\",\"inputs\":[{\"name\":\"id\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"execute\",\"inputs\":[{\"name\":\"target\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"value\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"payload\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"predecessor\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"salt\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"executeBatch\",\"inputs\":[{\"name\":\"targets\",\"type\":\"address[]\",\"internalType\":\"address[]\"},{\"name\":\"values\",\"type\":\"uint256[]\",\"internalType\":\"uint256[]\"},{\"name\":\"payloads\",\"type\":\"bytes[]\",\"internalType\":\"bytes[]\"},{\"name\":\"predecessor\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"salt\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"getMinDelay\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getRoleAdmin\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getTimestamp\",\"inputs\":[{\"name\":\"id\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"grantRole\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"hasRole\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"hashOperation\",\"inputs\":[{\"name\":\"target\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"value\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"data\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"predecessor\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"salt\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"pure\"},{\"type\":\"function\",\"name\":\"hashOperationBatch\",\"inputs\":[{\"name\":\"targets\",\"type\":\"address[]\",\"internalType\":\"address[]\"},{\"name\":\"values\",\"type\":\"uint256[]\",\"internalType\":\"uint256[]\"},{\"name\":\"payloads\",\"type\":\"bytes[]\",\"internalType\":\"bytes[]\"},{\"name\":\"predecessor\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"salt\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"pure\"},{\"type\":\"function\",\"name\":\"initialize\",\"inputs\":[{\"name\":\"minDelay\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"proposers\",\"type\":\"address[]\",\"internalType\":\"address[]\"},{\"name\":\"executors\",\"type\":\"address[]\",\"internalType\":\"address[]\"},{\"name\":\"admin\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"isOperation\",\"inputs\":[{\"name\":\"id\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"isOperationDone\",\"inputs\":[{\"name\":\"id\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"isOperationPending\",\"inputs\":[{\"name\":\"id\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"isOperationReady\",\"inputs\":[{\"name\":\"id\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"onERC1155BatchReceived\",\"inputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"\",\"type\":\"uint256[]\",\"internalType\":\"uint256[]\"},{\"name\":\"\",\"type\":\"uint256[]\",\"internalType\":\"uint256[]\"},{\"name\":\"\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes4\",\"internalType\":\"bytes4\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"onERC1155Received\",\"inputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes4\",\"internalType\":\"bytes4\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"onERC721Received\",\"inputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes4\",\"internalType\":\"bytes4\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"renounceRole\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"revokeRole\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"schedule\",\"inputs\":[{\"name\":\"target\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"value\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"data\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"predecessor\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"salt\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"delay\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"scheduleBatch\",\"inputs\":[{\"name\":\"targets\",\"type\":\"address[]\",\"internalType\":\"address[]\"},{\"name\":\"values\",\"type\":\"uint256[]\",\"internalType\":\"uint256[]\"},{\"name\":\"payloads\",\"type\":\"bytes[]\",\"internalType\":\"bytes[]\"},{\"name\":\"predecessor\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"salt\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"delay\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"supportsInterface\",\"inputs\":[{\"name\":\"interfaceId\",\"type\":\"bytes4\",\"internalType\":\"bytes4\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"updateDelay\",\"inputs\":[{\"name\":\"newDelay\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"event\",\"name\":\"CallExecuted\",\"inputs\":[{\"name\":\"id\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"index\",\"type\":\"uint256\",\"indexed\":true,\"internalType\":\"uint256\"},{\"name\":\"target\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"},{\"name\":\"value\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"data\",\"type\":\"bytes\",\"indexed\":false,\"internalType\":\"bytes\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"CallSalt\",\"inputs\":[{\"name\":\"id\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"salt\",\"type\":\"bytes32\",\"indexed\":false,\"internalType\":\"bytes32\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"CallScheduled\",\"inputs\":[{\"name\":\"id\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"index\",\"type\":\"uint256\",\"indexed\":true,\"internalType\":\"uint256\"},{\"name\":\"target\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"},{\"name\":\"value\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"data\",\"type\":\"bytes\",\"indexed\":false,\"internalType\":\"bytes\"},{\"name\":\"predecessor\",\"type\":\"bytes32\",\"indexed\":false,\"internalType\":\"bytes32\"},{\"name\":\"delay\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Cancelled\",\"inputs\":[{\"name\":\"id\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Initialized\",\"inputs\":[{\"name\":\"version\",\"type\":\"uint8\",\"indexed\":false,\"internalType\":\"uint8\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"MinDelayChange\",\"inputs\":[{\"name\":\"oldDuration\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"newDuration\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"RoleAdminChanged\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"previousAdminRole\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"newAdminRole\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"RoleGranted\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"account\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"sender\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"RoleRevoked\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"account\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"sender\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false}]", + ID: "TimelockControllerImpl", +} + +// TimelockControllerImpl is an auto generated Go binding around an Ethereum contract. +type TimelockControllerImpl struct { + abi abi.ABI +} + +// NewTimelockControllerImpl creates a new instance of TimelockControllerImpl. +func NewTimelockControllerImpl() *TimelockControllerImpl { + parsed, err := TimelockControllerImplMetaData.ParseABI() + if err != nil { + panic(errors.New("invalid ABI: " + err.Error())) + } + return &TimelockControllerImpl{abi: *parsed} +} + +// Instance creates a wrapper for a deployed contract instance at the given address. +// Use this to create the instance object passed to abigen v2 library functions Call, Transact, etc. +func (c *TimelockControllerImpl) Instance(backend bind.ContractBackend, addr common.Address) *bind.BoundContract { + return bind.NewBoundContract(addr, c.abi, backend, backend, backend) +} + +// PackCANCELLERROLE is the Go binding used to pack the parameters required for calling +// the contract method with ID 0xb08e51c0. This method will panic if any +// invalid/nil inputs are passed. +// +// Solidity: function CANCELLER_ROLE() view returns(bytes32) +func (timelockControllerImpl *TimelockControllerImpl) PackCANCELLERROLE() []byte { + enc, err := timelockControllerImpl.abi.Pack("CANCELLER_ROLE") + if err != nil { + panic(err) + } + return enc +} + +// TryPackCANCELLERROLE is the Go binding used to pack the parameters required for calling +// the contract method with ID 0xb08e51c0. This method will return an error +// if any inputs are invalid/nil. +// +// Solidity: function CANCELLER_ROLE() view returns(bytes32) +func (timelockControllerImpl *TimelockControllerImpl) TryPackCANCELLERROLE() ([]byte, error) { + return timelockControllerImpl.abi.Pack("CANCELLER_ROLE") +} + +// UnpackCANCELLERROLE is the Go binding that unpacks the parameters returned +// from invoking the contract method with ID 0xb08e51c0. +// +// Solidity: function CANCELLER_ROLE() view returns(bytes32) +func (timelockControllerImpl *TimelockControllerImpl) UnpackCANCELLERROLE(data []byte) ([32]byte, error) { + out, err := timelockControllerImpl.abi.Unpack("CANCELLER_ROLE", data) + if err != nil { + return *new([32]byte), err + } + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + return out0, nil +} + +// PackDEFAULTADMINROLE is the Go binding used to pack the parameters required for calling +// the contract method with ID 0xa217fddf. This method will panic if any +// invalid/nil inputs are passed. +// +// Solidity: function DEFAULT_ADMIN_ROLE() view returns(bytes32) +func (timelockControllerImpl *TimelockControllerImpl) PackDEFAULTADMINROLE() []byte { + enc, err := timelockControllerImpl.abi.Pack("DEFAULT_ADMIN_ROLE") + if err != nil { + panic(err) + } + return enc +} + +// TryPackDEFAULTADMINROLE is the Go binding used to pack the parameters required for calling +// the contract method with ID 0xa217fddf. This method will return an error +// if any inputs are invalid/nil. +// +// Solidity: function DEFAULT_ADMIN_ROLE() view returns(bytes32) +func (timelockControllerImpl *TimelockControllerImpl) TryPackDEFAULTADMINROLE() ([]byte, error) { + return timelockControllerImpl.abi.Pack("DEFAULT_ADMIN_ROLE") +} + +// UnpackDEFAULTADMINROLE is the Go binding that unpacks the parameters returned +// from invoking the contract method with ID 0xa217fddf. +// +// Solidity: function DEFAULT_ADMIN_ROLE() view returns(bytes32) +func (timelockControllerImpl *TimelockControllerImpl) UnpackDEFAULTADMINROLE(data []byte) ([32]byte, error) { + out, err := timelockControllerImpl.abi.Unpack("DEFAULT_ADMIN_ROLE", data) + if err != nil { + return *new([32]byte), err + } + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + return out0, nil +} + +// PackEXECUTORROLE is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x07bd0265. This method will panic if any +// invalid/nil inputs are passed. +// +// Solidity: function EXECUTOR_ROLE() view returns(bytes32) +func (timelockControllerImpl *TimelockControllerImpl) PackEXECUTORROLE() []byte { + enc, err := timelockControllerImpl.abi.Pack("EXECUTOR_ROLE") + if err != nil { + panic(err) + } + return enc +} + +// TryPackEXECUTORROLE is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x07bd0265. This method will return an error +// if any inputs are invalid/nil. +// +// Solidity: function EXECUTOR_ROLE() view returns(bytes32) +func (timelockControllerImpl *TimelockControllerImpl) TryPackEXECUTORROLE() ([]byte, error) { + return timelockControllerImpl.abi.Pack("EXECUTOR_ROLE") +} + +// UnpackEXECUTORROLE is the Go binding that unpacks the parameters returned +// from invoking the contract method with ID 0x07bd0265. +// +// Solidity: function EXECUTOR_ROLE() view returns(bytes32) +func (timelockControllerImpl *TimelockControllerImpl) UnpackEXECUTORROLE(data []byte) ([32]byte, error) { + out, err := timelockControllerImpl.abi.Unpack("EXECUTOR_ROLE", data) + if err != nil { + return *new([32]byte), err + } + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + return out0, nil +} + +// PackPROPOSERROLE is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x8f61f4f5. This method will panic if any +// invalid/nil inputs are passed. +// +// Solidity: function PROPOSER_ROLE() view returns(bytes32) +func (timelockControllerImpl *TimelockControllerImpl) PackPROPOSERROLE() []byte { + enc, err := timelockControllerImpl.abi.Pack("PROPOSER_ROLE") + if err != nil { + panic(err) + } + return enc +} + +// TryPackPROPOSERROLE is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x8f61f4f5. This method will return an error +// if any inputs are invalid/nil. +// +// Solidity: function PROPOSER_ROLE() view returns(bytes32) +func (timelockControllerImpl *TimelockControllerImpl) TryPackPROPOSERROLE() ([]byte, error) { + return timelockControllerImpl.abi.Pack("PROPOSER_ROLE") +} + +// UnpackPROPOSERROLE is the Go binding that unpacks the parameters returned +// from invoking the contract method with ID 0x8f61f4f5. +// +// Solidity: function PROPOSER_ROLE() view returns(bytes32) +func (timelockControllerImpl *TimelockControllerImpl) UnpackPROPOSERROLE(data []byte) ([32]byte, error) { + out, err := timelockControllerImpl.abi.Unpack("PROPOSER_ROLE", data) + if err != nil { + return *new([32]byte), err + } + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + return out0, nil +} + +// PackTIMELOCKADMINROLE is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x0d3cf6fc. This method will panic if any +// invalid/nil inputs are passed. +// +// Solidity: function TIMELOCK_ADMIN_ROLE() view returns(bytes32) +func (timelockControllerImpl *TimelockControllerImpl) PackTIMELOCKADMINROLE() []byte { + enc, err := timelockControllerImpl.abi.Pack("TIMELOCK_ADMIN_ROLE") + if err != nil { + panic(err) + } + return enc +} + +// TryPackTIMELOCKADMINROLE is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x0d3cf6fc. This method will return an error +// if any inputs are invalid/nil. +// +// Solidity: function TIMELOCK_ADMIN_ROLE() view returns(bytes32) +func (timelockControllerImpl *TimelockControllerImpl) TryPackTIMELOCKADMINROLE() ([]byte, error) { + return timelockControllerImpl.abi.Pack("TIMELOCK_ADMIN_ROLE") +} + +// UnpackTIMELOCKADMINROLE is the Go binding that unpacks the parameters returned +// from invoking the contract method with ID 0x0d3cf6fc. +// +// Solidity: function TIMELOCK_ADMIN_ROLE() view returns(bytes32) +func (timelockControllerImpl *TimelockControllerImpl) UnpackTIMELOCKADMINROLE(data []byte) ([32]byte, error) { + out, err := timelockControllerImpl.abi.Unpack("TIMELOCK_ADMIN_ROLE", data) + if err != nil { + return *new([32]byte), err + } + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + return out0, nil +} + +// PackCancel is the Go binding used to pack the parameters required for calling +// the contract method with ID 0xc4d252f5. This method will panic if any +// invalid/nil inputs are passed. +// +// Solidity: function cancel(bytes32 id) returns() +func (timelockControllerImpl *TimelockControllerImpl) PackCancel(id [32]byte) []byte { + enc, err := timelockControllerImpl.abi.Pack("cancel", id) + if err != nil { + panic(err) + } + return enc +} + +// TryPackCancel is the Go binding used to pack the parameters required for calling +// the contract method with ID 0xc4d252f5. This method will return an error +// if any inputs are invalid/nil. +// +// Solidity: function cancel(bytes32 id) returns() +func (timelockControllerImpl *TimelockControllerImpl) TryPackCancel(id [32]byte) ([]byte, error) { + return timelockControllerImpl.abi.Pack("cancel", id) +} + +// PackExecute is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x134008d3. This method will panic if any +// invalid/nil inputs are passed. +// +// Solidity: function execute(address target, uint256 value, bytes payload, bytes32 predecessor, bytes32 salt) payable returns() +func (timelockControllerImpl *TimelockControllerImpl) PackExecute(target common.Address, value *big.Int, payload []byte, predecessor [32]byte, salt [32]byte) []byte { + enc, err := timelockControllerImpl.abi.Pack("execute", target, value, payload, predecessor, salt) + if err != nil { + panic(err) + } + return enc +} + +// TryPackExecute is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x134008d3. This method will return an error +// if any inputs are invalid/nil. +// +// Solidity: function execute(address target, uint256 value, bytes payload, bytes32 predecessor, bytes32 salt) payable returns() +func (timelockControllerImpl *TimelockControllerImpl) TryPackExecute(target common.Address, value *big.Int, payload []byte, predecessor [32]byte, salt [32]byte) ([]byte, error) { + return timelockControllerImpl.abi.Pack("execute", target, value, payload, predecessor, salt) +} + +// PackExecuteBatch is the Go binding used to pack the parameters required for calling +// the contract method with ID 0xe38335e5. This method will panic if any +// invalid/nil inputs are passed. +// +// Solidity: function executeBatch(address[] targets, uint256[] values, bytes[] payloads, bytes32 predecessor, bytes32 salt) payable returns() +func (timelockControllerImpl *TimelockControllerImpl) PackExecuteBatch(targets []common.Address, values []*big.Int, payloads [][]byte, predecessor [32]byte, salt [32]byte) []byte { + enc, err := timelockControllerImpl.abi.Pack("executeBatch", targets, values, payloads, predecessor, salt) + if err != nil { + panic(err) + } + return enc +} + +// TryPackExecuteBatch is the Go binding used to pack the parameters required for calling +// the contract method with ID 0xe38335e5. This method will return an error +// if any inputs are invalid/nil. +// +// Solidity: function executeBatch(address[] targets, uint256[] values, bytes[] payloads, bytes32 predecessor, bytes32 salt) payable returns() +func (timelockControllerImpl *TimelockControllerImpl) TryPackExecuteBatch(targets []common.Address, values []*big.Int, payloads [][]byte, predecessor [32]byte, salt [32]byte) ([]byte, error) { + return timelockControllerImpl.abi.Pack("executeBatch", targets, values, payloads, predecessor, salt) +} + +// PackGetMinDelay is the Go binding used to pack the parameters required for calling +// the contract method with ID 0xf27a0c92. This method will panic if any +// invalid/nil inputs are passed. +// +// Solidity: function getMinDelay() view returns(uint256) +func (timelockControllerImpl *TimelockControllerImpl) PackGetMinDelay() []byte { + enc, err := timelockControllerImpl.abi.Pack("getMinDelay") + if err != nil { + panic(err) + } + return enc +} + +// TryPackGetMinDelay is the Go binding used to pack the parameters required for calling +// the contract method with ID 0xf27a0c92. This method will return an error +// if any inputs are invalid/nil. +// +// Solidity: function getMinDelay() view returns(uint256) +func (timelockControllerImpl *TimelockControllerImpl) TryPackGetMinDelay() ([]byte, error) { + return timelockControllerImpl.abi.Pack("getMinDelay") +} + +// UnpackGetMinDelay is the Go binding that unpacks the parameters returned +// from invoking the contract method with ID 0xf27a0c92. +// +// Solidity: function getMinDelay() view returns(uint256) +func (timelockControllerImpl *TimelockControllerImpl) UnpackGetMinDelay(data []byte) (*big.Int, error) { + out, err := timelockControllerImpl.abi.Unpack("getMinDelay", data) + if err != nil { + return new(big.Int), err + } + out0 := abi.ConvertType(out[0], new(big.Int)).(*big.Int) + return out0, nil +} + +// PackGetRoleAdmin is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x248a9ca3. This method will panic if any +// invalid/nil inputs are passed. +// +// Solidity: function getRoleAdmin(bytes32 role) view returns(bytes32) +func (timelockControllerImpl *TimelockControllerImpl) PackGetRoleAdmin(role [32]byte) []byte { + enc, err := timelockControllerImpl.abi.Pack("getRoleAdmin", role) + if err != nil { + panic(err) + } + return enc +} + +// TryPackGetRoleAdmin is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x248a9ca3. This method will return an error +// if any inputs are invalid/nil. +// +// Solidity: function getRoleAdmin(bytes32 role) view returns(bytes32) +func (timelockControllerImpl *TimelockControllerImpl) TryPackGetRoleAdmin(role [32]byte) ([]byte, error) { + return timelockControllerImpl.abi.Pack("getRoleAdmin", role) +} + +// UnpackGetRoleAdmin is the Go binding that unpacks the parameters returned +// from invoking the contract method with ID 0x248a9ca3. +// +// Solidity: function getRoleAdmin(bytes32 role) view returns(bytes32) +func (timelockControllerImpl *TimelockControllerImpl) UnpackGetRoleAdmin(data []byte) ([32]byte, error) { + out, err := timelockControllerImpl.abi.Unpack("getRoleAdmin", data) + if err != nil { + return *new([32]byte), err + } + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + return out0, nil +} + +// PackGetTimestamp is the Go binding used to pack the parameters required for calling +// the contract method with ID 0xd45c4435. This method will panic if any +// invalid/nil inputs are passed. +// +// Solidity: function getTimestamp(bytes32 id) view returns(uint256) +func (timelockControllerImpl *TimelockControllerImpl) PackGetTimestamp(id [32]byte) []byte { + enc, err := timelockControllerImpl.abi.Pack("getTimestamp", id) + if err != nil { + panic(err) + } + return enc +} + +// TryPackGetTimestamp is the Go binding used to pack the parameters required for calling +// the contract method with ID 0xd45c4435. This method will return an error +// if any inputs are invalid/nil. +// +// Solidity: function getTimestamp(bytes32 id) view returns(uint256) +func (timelockControllerImpl *TimelockControllerImpl) TryPackGetTimestamp(id [32]byte) ([]byte, error) { + return timelockControllerImpl.abi.Pack("getTimestamp", id) +} + +// UnpackGetTimestamp is the Go binding that unpacks the parameters returned +// from invoking the contract method with ID 0xd45c4435. +// +// Solidity: function getTimestamp(bytes32 id) view returns(uint256) +func (timelockControllerImpl *TimelockControllerImpl) UnpackGetTimestamp(data []byte) (*big.Int, error) { + out, err := timelockControllerImpl.abi.Unpack("getTimestamp", data) + if err != nil { + return new(big.Int), err + } + out0 := abi.ConvertType(out[0], new(big.Int)).(*big.Int) + return out0, nil +} + +// PackGrantRole is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x2f2ff15d. This method will panic if any +// invalid/nil inputs are passed. +// +// Solidity: function grantRole(bytes32 role, address account) returns() +func (timelockControllerImpl *TimelockControllerImpl) PackGrantRole(role [32]byte, account common.Address) []byte { + enc, err := timelockControllerImpl.abi.Pack("grantRole", role, account) + if err != nil { + panic(err) + } + return enc +} + +// TryPackGrantRole is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x2f2ff15d. This method will return an error +// if any inputs are invalid/nil. +// +// Solidity: function grantRole(bytes32 role, address account) returns() +func (timelockControllerImpl *TimelockControllerImpl) TryPackGrantRole(role [32]byte, account common.Address) ([]byte, error) { + return timelockControllerImpl.abi.Pack("grantRole", role, account) +} + +// PackHasRole is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x91d14854. This method will panic if any +// invalid/nil inputs are passed. +// +// Solidity: function hasRole(bytes32 role, address account) view returns(bool) +func (timelockControllerImpl *TimelockControllerImpl) PackHasRole(role [32]byte, account common.Address) []byte { + enc, err := timelockControllerImpl.abi.Pack("hasRole", role, account) + if err != nil { + panic(err) + } + return enc +} + +// TryPackHasRole is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x91d14854. This method will return an error +// if any inputs are invalid/nil. +// +// Solidity: function hasRole(bytes32 role, address account) view returns(bool) +func (timelockControllerImpl *TimelockControllerImpl) TryPackHasRole(role [32]byte, account common.Address) ([]byte, error) { + return timelockControllerImpl.abi.Pack("hasRole", role, account) +} + +// UnpackHasRole is the Go binding that unpacks the parameters returned +// from invoking the contract method with ID 0x91d14854. +// +// Solidity: function hasRole(bytes32 role, address account) view returns(bool) +func (timelockControllerImpl *TimelockControllerImpl) UnpackHasRole(data []byte) (bool, error) { + out, err := timelockControllerImpl.abi.Unpack("hasRole", data) + if err != nil { + return *new(bool), err + } + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + return out0, nil +} + +// PackHashOperation is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x8065657f. This method will panic if any +// invalid/nil inputs are passed. +// +// Solidity: function hashOperation(address target, uint256 value, bytes data, bytes32 predecessor, bytes32 salt) pure returns(bytes32) +func (timelockControllerImpl *TimelockControllerImpl) PackHashOperation(target common.Address, value *big.Int, data []byte, predecessor [32]byte, salt [32]byte) []byte { + enc, err := timelockControllerImpl.abi.Pack("hashOperation", target, value, data, predecessor, salt) + if err != nil { + panic(err) + } + return enc +} + +// TryPackHashOperation is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x8065657f. This method will return an error +// if any inputs are invalid/nil. +// +// Solidity: function hashOperation(address target, uint256 value, bytes data, bytes32 predecessor, bytes32 salt) pure returns(bytes32) +func (timelockControllerImpl *TimelockControllerImpl) TryPackHashOperation(target common.Address, value *big.Int, data []byte, predecessor [32]byte, salt [32]byte) ([]byte, error) { + return timelockControllerImpl.abi.Pack("hashOperation", target, value, data, predecessor, salt) +} + +// UnpackHashOperation is the Go binding that unpacks the parameters returned +// from invoking the contract method with ID 0x8065657f. +// +// Solidity: function hashOperation(address target, uint256 value, bytes data, bytes32 predecessor, bytes32 salt) pure returns(bytes32) +func (timelockControllerImpl *TimelockControllerImpl) UnpackHashOperation(data []byte) ([32]byte, error) { + out, err := timelockControllerImpl.abi.Unpack("hashOperation", data) + if err != nil { + return *new([32]byte), err + } + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + return out0, nil +} + +// PackHashOperationBatch is the Go binding used to pack the parameters required for calling +// the contract method with ID 0xb1c5f427. This method will panic if any +// invalid/nil inputs are passed. +// +// Solidity: function hashOperationBatch(address[] targets, uint256[] values, bytes[] payloads, bytes32 predecessor, bytes32 salt) pure returns(bytes32) +func (timelockControllerImpl *TimelockControllerImpl) PackHashOperationBatch(targets []common.Address, values []*big.Int, payloads [][]byte, predecessor [32]byte, salt [32]byte) []byte { + enc, err := timelockControllerImpl.abi.Pack("hashOperationBatch", targets, values, payloads, predecessor, salt) + if err != nil { + panic(err) + } + return enc +} + +// TryPackHashOperationBatch is the Go binding used to pack the parameters required for calling +// the contract method with ID 0xb1c5f427. This method will return an error +// if any inputs are invalid/nil. +// +// Solidity: function hashOperationBatch(address[] targets, uint256[] values, bytes[] payloads, bytes32 predecessor, bytes32 salt) pure returns(bytes32) +func (timelockControllerImpl *TimelockControllerImpl) TryPackHashOperationBatch(targets []common.Address, values []*big.Int, payloads [][]byte, predecessor [32]byte, salt [32]byte) ([]byte, error) { + return timelockControllerImpl.abi.Pack("hashOperationBatch", targets, values, payloads, predecessor, salt) +} + +// UnpackHashOperationBatch is the Go binding that unpacks the parameters returned +// from invoking the contract method with ID 0xb1c5f427. +// +// Solidity: function hashOperationBatch(address[] targets, uint256[] values, bytes[] payloads, bytes32 predecessor, bytes32 salt) pure returns(bytes32) +func (timelockControllerImpl *TimelockControllerImpl) UnpackHashOperationBatch(data []byte) ([32]byte, error) { + out, err := timelockControllerImpl.abi.Unpack("hashOperationBatch", data) + if err != nil { + return *new([32]byte), err + } + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + return out0, nil +} + +// PackInitialize is the Go binding used to pack the parameters required for calling +// the contract method with ID 0xc4c4c7b3. This method will panic if any +// invalid/nil inputs are passed. +// +// Solidity: function initialize(uint256 minDelay, address[] proposers, address[] executors, address admin) returns() +func (timelockControllerImpl *TimelockControllerImpl) PackInitialize(minDelay *big.Int, proposers []common.Address, executors []common.Address, admin common.Address) []byte { + enc, err := timelockControllerImpl.abi.Pack("initialize", minDelay, proposers, executors, admin) + if err != nil { + panic(err) + } + return enc +} + +// TryPackInitialize is the Go binding used to pack the parameters required for calling +// the contract method with ID 0xc4c4c7b3. This method will return an error +// if any inputs are invalid/nil. +// +// Solidity: function initialize(uint256 minDelay, address[] proposers, address[] executors, address admin) returns() +func (timelockControllerImpl *TimelockControllerImpl) TryPackInitialize(minDelay *big.Int, proposers []common.Address, executors []common.Address, admin common.Address) ([]byte, error) { + return timelockControllerImpl.abi.Pack("initialize", minDelay, proposers, executors, admin) +} + +// PackIsOperation is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x31d50750. This method will panic if any +// invalid/nil inputs are passed. +// +// Solidity: function isOperation(bytes32 id) view returns(bool) +func (timelockControllerImpl *TimelockControllerImpl) PackIsOperation(id [32]byte) []byte { + enc, err := timelockControllerImpl.abi.Pack("isOperation", id) + if err != nil { + panic(err) + } + return enc +} + +// TryPackIsOperation is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x31d50750. This method will return an error +// if any inputs are invalid/nil. +// +// Solidity: function isOperation(bytes32 id) view returns(bool) +func (timelockControllerImpl *TimelockControllerImpl) TryPackIsOperation(id [32]byte) ([]byte, error) { + return timelockControllerImpl.abi.Pack("isOperation", id) +} + +// UnpackIsOperation is the Go binding that unpacks the parameters returned +// from invoking the contract method with ID 0x31d50750. +// +// Solidity: function isOperation(bytes32 id) view returns(bool) +func (timelockControllerImpl *TimelockControllerImpl) UnpackIsOperation(data []byte) (bool, error) { + out, err := timelockControllerImpl.abi.Unpack("isOperation", data) + if err != nil { + return *new(bool), err + } + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + return out0, nil +} + +// PackIsOperationDone is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x2ab0f529. This method will panic if any +// invalid/nil inputs are passed. +// +// Solidity: function isOperationDone(bytes32 id) view returns(bool) +func (timelockControllerImpl *TimelockControllerImpl) PackIsOperationDone(id [32]byte) []byte { + enc, err := timelockControllerImpl.abi.Pack("isOperationDone", id) + if err != nil { + panic(err) + } + return enc +} + +// TryPackIsOperationDone is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x2ab0f529. This method will return an error +// if any inputs are invalid/nil. +// +// Solidity: function isOperationDone(bytes32 id) view returns(bool) +func (timelockControllerImpl *TimelockControllerImpl) TryPackIsOperationDone(id [32]byte) ([]byte, error) { + return timelockControllerImpl.abi.Pack("isOperationDone", id) +} + +// UnpackIsOperationDone is the Go binding that unpacks the parameters returned +// from invoking the contract method with ID 0x2ab0f529. +// +// Solidity: function isOperationDone(bytes32 id) view returns(bool) +func (timelockControllerImpl *TimelockControllerImpl) UnpackIsOperationDone(data []byte) (bool, error) { + out, err := timelockControllerImpl.abi.Unpack("isOperationDone", data) + if err != nil { + return *new(bool), err + } + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + return out0, nil +} + +// PackIsOperationPending is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x584b153e. This method will panic if any +// invalid/nil inputs are passed. +// +// Solidity: function isOperationPending(bytes32 id) view returns(bool) +func (timelockControllerImpl *TimelockControllerImpl) PackIsOperationPending(id [32]byte) []byte { + enc, err := timelockControllerImpl.abi.Pack("isOperationPending", id) + if err != nil { + panic(err) + } + return enc +} + +// TryPackIsOperationPending is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x584b153e. This method will return an error +// if any inputs are invalid/nil. +// +// Solidity: function isOperationPending(bytes32 id) view returns(bool) +func (timelockControllerImpl *TimelockControllerImpl) TryPackIsOperationPending(id [32]byte) ([]byte, error) { + return timelockControllerImpl.abi.Pack("isOperationPending", id) +} + +// UnpackIsOperationPending is the Go binding that unpacks the parameters returned +// from invoking the contract method with ID 0x584b153e. +// +// Solidity: function isOperationPending(bytes32 id) view returns(bool) +func (timelockControllerImpl *TimelockControllerImpl) UnpackIsOperationPending(data []byte) (bool, error) { + out, err := timelockControllerImpl.abi.Unpack("isOperationPending", data) + if err != nil { + return *new(bool), err + } + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + return out0, nil +} + +// PackIsOperationReady is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x13bc9f20. This method will panic if any +// invalid/nil inputs are passed. +// +// Solidity: function isOperationReady(bytes32 id) view returns(bool) +func (timelockControllerImpl *TimelockControllerImpl) PackIsOperationReady(id [32]byte) []byte { + enc, err := timelockControllerImpl.abi.Pack("isOperationReady", id) + if err != nil { + panic(err) + } + return enc +} + +// TryPackIsOperationReady is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x13bc9f20. This method will return an error +// if any inputs are invalid/nil. +// +// Solidity: function isOperationReady(bytes32 id) view returns(bool) +func (timelockControllerImpl *TimelockControllerImpl) TryPackIsOperationReady(id [32]byte) ([]byte, error) { + return timelockControllerImpl.abi.Pack("isOperationReady", id) +} + +// UnpackIsOperationReady is the Go binding that unpacks the parameters returned +// from invoking the contract method with ID 0x13bc9f20. +// +// Solidity: function isOperationReady(bytes32 id) view returns(bool) +func (timelockControllerImpl *TimelockControllerImpl) UnpackIsOperationReady(data []byte) (bool, error) { + out, err := timelockControllerImpl.abi.Unpack("isOperationReady", data) + if err != nil { + return *new(bool), err + } + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + return out0, nil +} + +// PackOnERC1155BatchReceived is the Go binding used to pack the parameters required for calling +// the contract method with ID 0xbc197c81. This method will panic if any +// invalid/nil inputs are passed. +// +// Solidity: function onERC1155BatchReceived(address , address , uint256[] , uint256[] , bytes ) returns(bytes4) +func (timelockControllerImpl *TimelockControllerImpl) PackOnERC1155BatchReceived(arg0 common.Address, arg1 common.Address, arg2 []*big.Int, arg3 []*big.Int, arg4 []byte) []byte { + enc, err := timelockControllerImpl.abi.Pack("onERC1155BatchReceived", arg0, arg1, arg2, arg3, arg4) + if err != nil { + panic(err) + } + return enc +} + +// TryPackOnERC1155BatchReceived is the Go binding used to pack the parameters required for calling +// the contract method with ID 0xbc197c81. This method will return an error +// if any inputs are invalid/nil. +// +// Solidity: function onERC1155BatchReceived(address , address , uint256[] , uint256[] , bytes ) returns(bytes4) +func (timelockControllerImpl *TimelockControllerImpl) TryPackOnERC1155BatchReceived(arg0 common.Address, arg1 common.Address, arg2 []*big.Int, arg3 []*big.Int, arg4 []byte) ([]byte, error) { + return timelockControllerImpl.abi.Pack("onERC1155BatchReceived", arg0, arg1, arg2, arg3, arg4) +} + +// UnpackOnERC1155BatchReceived is the Go binding that unpacks the parameters returned +// from invoking the contract method with ID 0xbc197c81. +// +// Solidity: function onERC1155BatchReceived(address , address , uint256[] , uint256[] , bytes ) returns(bytes4) +func (timelockControllerImpl *TimelockControllerImpl) UnpackOnERC1155BatchReceived(data []byte) ([4]byte, error) { + out, err := timelockControllerImpl.abi.Unpack("onERC1155BatchReceived", data) + if err != nil { + return *new([4]byte), err + } + out0 := *abi.ConvertType(out[0], new([4]byte)).(*[4]byte) + return out0, nil +} + +// PackOnERC1155Received is the Go binding used to pack the parameters required for calling +// the contract method with ID 0xf23a6e61. This method will panic if any +// invalid/nil inputs are passed. +// +// Solidity: function onERC1155Received(address , address , uint256 , uint256 , bytes ) returns(bytes4) +func (timelockControllerImpl *TimelockControllerImpl) PackOnERC1155Received(arg0 common.Address, arg1 common.Address, arg2 *big.Int, arg3 *big.Int, arg4 []byte) []byte { + enc, err := timelockControllerImpl.abi.Pack("onERC1155Received", arg0, arg1, arg2, arg3, arg4) + if err != nil { + panic(err) + } + return enc +} + +// TryPackOnERC1155Received is the Go binding used to pack the parameters required for calling +// the contract method with ID 0xf23a6e61. This method will return an error +// if any inputs are invalid/nil. +// +// Solidity: function onERC1155Received(address , address , uint256 , uint256 , bytes ) returns(bytes4) +func (timelockControllerImpl *TimelockControllerImpl) TryPackOnERC1155Received(arg0 common.Address, arg1 common.Address, arg2 *big.Int, arg3 *big.Int, arg4 []byte) ([]byte, error) { + return timelockControllerImpl.abi.Pack("onERC1155Received", arg0, arg1, arg2, arg3, arg4) +} + +// UnpackOnERC1155Received is the Go binding that unpacks the parameters returned +// from invoking the contract method with ID 0xf23a6e61. +// +// Solidity: function onERC1155Received(address , address , uint256 , uint256 , bytes ) returns(bytes4) +func (timelockControllerImpl *TimelockControllerImpl) UnpackOnERC1155Received(data []byte) ([4]byte, error) { + out, err := timelockControllerImpl.abi.Unpack("onERC1155Received", data) + if err != nil { + return *new([4]byte), err + } + out0 := *abi.ConvertType(out[0], new([4]byte)).(*[4]byte) + return out0, nil +} + +// PackOnERC721Received is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x150b7a02. This method will panic if any +// invalid/nil inputs are passed. +// +// Solidity: function onERC721Received(address , address , uint256 , bytes ) returns(bytes4) +func (timelockControllerImpl *TimelockControllerImpl) PackOnERC721Received(arg0 common.Address, arg1 common.Address, arg2 *big.Int, arg3 []byte) []byte { + enc, err := timelockControllerImpl.abi.Pack("onERC721Received", arg0, arg1, arg2, arg3) + if err != nil { + panic(err) + } + return enc +} + +// TryPackOnERC721Received is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x150b7a02. This method will return an error +// if any inputs are invalid/nil. +// +// Solidity: function onERC721Received(address , address , uint256 , bytes ) returns(bytes4) +func (timelockControllerImpl *TimelockControllerImpl) TryPackOnERC721Received(arg0 common.Address, arg1 common.Address, arg2 *big.Int, arg3 []byte) ([]byte, error) { + return timelockControllerImpl.abi.Pack("onERC721Received", arg0, arg1, arg2, arg3) +} + +// UnpackOnERC721Received is the Go binding that unpacks the parameters returned +// from invoking the contract method with ID 0x150b7a02. +// +// Solidity: function onERC721Received(address , address , uint256 , bytes ) returns(bytes4) +func (timelockControllerImpl *TimelockControllerImpl) UnpackOnERC721Received(data []byte) ([4]byte, error) { + out, err := timelockControllerImpl.abi.Unpack("onERC721Received", data) + if err != nil { + return *new([4]byte), err + } + out0 := *abi.ConvertType(out[0], new([4]byte)).(*[4]byte) + return out0, nil +} + +// PackRenounceRole is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x36568abe. This method will panic if any +// invalid/nil inputs are passed. +// +// Solidity: function renounceRole(bytes32 role, address account) returns() +func (timelockControllerImpl *TimelockControllerImpl) PackRenounceRole(role [32]byte, account common.Address) []byte { + enc, err := timelockControllerImpl.abi.Pack("renounceRole", role, account) + if err != nil { + panic(err) + } + return enc +} + +// TryPackRenounceRole is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x36568abe. This method will return an error +// if any inputs are invalid/nil. +// +// Solidity: function renounceRole(bytes32 role, address account) returns() +func (timelockControllerImpl *TimelockControllerImpl) TryPackRenounceRole(role [32]byte, account common.Address) ([]byte, error) { + return timelockControllerImpl.abi.Pack("renounceRole", role, account) +} + +// PackRevokeRole is the Go binding used to pack the parameters required for calling +// the contract method with ID 0xd547741f. This method will panic if any +// invalid/nil inputs are passed. +// +// Solidity: function revokeRole(bytes32 role, address account) returns() +func (timelockControllerImpl *TimelockControllerImpl) PackRevokeRole(role [32]byte, account common.Address) []byte { + enc, err := timelockControllerImpl.abi.Pack("revokeRole", role, account) + if err != nil { + panic(err) + } + return enc +} + +// TryPackRevokeRole is the Go binding used to pack the parameters required for calling +// the contract method with ID 0xd547741f. This method will return an error +// if any inputs are invalid/nil. +// +// Solidity: function revokeRole(bytes32 role, address account) returns() +func (timelockControllerImpl *TimelockControllerImpl) TryPackRevokeRole(role [32]byte, account common.Address) ([]byte, error) { + return timelockControllerImpl.abi.Pack("revokeRole", role, account) +} + +// PackSchedule is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x01d5062a. This method will panic if any +// invalid/nil inputs are passed. +// +// Solidity: function schedule(address target, uint256 value, bytes data, bytes32 predecessor, bytes32 salt, uint256 delay) returns() +func (timelockControllerImpl *TimelockControllerImpl) PackSchedule(target common.Address, value *big.Int, data []byte, predecessor [32]byte, salt [32]byte, delay *big.Int) []byte { + enc, err := timelockControllerImpl.abi.Pack("schedule", target, value, data, predecessor, salt, delay) + if err != nil { + panic(err) + } + return enc +} + +// TryPackSchedule is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x01d5062a. This method will return an error +// if any inputs are invalid/nil. +// +// Solidity: function schedule(address target, uint256 value, bytes data, bytes32 predecessor, bytes32 salt, uint256 delay) returns() +func (timelockControllerImpl *TimelockControllerImpl) TryPackSchedule(target common.Address, value *big.Int, data []byte, predecessor [32]byte, salt [32]byte, delay *big.Int) ([]byte, error) { + return timelockControllerImpl.abi.Pack("schedule", target, value, data, predecessor, salt, delay) +} + +// PackScheduleBatch is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x8f2a0bb0. This method will panic if any +// invalid/nil inputs are passed. +// +// Solidity: function scheduleBatch(address[] targets, uint256[] values, bytes[] payloads, bytes32 predecessor, bytes32 salt, uint256 delay) returns() +func (timelockControllerImpl *TimelockControllerImpl) PackScheduleBatch(targets []common.Address, values []*big.Int, payloads [][]byte, predecessor [32]byte, salt [32]byte, delay *big.Int) []byte { + enc, err := timelockControllerImpl.abi.Pack("scheduleBatch", targets, values, payloads, predecessor, salt, delay) + if err != nil { + panic(err) + } + return enc +} + +// TryPackScheduleBatch is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x8f2a0bb0. This method will return an error +// if any inputs are invalid/nil. +// +// Solidity: function scheduleBatch(address[] targets, uint256[] values, bytes[] payloads, bytes32 predecessor, bytes32 salt, uint256 delay) returns() +func (timelockControllerImpl *TimelockControllerImpl) TryPackScheduleBatch(targets []common.Address, values []*big.Int, payloads [][]byte, predecessor [32]byte, salt [32]byte, delay *big.Int) ([]byte, error) { + return timelockControllerImpl.abi.Pack("scheduleBatch", targets, values, payloads, predecessor, salt, delay) +} + +// PackSupportsInterface is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x01ffc9a7. This method will panic if any +// invalid/nil inputs are passed. +// +// Solidity: function supportsInterface(bytes4 interfaceId) view returns(bool) +func (timelockControllerImpl *TimelockControllerImpl) PackSupportsInterface(interfaceId [4]byte) []byte { + enc, err := timelockControllerImpl.abi.Pack("supportsInterface", interfaceId) + if err != nil { + panic(err) + } + return enc +} + +// TryPackSupportsInterface is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x01ffc9a7. This method will return an error +// if any inputs are invalid/nil. +// +// Solidity: function supportsInterface(bytes4 interfaceId) view returns(bool) +func (timelockControllerImpl *TimelockControllerImpl) TryPackSupportsInterface(interfaceId [4]byte) ([]byte, error) { + return timelockControllerImpl.abi.Pack("supportsInterface", interfaceId) +} + +// UnpackSupportsInterface is the Go binding that unpacks the parameters returned +// from invoking the contract method with ID 0x01ffc9a7. +// +// Solidity: function supportsInterface(bytes4 interfaceId) view returns(bool) +func (timelockControllerImpl *TimelockControllerImpl) UnpackSupportsInterface(data []byte) (bool, error) { + out, err := timelockControllerImpl.abi.Unpack("supportsInterface", data) + if err != nil { + return *new(bool), err + } + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + return out0, nil +} + +// PackUpdateDelay is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x64d62353. This method will panic if any +// invalid/nil inputs are passed. +// +// Solidity: function updateDelay(uint256 newDelay) returns() +func (timelockControllerImpl *TimelockControllerImpl) PackUpdateDelay(newDelay *big.Int) []byte { + enc, err := timelockControllerImpl.abi.Pack("updateDelay", newDelay) + if err != nil { + panic(err) + } + return enc +} + +// TryPackUpdateDelay is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x64d62353. This method will return an error +// if any inputs are invalid/nil. +// +// Solidity: function updateDelay(uint256 newDelay) returns() +func (timelockControllerImpl *TimelockControllerImpl) TryPackUpdateDelay(newDelay *big.Int) ([]byte, error) { + return timelockControllerImpl.abi.Pack("updateDelay", newDelay) +} + +// TimelockControllerImplCallExecuted represents a CallExecuted event raised by the TimelockControllerImpl contract. +type TimelockControllerImplCallExecuted struct { + Id [32]byte + Index *big.Int + Target common.Address + Value *big.Int + Data []byte + Raw *types.Log // Blockchain specific contextual infos +} + +const TimelockControllerImplCallExecutedEventName = "CallExecuted" + +// ContractEventName returns the user-defined event name. +func (TimelockControllerImplCallExecuted) ContractEventName() string { + return TimelockControllerImplCallExecutedEventName +} + +// UnpackCallExecutedEvent is the Go binding that unpacks the event data emitted +// by contract. +// +// Solidity: event CallExecuted(bytes32 indexed id, uint256 indexed index, address target, uint256 value, bytes data) +func (timelockControllerImpl *TimelockControllerImpl) UnpackCallExecutedEvent(log *types.Log) (*TimelockControllerImplCallExecuted, error) { + event := "CallExecuted" + if len(log.Topics) == 0 || log.Topics[0] != timelockControllerImpl.abi.Events[event].ID { + return nil, errors.New("event signature mismatch") + } + out := new(TimelockControllerImplCallExecuted) + if len(log.Data) > 0 { + if err := timelockControllerImpl.abi.UnpackIntoInterface(out, event, log.Data); err != nil { + return nil, err + } + } + var indexed abi.Arguments + for _, arg := range timelockControllerImpl.abi.Events[event].Inputs { + if arg.Indexed { + indexed = append(indexed, arg) + } + } + if err := abi.ParseTopics(out, indexed, log.Topics[1:]); err != nil { + return nil, err + } + out.Raw = log + return out, nil +} + +// TimelockControllerImplCallSalt represents a CallSalt event raised by the TimelockControllerImpl contract. +type TimelockControllerImplCallSalt struct { + Id [32]byte + Salt [32]byte + Raw *types.Log // Blockchain specific contextual infos +} + +const TimelockControllerImplCallSaltEventName = "CallSalt" + +// ContractEventName returns the user-defined event name. +func (TimelockControllerImplCallSalt) ContractEventName() string { + return TimelockControllerImplCallSaltEventName +} + +// UnpackCallSaltEvent is the Go binding that unpacks the event data emitted +// by contract. +// +// Solidity: event CallSalt(bytes32 indexed id, bytes32 salt) +func (timelockControllerImpl *TimelockControllerImpl) UnpackCallSaltEvent(log *types.Log) (*TimelockControllerImplCallSalt, error) { + event := "CallSalt" + if len(log.Topics) == 0 || log.Topics[0] != timelockControllerImpl.abi.Events[event].ID { + return nil, errors.New("event signature mismatch") + } + out := new(TimelockControllerImplCallSalt) + if len(log.Data) > 0 { + if err := timelockControllerImpl.abi.UnpackIntoInterface(out, event, log.Data); err != nil { + return nil, err + } + } + var indexed abi.Arguments + for _, arg := range timelockControllerImpl.abi.Events[event].Inputs { + if arg.Indexed { + indexed = append(indexed, arg) + } + } + if err := abi.ParseTopics(out, indexed, log.Topics[1:]); err != nil { + return nil, err + } + out.Raw = log + return out, nil +} + +// TimelockControllerImplCallScheduled represents a CallScheduled event raised by the TimelockControllerImpl contract. +type TimelockControllerImplCallScheduled struct { + Id [32]byte + Index *big.Int + Target common.Address + Value *big.Int + Data []byte + Predecessor [32]byte + Delay *big.Int + Raw *types.Log // Blockchain specific contextual infos +} + +const TimelockControllerImplCallScheduledEventName = "CallScheduled" + +// ContractEventName returns the user-defined event name. +func (TimelockControllerImplCallScheduled) ContractEventName() string { + return TimelockControllerImplCallScheduledEventName +} + +// UnpackCallScheduledEvent is the Go binding that unpacks the event data emitted +// by contract. +// +// Solidity: event CallScheduled(bytes32 indexed id, uint256 indexed index, address target, uint256 value, bytes data, bytes32 predecessor, uint256 delay) +func (timelockControllerImpl *TimelockControllerImpl) UnpackCallScheduledEvent(log *types.Log) (*TimelockControllerImplCallScheduled, error) { + event := "CallScheduled" + if len(log.Topics) == 0 || log.Topics[0] != timelockControllerImpl.abi.Events[event].ID { + return nil, errors.New("event signature mismatch") + } + out := new(TimelockControllerImplCallScheduled) + if len(log.Data) > 0 { + if err := timelockControllerImpl.abi.UnpackIntoInterface(out, event, log.Data); err != nil { + return nil, err + } + } + var indexed abi.Arguments + for _, arg := range timelockControllerImpl.abi.Events[event].Inputs { + if arg.Indexed { + indexed = append(indexed, arg) + } + } + if err := abi.ParseTopics(out, indexed, log.Topics[1:]); err != nil { + return nil, err + } + out.Raw = log + return out, nil +} + +// TimelockControllerImplCancelled represents a Cancelled event raised by the TimelockControllerImpl contract. +type TimelockControllerImplCancelled struct { + Id [32]byte + Raw *types.Log // Blockchain specific contextual infos +} + +const TimelockControllerImplCancelledEventName = "Cancelled" + +// ContractEventName returns the user-defined event name. +func (TimelockControllerImplCancelled) ContractEventName() string { + return TimelockControllerImplCancelledEventName +} + +// UnpackCancelledEvent is the Go binding that unpacks the event data emitted +// by contract. +// +// Solidity: event Cancelled(bytes32 indexed id) +func (timelockControllerImpl *TimelockControllerImpl) UnpackCancelledEvent(log *types.Log) (*TimelockControllerImplCancelled, error) { + event := "Cancelled" + if len(log.Topics) == 0 || log.Topics[0] != timelockControllerImpl.abi.Events[event].ID { + return nil, errors.New("event signature mismatch") + } + out := new(TimelockControllerImplCancelled) + if len(log.Data) > 0 { + if err := timelockControllerImpl.abi.UnpackIntoInterface(out, event, log.Data); err != nil { + return nil, err + } + } + var indexed abi.Arguments + for _, arg := range timelockControllerImpl.abi.Events[event].Inputs { + if arg.Indexed { + indexed = append(indexed, arg) + } + } + if err := abi.ParseTopics(out, indexed, log.Topics[1:]); err != nil { + return nil, err + } + out.Raw = log + return out, nil +} + +// TimelockControllerImplInitialized represents a Initialized event raised by the TimelockControllerImpl contract. +type TimelockControllerImplInitialized struct { + Version uint8 + Raw *types.Log // Blockchain specific contextual infos +} + +const TimelockControllerImplInitializedEventName = "Initialized" + +// ContractEventName returns the user-defined event name. +func (TimelockControllerImplInitialized) ContractEventName() string { + return TimelockControllerImplInitializedEventName +} + +// UnpackInitializedEvent is the Go binding that unpacks the event data emitted +// by contract. +// +// Solidity: event Initialized(uint8 version) +func (timelockControllerImpl *TimelockControllerImpl) UnpackInitializedEvent(log *types.Log) (*TimelockControllerImplInitialized, error) { + event := "Initialized" + if len(log.Topics) == 0 || log.Topics[0] != timelockControllerImpl.abi.Events[event].ID { + return nil, errors.New("event signature mismatch") + } + out := new(TimelockControllerImplInitialized) + if len(log.Data) > 0 { + if err := timelockControllerImpl.abi.UnpackIntoInterface(out, event, log.Data); err != nil { + return nil, err + } + } + var indexed abi.Arguments + for _, arg := range timelockControllerImpl.abi.Events[event].Inputs { + if arg.Indexed { + indexed = append(indexed, arg) + } + } + if err := abi.ParseTopics(out, indexed, log.Topics[1:]); err != nil { + return nil, err + } + out.Raw = log + return out, nil +} + +// TimelockControllerImplMinDelayChange represents a MinDelayChange event raised by the TimelockControllerImpl contract. +type TimelockControllerImplMinDelayChange struct { + OldDuration *big.Int + NewDuration *big.Int + Raw *types.Log // Blockchain specific contextual infos +} + +const TimelockControllerImplMinDelayChangeEventName = "MinDelayChange" + +// ContractEventName returns the user-defined event name. +func (TimelockControllerImplMinDelayChange) ContractEventName() string { + return TimelockControllerImplMinDelayChangeEventName +} + +// UnpackMinDelayChangeEvent is the Go binding that unpacks the event data emitted +// by contract. +// +// Solidity: event MinDelayChange(uint256 oldDuration, uint256 newDuration) +func (timelockControllerImpl *TimelockControllerImpl) UnpackMinDelayChangeEvent(log *types.Log) (*TimelockControllerImplMinDelayChange, error) { + event := "MinDelayChange" + if len(log.Topics) == 0 || log.Topics[0] != timelockControllerImpl.abi.Events[event].ID { + return nil, errors.New("event signature mismatch") + } + out := new(TimelockControllerImplMinDelayChange) + if len(log.Data) > 0 { + if err := timelockControllerImpl.abi.UnpackIntoInterface(out, event, log.Data); err != nil { + return nil, err + } + } + var indexed abi.Arguments + for _, arg := range timelockControllerImpl.abi.Events[event].Inputs { + if arg.Indexed { + indexed = append(indexed, arg) + } + } + if err := abi.ParseTopics(out, indexed, log.Topics[1:]); err != nil { + return nil, err + } + out.Raw = log + return out, nil +} + +// TimelockControllerImplRoleAdminChanged represents a RoleAdminChanged event raised by the TimelockControllerImpl contract. +type TimelockControllerImplRoleAdminChanged struct { + Role [32]byte + PreviousAdminRole [32]byte + NewAdminRole [32]byte + Raw *types.Log // Blockchain specific contextual infos +} + +const TimelockControllerImplRoleAdminChangedEventName = "RoleAdminChanged" + +// ContractEventName returns the user-defined event name. +func (TimelockControllerImplRoleAdminChanged) ContractEventName() string { + return TimelockControllerImplRoleAdminChangedEventName +} + +// UnpackRoleAdminChangedEvent is the Go binding that unpacks the event data emitted +// by contract. +// +// Solidity: event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole) +func (timelockControllerImpl *TimelockControllerImpl) UnpackRoleAdminChangedEvent(log *types.Log) (*TimelockControllerImplRoleAdminChanged, error) { + event := "RoleAdminChanged" + if len(log.Topics) == 0 || log.Topics[0] != timelockControllerImpl.abi.Events[event].ID { + return nil, errors.New("event signature mismatch") + } + out := new(TimelockControllerImplRoleAdminChanged) + if len(log.Data) > 0 { + if err := timelockControllerImpl.abi.UnpackIntoInterface(out, event, log.Data); err != nil { + return nil, err + } + } + var indexed abi.Arguments + for _, arg := range timelockControllerImpl.abi.Events[event].Inputs { + if arg.Indexed { + indexed = append(indexed, arg) + } + } + if err := abi.ParseTopics(out, indexed, log.Topics[1:]); err != nil { + return nil, err + } + out.Raw = log + return out, nil +} + +// TimelockControllerImplRoleGranted represents a RoleGranted event raised by the TimelockControllerImpl contract. +type TimelockControllerImplRoleGranted struct { + Role [32]byte + Account common.Address + Sender common.Address + Raw *types.Log // Blockchain specific contextual infos +} + +const TimelockControllerImplRoleGrantedEventName = "RoleGranted" + +// ContractEventName returns the user-defined event name. +func (TimelockControllerImplRoleGranted) ContractEventName() string { + return TimelockControllerImplRoleGrantedEventName +} + +// UnpackRoleGrantedEvent is the Go binding that unpacks the event data emitted +// by contract. +// +// Solidity: event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender) +func (timelockControllerImpl *TimelockControllerImpl) UnpackRoleGrantedEvent(log *types.Log) (*TimelockControllerImplRoleGranted, error) { + event := "RoleGranted" + if len(log.Topics) == 0 || log.Topics[0] != timelockControllerImpl.abi.Events[event].ID { + return nil, errors.New("event signature mismatch") + } + out := new(TimelockControllerImplRoleGranted) + if len(log.Data) > 0 { + if err := timelockControllerImpl.abi.UnpackIntoInterface(out, event, log.Data); err != nil { + return nil, err + } + } + var indexed abi.Arguments + for _, arg := range timelockControllerImpl.abi.Events[event].Inputs { + if arg.Indexed { + indexed = append(indexed, arg) + } + } + if err := abi.ParseTopics(out, indexed, log.Topics[1:]); err != nil { + return nil, err + } + out.Raw = log + return out, nil +} + +// TimelockControllerImplRoleRevoked represents a RoleRevoked event raised by the TimelockControllerImpl contract. +type TimelockControllerImplRoleRevoked struct { + Role [32]byte + Account common.Address + Sender common.Address + Raw *types.Log // Blockchain specific contextual infos +} + +const TimelockControllerImplRoleRevokedEventName = "RoleRevoked" + +// ContractEventName returns the user-defined event name. +func (TimelockControllerImplRoleRevoked) ContractEventName() string { + return TimelockControllerImplRoleRevokedEventName +} + +// UnpackRoleRevokedEvent is the Go binding that unpacks the event data emitted +// by contract. +// +// Solidity: event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender) +func (timelockControllerImpl *TimelockControllerImpl) UnpackRoleRevokedEvent(log *types.Log) (*TimelockControllerImplRoleRevoked, error) { + event := "RoleRevoked" + if len(log.Topics) == 0 || log.Topics[0] != timelockControllerImpl.abi.Events[event].ID { + return nil, errors.New("event signature mismatch") + } + out := new(TimelockControllerImplRoleRevoked) + if len(log.Data) > 0 { + if err := timelockControllerImpl.abi.UnpackIntoInterface(out, event, log.Data); err != nil { + return nil, err + } + } + var indexed abi.Arguments + for _, arg := range timelockControllerImpl.abi.Events[event].Inputs { + if arg.Indexed { + indexed = append(indexed, arg) + } + } + if err := abi.ParseTopics(out, indexed, log.Topics[1:]); err != nil { + return nil, err + } + out.Raw = log + return out, nil +} From 1b815747772f0262d34229dbdec48c44c065071c Mon Sep 17 00:00:00 2001 From: Taras Shchybovyk Date: Wed, 15 Apr 2026 13:09:03 -0700 Subject: [PATCH 18/31] refactor: remove scheduleUpgrade/executeUpgrade, route all sensitive ops through Timelock MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit All sensitive operations (upgradeApp, terminateApp, transferOwnership, grantTeamRole ADMIN) now require msg.sender == owner when timelocked, enforcing that they go through Timelock.schedule → execute. The AppController-level scheduleUpgrade/executeUpgrade/cancelUpgrade functions and _pendingUpgrades storage are removed — the Timelock's own queue provides equivalent guarantees for all operations uniformly. --- src/AppController.sol | 51 +--- src/interfaces/IAppController.sol | 83 +----- src/storage/AppControllerStorage.sol | 5 +- test/AppController.t.sol | 371 ++------------------------- 4 files changed, 34 insertions(+), 476 deletions(-) diff --git a/src/AppController.sol b/src/AppController.sol index a6aff66..40155e0 100644 --- a/src/AppController.sol +++ b/src/AppController.sol @@ -179,7 +179,9 @@ contract AppController is /// @inheritdoc IAppController function upgradeApp(IApp app, Release calldata release) external appIsActive(app) onlyAdmin(app) returns (uint256) { - require(!_appConfigs[app].timelocked, TimelockRequired()); + if (_appConfigs[app].timelocked) { + require(msg.sender == _appConfigs[app].owner, InvalidPermissions()); + } return _upgradeApp(app, release); } @@ -193,8 +195,6 @@ contract AppController is } address previousOwner = _appConfigs[app].owner; _appConfigs[app].owner = newOwner; - // Timelock owner → timelocked = true (must use scheduleUpgrade/executeUpgrade) - // Safe or EOA owner → timelocked = false (upgradeApp directly; Safe handles threshold externally) _appConfigs[app].timelocked = safeTimelockFactory.isTimelock(newOwner); _grantRole(_teamRole(newOwner, TeamRole.ADMIN), newOwner); // Transfer active app accounting from old owner to new owner so that future @@ -206,46 +206,6 @@ contract AppController is emit AppOwnershipTransferred(app, previousOwner, newOwner); } - /// @inheritdoc IAppController - function scheduleUpgrade(IApp app, Release calldata release, uint256 delay) - external - appIsActive(app) - onlyAdmin(app) - { - require(_appConfigs[app].timelocked, NotTimelocked()); - require(release.rmsRelease.artifacts.length == 1, MoreThanOneArtifact()); - if (_pendingUpgrades[app].readyAt != 0) { - emit AppUpgradeCancelled(app); - } - uint256 readyAt = block.timestamp + delay; - _pendingUpgrades[app] = PendingUpgrade({releaseHash: keccak256(abi.encode(release)), readyAt: readyAt}); - emit AppUpgradeScheduled(app, readyAt, release); - } - - /// @inheritdoc IAppController - function executeUpgrade(IApp app, Release calldata release) - external - appIsActive(app) - onlyAdmin(app) - returns (uint256) - { - require(_appConfigs[app].timelocked, NotTimelocked()); - PendingUpgrade memory pending = _pendingUpgrades[app]; - require(pending.readyAt != 0, NoScheduledUpgrade()); - require(block.timestamp >= pending.readyAt, UpgradeNotReady()); - require(keccak256(abi.encode(release)) == pending.releaseHash, ReleaseMismatch()); - delete _pendingUpgrades[app]; - return _upgradeApp(app, release); - } - - /// @inheritdoc IAppController - function cancelUpgrade(IApp app) external appExists(app) onlyAdmin(app) { - require(_appConfigs[app].timelocked, NotTimelocked()); - require(_pendingUpgrades[app].readyAt != 0, NoScheduledUpgrade()); - delete _pendingUpgrades[app]; - emit AppUpgradeCancelled(app); - } - /// @inheritdoc IAppController function updateAppMetadataURI(IApp app, string calldata metadataURI) external @@ -611,11 +571,6 @@ contract AppController is /// VIEW FUNCTIONS - /// @inheritdoc IAppController - function getPendingUpgrade(IApp app) external view returns (PendingUpgrade memory) { - return _pendingUpgrades[app]; - } - /// @inheritdoc IAppController function getMaxActiveAppsPerUser(address user) external view returns (uint32) { return _userConfigs[user].maxActiveApps; diff --git a/src/interfaces/IAppController.sol b/src/interfaces/IAppController.sol index d10aa3f..058a3a3 100644 --- a/src/interfaces/IAppController.sol +++ b/src/interfaces/IAppController.sol @@ -33,22 +33,7 @@ interface IAppController { /// @notice Thrown when trying to revoke or renounce the last admin error CannotRevokeLastAdmin(); - /// @notice Thrown when calling upgradeApp on an app whose owner is a Timelock — use scheduleUpgrade + executeUpgrade - error TimelockRequired(); - - /// @notice Thrown when calling scheduleUpgrade/executeUpgrade on an app whose owner is not a Timelock - error NotTimelocked(); - - /// @notice Thrown when trying to execute an upgrade before the delay has elapsed - error UpgradeNotReady(); - - /// @notice Thrown when trying to execute with no pending upgrade - error NoScheduledUpgrade(); - - /// @notice Thrown when the release supplied to executeUpgrade does not match the scheduled hash - error ReleaseMismatch(); - - /// @notice Emitted when a new app is successfully created +/// @notice Emitted when a new app is successfully created event AppCreated(address indexed owner, IApp indexed app, uint32 operatorSetId); /// @notice Emitted when an app is upgraded @@ -81,13 +66,7 @@ interface IAppController { /// @notice Emitted when app ownership is transferred event AppOwnershipTransferred(IApp indexed app, address indexed previousOwner, address indexed newOwner); - /// @notice Emitted when an upgrade is scheduled for a timelocked app; off-chain controller takes no action - event AppUpgradeScheduled(IApp indexed app, uint256 readyAt, Release release); - - /// @notice Emitted when a pending upgrade is cancelled for a timelocked app - event AppUpgradeCancelled(IApp indexed app); - - /** +/** * @notice Enum for app status */ enum AppStatus { @@ -134,13 +113,7 @@ interface IAppController { uint32 operatorSetId; uint32 latestReleaseBlockNumber; AppStatus status; - bool timelocked; // true = owner is a Timelock; upgradeApp() blocked, must use scheduleUpgrade + executeUpgrade - } - - /// @notice A pending upgrade scheduled for a governed app - struct PendingUpgrade { - bytes32 releaseHash; // keccak256(abi.encode(release)) — verified at execution time - uint256 readyAt; // block.timestamp after which executeUpgrade() is allowed (0 = none pending) + bool timelocked; // true = owner is a factory Timelock; all sensitive ops must go through Timelock.schedule → execute } /// @notice User configuration and state @@ -201,64 +174,24 @@ interface IAppController { * @param app The app to upgrade with the release * @param release The release to upgrade to * @return releaseId The unique identifier for the published release - * @dev Caller must be UAM permissioned for the app + * @dev Caller must be an ADMIN for the app + * @dev When timelocked, caller must be the Timelock (owner) itself — route through Timelock.schedule → execute * @dev The rms release must have exactly one artifact, with the digest being the docker * image digest and the registry being the docker registry it is stored at. - * @dev The env must be a JSON marshalled bytes representing the public environment variables for the app. - * @dev The encryptedSecrets must be a JSON Web Encryption objects of the encrypted secrets for the app encrypted with - * the kms's public key. * @dev The app must not be AppStatus.TERMINATED */ function upgradeApp(IApp app, Release calldata release) external returns (uint256); /** - * @notice Transfers app ownership to a new address and enables governance mode + * @notice Transfers app ownership to a new address * @param app The app to transfer ownership of - * @param newOwner The new owner address (multisig or timelock) + * @param newOwner The new owner address * @dev Caller must be an ADMIN for the app - * @dev Once transferred, governance mode is permanent: upgradeApp() is blocked + * @dev When timelocked, caller must be the Timelock (owner) itself and new owner must also be a factory Timelock * @dev Grants ADMIN role to newOwner under the new team namespace */ function transferOwnership(IApp app, address newOwner) external; - /** - * @notice Schedules an upgrade for a timelocked app - * @param app The app to schedule an upgrade for - * @param release The release to upgrade to - * @param delay Seconds from now until the upgrade can be executed - * @dev Caller must be an ADMIN for the app - * @dev App owner must be a Timelock (timelocked == true) - * @dev A new schedule call overwrites any existing pending upgrade; emits AppUpgradeCancelled if one existed - */ - function scheduleUpgrade(IApp app, Release calldata release, uint256 delay) external; - - /** - * @notice Executes a previously scheduled upgrade after the delay has elapsed - * @param app The app to execute the pending upgrade for - * @param release The release to upgrade to — must match the hash committed in scheduleUpgrade - * @return releaseId The unique identifier for the published release - * @dev Caller must be an ADMIN for the app - * @dev App owner must be a Timelock with a pending upgrade whose readyAt <= block.timestamp - * @dev The release is not stored on-chain; callers must retrieve it from the AppUpgradeScheduled event - */ - function executeUpgrade(IApp app, Release calldata release) external returns (uint256); - - /** - * @notice Cancels a pending scheduled upgrade for a timelocked app - * @param app The app to cancel the pending upgrade for - * @dev Caller must be an ADMIN for the app - * @dev App owner must be a Timelock (timelocked == true) - * @dev Reverts with NoScheduledUpgrade if there is no pending upgrade to cancel - */ - function cancelUpgrade(IApp app) external; - - /** - * @notice Returns the pending upgrade for a timelocked app - * @param app The app to query - * @return The PendingUpgrade struct (readyAt == 0 means no pending upgrade) - */ - function getPendingUpgrade(IApp app) external view returns (PendingUpgrade memory); - /** * @notice Updates the metadata URI for an app * @param app The app to update the metadata URI for diff --git a/src/storage/AppControllerStorage.sol b/src/storage/AppControllerStorage.sol index 33d2402..7bc07c9 100644 --- a/src/storage/AppControllerStorage.sol +++ b/src/storage/AppControllerStorage.sol @@ -51,9 +51,6 @@ abstract contract AppControllerStorage is IAppController { /// @notice User configuration and state mapping(address => UserConfig) internal _userConfigs; - /// @notice Pending upgrades for governed apps - mapping(IApp => PendingUpgrade) internal _pendingUpgrades; - /// @inheritdoc IAppController uint32 public maxGlobalActiveApps; @@ -79,5 +76,5 @@ abstract contract AppControllerStorage is IAppController { * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ - uint256[44] private __gap; + uint256[45] private __gap; } diff --git a/test/AppController.t.sol b/test/AppController.t.sol index cde9d31..a09e54e 100644 --- a/test/AppController.t.sol +++ b/test/AppController.t.sol @@ -18,8 +18,6 @@ contract AppControllerTest is ComputeDeployer { event AppSuspendedByAdmin(IApp indexed app); event AppMetadataURIUpdated(IApp indexed app, string metadataURI); event AppOwnershipTransferred(IApp indexed app, address indexed previousOwner, address indexed newOwner); - event AppUpgradeScheduled(IApp indexed app, uint256 readyAt, IAppController.Release release); - event AppUpgradeCancelled(IApp indexed app); function setUp() public { _deployContracts(); @@ -1804,10 +1802,16 @@ contract AppControllerTest is ComputeDeployer { appController.transferOwnership(app, mockTimelock); assertEq(appController.getAppOwner(app), mockTimelock); - // Timelock owner must use scheduleUpgrade/executeUpgrade — direct upgrade blocked assertTrue(appController.getAppTimelocked(app), "Timelock owner should set timelocked"); + // Non-owner admin cannot call upgradeApp when timelocked + address otherAdmin = makeAddr("otherAdmin"); + vm.prank(mockTimelock); + appController.grantTeamRole(mockTimelock, IAppController.TeamRole.ADMIN, otherAdmin); + vm.prank(otherAdmin); + vm.expectRevert(PermissionControllerMixin.InvalidPermissions.selector); + appController.upgradeApp(app, _assembleRelease()); + // The Timelock itself can call upgradeApp directly vm.prank(mockTimelock); - vm.expectRevert(IAppController.TimelockRequired.selector); appController.upgradeApp(app, _assembleRelease()); } @@ -1991,360 +1995,37 @@ contract AppControllerTest is ComputeDeployer { assertTrue(appController.hasTeamRole(developer, IAppController.TeamRole.ADMIN, newAdmin)); } - // ========== scheduleUpgrade Tests ========== - - function test_scheduleUpgrade() public { - (IApp app, address mockSafe) = _createGovernedApp(); - - IAppController.Release memory release = _assembleRelease(); - uint256 delay = 2 hours; - - vm.prank(mockSafe); - appController.scheduleUpgrade(app, release, delay); - - IAppController.PendingUpgrade memory pending = appController.getPendingUpgrade(app); - assertEq(pending.readyAt, block.timestamp + delay); - assertEq(pending.releaseHash, keccak256(abi.encode(release))); - } - - function test_scheduleUpgrade_emitsEvent() public { - (IApp app, address mockSafe) = _createGovernedApp(); - - IAppController.Release memory release = _assembleRelease(); - uint256 delay = 2 hours; - - // Only verify the indexed app topic; Release data is too dynamic to match exactly - vm.expectEmit(true, false, false, false); - emit AppUpgradeScheduled(app, block.timestamp + delay, release); - - vm.prank(mockSafe); - appController.scheduleUpgrade(app, release, delay); - } - - function test_scheduleUpgrade_requiresGovernance() public { - vm.prank(developer); - IApp app = appController.createApp(SALT, _assembleRelease()); - - vm.prank(developer); - vm.expectRevert(IAppController.NotTimelocked.selector); - appController.scheduleUpgrade(app, _assembleRelease(), 1 hours); - } - - function test_scheduleUpgrade_requiresAdmin() public { - (IApp app,) = _createGovernedApp(); - - address rando = makeAddr("rando"); - vm.prank(rando); - vm.expectRevert(PermissionControllerMixin.InvalidPermissions.selector); - appController.scheduleUpgrade(app, _assembleRelease(), 1 hours); - } - - function test_scheduleUpgrade_overwriteEmitsCancelled() public { - (IApp app, address mockSafe) = _createGovernedApp(); - - vm.prank(mockSafe); - appController.scheduleUpgrade(app, _assembleRelease(), 2 hours); - - // Rescheduling with a pending upgrade should emit AppUpgradeCancelled before AppUpgradeScheduled - vm.expectEmit(true, false, false, false); - emit AppUpgradeCancelled(app); - - vm.prank(mockSafe); - appController.scheduleUpgrade(app, _assembleAltRelease(), 1 hours); - } - - function test_scheduleUpgrade_overwritesPending() public { - (IApp app, address mockSafe) = _createGovernedApp(); - - IAppController.Release memory release1 = _assembleRelease(); - IAppController.Release memory release2 = _assembleAltRelease(); - - vm.prank(mockSafe); - appController.scheduleUpgrade(app, release1, 1 hours); - - vm.prank(mockSafe); - appController.scheduleUpgrade(app, release2, 3 hours); - - IAppController.PendingUpgrade memory pending = appController.getPendingUpgrade(app); - assertEq(pending.releaseHash, keccak256(abi.encode(release2))); - assertEq(pending.readyAt, block.timestamp + 3 hours); - } - - function test_scheduleUpgrade_zeroDelay() public { - (IApp app, address mockSafe) = _createGovernedApp(); - - IAppController.Release memory release = _assembleRelease(); - - vm.prank(mockSafe); - appController.scheduleUpgrade(app, release, 0); - - assertEq(appController.getPendingUpgrade(app).readyAt, block.timestamp); - } - - // ========== executeUpgrade Tests ========== - - function test_executeUpgrade() public { - (IApp app, address mockSafe) = _createGovernedApp(); - - IAppController.Release memory release = _assembleRelease(); - uint256 delay = 2 hours; + // ========== upgradeApp timelocked ========== - vm.prank(mockSafe); - appController.scheduleUpgrade(app, release, delay); - - vm.warp(block.timestamp + delay); + function test_upgradeApp_timelocked_ownerCanUpgrade() public { + (IApp app, address mockTimelock) = _createGovernedApp(); - vm.prank(mockSafe); - uint256 releaseId = appController.executeUpgrade(app, release); + vm.prank(mockTimelock); + uint256 releaseId = appController.upgradeApp(app, _assembleRelease()); assertTrue(releaseId > 0); - assertEq(appController.getPendingUpgrade(app).readyAt, 0, "pending upgrade should be cleared"); - assertEq(appController.getAppLatestReleaseBlockNumber(app), uint32(block.number)); } - function test_executeUpgrade_atExactDelay() public { - (IApp app, address mockSafe) = _createGovernedApp(); - - IAppController.Release memory release = _assembleRelease(); - uint256 delay = 1 hours; - - vm.prank(mockSafe); - appController.scheduleUpgrade(app, release, delay); - - vm.warp(block.timestamp + delay); // exactly at readyAt - - vm.prank(mockSafe); - appController.executeUpgrade(app, release); // should not revert - } - - function test_executeUpgrade_requiresGovernance() public { - vm.prank(developer); - IApp app = appController.createApp(SALT, _assembleRelease()); - - vm.prank(developer); - vm.expectRevert(IAppController.NotTimelocked.selector); - appController.executeUpgrade(app, _assembleRelease()); - } - - function test_executeUpgrade_noScheduledUpgrade() public { - (IApp app, address mockSafe) = _createGovernedApp(); - - vm.prank(mockSafe); - vm.expectRevert(IAppController.NoScheduledUpgrade.selector); - appController.executeUpgrade(app, _assembleRelease()); - } - - function test_executeUpgrade_notReady() public { - (IApp app, address mockSafe) = _createGovernedApp(); - - IAppController.Release memory release = _assembleRelease(); - - vm.prank(mockSafe); - appController.scheduleUpgrade(app, release, 2 hours); - - vm.warp(block.timestamp + 2 hours - 1); - - vm.prank(mockSafe); - vm.expectRevert(IAppController.UpgradeNotReady.selector); - appController.executeUpgrade(app, release); - } - - function test_executeUpgrade_releaseMismatch() public { - (IApp app, address mockSafe) = _createGovernedApp(); - - vm.prank(mockSafe); - appController.scheduleUpgrade(app, _assembleRelease(), 1 hours); - - vm.warp(block.timestamp + 1 hours); - - vm.prank(mockSafe); - vm.expectRevert(IAppController.ReleaseMismatch.selector); - appController.executeUpgrade(app, _assembleAltRelease()); - } - - function test_executeUpgrade_requiresAdmin() public { - (IApp app, address mockSafe) = _createGovernedApp(); - - IAppController.Release memory release = _assembleRelease(); - - vm.prank(mockSafe); - appController.scheduleUpgrade(app, release, 1 hours); - - vm.warp(block.timestamp + 1 hours); - - address rando = makeAddr("rando"); - vm.prank(rando); - vm.expectRevert(PermissionControllerMixin.InvalidPermissions.selector); - appController.executeUpgrade(app, release); - } - - function test_executeUpgrade_clearsPendingAfterExecution() public { - (IApp app, address mockSafe) = _createGovernedApp(); - - IAppController.Release memory release = _assembleRelease(); - - vm.prank(mockSafe); - appController.scheduleUpgrade(app, release, 0); - - vm.prank(mockSafe); - appController.executeUpgrade(app, release); - - IAppController.PendingUpgrade memory pending = appController.getPendingUpgrade(app); - assertEq(pending.readyAt, 0); - assertEq(pending.releaseHash, bytes32(0)); - } - - // ========== cancelUpgrade Tests ========== - - function test_cancelUpgrade() public { - (IApp app, address mockSafe) = _createGovernedApp(); - - IAppController.Release memory release = _assembleRelease(); - - vm.prank(mockSafe); - appController.scheduleUpgrade(app, release, 2 hours); - - vm.prank(mockSafe); - appController.cancelUpgrade(app); - - IAppController.PendingUpgrade memory pending = appController.getPendingUpgrade(app); - assertEq(pending.readyAt, 0); - assertEq(pending.releaseHash, bytes32(0)); - } - - function test_cancelUpgrade_emitsEvent() public { - (IApp app, address mockSafe) = _createGovernedApp(); - - vm.prank(mockSafe); - appController.scheduleUpgrade(app, _assembleRelease(), 2 hours); - - vm.expectEmit(true, false, false, false); - emit AppUpgradeCancelled(app); - - vm.prank(mockSafe); - appController.cancelUpgrade(app); - } - - function test_cancelUpgrade_afterDelayElapsed() public { - (IApp app, address mockSafe) = _createGovernedApp(); - - IAppController.Release memory release = _assembleRelease(); - uint256 delay = 1 hours; - - vm.prank(mockSafe); - appController.scheduleUpgrade(app, release, delay); - - // Advance past readyAt — upgrade is executable but not yet executed - vm.warp(block.timestamp + delay + 1); - - vm.prank(mockSafe); - appController.cancelUpgrade(app); - - IAppController.PendingUpgrade memory pending = appController.getPendingUpgrade(app); - assertEq(pending.readyAt, 0); - } - - function test_cancelUpgrade_requiresGovernance() public { - vm.prank(developer); - IApp app = appController.createApp(SALT, _assembleRelease()); - - vm.prank(developer); - vm.expectRevert(IAppController.NotTimelocked.selector); - appController.cancelUpgrade(app); - } - - function test_cancelUpgrade_noPendingUpgrade() public { - (IApp app, address mockSafe) = _createGovernedApp(); - - vm.prank(mockSafe); - vm.expectRevert(IAppController.NoScheduledUpgrade.selector); - appController.cancelUpgrade(app); - } + function test_upgradeApp_timelocked_nonOwnerAdminReverts() public { + (IApp app, address mockTimelock) = _createGovernedApp(); - function test_cancelUpgrade_requiresAdmin() public { - (IApp app,) = _createGovernedApp(); + address otherAdmin = makeAddr("otherAdmin"); + vm.prank(mockTimelock); + appController.grantTeamRole(mockTimelock, IAppController.TeamRole.ADMIN, otherAdmin); - address rando = makeAddr("rando"); - vm.prank(rando); + vm.prank(otherAdmin); vm.expectRevert(PermissionControllerMixin.InvalidPermissions.selector); - appController.cancelUpgrade(app); - } - - function test_cancelUpgrade_allowsReschedule() public { - (IApp app, address mockSafe) = _createGovernedApp(); - - IAppController.Release memory release1 = _assembleRelease(); - - vm.prank(mockSafe); - appController.scheduleUpgrade(app, release1, 2 hours); - - vm.prank(mockSafe); - appController.cancelUpgrade(app); - - // Schedule again with a different release — should succeed - IAppController.Release memory release2 = _assembleAltRelease(); - vm.prank(mockSafe); - appController.scheduleUpgrade(app, release2, 1 hours); - - IAppController.PendingUpgrade memory pending = appController.getPendingUpgrade(app); - assertEq(pending.releaseHash, keccak256(abi.encode(release2))); - } - - // ========== upgradeApp blocked by governance ========== - - function test_upgradeApp_blockedWhenGoverned() public { - (IApp app, address mockSafe) = _createGovernedApp(); - - vm.prank(mockSafe); - vm.expectRevert(IAppController.TimelockRequired.selector); appController.upgradeApp(app, _assembleRelease()); } - // ========== Full governance flow ========== - - function test_governance_fullFlow() public { - // 1. EOA creates app — direct upgrade works + function test_upgradeApp_notTimelocked_anyAdminCanUpgrade() public { vm.prank(developer); IApp app = appController.createApp(SALT, _assembleRelease()); vm.prank(developer); - appController.upgradeApp(app, _assembleRelease()); // no revert - - // 2. Transfer ownership to Timelock — timelocked mode enabled - address mockTimelock = makeAddr("mockTimelock"); - _mockIsTimelock(mockTimelock); - - vm.prank(developer); - appController.transferOwnership(app, mockTimelock); - - assertEq(appController.getAppOwner(app), mockTimelock); - assertTrue(appController.getAppTimelocked(app)); - - // Direct upgrade now blocked - vm.prank(mockTimelock); - vm.expectRevert(IAppController.TimelockRequired.selector); - appController.upgradeApp(app, _assembleRelease()); - - // 3. Schedule upgrade - IAppController.Release memory release = _assembleRelease(); - uint256 delay = 2 hours; - - vm.prank(mockTimelock); - appController.scheduleUpgrade(app, release, delay); - - // Can't execute before delay - vm.prank(mockTimelock); - vm.expectRevert(IAppController.UpgradeNotReady.selector); - appController.executeUpgrade(app, release); - - // 4. Wait and execute - vm.warp(block.timestamp + delay); - - vm.prank(mockTimelock); - uint256 releaseId = appController.executeUpgrade(app, release); + uint256 releaseId = appController.upgradeApp(app, _assembleRelease()); assertTrue(releaseId > 0); - assertEq(appController.getPendingUpgrade(app).readyAt, 0, "pending upgrade should be cleared"); } // ========== Governance helpers ========== @@ -2376,13 +2057,5 @@ contract AppControllerTest is ComputeDeployer { ); } - function _assembleAltRelease() internal view returns (IAppController.Release memory) { - IReleaseManagerTypes.Artifact[] memory artifacts = new IReleaseManagerTypes.Artifact[](1); - artifacts[0] = IReleaseManagerTypes.Artifact({digest: keccak256("alt-digest"), registry: "ipfs://alt-registry"}); - - IReleaseManagerTypes.Release memory rmsRelease = - IReleaseManagerTypes.Release({artifacts: artifacts, upgradeByTime: uint32(block.timestamp + 2 days)}); - - return IAppController.Release({rmsRelease: rmsRelease, publicEnv: "alt", encryptedEnv: "alt"}); - } } + From c8acadd73f7df193f72bd5b41402c54aee008137 Mon Sep 17 00:00:00 2001 From: Taras Shchybovyk Date: Wed, 15 Apr 2026 13:20:56 -0700 Subject: [PATCH 19/31] chore: run forge fmt --- src/interfaces/IAppController.sol | 4 ++-- test/AppController.t.sol | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/interfaces/IAppController.sol b/src/interfaces/IAppController.sol index 058a3a3..d9759b5 100644 --- a/src/interfaces/IAppController.sol +++ b/src/interfaces/IAppController.sol @@ -33,7 +33,7 @@ interface IAppController { /// @notice Thrown when trying to revoke or renounce the last admin error CannotRevokeLastAdmin(); -/// @notice Emitted when a new app is successfully created + /// @notice Emitted when a new app is successfully created event AppCreated(address indexed owner, IApp indexed app, uint32 operatorSetId); /// @notice Emitted when an app is upgraded @@ -66,7 +66,7 @@ interface IAppController { /// @notice Emitted when app ownership is transferred event AppOwnershipTransferred(IApp indexed app, address indexed previousOwner, address indexed newOwner); -/** + /** * @notice Enum for app status */ enum AppStatus { diff --git a/test/AppController.t.sol b/test/AppController.t.sol index a09e54e..f2c562d 100644 --- a/test/AppController.t.sol +++ b/test/AppController.t.sol @@ -2056,6 +2056,5 @@ contract AppControllerTest is ComputeDeployer { abi.encode(true) ); } - } From cef7b480e7c5c4ebd5da7f76e75d2d4a1936102b Mon Sep 17 00:00:00 2001 From: Taras Shchybovyk Date: Wed, 15 Apr 2026 13:23:39 -0700 Subject: [PATCH 20/31] chore: regenerate Go bindings after scheduleUpgrade removal --- pkg/bindings/v1/AppController/binding.go | 392 +---------------------- pkg/bindings/v2/AppController/binding.go | 336 +------------------ 2 files changed, 2 insertions(+), 726 deletions(-) diff --git a/pkg/bindings/v1/AppController/binding.go b/pkg/bindings/v1/AppController/binding.go index 459aaf2..83a0827 100644 --- a/pkg/bindings/v1/AppController/binding.go +++ b/pkg/bindings/v1/AppController/binding.go @@ -45,12 +45,6 @@ type IAppControllerAppRoles struct { Roles []uint8 } -// IAppControllerPendingUpgrade is an auto generated low-level Go binding around an user-defined struct. -type IAppControllerPendingUpgrade struct { - ReleaseHash [32]byte - ReadyAt *big.Int -} - // IAppControllerRelease is an auto generated low-level Go binding around an user-defined struct. type IAppControllerRelease struct { RmsRelease IReleaseManagerTypesRelease @@ -72,7 +66,7 @@ type IReleaseManagerTypesRelease struct { // AppControllerMetaData contains all meta data concerning the AppController contract. var AppControllerMetaData = &bind.MetaData{ - ABI: "[{\"type\":\"constructor\",\"inputs\":[{\"name\":\"_version\",\"type\":\"string\",\"internalType\":\"string\"},{\"name\":\"_permissionController\",\"type\":\"address\",\"internalType\":\"contractIPermissionController\"},{\"name\":\"_releaseManager\",\"type\":\"address\",\"internalType\":\"contractIReleaseManager\"},{\"name\":\"_computeAVSRegistrar\",\"type\":\"address\",\"internalType\":\"contractIComputeAVSRegistrar\"},{\"name\":\"_computeOperator\",\"type\":\"address\",\"internalType\":\"contractIComputeOperator\"},{\"name\":\"_appBeacon\",\"type\":\"address\",\"internalType\":\"contractIBeacon\"},{\"name\":\"_safeTimelockFactory\",\"type\":\"address\",\"internalType\":\"contractISafeTimelockFactory\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"API_PERMISSION_TYPEHASH\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"DEFAULT_ADMIN_ROLE\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"appBeacon\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIBeacon\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"calculateApiPermissionDigestHash\",\"inputs\":[{\"name\":\"permission\",\"type\":\"bytes4\",\"internalType\":\"bytes4\"},{\"name\":\"expiry\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"calculateAppId\",\"inputs\":[{\"name\":\"deployer\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"salt\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"cancelUpgrade\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"computeAVSRegistrar\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIComputeAVSRegistrar\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"computeOperator\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIComputeOperator\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"createApp\",\"inputs\":[{\"name\":\"salt\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"release\",\"type\":\"tuple\",\"internalType\":\"structIAppController.Release\",\"components\":[{\"name\":\"rmsRelease\",\"type\":\"tuple\",\"internalType\":\"structIReleaseManagerTypes.Release\",\"components\":[{\"name\":\"artifacts\",\"type\":\"tuple[]\",\"internalType\":\"structIReleaseManagerTypes.Artifact[]\",\"components\":[{\"name\":\"digest\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"registry\",\"type\":\"string\",\"internalType\":\"string\"}]},{\"name\":\"upgradeByTime\",\"type\":\"uint32\",\"internalType\":\"uint32\"}]},{\"name\":\"publicEnv\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"encryptedEnv\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]}],\"outputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"createAppForTeam\",\"inputs\":[{\"name\":\"team\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"salt\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"release\",\"type\":\"tuple\",\"internalType\":\"structIAppController.Release\",\"components\":[{\"name\":\"rmsRelease\",\"type\":\"tuple\",\"internalType\":\"structIReleaseManagerTypes.Release\",\"components\":[{\"name\":\"artifacts\",\"type\":\"tuple[]\",\"internalType\":\"structIReleaseManagerTypes.Artifact[]\",\"components\":[{\"name\":\"digest\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"registry\",\"type\":\"string\",\"internalType\":\"string\"}]},{\"name\":\"upgradeByTime\",\"type\":\"uint32\",\"internalType\":\"uint32\"}]},{\"name\":\"publicEnv\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"encryptedEnv\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]}],\"outputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"domainSeparator\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"executeUpgrade\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"},{\"name\":\"release\",\"type\":\"tuple\",\"internalType\":\"structIAppController.Release\",\"components\":[{\"name\":\"rmsRelease\",\"type\":\"tuple\",\"internalType\":\"structIReleaseManagerTypes.Release\",\"components\":[{\"name\":\"artifacts\",\"type\":\"tuple[]\",\"internalType\":\"structIReleaseManagerTypes.Artifact[]\",\"components\":[{\"name\":\"digest\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"registry\",\"type\":\"string\",\"internalType\":\"string\"}]},{\"name\":\"upgradeByTime\",\"type\":\"uint32\",\"internalType\":\"uint32\"}]},{\"name\":\"publicEnv\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"encryptedEnv\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"getActiveAppCount\",\"inputs\":[{\"name\":\"user\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getAppLatestReleaseBlockNumber\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getAppOperatorSetId\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getAppOwner\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getAppStatus\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint8\",\"internalType\":\"enumIAppController.AppStatus\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getAppTimelocked\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getApps\",\"inputs\":[{\"name\":\"offset\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"limit\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"apps\",\"type\":\"address[]\",\"internalType\":\"contractIApp[]\"},{\"name\":\"appConfigsMem\",\"type\":\"tuple[]\",\"internalType\":\"structIAppController.AppConfig[]\",\"components\":[{\"name\":\"owner\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"operatorSetId\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"latestReleaseBlockNumber\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"status\",\"type\":\"uint8\",\"internalType\":\"enumIAppController.AppStatus\"},{\"name\":\"timelocked\",\"type\":\"bool\",\"internalType\":\"bool\"}]}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getAppsByCreator\",\"inputs\":[{\"name\":\"creator\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"offset\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"limit\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"apps\",\"type\":\"address[]\",\"internalType\":\"contractIApp[]\"},{\"name\":\"appConfigsMem\",\"type\":\"tuple[]\",\"internalType\":\"structIAppController.AppConfig[]\",\"components\":[{\"name\":\"owner\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"operatorSetId\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"latestReleaseBlockNumber\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"status\",\"type\":\"uint8\",\"internalType\":\"enumIAppController.AppStatus\"},{\"name\":\"timelocked\",\"type\":\"bool\",\"internalType\":\"bool\"}]}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getAppsByDeveloper\",\"inputs\":[{\"name\":\"developer\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"offset\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"limit\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"apps\",\"type\":\"address[]\",\"internalType\":\"contractIApp[]\"},{\"name\":\"appConfigsMem\",\"type\":\"tuple[]\",\"internalType\":\"structIAppController.AppConfig[]\",\"components\":[{\"name\":\"owner\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"operatorSetId\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"latestReleaseBlockNumber\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"status\",\"type\":\"uint8\",\"internalType\":\"enumIAppController.AppStatus\"},{\"name\":\"timelocked\",\"type\":\"bool\",\"internalType\":\"bool\"}]}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getAppsForAccount\",\"inputs\":[{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"offset\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"limit\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"appRoles\",\"type\":\"tuple[]\",\"internalType\":\"structIAppController.AppRoles[]\",\"components\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"},{\"name\":\"isOwner\",\"type\":\"bool\",\"internalType\":\"bool\"},{\"name\":\"roles\",\"type\":\"uint8[]\",\"internalType\":\"enumIAppController.TeamRole[]\"}]}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getMaxActiveAppsPerUser\",\"inputs\":[{\"name\":\"user\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getPendingUpgrade\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"outputs\":[{\"name\":\"\",\"type\":\"tuple\",\"internalType\":\"structIAppController.PendingUpgrade\",\"components\":[{\"name\":\"releaseHash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"readyAt\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getRoleAdmin\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getRoleMember\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"index\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getRoleMemberCount\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getTeamRoleMember\",\"inputs\":[{\"name\":\"team\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"role\",\"type\":\"uint8\",\"internalType\":\"enumIAppController.TeamRole\"},{\"name\":\"index\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getTeamRoleMemberCount\",\"inputs\":[{\"name\":\"team\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"role\",\"type\":\"uint8\",\"internalType\":\"enumIAppController.TeamRole\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getTeamRoleMembers\",\"inputs\":[{\"name\":\"team\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"role\",\"type\":\"uint8\",\"internalType\":\"enumIAppController.TeamRole\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address[]\",\"internalType\":\"address[]\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"globalActiveAppCount\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"grantRole\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"grantTeamRole\",\"inputs\":[{\"name\":\"team\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"role\",\"type\":\"uint8\",\"internalType\":\"enumIAppController.TeamRole\"},{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"hasRole\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"hasTeamRole\",\"inputs\":[{\"name\":\"team\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"role\",\"type\":\"uint8\",\"internalType\":\"enumIAppController.TeamRole\"},{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"initialize\",\"inputs\":[{\"name\":\"admin\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"maxGlobalActiveApps\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"migrateAdmins\",\"inputs\":[{\"name\":\"apps\",\"type\":\"address[]\",\"internalType\":\"contractIApp[]\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"permissionController\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIPermissionController\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"releaseManager\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIReleaseManager\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"renounceRole\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"renounceTeamRole\",\"inputs\":[{\"name\":\"team\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"role\",\"type\":\"uint8\",\"internalType\":\"enumIAppController.TeamRole\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"revokeRole\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"revokeTeamRole\",\"inputs\":[{\"name\":\"team\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"role\",\"type\":\"uint8\",\"internalType\":\"enumIAppController.TeamRole\"},{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"safeTimelockFactory\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractISafeTimelockFactory\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"scheduleUpgrade\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"},{\"name\":\"release\",\"type\":\"tuple\",\"internalType\":\"structIAppController.Release\",\"components\":[{\"name\":\"rmsRelease\",\"type\":\"tuple\",\"internalType\":\"structIReleaseManagerTypes.Release\",\"components\":[{\"name\":\"artifacts\",\"type\":\"tuple[]\",\"internalType\":\"structIReleaseManagerTypes.Artifact[]\",\"components\":[{\"name\":\"digest\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"registry\",\"type\":\"string\",\"internalType\":\"string\"}]},{\"name\":\"upgradeByTime\",\"type\":\"uint32\",\"internalType\":\"uint32\"}]},{\"name\":\"publicEnv\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"encryptedEnv\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]},{\"name\":\"delay\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"setMaxActiveAppsPerUser\",\"inputs\":[{\"name\":\"user\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"limit\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"setMaxGlobalActiveApps\",\"inputs\":[{\"name\":\"limit\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"startApp\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"stopApp\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"supportsInterface\",\"inputs\":[{\"name\":\"interfaceId\",\"type\":\"bytes4\",\"internalType\":\"bytes4\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"suspend\",\"inputs\":[{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"apps\",\"type\":\"address[]\",\"internalType\":\"contractIApp[]\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"terminateApp\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"terminateAppByAdmin\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"transferOwnership\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"},{\"name\":\"newOwner\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"updateAppMetadataURI\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"},{\"name\":\"metadataURI\",\"type\":\"string\",\"internalType\":\"string\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"upgradeApp\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"},{\"name\":\"release\",\"type\":\"tuple\",\"internalType\":\"structIAppController.Release\",\"components\":[{\"name\":\"rmsRelease\",\"type\":\"tuple\",\"internalType\":\"structIReleaseManagerTypes.Release\",\"components\":[{\"name\":\"artifacts\",\"type\":\"tuple[]\",\"internalType\":\"structIReleaseManagerTypes.Artifact[]\",\"components\":[{\"name\":\"digest\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"registry\",\"type\":\"string\",\"internalType\":\"string\"}]},{\"name\":\"upgradeByTime\",\"type\":\"uint32\",\"internalType\":\"uint32\"}]},{\"name\":\"publicEnv\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"encryptedEnv\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"version\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"string\",\"internalType\":\"string\"}],\"stateMutability\":\"view\"},{\"type\":\"event\",\"name\":\"AppCreated\",\"inputs\":[{\"name\":\"owner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"app\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"contractIApp\"},{\"name\":\"operatorSetId\",\"type\":\"uint32\",\"indexed\":false,\"internalType\":\"uint32\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"AppMetadataURIUpdated\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"contractIApp\"},{\"name\":\"metadataURI\",\"type\":\"string\",\"indexed\":false,\"internalType\":\"string\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"AppOwnershipTransferred\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"contractIApp\"},{\"name\":\"previousOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"newOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"AppStarted\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"contractIApp\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"AppStopped\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"contractIApp\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"AppSuspended\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"contractIApp\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"AppTerminated\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"contractIApp\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"AppTerminatedByAdmin\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"contractIApp\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"AppUpgradeCancelled\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"contractIApp\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"AppUpgradeScheduled\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"contractIApp\"},{\"name\":\"readyAt\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"release\",\"type\":\"tuple\",\"indexed\":false,\"internalType\":\"structIAppController.Release\",\"components\":[{\"name\":\"rmsRelease\",\"type\":\"tuple\",\"internalType\":\"structIReleaseManagerTypes.Release\",\"components\":[{\"name\":\"artifacts\",\"type\":\"tuple[]\",\"internalType\":\"structIReleaseManagerTypes.Artifact[]\",\"components\":[{\"name\":\"digest\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"registry\",\"type\":\"string\",\"internalType\":\"string\"}]},{\"name\":\"upgradeByTime\",\"type\":\"uint32\",\"internalType\":\"uint32\"}]},{\"name\":\"publicEnv\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"encryptedEnv\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"AppUpgraded\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"contractIApp\"},{\"name\":\"rmsReleaseId\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"release\",\"type\":\"tuple\",\"indexed\":false,\"internalType\":\"structIAppController.Release\",\"components\":[{\"name\":\"rmsRelease\",\"type\":\"tuple\",\"internalType\":\"structIReleaseManagerTypes.Release\",\"components\":[{\"name\":\"artifacts\",\"type\":\"tuple[]\",\"internalType\":\"structIReleaseManagerTypes.Artifact[]\",\"components\":[{\"name\":\"digest\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"registry\",\"type\":\"string\",\"internalType\":\"string\"}]},{\"name\":\"upgradeByTime\",\"type\":\"uint32\",\"internalType\":\"uint32\"}]},{\"name\":\"publicEnv\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"encryptedEnv\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"GlobalMaxActiveAppsSet\",\"inputs\":[{\"name\":\"limit\",\"type\":\"uint32\",\"indexed\":false,\"internalType\":\"uint32\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Initialized\",\"inputs\":[{\"name\":\"version\",\"type\":\"uint8\",\"indexed\":false,\"internalType\":\"uint8\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"MaxActiveAppsSet\",\"inputs\":[{\"name\":\"user\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"limit\",\"type\":\"uint32\",\"indexed\":false,\"internalType\":\"uint32\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"RoleAdminChanged\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"previousAdminRole\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"newAdminRole\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"RoleGranted\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"account\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"sender\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"RoleRevoked\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"account\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"sender\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"error\",\"name\":\"AccountHasActiveApps\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"AppAlreadyExists\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"AppDoesNotExist\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"CannotRevokeLastAdmin\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"GlobalMaxActiveAppsExceeded\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidAppStatus\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidPermissions\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidReleaseMetadataURI\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidShortString\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidSignature\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"MaxActiveAppsExceeded\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"MoreThanOneArtifact\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"NoScheduledUpgrade\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"NotTimelocked\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"ReleaseMismatch\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"SignatureExpired\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"StringTooLong\",\"inputs\":[{\"name\":\"str\",\"type\":\"string\",\"internalType\":\"string\"}]},{\"type\":\"error\",\"name\":\"TimelockRequired\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"UpgradeNotReady\",\"inputs\":[]}]", + ABI: "[{\"type\":\"constructor\",\"inputs\":[{\"name\":\"_version\",\"type\":\"string\",\"internalType\":\"string\"},{\"name\":\"_permissionController\",\"type\":\"address\",\"internalType\":\"contractIPermissionController\"},{\"name\":\"_releaseManager\",\"type\":\"address\",\"internalType\":\"contractIReleaseManager\"},{\"name\":\"_computeAVSRegistrar\",\"type\":\"address\",\"internalType\":\"contractIComputeAVSRegistrar\"},{\"name\":\"_computeOperator\",\"type\":\"address\",\"internalType\":\"contractIComputeOperator\"},{\"name\":\"_appBeacon\",\"type\":\"address\",\"internalType\":\"contractIBeacon\"},{\"name\":\"_safeTimelockFactory\",\"type\":\"address\",\"internalType\":\"contractISafeTimelockFactory\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"API_PERMISSION_TYPEHASH\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"DEFAULT_ADMIN_ROLE\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"appBeacon\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIBeacon\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"calculateApiPermissionDigestHash\",\"inputs\":[{\"name\":\"permission\",\"type\":\"bytes4\",\"internalType\":\"bytes4\"},{\"name\":\"expiry\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"calculateAppId\",\"inputs\":[{\"name\":\"deployer\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"salt\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"computeAVSRegistrar\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIComputeAVSRegistrar\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"computeOperator\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIComputeOperator\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"createApp\",\"inputs\":[{\"name\":\"salt\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"release\",\"type\":\"tuple\",\"internalType\":\"structIAppController.Release\",\"components\":[{\"name\":\"rmsRelease\",\"type\":\"tuple\",\"internalType\":\"structIReleaseManagerTypes.Release\",\"components\":[{\"name\":\"artifacts\",\"type\":\"tuple[]\",\"internalType\":\"structIReleaseManagerTypes.Artifact[]\",\"components\":[{\"name\":\"digest\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"registry\",\"type\":\"string\",\"internalType\":\"string\"}]},{\"name\":\"upgradeByTime\",\"type\":\"uint32\",\"internalType\":\"uint32\"}]},{\"name\":\"publicEnv\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"encryptedEnv\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]}],\"outputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"createAppForTeam\",\"inputs\":[{\"name\":\"team\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"salt\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"release\",\"type\":\"tuple\",\"internalType\":\"structIAppController.Release\",\"components\":[{\"name\":\"rmsRelease\",\"type\":\"tuple\",\"internalType\":\"structIReleaseManagerTypes.Release\",\"components\":[{\"name\":\"artifacts\",\"type\":\"tuple[]\",\"internalType\":\"structIReleaseManagerTypes.Artifact[]\",\"components\":[{\"name\":\"digest\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"registry\",\"type\":\"string\",\"internalType\":\"string\"}]},{\"name\":\"upgradeByTime\",\"type\":\"uint32\",\"internalType\":\"uint32\"}]},{\"name\":\"publicEnv\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"encryptedEnv\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]}],\"outputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"domainSeparator\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getActiveAppCount\",\"inputs\":[{\"name\":\"user\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getAppLatestReleaseBlockNumber\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getAppOperatorSetId\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getAppOwner\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getAppStatus\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint8\",\"internalType\":\"enumIAppController.AppStatus\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getAppTimelocked\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getApps\",\"inputs\":[{\"name\":\"offset\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"limit\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"apps\",\"type\":\"address[]\",\"internalType\":\"contractIApp[]\"},{\"name\":\"appConfigsMem\",\"type\":\"tuple[]\",\"internalType\":\"structIAppController.AppConfig[]\",\"components\":[{\"name\":\"owner\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"operatorSetId\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"latestReleaseBlockNumber\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"status\",\"type\":\"uint8\",\"internalType\":\"enumIAppController.AppStatus\"},{\"name\":\"timelocked\",\"type\":\"bool\",\"internalType\":\"bool\"}]}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getAppsByCreator\",\"inputs\":[{\"name\":\"creator\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"offset\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"limit\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"apps\",\"type\":\"address[]\",\"internalType\":\"contractIApp[]\"},{\"name\":\"appConfigsMem\",\"type\":\"tuple[]\",\"internalType\":\"structIAppController.AppConfig[]\",\"components\":[{\"name\":\"owner\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"operatorSetId\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"latestReleaseBlockNumber\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"status\",\"type\":\"uint8\",\"internalType\":\"enumIAppController.AppStatus\"},{\"name\":\"timelocked\",\"type\":\"bool\",\"internalType\":\"bool\"}]}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getAppsByDeveloper\",\"inputs\":[{\"name\":\"developer\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"offset\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"limit\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"apps\",\"type\":\"address[]\",\"internalType\":\"contractIApp[]\"},{\"name\":\"appConfigsMem\",\"type\":\"tuple[]\",\"internalType\":\"structIAppController.AppConfig[]\",\"components\":[{\"name\":\"owner\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"operatorSetId\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"latestReleaseBlockNumber\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"status\",\"type\":\"uint8\",\"internalType\":\"enumIAppController.AppStatus\"},{\"name\":\"timelocked\",\"type\":\"bool\",\"internalType\":\"bool\"}]}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getAppsForAccount\",\"inputs\":[{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"offset\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"limit\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"appRoles\",\"type\":\"tuple[]\",\"internalType\":\"structIAppController.AppRoles[]\",\"components\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"},{\"name\":\"isOwner\",\"type\":\"bool\",\"internalType\":\"bool\"},{\"name\":\"roles\",\"type\":\"uint8[]\",\"internalType\":\"enumIAppController.TeamRole[]\"}]}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getMaxActiveAppsPerUser\",\"inputs\":[{\"name\":\"user\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getRoleAdmin\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getRoleMember\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"index\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getRoleMemberCount\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getTeamRoleMember\",\"inputs\":[{\"name\":\"team\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"role\",\"type\":\"uint8\",\"internalType\":\"enumIAppController.TeamRole\"},{\"name\":\"index\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getTeamRoleMemberCount\",\"inputs\":[{\"name\":\"team\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"role\",\"type\":\"uint8\",\"internalType\":\"enumIAppController.TeamRole\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getTeamRoleMembers\",\"inputs\":[{\"name\":\"team\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"role\",\"type\":\"uint8\",\"internalType\":\"enumIAppController.TeamRole\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address[]\",\"internalType\":\"address[]\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"globalActiveAppCount\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"grantRole\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"grantTeamRole\",\"inputs\":[{\"name\":\"team\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"role\",\"type\":\"uint8\",\"internalType\":\"enumIAppController.TeamRole\"},{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"hasRole\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"hasTeamRole\",\"inputs\":[{\"name\":\"team\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"role\",\"type\":\"uint8\",\"internalType\":\"enumIAppController.TeamRole\"},{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"initialize\",\"inputs\":[{\"name\":\"admin\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"maxGlobalActiveApps\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"migrateAdmins\",\"inputs\":[{\"name\":\"apps\",\"type\":\"address[]\",\"internalType\":\"contractIApp[]\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"permissionController\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIPermissionController\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"releaseManager\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIReleaseManager\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"renounceRole\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"renounceTeamRole\",\"inputs\":[{\"name\":\"team\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"role\",\"type\":\"uint8\",\"internalType\":\"enumIAppController.TeamRole\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"revokeRole\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"revokeTeamRole\",\"inputs\":[{\"name\":\"team\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"role\",\"type\":\"uint8\",\"internalType\":\"enumIAppController.TeamRole\"},{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"safeTimelockFactory\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractISafeTimelockFactory\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"setMaxActiveAppsPerUser\",\"inputs\":[{\"name\":\"user\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"limit\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"setMaxGlobalActiveApps\",\"inputs\":[{\"name\":\"limit\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"startApp\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"stopApp\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"supportsInterface\",\"inputs\":[{\"name\":\"interfaceId\",\"type\":\"bytes4\",\"internalType\":\"bytes4\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"suspend\",\"inputs\":[{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"apps\",\"type\":\"address[]\",\"internalType\":\"contractIApp[]\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"terminateApp\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"terminateAppByAdmin\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"transferOwnership\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"},{\"name\":\"newOwner\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"updateAppMetadataURI\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"},{\"name\":\"metadataURI\",\"type\":\"string\",\"internalType\":\"string\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"upgradeApp\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"},{\"name\":\"release\",\"type\":\"tuple\",\"internalType\":\"structIAppController.Release\",\"components\":[{\"name\":\"rmsRelease\",\"type\":\"tuple\",\"internalType\":\"structIReleaseManagerTypes.Release\",\"components\":[{\"name\":\"artifacts\",\"type\":\"tuple[]\",\"internalType\":\"structIReleaseManagerTypes.Artifact[]\",\"components\":[{\"name\":\"digest\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"registry\",\"type\":\"string\",\"internalType\":\"string\"}]},{\"name\":\"upgradeByTime\",\"type\":\"uint32\",\"internalType\":\"uint32\"}]},{\"name\":\"publicEnv\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"encryptedEnv\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"version\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"string\",\"internalType\":\"string\"}],\"stateMutability\":\"view\"},{\"type\":\"event\",\"name\":\"AppCreated\",\"inputs\":[{\"name\":\"owner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"app\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"contractIApp\"},{\"name\":\"operatorSetId\",\"type\":\"uint32\",\"indexed\":false,\"internalType\":\"uint32\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"AppMetadataURIUpdated\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"contractIApp\"},{\"name\":\"metadataURI\",\"type\":\"string\",\"indexed\":false,\"internalType\":\"string\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"AppOwnershipTransferred\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"contractIApp\"},{\"name\":\"previousOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"newOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"AppStarted\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"contractIApp\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"AppStopped\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"contractIApp\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"AppSuspended\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"contractIApp\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"AppTerminated\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"contractIApp\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"AppTerminatedByAdmin\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"contractIApp\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"AppUpgraded\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"contractIApp\"},{\"name\":\"rmsReleaseId\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"release\",\"type\":\"tuple\",\"indexed\":false,\"internalType\":\"structIAppController.Release\",\"components\":[{\"name\":\"rmsRelease\",\"type\":\"tuple\",\"internalType\":\"structIReleaseManagerTypes.Release\",\"components\":[{\"name\":\"artifacts\",\"type\":\"tuple[]\",\"internalType\":\"structIReleaseManagerTypes.Artifact[]\",\"components\":[{\"name\":\"digest\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"registry\",\"type\":\"string\",\"internalType\":\"string\"}]},{\"name\":\"upgradeByTime\",\"type\":\"uint32\",\"internalType\":\"uint32\"}]},{\"name\":\"publicEnv\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"encryptedEnv\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"GlobalMaxActiveAppsSet\",\"inputs\":[{\"name\":\"limit\",\"type\":\"uint32\",\"indexed\":false,\"internalType\":\"uint32\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Initialized\",\"inputs\":[{\"name\":\"version\",\"type\":\"uint8\",\"indexed\":false,\"internalType\":\"uint8\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"MaxActiveAppsSet\",\"inputs\":[{\"name\":\"user\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"limit\",\"type\":\"uint32\",\"indexed\":false,\"internalType\":\"uint32\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"RoleAdminChanged\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"previousAdminRole\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"newAdminRole\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"RoleGranted\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"account\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"sender\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"RoleRevoked\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"account\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"sender\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"error\",\"name\":\"AccountHasActiveApps\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"AppAlreadyExists\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"AppDoesNotExist\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"CannotRevokeLastAdmin\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"GlobalMaxActiveAppsExceeded\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidAppStatus\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidPermissions\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidReleaseMetadataURI\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidShortString\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidSignature\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"MaxActiveAppsExceeded\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"MoreThanOneArtifact\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"SignatureExpired\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"StringTooLong\",\"inputs\":[{\"name\":\"str\",\"type\":\"string\",\"internalType\":\"string\"}]}]", } // AppControllerABI is the input ABI used to generate the binding from. @@ -852,37 +846,6 @@ func (_AppController *AppControllerCallerSession) GetMaxActiveAppsPerUser(user c return _AppController.Contract.GetMaxActiveAppsPerUser(&_AppController.CallOpts, user) } -// GetPendingUpgrade is a free data retrieval call binding the contract method 0x57ececcd. -// -// Solidity: function getPendingUpgrade(address app) view returns((bytes32,uint256)) -func (_AppController *AppControllerCaller) GetPendingUpgrade(opts *bind.CallOpts, app common.Address) (IAppControllerPendingUpgrade, error) { - var out []interface{} - err := _AppController.contract.Call(opts, &out, "getPendingUpgrade", app) - - if err != nil { - return *new(IAppControllerPendingUpgrade), err - } - - out0 := *abi.ConvertType(out[0], new(IAppControllerPendingUpgrade)).(*IAppControllerPendingUpgrade) - - return out0, err - -} - -// GetPendingUpgrade is a free data retrieval call binding the contract method 0x57ececcd. -// -// Solidity: function getPendingUpgrade(address app) view returns((bytes32,uint256)) -func (_AppController *AppControllerSession) GetPendingUpgrade(app common.Address) (IAppControllerPendingUpgrade, error) { - return _AppController.Contract.GetPendingUpgrade(&_AppController.CallOpts, app) -} - -// GetPendingUpgrade is a free data retrieval call binding the contract method 0x57ececcd. -// -// Solidity: function getPendingUpgrade(address app) view returns((bytes32,uint256)) -func (_AppController *AppControllerCallerSession) GetPendingUpgrade(app common.Address) (IAppControllerPendingUpgrade, error) { - return _AppController.Contract.GetPendingUpgrade(&_AppController.CallOpts, app) -} - // GetRoleAdmin is a free data retrieval call binding the contract method 0x248a9ca3. // // Solidity: function getRoleAdmin(bytes32 role) view returns(bytes32) @@ -1348,27 +1311,6 @@ func (_AppController *AppControllerCallerSession) Version() (string, error) { return _AppController.Contract.Version(&_AppController.CallOpts) } -// CancelUpgrade is a paid mutator transaction binding the contract method 0xc44fb8ec. -// -// Solidity: function cancelUpgrade(address app) returns() -func (_AppController *AppControllerTransactor) CancelUpgrade(opts *bind.TransactOpts, app common.Address) (*types.Transaction, error) { - return _AppController.contract.Transact(opts, "cancelUpgrade", app) -} - -// CancelUpgrade is a paid mutator transaction binding the contract method 0xc44fb8ec. -// -// Solidity: function cancelUpgrade(address app) returns() -func (_AppController *AppControllerSession) CancelUpgrade(app common.Address) (*types.Transaction, error) { - return _AppController.Contract.CancelUpgrade(&_AppController.TransactOpts, app) -} - -// CancelUpgrade is a paid mutator transaction binding the contract method 0xc44fb8ec. -// -// Solidity: function cancelUpgrade(address app) returns() -func (_AppController *AppControllerTransactorSession) CancelUpgrade(app common.Address) (*types.Transaction, error) { - return _AppController.Contract.CancelUpgrade(&_AppController.TransactOpts, app) -} - // CreateApp is a paid mutator transaction binding the contract method 0xa60daa8f. // // Solidity: function createApp(bytes32 salt, (((bytes32,string)[],uint32),bytes,bytes) release) returns(address app) @@ -1411,27 +1353,6 @@ func (_AppController *AppControllerTransactorSession) CreateAppForTeam(team comm return _AppController.Contract.CreateAppForTeam(&_AppController.TransactOpts, team, salt, release) } -// ExecuteUpgrade is a paid mutator transaction binding the contract method 0x57d1a51b. -// -// Solidity: function executeUpgrade(address app, (((bytes32,string)[],uint32),bytes,bytes) release) returns(uint256) -func (_AppController *AppControllerTransactor) ExecuteUpgrade(opts *bind.TransactOpts, app common.Address, release IAppControllerRelease) (*types.Transaction, error) { - return _AppController.contract.Transact(opts, "executeUpgrade", app, release) -} - -// ExecuteUpgrade is a paid mutator transaction binding the contract method 0x57d1a51b. -// -// Solidity: function executeUpgrade(address app, (((bytes32,string)[],uint32),bytes,bytes) release) returns(uint256) -func (_AppController *AppControllerSession) ExecuteUpgrade(app common.Address, release IAppControllerRelease) (*types.Transaction, error) { - return _AppController.Contract.ExecuteUpgrade(&_AppController.TransactOpts, app, release) -} - -// ExecuteUpgrade is a paid mutator transaction binding the contract method 0x57d1a51b. -// -// Solidity: function executeUpgrade(address app, (((bytes32,string)[],uint32),bytes,bytes) release) returns(uint256) -func (_AppController *AppControllerTransactorSession) ExecuteUpgrade(app common.Address, release IAppControllerRelease) (*types.Transaction, error) { - return _AppController.Contract.ExecuteUpgrade(&_AppController.TransactOpts, app, release) -} - // GrantRole is a paid mutator transaction binding the contract method 0x2f2ff15d. // // Solidity: function grantRole(bytes32 role, address account) returns() @@ -1600,27 +1521,6 @@ func (_AppController *AppControllerTransactorSession) RevokeTeamRole(team common return _AppController.Contract.RevokeTeamRole(&_AppController.TransactOpts, team, role, account) } -// ScheduleUpgrade is a paid mutator transaction binding the contract method 0x890b78c4. -// -// Solidity: function scheduleUpgrade(address app, (((bytes32,string)[],uint32),bytes,bytes) release, uint256 delay) returns() -func (_AppController *AppControllerTransactor) ScheduleUpgrade(opts *bind.TransactOpts, app common.Address, release IAppControllerRelease, delay *big.Int) (*types.Transaction, error) { - return _AppController.contract.Transact(opts, "scheduleUpgrade", app, release, delay) -} - -// ScheduleUpgrade is a paid mutator transaction binding the contract method 0x890b78c4. -// -// Solidity: function scheduleUpgrade(address app, (((bytes32,string)[],uint32),bytes,bytes) release, uint256 delay) returns() -func (_AppController *AppControllerSession) ScheduleUpgrade(app common.Address, release IAppControllerRelease, delay *big.Int) (*types.Transaction, error) { - return _AppController.Contract.ScheduleUpgrade(&_AppController.TransactOpts, app, release, delay) -} - -// ScheduleUpgrade is a paid mutator transaction binding the contract method 0x890b78c4. -// -// Solidity: function scheduleUpgrade(address app, (((bytes32,string)[],uint32),bytes,bytes) release, uint256 delay) returns() -func (_AppController *AppControllerTransactorSession) ScheduleUpgrade(app common.Address, release IAppControllerRelease, delay *big.Int) (*types.Transaction, error) { - return _AppController.Contract.ScheduleUpgrade(&_AppController.TransactOpts, app, release, delay) -} - // SetMaxActiveAppsPerUser is a paid mutator transaction binding the contract method 0xd49fec2b. // // Solidity: function setMaxActiveAppsPerUser(address user, uint32 limit) returns() @@ -3012,296 +2912,6 @@ func (_AppController *AppControllerFilterer) ParseAppTerminatedByAdmin(log types return event, nil } -// AppControllerAppUpgradeCancelledIterator is returned from FilterAppUpgradeCancelled and is used to iterate over the raw logs and unpacked data for AppUpgradeCancelled events raised by the AppController contract. -type AppControllerAppUpgradeCancelledIterator struct { - Event *AppControllerAppUpgradeCancelled // Event containing the contract specifics and raw log - - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data - - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration -} - -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *AppControllerAppUpgradeCancelledIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(AppControllerAppUpgradeCancelled) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(AppControllerAppUpgradeCancelled) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -// Error returns any retrieval or parsing error occurred during filtering. -func (it *AppControllerAppUpgradeCancelledIterator) Error() error { - return it.fail -} - -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *AppControllerAppUpgradeCancelledIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -// AppControllerAppUpgradeCancelled represents a AppUpgradeCancelled event raised by the AppController contract. -type AppControllerAppUpgradeCancelled struct { - App common.Address - Raw types.Log // Blockchain specific contextual infos -} - -// FilterAppUpgradeCancelled is a free log retrieval operation binding the contract event 0x0be18385bb55003c4f94a806abad0f73a8e17c169c3efa800bf869245112f465. -// -// Solidity: event AppUpgradeCancelled(address indexed app) -func (_AppController *AppControllerFilterer) FilterAppUpgradeCancelled(opts *bind.FilterOpts, app []common.Address) (*AppControllerAppUpgradeCancelledIterator, error) { - - var appRule []interface{} - for _, appItem := range app { - appRule = append(appRule, appItem) - } - - logs, sub, err := _AppController.contract.FilterLogs(opts, "AppUpgradeCancelled", appRule) - if err != nil { - return nil, err - } - return &AppControllerAppUpgradeCancelledIterator{contract: _AppController.contract, event: "AppUpgradeCancelled", logs: logs, sub: sub}, nil -} - -// WatchAppUpgradeCancelled is a free log subscription operation binding the contract event 0x0be18385bb55003c4f94a806abad0f73a8e17c169c3efa800bf869245112f465. -// -// Solidity: event AppUpgradeCancelled(address indexed app) -func (_AppController *AppControllerFilterer) WatchAppUpgradeCancelled(opts *bind.WatchOpts, sink chan<- *AppControllerAppUpgradeCancelled, app []common.Address) (event.Subscription, error) { - - var appRule []interface{} - for _, appItem := range app { - appRule = append(appRule, appItem) - } - - logs, sub, err := _AppController.contract.WatchLogs(opts, "AppUpgradeCancelled", appRule) - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(AppControllerAppUpgradeCancelled) - if err := _AppController.contract.UnpackLog(event, "AppUpgradeCancelled", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} - -// ParseAppUpgradeCancelled is a log parse operation binding the contract event 0x0be18385bb55003c4f94a806abad0f73a8e17c169c3efa800bf869245112f465. -// -// Solidity: event AppUpgradeCancelled(address indexed app) -func (_AppController *AppControllerFilterer) ParseAppUpgradeCancelled(log types.Log) (*AppControllerAppUpgradeCancelled, error) { - event := new(AppControllerAppUpgradeCancelled) - if err := _AppController.contract.UnpackLog(event, "AppUpgradeCancelled", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -// AppControllerAppUpgradeScheduledIterator is returned from FilterAppUpgradeScheduled and is used to iterate over the raw logs and unpacked data for AppUpgradeScheduled events raised by the AppController contract. -type AppControllerAppUpgradeScheduledIterator struct { - Event *AppControllerAppUpgradeScheduled // Event containing the contract specifics and raw log - - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data - - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration -} - -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *AppControllerAppUpgradeScheduledIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(AppControllerAppUpgradeScheduled) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(AppControllerAppUpgradeScheduled) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -// Error returns any retrieval or parsing error occurred during filtering. -func (it *AppControllerAppUpgradeScheduledIterator) Error() error { - return it.fail -} - -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *AppControllerAppUpgradeScheduledIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -// AppControllerAppUpgradeScheduled represents a AppUpgradeScheduled event raised by the AppController contract. -type AppControllerAppUpgradeScheduled struct { - App common.Address - ReadyAt *big.Int - Release IAppControllerRelease - Raw types.Log // Blockchain specific contextual infos -} - -// FilterAppUpgradeScheduled is a free log retrieval operation binding the contract event 0x03309d4e2c0aeff0eb5b642fa98b38401692c0d68249374693f397e06ae6077b. -// -// Solidity: event AppUpgradeScheduled(address indexed app, uint256 readyAt, (((bytes32,string)[],uint32),bytes,bytes) release) -func (_AppController *AppControllerFilterer) FilterAppUpgradeScheduled(opts *bind.FilterOpts, app []common.Address) (*AppControllerAppUpgradeScheduledIterator, error) { - - var appRule []interface{} - for _, appItem := range app { - appRule = append(appRule, appItem) - } - - logs, sub, err := _AppController.contract.FilterLogs(opts, "AppUpgradeScheduled", appRule) - if err != nil { - return nil, err - } - return &AppControllerAppUpgradeScheduledIterator{contract: _AppController.contract, event: "AppUpgradeScheduled", logs: logs, sub: sub}, nil -} - -// WatchAppUpgradeScheduled is a free log subscription operation binding the contract event 0x03309d4e2c0aeff0eb5b642fa98b38401692c0d68249374693f397e06ae6077b. -// -// Solidity: event AppUpgradeScheduled(address indexed app, uint256 readyAt, (((bytes32,string)[],uint32),bytes,bytes) release) -func (_AppController *AppControllerFilterer) WatchAppUpgradeScheduled(opts *bind.WatchOpts, sink chan<- *AppControllerAppUpgradeScheduled, app []common.Address) (event.Subscription, error) { - - var appRule []interface{} - for _, appItem := range app { - appRule = append(appRule, appItem) - } - - logs, sub, err := _AppController.contract.WatchLogs(opts, "AppUpgradeScheduled", appRule) - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(AppControllerAppUpgradeScheduled) - if err := _AppController.contract.UnpackLog(event, "AppUpgradeScheduled", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} - -// ParseAppUpgradeScheduled is a log parse operation binding the contract event 0x03309d4e2c0aeff0eb5b642fa98b38401692c0d68249374693f397e06ae6077b. -// -// Solidity: event AppUpgradeScheduled(address indexed app, uint256 readyAt, (((bytes32,string)[],uint32),bytes,bytes) release) -func (_AppController *AppControllerFilterer) ParseAppUpgradeScheduled(log types.Log) (*AppControllerAppUpgradeScheduled, error) { - event := new(AppControllerAppUpgradeScheduled) - if err := _AppController.contract.UnpackLog(event, "AppUpgradeScheduled", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - // AppControllerAppUpgradedIterator is returned from FilterAppUpgraded and is used to iterate over the raw logs and unpacked data for AppUpgraded events raised by the AppController contract. type AppControllerAppUpgradedIterator struct { Event *AppControllerAppUpgraded // Event containing the contract specifics and raw log diff --git a/pkg/bindings/v2/AppController/binding.go b/pkg/bindings/v2/AppController/binding.go index 842174a..46906e1 100644 --- a/pkg/bindings/v2/AppController/binding.go +++ b/pkg/bindings/v2/AppController/binding.go @@ -40,12 +40,6 @@ type IAppControllerAppRoles struct { Roles []uint8 } -// IAppControllerPendingUpgrade is an auto generated low-level Go binding around an user-defined struct. -type IAppControllerPendingUpgrade struct { - ReleaseHash [32]byte - ReadyAt *big.Int -} - // IAppControllerRelease is an auto generated low-level Go binding around an user-defined struct. type IAppControllerRelease struct { RmsRelease IReleaseManagerTypesRelease @@ -67,7 +61,7 @@ type IReleaseManagerTypesRelease struct { // AppControllerMetaData contains all meta data concerning the AppController contract. var AppControllerMetaData = bind.MetaData{ - ABI: "[{\"type\":\"constructor\",\"inputs\":[{\"name\":\"_version\",\"type\":\"string\",\"internalType\":\"string\"},{\"name\":\"_permissionController\",\"type\":\"address\",\"internalType\":\"contractIPermissionController\"},{\"name\":\"_releaseManager\",\"type\":\"address\",\"internalType\":\"contractIReleaseManager\"},{\"name\":\"_computeAVSRegistrar\",\"type\":\"address\",\"internalType\":\"contractIComputeAVSRegistrar\"},{\"name\":\"_computeOperator\",\"type\":\"address\",\"internalType\":\"contractIComputeOperator\"},{\"name\":\"_appBeacon\",\"type\":\"address\",\"internalType\":\"contractIBeacon\"},{\"name\":\"_safeTimelockFactory\",\"type\":\"address\",\"internalType\":\"contractISafeTimelockFactory\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"API_PERMISSION_TYPEHASH\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"DEFAULT_ADMIN_ROLE\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"appBeacon\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIBeacon\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"calculateApiPermissionDigestHash\",\"inputs\":[{\"name\":\"permission\",\"type\":\"bytes4\",\"internalType\":\"bytes4\"},{\"name\":\"expiry\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"calculateAppId\",\"inputs\":[{\"name\":\"deployer\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"salt\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"cancelUpgrade\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"computeAVSRegistrar\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIComputeAVSRegistrar\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"computeOperator\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIComputeOperator\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"createApp\",\"inputs\":[{\"name\":\"salt\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"release\",\"type\":\"tuple\",\"internalType\":\"structIAppController.Release\",\"components\":[{\"name\":\"rmsRelease\",\"type\":\"tuple\",\"internalType\":\"structIReleaseManagerTypes.Release\",\"components\":[{\"name\":\"artifacts\",\"type\":\"tuple[]\",\"internalType\":\"structIReleaseManagerTypes.Artifact[]\",\"components\":[{\"name\":\"digest\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"registry\",\"type\":\"string\",\"internalType\":\"string\"}]},{\"name\":\"upgradeByTime\",\"type\":\"uint32\",\"internalType\":\"uint32\"}]},{\"name\":\"publicEnv\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"encryptedEnv\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]}],\"outputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"createAppForTeam\",\"inputs\":[{\"name\":\"team\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"salt\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"release\",\"type\":\"tuple\",\"internalType\":\"structIAppController.Release\",\"components\":[{\"name\":\"rmsRelease\",\"type\":\"tuple\",\"internalType\":\"structIReleaseManagerTypes.Release\",\"components\":[{\"name\":\"artifacts\",\"type\":\"tuple[]\",\"internalType\":\"structIReleaseManagerTypes.Artifact[]\",\"components\":[{\"name\":\"digest\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"registry\",\"type\":\"string\",\"internalType\":\"string\"}]},{\"name\":\"upgradeByTime\",\"type\":\"uint32\",\"internalType\":\"uint32\"}]},{\"name\":\"publicEnv\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"encryptedEnv\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]}],\"outputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"domainSeparator\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"executeUpgrade\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"},{\"name\":\"release\",\"type\":\"tuple\",\"internalType\":\"structIAppController.Release\",\"components\":[{\"name\":\"rmsRelease\",\"type\":\"tuple\",\"internalType\":\"structIReleaseManagerTypes.Release\",\"components\":[{\"name\":\"artifacts\",\"type\":\"tuple[]\",\"internalType\":\"structIReleaseManagerTypes.Artifact[]\",\"components\":[{\"name\":\"digest\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"registry\",\"type\":\"string\",\"internalType\":\"string\"}]},{\"name\":\"upgradeByTime\",\"type\":\"uint32\",\"internalType\":\"uint32\"}]},{\"name\":\"publicEnv\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"encryptedEnv\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"getActiveAppCount\",\"inputs\":[{\"name\":\"user\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getAppLatestReleaseBlockNumber\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getAppOperatorSetId\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getAppOwner\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getAppStatus\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint8\",\"internalType\":\"enumIAppController.AppStatus\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getAppTimelocked\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getApps\",\"inputs\":[{\"name\":\"offset\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"limit\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"apps\",\"type\":\"address[]\",\"internalType\":\"contractIApp[]\"},{\"name\":\"appConfigsMem\",\"type\":\"tuple[]\",\"internalType\":\"structIAppController.AppConfig[]\",\"components\":[{\"name\":\"owner\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"operatorSetId\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"latestReleaseBlockNumber\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"status\",\"type\":\"uint8\",\"internalType\":\"enumIAppController.AppStatus\"},{\"name\":\"timelocked\",\"type\":\"bool\",\"internalType\":\"bool\"}]}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getAppsByCreator\",\"inputs\":[{\"name\":\"creator\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"offset\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"limit\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"apps\",\"type\":\"address[]\",\"internalType\":\"contractIApp[]\"},{\"name\":\"appConfigsMem\",\"type\":\"tuple[]\",\"internalType\":\"structIAppController.AppConfig[]\",\"components\":[{\"name\":\"owner\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"operatorSetId\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"latestReleaseBlockNumber\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"status\",\"type\":\"uint8\",\"internalType\":\"enumIAppController.AppStatus\"},{\"name\":\"timelocked\",\"type\":\"bool\",\"internalType\":\"bool\"}]}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getAppsByDeveloper\",\"inputs\":[{\"name\":\"developer\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"offset\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"limit\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"apps\",\"type\":\"address[]\",\"internalType\":\"contractIApp[]\"},{\"name\":\"appConfigsMem\",\"type\":\"tuple[]\",\"internalType\":\"structIAppController.AppConfig[]\",\"components\":[{\"name\":\"owner\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"operatorSetId\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"latestReleaseBlockNumber\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"status\",\"type\":\"uint8\",\"internalType\":\"enumIAppController.AppStatus\"},{\"name\":\"timelocked\",\"type\":\"bool\",\"internalType\":\"bool\"}]}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getAppsForAccount\",\"inputs\":[{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"offset\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"limit\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"appRoles\",\"type\":\"tuple[]\",\"internalType\":\"structIAppController.AppRoles[]\",\"components\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"},{\"name\":\"isOwner\",\"type\":\"bool\",\"internalType\":\"bool\"},{\"name\":\"roles\",\"type\":\"uint8[]\",\"internalType\":\"enumIAppController.TeamRole[]\"}]}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getMaxActiveAppsPerUser\",\"inputs\":[{\"name\":\"user\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getPendingUpgrade\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"outputs\":[{\"name\":\"\",\"type\":\"tuple\",\"internalType\":\"structIAppController.PendingUpgrade\",\"components\":[{\"name\":\"releaseHash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"readyAt\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getRoleAdmin\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getRoleMember\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"index\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getRoleMemberCount\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getTeamRoleMember\",\"inputs\":[{\"name\":\"team\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"role\",\"type\":\"uint8\",\"internalType\":\"enumIAppController.TeamRole\"},{\"name\":\"index\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getTeamRoleMemberCount\",\"inputs\":[{\"name\":\"team\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"role\",\"type\":\"uint8\",\"internalType\":\"enumIAppController.TeamRole\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getTeamRoleMembers\",\"inputs\":[{\"name\":\"team\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"role\",\"type\":\"uint8\",\"internalType\":\"enumIAppController.TeamRole\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address[]\",\"internalType\":\"address[]\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"globalActiveAppCount\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"grantRole\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"grantTeamRole\",\"inputs\":[{\"name\":\"team\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"role\",\"type\":\"uint8\",\"internalType\":\"enumIAppController.TeamRole\"},{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"hasRole\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"hasTeamRole\",\"inputs\":[{\"name\":\"team\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"role\",\"type\":\"uint8\",\"internalType\":\"enumIAppController.TeamRole\"},{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"initialize\",\"inputs\":[{\"name\":\"admin\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"maxGlobalActiveApps\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"migrateAdmins\",\"inputs\":[{\"name\":\"apps\",\"type\":\"address[]\",\"internalType\":\"contractIApp[]\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"permissionController\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIPermissionController\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"releaseManager\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIReleaseManager\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"renounceRole\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"renounceTeamRole\",\"inputs\":[{\"name\":\"team\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"role\",\"type\":\"uint8\",\"internalType\":\"enumIAppController.TeamRole\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"revokeRole\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"revokeTeamRole\",\"inputs\":[{\"name\":\"team\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"role\",\"type\":\"uint8\",\"internalType\":\"enumIAppController.TeamRole\"},{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"safeTimelockFactory\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractISafeTimelockFactory\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"scheduleUpgrade\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"},{\"name\":\"release\",\"type\":\"tuple\",\"internalType\":\"structIAppController.Release\",\"components\":[{\"name\":\"rmsRelease\",\"type\":\"tuple\",\"internalType\":\"structIReleaseManagerTypes.Release\",\"components\":[{\"name\":\"artifacts\",\"type\":\"tuple[]\",\"internalType\":\"structIReleaseManagerTypes.Artifact[]\",\"components\":[{\"name\":\"digest\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"registry\",\"type\":\"string\",\"internalType\":\"string\"}]},{\"name\":\"upgradeByTime\",\"type\":\"uint32\",\"internalType\":\"uint32\"}]},{\"name\":\"publicEnv\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"encryptedEnv\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]},{\"name\":\"delay\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"setMaxActiveAppsPerUser\",\"inputs\":[{\"name\":\"user\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"limit\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"setMaxGlobalActiveApps\",\"inputs\":[{\"name\":\"limit\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"startApp\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"stopApp\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"supportsInterface\",\"inputs\":[{\"name\":\"interfaceId\",\"type\":\"bytes4\",\"internalType\":\"bytes4\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"suspend\",\"inputs\":[{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"apps\",\"type\":\"address[]\",\"internalType\":\"contractIApp[]\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"terminateApp\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"terminateAppByAdmin\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"transferOwnership\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"},{\"name\":\"newOwner\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"updateAppMetadataURI\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"},{\"name\":\"metadataURI\",\"type\":\"string\",\"internalType\":\"string\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"upgradeApp\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"},{\"name\":\"release\",\"type\":\"tuple\",\"internalType\":\"structIAppController.Release\",\"components\":[{\"name\":\"rmsRelease\",\"type\":\"tuple\",\"internalType\":\"structIReleaseManagerTypes.Release\",\"components\":[{\"name\":\"artifacts\",\"type\":\"tuple[]\",\"internalType\":\"structIReleaseManagerTypes.Artifact[]\",\"components\":[{\"name\":\"digest\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"registry\",\"type\":\"string\",\"internalType\":\"string\"}]},{\"name\":\"upgradeByTime\",\"type\":\"uint32\",\"internalType\":\"uint32\"}]},{\"name\":\"publicEnv\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"encryptedEnv\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"version\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"string\",\"internalType\":\"string\"}],\"stateMutability\":\"view\"},{\"type\":\"event\",\"name\":\"AppCreated\",\"inputs\":[{\"name\":\"owner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"app\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"contractIApp\"},{\"name\":\"operatorSetId\",\"type\":\"uint32\",\"indexed\":false,\"internalType\":\"uint32\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"AppMetadataURIUpdated\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"contractIApp\"},{\"name\":\"metadataURI\",\"type\":\"string\",\"indexed\":false,\"internalType\":\"string\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"AppOwnershipTransferred\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"contractIApp\"},{\"name\":\"previousOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"newOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"AppStarted\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"contractIApp\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"AppStopped\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"contractIApp\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"AppSuspended\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"contractIApp\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"AppTerminated\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"contractIApp\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"AppTerminatedByAdmin\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"contractIApp\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"AppUpgradeCancelled\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"contractIApp\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"AppUpgradeScheduled\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"contractIApp\"},{\"name\":\"readyAt\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"release\",\"type\":\"tuple\",\"indexed\":false,\"internalType\":\"structIAppController.Release\",\"components\":[{\"name\":\"rmsRelease\",\"type\":\"tuple\",\"internalType\":\"structIReleaseManagerTypes.Release\",\"components\":[{\"name\":\"artifacts\",\"type\":\"tuple[]\",\"internalType\":\"structIReleaseManagerTypes.Artifact[]\",\"components\":[{\"name\":\"digest\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"registry\",\"type\":\"string\",\"internalType\":\"string\"}]},{\"name\":\"upgradeByTime\",\"type\":\"uint32\",\"internalType\":\"uint32\"}]},{\"name\":\"publicEnv\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"encryptedEnv\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"AppUpgraded\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"contractIApp\"},{\"name\":\"rmsReleaseId\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"release\",\"type\":\"tuple\",\"indexed\":false,\"internalType\":\"structIAppController.Release\",\"components\":[{\"name\":\"rmsRelease\",\"type\":\"tuple\",\"internalType\":\"structIReleaseManagerTypes.Release\",\"components\":[{\"name\":\"artifacts\",\"type\":\"tuple[]\",\"internalType\":\"structIReleaseManagerTypes.Artifact[]\",\"components\":[{\"name\":\"digest\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"registry\",\"type\":\"string\",\"internalType\":\"string\"}]},{\"name\":\"upgradeByTime\",\"type\":\"uint32\",\"internalType\":\"uint32\"}]},{\"name\":\"publicEnv\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"encryptedEnv\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"GlobalMaxActiveAppsSet\",\"inputs\":[{\"name\":\"limit\",\"type\":\"uint32\",\"indexed\":false,\"internalType\":\"uint32\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Initialized\",\"inputs\":[{\"name\":\"version\",\"type\":\"uint8\",\"indexed\":false,\"internalType\":\"uint8\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"MaxActiveAppsSet\",\"inputs\":[{\"name\":\"user\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"limit\",\"type\":\"uint32\",\"indexed\":false,\"internalType\":\"uint32\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"RoleAdminChanged\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"previousAdminRole\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"newAdminRole\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"RoleGranted\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"account\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"sender\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"RoleRevoked\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"account\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"sender\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"error\",\"name\":\"AccountHasActiveApps\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"AppAlreadyExists\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"AppDoesNotExist\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"CannotRevokeLastAdmin\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"GlobalMaxActiveAppsExceeded\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidAppStatus\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidPermissions\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidReleaseMetadataURI\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidShortString\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidSignature\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"MaxActiveAppsExceeded\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"MoreThanOneArtifact\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"NoScheduledUpgrade\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"NotTimelocked\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"ReleaseMismatch\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"SignatureExpired\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"StringTooLong\",\"inputs\":[{\"name\":\"str\",\"type\":\"string\",\"internalType\":\"string\"}]},{\"type\":\"error\",\"name\":\"TimelockRequired\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"UpgradeNotReady\",\"inputs\":[]}]", + ABI: "[{\"type\":\"constructor\",\"inputs\":[{\"name\":\"_version\",\"type\":\"string\",\"internalType\":\"string\"},{\"name\":\"_permissionController\",\"type\":\"address\",\"internalType\":\"contractIPermissionController\"},{\"name\":\"_releaseManager\",\"type\":\"address\",\"internalType\":\"contractIReleaseManager\"},{\"name\":\"_computeAVSRegistrar\",\"type\":\"address\",\"internalType\":\"contractIComputeAVSRegistrar\"},{\"name\":\"_computeOperator\",\"type\":\"address\",\"internalType\":\"contractIComputeOperator\"},{\"name\":\"_appBeacon\",\"type\":\"address\",\"internalType\":\"contractIBeacon\"},{\"name\":\"_safeTimelockFactory\",\"type\":\"address\",\"internalType\":\"contractISafeTimelockFactory\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"API_PERMISSION_TYPEHASH\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"DEFAULT_ADMIN_ROLE\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"appBeacon\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIBeacon\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"calculateApiPermissionDigestHash\",\"inputs\":[{\"name\":\"permission\",\"type\":\"bytes4\",\"internalType\":\"bytes4\"},{\"name\":\"expiry\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"calculateAppId\",\"inputs\":[{\"name\":\"deployer\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"salt\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"computeAVSRegistrar\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIComputeAVSRegistrar\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"computeOperator\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIComputeOperator\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"createApp\",\"inputs\":[{\"name\":\"salt\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"release\",\"type\":\"tuple\",\"internalType\":\"structIAppController.Release\",\"components\":[{\"name\":\"rmsRelease\",\"type\":\"tuple\",\"internalType\":\"structIReleaseManagerTypes.Release\",\"components\":[{\"name\":\"artifacts\",\"type\":\"tuple[]\",\"internalType\":\"structIReleaseManagerTypes.Artifact[]\",\"components\":[{\"name\":\"digest\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"registry\",\"type\":\"string\",\"internalType\":\"string\"}]},{\"name\":\"upgradeByTime\",\"type\":\"uint32\",\"internalType\":\"uint32\"}]},{\"name\":\"publicEnv\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"encryptedEnv\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]}],\"outputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"createAppForTeam\",\"inputs\":[{\"name\":\"team\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"salt\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"release\",\"type\":\"tuple\",\"internalType\":\"structIAppController.Release\",\"components\":[{\"name\":\"rmsRelease\",\"type\":\"tuple\",\"internalType\":\"structIReleaseManagerTypes.Release\",\"components\":[{\"name\":\"artifacts\",\"type\":\"tuple[]\",\"internalType\":\"structIReleaseManagerTypes.Artifact[]\",\"components\":[{\"name\":\"digest\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"registry\",\"type\":\"string\",\"internalType\":\"string\"}]},{\"name\":\"upgradeByTime\",\"type\":\"uint32\",\"internalType\":\"uint32\"}]},{\"name\":\"publicEnv\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"encryptedEnv\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]}],\"outputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"domainSeparator\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getActiveAppCount\",\"inputs\":[{\"name\":\"user\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getAppLatestReleaseBlockNumber\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getAppOperatorSetId\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getAppOwner\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getAppStatus\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint8\",\"internalType\":\"enumIAppController.AppStatus\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getAppTimelocked\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getApps\",\"inputs\":[{\"name\":\"offset\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"limit\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"apps\",\"type\":\"address[]\",\"internalType\":\"contractIApp[]\"},{\"name\":\"appConfigsMem\",\"type\":\"tuple[]\",\"internalType\":\"structIAppController.AppConfig[]\",\"components\":[{\"name\":\"owner\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"operatorSetId\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"latestReleaseBlockNumber\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"status\",\"type\":\"uint8\",\"internalType\":\"enumIAppController.AppStatus\"},{\"name\":\"timelocked\",\"type\":\"bool\",\"internalType\":\"bool\"}]}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getAppsByCreator\",\"inputs\":[{\"name\":\"creator\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"offset\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"limit\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"apps\",\"type\":\"address[]\",\"internalType\":\"contractIApp[]\"},{\"name\":\"appConfigsMem\",\"type\":\"tuple[]\",\"internalType\":\"structIAppController.AppConfig[]\",\"components\":[{\"name\":\"owner\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"operatorSetId\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"latestReleaseBlockNumber\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"status\",\"type\":\"uint8\",\"internalType\":\"enumIAppController.AppStatus\"},{\"name\":\"timelocked\",\"type\":\"bool\",\"internalType\":\"bool\"}]}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getAppsByDeveloper\",\"inputs\":[{\"name\":\"developer\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"offset\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"limit\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"apps\",\"type\":\"address[]\",\"internalType\":\"contractIApp[]\"},{\"name\":\"appConfigsMem\",\"type\":\"tuple[]\",\"internalType\":\"structIAppController.AppConfig[]\",\"components\":[{\"name\":\"owner\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"operatorSetId\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"latestReleaseBlockNumber\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"status\",\"type\":\"uint8\",\"internalType\":\"enumIAppController.AppStatus\"},{\"name\":\"timelocked\",\"type\":\"bool\",\"internalType\":\"bool\"}]}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getAppsForAccount\",\"inputs\":[{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"offset\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"limit\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"appRoles\",\"type\":\"tuple[]\",\"internalType\":\"structIAppController.AppRoles[]\",\"components\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"},{\"name\":\"isOwner\",\"type\":\"bool\",\"internalType\":\"bool\"},{\"name\":\"roles\",\"type\":\"uint8[]\",\"internalType\":\"enumIAppController.TeamRole[]\"}]}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getMaxActiveAppsPerUser\",\"inputs\":[{\"name\":\"user\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getRoleAdmin\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getRoleMember\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"index\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getRoleMemberCount\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getTeamRoleMember\",\"inputs\":[{\"name\":\"team\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"role\",\"type\":\"uint8\",\"internalType\":\"enumIAppController.TeamRole\"},{\"name\":\"index\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getTeamRoleMemberCount\",\"inputs\":[{\"name\":\"team\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"role\",\"type\":\"uint8\",\"internalType\":\"enumIAppController.TeamRole\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getTeamRoleMembers\",\"inputs\":[{\"name\":\"team\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"role\",\"type\":\"uint8\",\"internalType\":\"enumIAppController.TeamRole\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address[]\",\"internalType\":\"address[]\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"globalActiveAppCount\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"grantRole\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"grantTeamRole\",\"inputs\":[{\"name\":\"team\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"role\",\"type\":\"uint8\",\"internalType\":\"enumIAppController.TeamRole\"},{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"hasRole\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"hasTeamRole\",\"inputs\":[{\"name\":\"team\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"role\",\"type\":\"uint8\",\"internalType\":\"enumIAppController.TeamRole\"},{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"initialize\",\"inputs\":[{\"name\":\"admin\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"maxGlobalActiveApps\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"migrateAdmins\",\"inputs\":[{\"name\":\"apps\",\"type\":\"address[]\",\"internalType\":\"contractIApp[]\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"permissionController\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIPermissionController\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"releaseManager\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIReleaseManager\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"renounceRole\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"renounceTeamRole\",\"inputs\":[{\"name\":\"team\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"role\",\"type\":\"uint8\",\"internalType\":\"enumIAppController.TeamRole\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"revokeRole\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"revokeTeamRole\",\"inputs\":[{\"name\":\"team\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"role\",\"type\":\"uint8\",\"internalType\":\"enumIAppController.TeamRole\"},{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"safeTimelockFactory\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractISafeTimelockFactory\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"setMaxActiveAppsPerUser\",\"inputs\":[{\"name\":\"user\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"limit\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"setMaxGlobalActiveApps\",\"inputs\":[{\"name\":\"limit\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"startApp\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"stopApp\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"supportsInterface\",\"inputs\":[{\"name\":\"interfaceId\",\"type\":\"bytes4\",\"internalType\":\"bytes4\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"suspend\",\"inputs\":[{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"apps\",\"type\":\"address[]\",\"internalType\":\"contractIApp[]\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"terminateApp\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"terminateAppByAdmin\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"transferOwnership\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"},{\"name\":\"newOwner\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"updateAppMetadataURI\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"},{\"name\":\"metadataURI\",\"type\":\"string\",\"internalType\":\"string\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"upgradeApp\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"},{\"name\":\"release\",\"type\":\"tuple\",\"internalType\":\"structIAppController.Release\",\"components\":[{\"name\":\"rmsRelease\",\"type\":\"tuple\",\"internalType\":\"structIReleaseManagerTypes.Release\",\"components\":[{\"name\":\"artifacts\",\"type\":\"tuple[]\",\"internalType\":\"structIReleaseManagerTypes.Artifact[]\",\"components\":[{\"name\":\"digest\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"registry\",\"type\":\"string\",\"internalType\":\"string\"}]},{\"name\":\"upgradeByTime\",\"type\":\"uint32\",\"internalType\":\"uint32\"}]},{\"name\":\"publicEnv\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"encryptedEnv\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"version\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"string\",\"internalType\":\"string\"}],\"stateMutability\":\"view\"},{\"type\":\"event\",\"name\":\"AppCreated\",\"inputs\":[{\"name\":\"owner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"app\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"contractIApp\"},{\"name\":\"operatorSetId\",\"type\":\"uint32\",\"indexed\":false,\"internalType\":\"uint32\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"AppMetadataURIUpdated\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"contractIApp\"},{\"name\":\"metadataURI\",\"type\":\"string\",\"indexed\":false,\"internalType\":\"string\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"AppOwnershipTransferred\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"contractIApp\"},{\"name\":\"previousOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"newOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"AppStarted\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"contractIApp\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"AppStopped\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"contractIApp\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"AppSuspended\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"contractIApp\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"AppTerminated\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"contractIApp\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"AppTerminatedByAdmin\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"contractIApp\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"AppUpgraded\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"contractIApp\"},{\"name\":\"rmsReleaseId\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"release\",\"type\":\"tuple\",\"indexed\":false,\"internalType\":\"structIAppController.Release\",\"components\":[{\"name\":\"rmsRelease\",\"type\":\"tuple\",\"internalType\":\"structIReleaseManagerTypes.Release\",\"components\":[{\"name\":\"artifacts\",\"type\":\"tuple[]\",\"internalType\":\"structIReleaseManagerTypes.Artifact[]\",\"components\":[{\"name\":\"digest\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"registry\",\"type\":\"string\",\"internalType\":\"string\"}]},{\"name\":\"upgradeByTime\",\"type\":\"uint32\",\"internalType\":\"uint32\"}]},{\"name\":\"publicEnv\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"encryptedEnv\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"GlobalMaxActiveAppsSet\",\"inputs\":[{\"name\":\"limit\",\"type\":\"uint32\",\"indexed\":false,\"internalType\":\"uint32\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Initialized\",\"inputs\":[{\"name\":\"version\",\"type\":\"uint8\",\"indexed\":false,\"internalType\":\"uint8\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"MaxActiveAppsSet\",\"inputs\":[{\"name\":\"user\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"limit\",\"type\":\"uint32\",\"indexed\":false,\"internalType\":\"uint32\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"RoleAdminChanged\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"previousAdminRole\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"newAdminRole\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"RoleGranted\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"account\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"sender\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"RoleRevoked\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"account\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"sender\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"error\",\"name\":\"AccountHasActiveApps\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"AppAlreadyExists\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"AppDoesNotExist\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"CannotRevokeLastAdmin\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"GlobalMaxActiveAppsExceeded\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidAppStatus\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidPermissions\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidReleaseMetadataURI\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidShortString\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidSignature\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"MaxActiveAppsExceeded\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"MoreThanOneArtifact\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"SignatureExpired\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"StringTooLong\",\"inputs\":[{\"name\":\"str\",\"type\":\"string\",\"internalType\":\"string\"}]}]", ID: "AppController", } @@ -278,28 +272,6 @@ func (appController *AppController) UnpackCalculateAppId(data []byte) (common.Ad return out0, nil } -// PackCancelUpgrade is the Go binding used to pack the parameters required for calling -// the contract method with ID 0xc44fb8ec. This method will panic if any -// invalid/nil inputs are passed. -// -// Solidity: function cancelUpgrade(address app) returns() -func (appController *AppController) PackCancelUpgrade(app common.Address) []byte { - enc, err := appController.abi.Pack("cancelUpgrade", app) - if err != nil { - panic(err) - } - return enc -} - -// TryPackCancelUpgrade is the Go binding used to pack the parameters required for calling -// the contract method with ID 0xc44fb8ec. This method will return an error -// if any inputs are invalid/nil. -// -// Solidity: function cancelUpgrade(address app) returns() -func (appController *AppController) TryPackCancelUpgrade(app common.Address) ([]byte, error) { - return appController.abi.Pack("cancelUpgrade", app) -} - // PackComputeAVSRegistrar is the Go binding used to pack the parameters required for calling // the contract method with ID 0xef6d92c6. This method will panic if any // invalid/nil inputs are passed. @@ -475,41 +447,6 @@ func (appController *AppController) UnpackDomainSeparator(data []byte) ([32]byte return out0, nil } -// PackExecuteUpgrade is the Go binding used to pack the parameters required for calling -// the contract method with ID 0x57d1a51b. This method will panic if any -// invalid/nil inputs are passed. -// -// Solidity: function executeUpgrade(address app, (((bytes32,string)[],uint32),bytes,bytes) release) returns(uint256) -func (appController *AppController) PackExecuteUpgrade(app common.Address, release IAppControllerRelease) []byte { - enc, err := appController.abi.Pack("executeUpgrade", app, release) - if err != nil { - panic(err) - } - return enc -} - -// TryPackExecuteUpgrade is the Go binding used to pack the parameters required for calling -// the contract method with ID 0x57d1a51b. This method will return an error -// if any inputs are invalid/nil. -// -// Solidity: function executeUpgrade(address app, (((bytes32,string)[],uint32),bytes,bytes) release) returns(uint256) -func (appController *AppController) TryPackExecuteUpgrade(app common.Address, release IAppControllerRelease) ([]byte, error) { - return appController.abi.Pack("executeUpgrade", app, release) -} - -// UnpackExecuteUpgrade is the Go binding that unpacks the parameters returned -// from invoking the contract method with ID 0x57d1a51b. -// -// Solidity: function executeUpgrade(address app, (((bytes32,string)[],uint32),bytes,bytes) release) returns(uint256) -func (appController *AppController) UnpackExecuteUpgrade(data []byte) (*big.Int, error) { - out, err := appController.abi.Unpack("executeUpgrade", data) - if err != nil { - return new(big.Int), err - } - out0 := abi.ConvertType(out[0], new(big.Int)).(*big.Int) - return out0, nil -} - // PackGetActiveAppCount is the Go binding used to pack the parameters required for calling // the contract method with ID 0x0c2199fb. This method will panic if any // invalid/nil inputs are passed. @@ -922,41 +859,6 @@ func (appController *AppController) UnpackGetMaxActiveAppsPerUser(data []byte) ( return out0, nil } -// PackGetPendingUpgrade is the Go binding used to pack the parameters required for calling -// the contract method with ID 0x57ececcd. This method will panic if any -// invalid/nil inputs are passed. -// -// Solidity: function getPendingUpgrade(address app) view returns((bytes32,uint256)) -func (appController *AppController) PackGetPendingUpgrade(app common.Address) []byte { - enc, err := appController.abi.Pack("getPendingUpgrade", app) - if err != nil { - panic(err) - } - return enc -} - -// TryPackGetPendingUpgrade is the Go binding used to pack the parameters required for calling -// the contract method with ID 0x57ececcd. This method will return an error -// if any inputs are invalid/nil. -// -// Solidity: function getPendingUpgrade(address app) view returns((bytes32,uint256)) -func (appController *AppController) TryPackGetPendingUpgrade(app common.Address) ([]byte, error) { - return appController.abi.Pack("getPendingUpgrade", app) -} - -// UnpackGetPendingUpgrade is the Go binding that unpacks the parameters returned -// from invoking the contract method with ID 0x57ececcd. -// -// Solidity: function getPendingUpgrade(address app) view returns((bytes32,uint256)) -func (appController *AppController) UnpackGetPendingUpgrade(data []byte) (IAppControllerPendingUpgrade, error) { - out, err := appController.abi.Unpack("getPendingUpgrade", data) - if err != nil { - return *new(IAppControllerPendingUpgrade), err - } - out0 := *abi.ConvertType(out[0], new(IAppControllerPendingUpgrade)).(*IAppControllerPendingUpgrade) - return out0, nil -} - // PackGetRoleAdmin is the Go binding used to pack the parameters required for calling // the contract method with ID 0x248a9ca3. This method will panic if any // invalid/nil inputs are passed. @@ -1588,28 +1490,6 @@ func (appController *AppController) UnpackSafeTimelockFactory(data []byte) (comm return out0, nil } -// PackScheduleUpgrade is the Go binding used to pack the parameters required for calling -// the contract method with ID 0x890b78c4. This method will panic if any -// invalid/nil inputs are passed. -// -// Solidity: function scheduleUpgrade(address app, (((bytes32,string)[],uint32),bytes,bytes) release, uint256 delay) returns() -func (appController *AppController) PackScheduleUpgrade(app common.Address, release IAppControllerRelease, delay *big.Int) []byte { - enc, err := appController.abi.Pack("scheduleUpgrade", app, release, delay) - if err != nil { - panic(err) - } - return enc -} - -// TryPackScheduleUpgrade is the Go binding used to pack the parameters required for calling -// the contract method with ID 0x890b78c4. This method will return an error -// if any inputs are invalid/nil. -// -// Solidity: function scheduleUpgrade(address app, (((bytes32,string)[],uint32),bytes,bytes) release, uint256 delay) returns() -func (appController *AppController) TryPackScheduleUpgrade(app common.Address, release IAppControllerRelease, delay *big.Int) ([]byte, error) { - return appController.abi.Pack("scheduleUpgrade", app, release, delay) -} - // PackSetMaxActiveAppsPerUser is the Go binding used to pack the parameters required for calling // the contract method with ID 0xd49fec2b. This method will panic if any // invalid/nil inputs are passed. @@ -2246,90 +2126,6 @@ func (appController *AppController) UnpackAppTerminatedByAdminEvent(log *types.L return out, nil } -// AppControllerAppUpgradeCancelled represents a AppUpgradeCancelled event raised by the AppController contract. -type AppControllerAppUpgradeCancelled struct { - App common.Address - Raw *types.Log // Blockchain specific contextual infos -} - -const AppControllerAppUpgradeCancelledEventName = "AppUpgradeCancelled" - -// ContractEventName returns the user-defined event name. -func (AppControllerAppUpgradeCancelled) ContractEventName() string { - return AppControllerAppUpgradeCancelledEventName -} - -// UnpackAppUpgradeCancelledEvent is the Go binding that unpacks the event data emitted -// by contract. -// -// Solidity: event AppUpgradeCancelled(address indexed app) -func (appController *AppController) UnpackAppUpgradeCancelledEvent(log *types.Log) (*AppControllerAppUpgradeCancelled, error) { - event := "AppUpgradeCancelled" - if len(log.Topics) == 0 || log.Topics[0] != appController.abi.Events[event].ID { - return nil, errors.New("event signature mismatch") - } - out := new(AppControllerAppUpgradeCancelled) - if len(log.Data) > 0 { - if err := appController.abi.UnpackIntoInterface(out, event, log.Data); err != nil { - return nil, err - } - } - var indexed abi.Arguments - for _, arg := range appController.abi.Events[event].Inputs { - if arg.Indexed { - indexed = append(indexed, arg) - } - } - if err := abi.ParseTopics(out, indexed, log.Topics[1:]); err != nil { - return nil, err - } - out.Raw = log - return out, nil -} - -// AppControllerAppUpgradeScheduled represents a AppUpgradeScheduled event raised by the AppController contract. -type AppControllerAppUpgradeScheduled struct { - App common.Address - ReadyAt *big.Int - Release IAppControllerRelease - Raw *types.Log // Blockchain specific contextual infos -} - -const AppControllerAppUpgradeScheduledEventName = "AppUpgradeScheduled" - -// ContractEventName returns the user-defined event name. -func (AppControllerAppUpgradeScheduled) ContractEventName() string { - return AppControllerAppUpgradeScheduledEventName -} - -// UnpackAppUpgradeScheduledEvent is the Go binding that unpacks the event data emitted -// by contract. -// -// Solidity: event AppUpgradeScheduled(address indexed app, uint256 readyAt, (((bytes32,string)[],uint32),bytes,bytes) release) -func (appController *AppController) UnpackAppUpgradeScheduledEvent(log *types.Log) (*AppControllerAppUpgradeScheduled, error) { - event := "AppUpgradeScheduled" - if len(log.Topics) == 0 || log.Topics[0] != appController.abi.Events[event].ID { - return nil, errors.New("event signature mismatch") - } - out := new(AppControllerAppUpgradeScheduled) - if len(log.Data) > 0 { - if err := appController.abi.UnpackIntoInterface(out, event, log.Data); err != nil { - return nil, err - } - } - var indexed abi.Arguments - for _, arg := range appController.abi.Events[event].Inputs { - if arg.Indexed { - indexed = append(indexed, arg) - } - } - if err := abi.ParseTopics(out, indexed, log.Topics[1:]); err != nil { - return nil, err - } - out.Raw = log - return out, nil -} - // AppControllerAppUpgraded represents a AppUpgraded event raised by the AppController contract. type AppControllerAppUpgraded struct { App common.Address @@ -2665,27 +2461,12 @@ func (appController *AppController) UnpackError(raw []byte) (any, error) { if bytes.Equal(raw[:4], appController.abi.Errors["MoreThanOneArtifact"].ID.Bytes()[:4]) { return appController.UnpackMoreThanOneArtifactError(raw[4:]) } - if bytes.Equal(raw[:4], appController.abi.Errors["NoScheduledUpgrade"].ID.Bytes()[:4]) { - return appController.UnpackNoScheduledUpgradeError(raw[4:]) - } - if bytes.Equal(raw[:4], appController.abi.Errors["NotTimelocked"].ID.Bytes()[:4]) { - return appController.UnpackNotTimelockedError(raw[4:]) - } - if bytes.Equal(raw[:4], appController.abi.Errors["ReleaseMismatch"].ID.Bytes()[:4]) { - return appController.UnpackReleaseMismatchError(raw[4:]) - } if bytes.Equal(raw[:4], appController.abi.Errors["SignatureExpired"].ID.Bytes()[:4]) { return appController.UnpackSignatureExpiredError(raw[4:]) } if bytes.Equal(raw[:4], appController.abi.Errors["StringTooLong"].ID.Bytes()[:4]) { return appController.UnpackStringTooLongError(raw[4:]) } - if bytes.Equal(raw[:4], appController.abi.Errors["TimelockRequired"].ID.Bytes()[:4]) { - return appController.UnpackTimelockRequiredError(raw[4:]) - } - if bytes.Equal(raw[:4], appController.abi.Errors["UpgradeNotReady"].ID.Bytes()[:4]) { - return appController.UnpackUpgradeNotReadyError(raw[4:]) - } return nil, errors.New("Unknown error") } @@ -2965,75 +2746,6 @@ func (appController *AppController) UnpackMoreThanOneArtifactError(raw []byte) ( return out, nil } -// AppControllerNoScheduledUpgrade represents a NoScheduledUpgrade error raised by the AppController contract. -type AppControllerNoScheduledUpgrade struct { -} - -// ErrorID returns the hash of canonical representation of the error's signature. -// -// Solidity: error NoScheduledUpgrade() -func AppControllerNoScheduledUpgradeErrorID() common.Hash { - return common.HexToHash("0xf120d0577a0f198a031035e639c713acc3097f93edd4a78271b856a126688a45") -} - -// UnpackNoScheduledUpgradeError is the Go binding used to decode the provided -// error data into the corresponding Go error struct. -// -// Solidity: error NoScheduledUpgrade() -func (appController *AppController) UnpackNoScheduledUpgradeError(raw []byte) (*AppControllerNoScheduledUpgrade, error) { - out := new(AppControllerNoScheduledUpgrade) - if err := appController.abi.UnpackIntoInterface(out, "NoScheduledUpgrade", raw); err != nil { - return nil, err - } - return out, nil -} - -// AppControllerNotTimelocked represents a NotTimelocked error raised by the AppController contract. -type AppControllerNotTimelocked struct { -} - -// ErrorID returns the hash of canonical representation of the error's signature. -// -// Solidity: error NotTimelocked() -func AppControllerNotTimelockedErrorID() common.Hash { - return common.HexToHash("0xb48b74db2c828a88a77710e47b80a5e7906b02e8be9cba32ca36252d00e2df7b") -} - -// UnpackNotTimelockedError is the Go binding used to decode the provided -// error data into the corresponding Go error struct. -// -// Solidity: error NotTimelocked() -func (appController *AppController) UnpackNotTimelockedError(raw []byte) (*AppControllerNotTimelocked, error) { - out := new(AppControllerNotTimelocked) - if err := appController.abi.UnpackIntoInterface(out, "NotTimelocked", raw); err != nil { - return nil, err - } - return out, nil -} - -// AppControllerReleaseMismatch represents a ReleaseMismatch error raised by the AppController contract. -type AppControllerReleaseMismatch struct { -} - -// ErrorID returns the hash of canonical representation of the error's signature. -// -// Solidity: error ReleaseMismatch() -func AppControllerReleaseMismatchErrorID() common.Hash { - return common.HexToHash("0x7e12f55f1c6d381c7259212a0db1adb04659234404021ffa440ec07c33c43269") -} - -// UnpackReleaseMismatchError is the Go binding used to decode the provided -// error data into the corresponding Go error struct. -// -// Solidity: error ReleaseMismatch() -func (appController *AppController) UnpackReleaseMismatchError(raw []byte) (*AppControllerReleaseMismatch, error) { - out := new(AppControllerReleaseMismatch) - if err := appController.abi.UnpackIntoInterface(out, "ReleaseMismatch", raw); err != nil { - return nil, err - } - return out, nil -} - // AppControllerSignatureExpired represents a SignatureExpired error raised by the AppController contract. type AppControllerSignatureExpired struct { } @@ -3080,49 +2792,3 @@ func (appController *AppController) UnpackStringTooLongError(raw []byte) (*AppCo } return out, nil } - -// AppControllerTimelockRequired represents a TimelockRequired error raised by the AppController contract. -type AppControllerTimelockRequired struct { -} - -// ErrorID returns the hash of canonical representation of the error's signature. -// -// Solidity: error TimelockRequired() -func AppControllerTimelockRequiredErrorID() common.Hash { - return common.HexToHash("0x99f26d5ba7d7b6eab4548ad1e80ab2f619d640fccce0209554cf0266178e110b") -} - -// UnpackTimelockRequiredError is the Go binding used to decode the provided -// error data into the corresponding Go error struct. -// -// Solidity: error TimelockRequired() -func (appController *AppController) UnpackTimelockRequiredError(raw []byte) (*AppControllerTimelockRequired, error) { - out := new(AppControllerTimelockRequired) - if err := appController.abi.UnpackIntoInterface(out, "TimelockRequired", raw); err != nil { - return nil, err - } - return out, nil -} - -// AppControllerUpgradeNotReady represents a UpgradeNotReady error raised by the AppController contract. -type AppControllerUpgradeNotReady struct { -} - -// ErrorID returns the hash of canonical representation of the error's signature. -// -// Solidity: error UpgradeNotReady() -func AppControllerUpgradeNotReadyErrorID() common.Hash { - return common.HexToHash("0x1bada80216aface91d6a430ccf87bb5350f653443d8c6fadbd883d765d28e31f") -} - -// UnpackUpgradeNotReadyError is the Go binding used to decode the provided -// error data into the corresponding Go error struct. -// -// Solidity: error UpgradeNotReady() -func (appController *AppController) UnpackUpgradeNotReadyError(raw []byte) (*AppControllerUpgradeNotReady, error) { - out := new(AppControllerUpgradeNotReady) - if err := appController.abi.UnpackIntoInterface(out, "UpgradeNotReady", raw); err != nil { - return nil, err - } - return out, nil -} From 8200b7a74e4583ec9559b09038944dce94136cb3 Mon Sep 17 00:00:00 2001 From: Taras Shchybovyk Date: Wed, 15 Apr 2026 13:26:05 -0700 Subject: [PATCH 21/31] ci: pin GitHub Actions to full commit SHAs per org policy --- .github/workflows/bindings.yml | 6 +++--- .github/workflows/test.yml | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/bindings.yml b/.github/workflows/bindings.yml index 7cce514..19a07ed 100644 --- a/.github/workflows/bindings.yml +++ b/.github/workflows/bindings.yml @@ -12,17 +12,17 @@ jobs: name: Check Go Bindings runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 with: submodules: recursive - name: Set up Go - uses: actions/setup-go@v4 + uses: actions/setup-go@f111f3307d8850f501ac008e886eec1fd1932a34 # v4 with: go-version: '1.24' - name: Install Foundry - uses: foundry-rs/foundry-toolchain@v1 + uses: foundry-rs/foundry-toolchain@82dee4ba654bd2146511f85f0d013af94670c4de # v1 - name: Build contracts run: forge build --no-metadata diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index da9b200..2aa245a 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -13,12 +13,12 @@ jobs: name: Foundry project runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 with: submodules: recursive - name: Install Foundry - uses: foundry-rs/foundry-toolchain@v1 + uses: foundry-rs/foundry-toolchain@82dee4ba654bd2146511f85f0d013af94670c4de # v1 - name: Show Forge version run: | From ba6c46aa3b670d3d14cc30aead97959a214cd490 Mon Sep 17 00:00:00 2001 From: Taras Shchybovyk Date: Wed, 15 Apr 2026 14:13:34 -0700 Subject: [PATCH 22/31] feat: add deployer-indexed registry to SafeTimelockFactory --- .../v1/SafeTimelockFactory/binding.go | 64 +++++++++++++- .../v2/SafeTimelockFactory/binding.go | 72 +++++++++++++++- src/factories/SafeTimelockFactory.sol | 12 +++ src/interfaces/ISafeTimelockFactory.sol | 14 ++++ src/storage/SafeTimelockFactoryStorage.sol | 8 +- test/SafeTimelockFactory.t.sol | 83 +++++++++++++++++++ 6 files changed, 250 insertions(+), 3 deletions(-) diff --git a/pkg/bindings/v1/SafeTimelockFactory/binding.go b/pkg/bindings/v1/SafeTimelockFactory/binding.go index f226d78..247e434 100644 --- a/pkg/bindings/v1/SafeTimelockFactory/binding.go +++ b/pkg/bindings/v1/SafeTimelockFactory/binding.go @@ -44,7 +44,7 @@ type ISafeTimelockFactoryTimelockConfig struct { // SafeTimelockFactoryMetaData contains all meta data concerning the SafeTimelockFactory contract. var SafeTimelockFactoryMetaData = &bind.MetaData{ - ABI: "[{\"type\":\"constructor\",\"inputs\":[{\"name\":\"_safeSingleton\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_safeProxyFactory\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_safeFallbackHandler\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_timelockImplementation\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"calculateSafeAddress\",\"inputs\":[{\"name\":\"deployer\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"config\",\"type\":\"tuple\",\"internalType\":\"structISafeTimelockFactory.SafeConfig\",\"components\":[{\"name\":\"owners\",\"type\":\"address[]\",\"internalType\":\"address[]\"},{\"name\":\"threshold\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]},{\"name\":\"salt\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"calculateTimelockAddress\",\"inputs\":[{\"name\":\"deployer\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"salt\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"deploySafe\",\"inputs\":[{\"name\":\"config\",\"type\":\"tuple\",\"internalType\":\"structISafeTimelockFactory.SafeConfig\",\"components\":[{\"name\":\"owners\",\"type\":\"address[]\",\"internalType\":\"address[]\"},{\"name\":\"threshold\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]},{\"name\":\"salt\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"safe\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"deployTimelock\",\"inputs\":[{\"name\":\"config\",\"type\":\"tuple\",\"internalType\":\"structISafeTimelockFactory.TimelockConfig\",\"components\":[{\"name\":\"minDelay\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"proposers\",\"type\":\"address[]\",\"internalType\":\"address[]\"},{\"name\":\"executors\",\"type\":\"address[]\",\"internalType\":\"address[]\"}]},{\"name\":\"salt\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"timelock\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"initialize\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"isSafe\",\"inputs\":[{\"name\":\"safe\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"isTimelock\",\"inputs\":[{\"name\":\"timelock\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"safeFallbackHandler\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"safeProxyFactory\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"safeSingleton\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"timelockImplementation\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"event\",\"name\":\"Initialized\",\"inputs\":[{\"name\":\"version\",\"type\":\"uint8\",\"indexed\":false,\"internalType\":\"uint8\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"SafeDeployed\",\"inputs\":[{\"name\":\"deployer\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"safe\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"owners\",\"type\":\"address[]\",\"indexed\":false,\"internalType\":\"address[]\"},{\"name\":\"threshold\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"salt\",\"type\":\"bytes32\",\"indexed\":false,\"internalType\":\"bytes32\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"TimelockDeployed\",\"inputs\":[{\"name\":\"deployer\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"timelock\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"minDelay\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"proposers\",\"type\":\"address[]\",\"indexed\":false,\"internalType\":\"address[]\"},{\"name\":\"executors\",\"type\":\"address[]\",\"indexed\":false,\"internalType\":\"address[]\"},{\"name\":\"salt\",\"type\":\"bytes32\",\"indexed\":false,\"internalType\":\"bytes32\"}],\"anonymous\":false},{\"type\":\"error\",\"name\":\"NoExecutors\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"NoProposers\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"ZeroAddressExecutor\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"ZeroAddressProposer\",\"inputs\":[]}]", + ABI: "[{\"type\":\"constructor\",\"inputs\":[{\"name\":\"_safeSingleton\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_safeProxyFactory\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_safeFallbackHandler\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_timelockImplementation\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"calculateSafeAddress\",\"inputs\":[{\"name\":\"deployer\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"config\",\"type\":\"tuple\",\"internalType\":\"structISafeTimelockFactory.SafeConfig\",\"components\":[{\"name\":\"owners\",\"type\":\"address[]\",\"internalType\":\"address[]\"},{\"name\":\"threshold\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]},{\"name\":\"salt\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"calculateTimelockAddress\",\"inputs\":[{\"name\":\"deployer\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"salt\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"deploySafe\",\"inputs\":[{\"name\":\"config\",\"type\":\"tuple\",\"internalType\":\"structISafeTimelockFactory.SafeConfig\",\"components\":[{\"name\":\"owners\",\"type\":\"address[]\",\"internalType\":\"address[]\"},{\"name\":\"threshold\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]},{\"name\":\"salt\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"safe\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"deployTimelock\",\"inputs\":[{\"name\":\"config\",\"type\":\"tuple\",\"internalType\":\"structISafeTimelockFactory.TimelockConfig\",\"components\":[{\"name\":\"minDelay\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"proposers\",\"type\":\"address[]\",\"internalType\":\"address[]\"},{\"name\":\"executors\",\"type\":\"address[]\",\"internalType\":\"address[]\"}]},{\"name\":\"salt\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"timelock\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"getSafesByDeployer\",\"inputs\":[{\"name\":\"deployer\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address[]\",\"internalType\":\"address[]\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getTimelocksByDeployer\",\"inputs\":[{\"name\":\"deployer\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address[]\",\"internalType\":\"address[]\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"initialize\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"isSafe\",\"inputs\":[{\"name\":\"safe\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"isTimelock\",\"inputs\":[{\"name\":\"timelock\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"safeFallbackHandler\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"safeProxyFactory\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"safeSingleton\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"timelockImplementation\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"event\",\"name\":\"Initialized\",\"inputs\":[{\"name\":\"version\",\"type\":\"uint8\",\"indexed\":false,\"internalType\":\"uint8\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"SafeDeployed\",\"inputs\":[{\"name\":\"deployer\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"safe\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"owners\",\"type\":\"address[]\",\"indexed\":false,\"internalType\":\"address[]\"},{\"name\":\"threshold\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"salt\",\"type\":\"bytes32\",\"indexed\":false,\"internalType\":\"bytes32\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"TimelockDeployed\",\"inputs\":[{\"name\":\"deployer\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"timelock\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"minDelay\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"proposers\",\"type\":\"address[]\",\"indexed\":false,\"internalType\":\"address[]\"},{\"name\":\"executors\",\"type\":\"address[]\",\"indexed\":false,\"internalType\":\"address[]\"},{\"name\":\"salt\",\"type\":\"bytes32\",\"indexed\":false,\"internalType\":\"bytes32\"}],\"anonymous\":false},{\"type\":\"error\",\"name\":\"NoExecutors\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"NoProposers\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"ZeroAddressExecutor\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"ZeroAddressProposer\",\"inputs\":[]}]", } // SafeTimelockFactoryABI is the input ABI used to generate the binding from. @@ -255,6 +255,68 @@ func (_SafeTimelockFactory *SafeTimelockFactoryCallerSession) CalculateTimelockA return _SafeTimelockFactory.Contract.CalculateTimelockAddress(&_SafeTimelockFactory.CallOpts, deployer, salt) } +// GetSafesByDeployer is a free data retrieval call binding the contract method 0x1eae53e8. +// +// Solidity: function getSafesByDeployer(address deployer) view returns(address[]) +func (_SafeTimelockFactory *SafeTimelockFactoryCaller) GetSafesByDeployer(opts *bind.CallOpts, deployer common.Address) ([]common.Address, error) { + var out []interface{} + err := _SafeTimelockFactory.contract.Call(opts, &out, "getSafesByDeployer", deployer) + + if err != nil { + return *new([]common.Address), err + } + + out0 := *abi.ConvertType(out[0], new([]common.Address)).(*[]common.Address) + + return out0, err + +} + +// GetSafesByDeployer is a free data retrieval call binding the contract method 0x1eae53e8. +// +// Solidity: function getSafesByDeployer(address deployer) view returns(address[]) +func (_SafeTimelockFactory *SafeTimelockFactorySession) GetSafesByDeployer(deployer common.Address) ([]common.Address, error) { + return _SafeTimelockFactory.Contract.GetSafesByDeployer(&_SafeTimelockFactory.CallOpts, deployer) +} + +// GetSafesByDeployer is a free data retrieval call binding the contract method 0x1eae53e8. +// +// Solidity: function getSafesByDeployer(address deployer) view returns(address[]) +func (_SafeTimelockFactory *SafeTimelockFactoryCallerSession) GetSafesByDeployer(deployer common.Address) ([]common.Address, error) { + return _SafeTimelockFactory.Contract.GetSafesByDeployer(&_SafeTimelockFactory.CallOpts, deployer) +} + +// GetTimelocksByDeployer is a free data retrieval call binding the contract method 0xb145953e. +// +// Solidity: function getTimelocksByDeployer(address deployer) view returns(address[]) +func (_SafeTimelockFactory *SafeTimelockFactoryCaller) GetTimelocksByDeployer(opts *bind.CallOpts, deployer common.Address) ([]common.Address, error) { + var out []interface{} + err := _SafeTimelockFactory.contract.Call(opts, &out, "getTimelocksByDeployer", deployer) + + if err != nil { + return *new([]common.Address), err + } + + out0 := *abi.ConvertType(out[0], new([]common.Address)).(*[]common.Address) + + return out0, err + +} + +// GetTimelocksByDeployer is a free data retrieval call binding the contract method 0xb145953e. +// +// Solidity: function getTimelocksByDeployer(address deployer) view returns(address[]) +func (_SafeTimelockFactory *SafeTimelockFactorySession) GetTimelocksByDeployer(deployer common.Address) ([]common.Address, error) { + return _SafeTimelockFactory.Contract.GetTimelocksByDeployer(&_SafeTimelockFactory.CallOpts, deployer) +} + +// GetTimelocksByDeployer is a free data retrieval call binding the contract method 0xb145953e. +// +// Solidity: function getTimelocksByDeployer(address deployer) view returns(address[]) +func (_SafeTimelockFactory *SafeTimelockFactoryCallerSession) GetTimelocksByDeployer(deployer common.Address) ([]common.Address, error) { + return _SafeTimelockFactory.Contract.GetTimelocksByDeployer(&_SafeTimelockFactory.CallOpts, deployer) +} + // IsSafe is a free data retrieval call binding the contract method 0x769a28ac. // // Solidity: function isSafe(address safe) view returns(bool) diff --git a/pkg/bindings/v2/SafeTimelockFactory/binding.go b/pkg/bindings/v2/SafeTimelockFactory/binding.go index 6558f9d..b0c1476 100644 --- a/pkg/bindings/v2/SafeTimelockFactory/binding.go +++ b/pkg/bindings/v2/SafeTimelockFactory/binding.go @@ -39,7 +39,7 @@ type ISafeTimelockFactoryTimelockConfig struct { // SafeTimelockFactoryMetaData contains all meta data concerning the SafeTimelockFactory contract. var SafeTimelockFactoryMetaData = bind.MetaData{ - ABI: "[{\"type\":\"constructor\",\"inputs\":[{\"name\":\"_safeSingleton\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_safeProxyFactory\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_safeFallbackHandler\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_timelockImplementation\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"calculateSafeAddress\",\"inputs\":[{\"name\":\"deployer\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"config\",\"type\":\"tuple\",\"internalType\":\"structISafeTimelockFactory.SafeConfig\",\"components\":[{\"name\":\"owners\",\"type\":\"address[]\",\"internalType\":\"address[]\"},{\"name\":\"threshold\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]},{\"name\":\"salt\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"calculateTimelockAddress\",\"inputs\":[{\"name\":\"deployer\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"salt\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"deploySafe\",\"inputs\":[{\"name\":\"config\",\"type\":\"tuple\",\"internalType\":\"structISafeTimelockFactory.SafeConfig\",\"components\":[{\"name\":\"owners\",\"type\":\"address[]\",\"internalType\":\"address[]\"},{\"name\":\"threshold\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]},{\"name\":\"salt\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"safe\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"deployTimelock\",\"inputs\":[{\"name\":\"config\",\"type\":\"tuple\",\"internalType\":\"structISafeTimelockFactory.TimelockConfig\",\"components\":[{\"name\":\"minDelay\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"proposers\",\"type\":\"address[]\",\"internalType\":\"address[]\"},{\"name\":\"executors\",\"type\":\"address[]\",\"internalType\":\"address[]\"}]},{\"name\":\"salt\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"timelock\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"initialize\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"isSafe\",\"inputs\":[{\"name\":\"safe\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"isTimelock\",\"inputs\":[{\"name\":\"timelock\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"safeFallbackHandler\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"safeProxyFactory\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"safeSingleton\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"timelockImplementation\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"event\",\"name\":\"Initialized\",\"inputs\":[{\"name\":\"version\",\"type\":\"uint8\",\"indexed\":false,\"internalType\":\"uint8\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"SafeDeployed\",\"inputs\":[{\"name\":\"deployer\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"safe\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"owners\",\"type\":\"address[]\",\"indexed\":false,\"internalType\":\"address[]\"},{\"name\":\"threshold\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"salt\",\"type\":\"bytes32\",\"indexed\":false,\"internalType\":\"bytes32\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"TimelockDeployed\",\"inputs\":[{\"name\":\"deployer\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"timelock\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"minDelay\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"proposers\",\"type\":\"address[]\",\"indexed\":false,\"internalType\":\"address[]\"},{\"name\":\"executors\",\"type\":\"address[]\",\"indexed\":false,\"internalType\":\"address[]\"},{\"name\":\"salt\",\"type\":\"bytes32\",\"indexed\":false,\"internalType\":\"bytes32\"}],\"anonymous\":false},{\"type\":\"error\",\"name\":\"NoExecutors\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"NoProposers\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"ZeroAddressExecutor\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"ZeroAddressProposer\",\"inputs\":[]}]", + ABI: "[{\"type\":\"constructor\",\"inputs\":[{\"name\":\"_safeSingleton\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_safeProxyFactory\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_safeFallbackHandler\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_timelockImplementation\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"calculateSafeAddress\",\"inputs\":[{\"name\":\"deployer\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"config\",\"type\":\"tuple\",\"internalType\":\"structISafeTimelockFactory.SafeConfig\",\"components\":[{\"name\":\"owners\",\"type\":\"address[]\",\"internalType\":\"address[]\"},{\"name\":\"threshold\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]},{\"name\":\"salt\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"calculateTimelockAddress\",\"inputs\":[{\"name\":\"deployer\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"salt\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"deploySafe\",\"inputs\":[{\"name\":\"config\",\"type\":\"tuple\",\"internalType\":\"structISafeTimelockFactory.SafeConfig\",\"components\":[{\"name\":\"owners\",\"type\":\"address[]\",\"internalType\":\"address[]\"},{\"name\":\"threshold\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]},{\"name\":\"salt\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"safe\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"deployTimelock\",\"inputs\":[{\"name\":\"config\",\"type\":\"tuple\",\"internalType\":\"structISafeTimelockFactory.TimelockConfig\",\"components\":[{\"name\":\"minDelay\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"proposers\",\"type\":\"address[]\",\"internalType\":\"address[]\"},{\"name\":\"executors\",\"type\":\"address[]\",\"internalType\":\"address[]\"}]},{\"name\":\"salt\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"timelock\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"getSafesByDeployer\",\"inputs\":[{\"name\":\"deployer\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address[]\",\"internalType\":\"address[]\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getTimelocksByDeployer\",\"inputs\":[{\"name\":\"deployer\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address[]\",\"internalType\":\"address[]\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"initialize\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"isSafe\",\"inputs\":[{\"name\":\"safe\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"isTimelock\",\"inputs\":[{\"name\":\"timelock\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"safeFallbackHandler\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"safeProxyFactory\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"safeSingleton\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"timelockImplementation\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"event\",\"name\":\"Initialized\",\"inputs\":[{\"name\":\"version\",\"type\":\"uint8\",\"indexed\":false,\"internalType\":\"uint8\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"SafeDeployed\",\"inputs\":[{\"name\":\"deployer\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"safe\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"owners\",\"type\":\"address[]\",\"indexed\":false,\"internalType\":\"address[]\"},{\"name\":\"threshold\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"salt\",\"type\":\"bytes32\",\"indexed\":false,\"internalType\":\"bytes32\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"TimelockDeployed\",\"inputs\":[{\"name\":\"deployer\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"timelock\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"minDelay\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"proposers\",\"type\":\"address[]\",\"indexed\":false,\"internalType\":\"address[]\"},{\"name\":\"executors\",\"type\":\"address[]\",\"indexed\":false,\"internalType\":\"address[]\"},{\"name\":\"salt\",\"type\":\"bytes32\",\"indexed\":false,\"internalType\":\"bytes32\"}],\"anonymous\":false},{\"type\":\"error\",\"name\":\"NoExecutors\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"NoProposers\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"ZeroAddressExecutor\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"ZeroAddressProposer\",\"inputs\":[]}]", ID: "SafeTimelockFactory", } @@ -215,6 +215,76 @@ func (safeTimelockFactory *SafeTimelockFactory) UnpackDeployTimelock(data []byte return out0, nil } +// PackGetSafesByDeployer is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x1eae53e8. This method will panic if any +// invalid/nil inputs are passed. +// +// Solidity: function getSafesByDeployer(address deployer) view returns(address[]) +func (safeTimelockFactory *SafeTimelockFactory) PackGetSafesByDeployer(deployer common.Address) []byte { + enc, err := safeTimelockFactory.abi.Pack("getSafesByDeployer", deployer) + if err != nil { + panic(err) + } + return enc +} + +// TryPackGetSafesByDeployer is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x1eae53e8. This method will return an error +// if any inputs are invalid/nil. +// +// Solidity: function getSafesByDeployer(address deployer) view returns(address[]) +func (safeTimelockFactory *SafeTimelockFactory) TryPackGetSafesByDeployer(deployer common.Address) ([]byte, error) { + return safeTimelockFactory.abi.Pack("getSafesByDeployer", deployer) +} + +// UnpackGetSafesByDeployer is the Go binding that unpacks the parameters returned +// from invoking the contract method with ID 0x1eae53e8. +// +// Solidity: function getSafesByDeployer(address deployer) view returns(address[]) +func (safeTimelockFactory *SafeTimelockFactory) UnpackGetSafesByDeployer(data []byte) ([]common.Address, error) { + out, err := safeTimelockFactory.abi.Unpack("getSafesByDeployer", data) + if err != nil { + return *new([]common.Address), err + } + out0 := *abi.ConvertType(out[0], new([]common.Address)).(*[]common.Address) + return out0, nil +} + +// PackGetTimelocksByDeployer is the Go binding used to pack the parameters required for calling +// the contract method with ID 0xb145953e. This method will panic if any +// invalid/nil inputs are passed. +// +// Solidity: function getTimelocksByDeployer(address deployer) view returns(address[]) +func (safeTimelockFactory *SafeTimelockFactory) PackGetTimelocksByDeployer(deployer common.Address) []byte { + enc, err := safeTimelockFactory.abi.Pack("getTimelocksByDeployer", deployer) + if err != nil { + panic(err) + } + return enc +} + +// TryPackGetTimelocksByDeployer is the Go binding used to pack the parameters required for calling +// the contract method with ID 0xb145953e. This method will return an error +// if any inputs are invalid/nil. +// +// Solidity: function getTimelocksByDeployer(address deployer) view returns(address[]) +func (safeTimelockFactory *SafeTimelockFactory) TryPackGetTimelocksByDeployer(deployer common.Address) ([]byte, error) { + return safeTimelockFactory.abi.Pack("getTimelocksByDeployer", deployer) +} + +// UnpackGetTimelocksByDeployer is the Go binding that unpacks the parameters returned +// from invoking the contract method with ID 0xb145953e. +// +// Solidity: function getTimelocksByDeployer(address deployer) view returns(address[]) +func (safeTimelockFactory *SafeTimelockFactory) UnpackGetTimelocksByDeployer(data []byte) ([]common.Address, error) { + out, err := safeTimelockFactory.abi.Unpack("getTimelocksByDeployer", data) + if err != nil { + return *new([]common.Address), err + } + out0 := *abi.ConvertType(out[0], new([]common.Address)).(*[]common.Address) + return out0, nil +} + // PackInitialize is the Go binding used to pack the parameters required for calling // the contract method with ID 0x8129fc1c. This method will panic if any // invalid/nil inputs are passed. diff --git a/src/factories/SafeTimelockFactory.sol b/src/factories/SafeTimelockFactory.sol index 9f9e084..ceb4eee 100644 --- a/src/factories/SafeTimelockFactory.sol +++ b/src/factories/SafeTimelockFactory.sol @@ -36,6 +36,7 @@ contract SafeTimelockFactory is Initializable, SafeTimelockFactoryStorage { function deploySafe(SafeConfig calldata config, bytes32 salt) external returns (address safe) { safe = _deploySafe(config, salt); _safes.add(safe); + _safesByDeployer[msg.sender].add(safe); emit SafeDeployed(msg.sender, safe, config.owners, config.threshold, salt); } @@ -44,6 +45,7 @@ contract SafeTimelockFactory is Initializable, SafeTimelockFactoryStorage { _validateTimelockConfig(config); timelock = _deployTimelock(config, salt); _timelocks.add(timelock); + _timelocksByDeployer[msg.sender].add(timelock); emit TimelockDeployed(msg.sender, timelock, config.minDelay, config.proposers, config.executors, salt); } @@ -59,6 +61,16 @@ contract SafeTimelockFactory is Initializable, SafeTimelockFactoryStorage { return _timelocks.contains(timelock); } + /// @inheritdoc ISafeTimelockFactory + function getTimelocksByDeployer(address deployer) external view returns (address[] memory) { + return _timelocksByDeployer[deployer].values(); + } + + /// @inheritdoc ISafeTimelockFactory + function getSafesByDeployer(address deployer) external view returns (address[] memory) { + return _safesByDeployer[deployer].values(); + } + /// @inheritdoc ISafeTimelockFactory function calculateSafeAddress(address deployer, SafeConfig calldata config, bytes32 salt) external diff --git a/src/interfaces/ISafeTimelockFactory.sol b/src/interfaces/ISafeTimelockFactory.sol index 2981ad4..8a78456 100644 --- a/src/interfaces/ISafeTimelockFactory.sol +++ b/src/interfaces/ISafeTimelockFactory.sol @@ -123,4 +123,18 @@ interface ISafeTimelockFactory { * @return The TimelockControllerImpl address */ function timelockImplementation() external view returns (address); + + /** + * @notice Returns all Timelocks deployed by a given deployer + * @param deployer The deployer address + * @return Array of Timelock addresses + */ + function getTimelocksByDeployer(address deployer) external view returns (address[] memory); + + /** + * @notice Returns all Safes deployed by a given deployer + * @param deployer The deployer address + * @return Array of Safe addresses + */ + function getSafesByDeployer(address deployer) external view returns (address[] memory); } diff --git a/src/storage/SafeTimelockFactoryStorage.sol b/src/storage/SafeTimelockFactoryStorage.sol index c8f30b8..bcc2a2d 100644 --- a/src/storage/SafeTimelockFactoryStorage.sol +++ b/src/storage/SafeTimelockFactoryStorage.sol @@ -33,10 +33,16 @@ abstract contract SafeTimelockFactoryStorage is ISafeTimelockFactory { /// @notice Set of all Timelocks deployed by this factory EnumerableSet.AddressSet internal _timelocks; + /// @notice Timelocks indexed by deployer address + mapping(address => EnumerableSet.AddressSet) internal _timelocksByDeployer; + + /// @notice Safes indexed by deployer address + mapping(address => EnumerableSet.AddressSet) internal _safesByDeployer; + /// STORAGE GAP /// @notice Storage gap for future upgrades - uint256[46] private __gap; + uint256[44] private __gap; /// CONSTRUCTOR diff --git a/test/SafeTimelockFactory.t.sol b/test/SafeTimelockFactory.t.sol index 23c1c55..fea162f 100644 --- a/test/SafeTimelockFactory.t.sol +++ b/test/SafeTimelockFactory.t.sol @@ -247,4 +247,87 @@ contract SafeTimelockFactoryTest is Test { function test_isSafe_false_for_random_address() public view { assertFalse(factory.isSafe(address(0xBEEF)), "random address should not be a safe"); } + + // ========== Deployer index tests ========== + + function test_getTimelocksByDeployer_returnsDeployedTimelocks() public { + address[] memory proposers = new address[](1); + proposers[0] = proposer; + address[] memory executors = new address[](1); + executors[0] = executor; + ISafeTimelockFactory.TimelockConfig memory config = + ISafeTimelockFactory.TimelockConfig({minDelay: 1 days, proposers: proposers, executors: executors}); + + address tl1 = factory.deployTimelock(config, keccak256("salt1")); + address tl2 = factory.deployTimelock(config, keccak256("salt2")); + + address[] memory result = factory.getTimelocksByDeployer(address(this)); + assertEq(result.length, 2, "should return 2 timelocks"); + assertTrue(result[0] == tl1 || result[1] == tl1, "tl1 not in result"); + assertTrue(result[0] == tl2 || result[1] == tl2, "tl2 not in result"); + } + + function test_getTimelocksByDeployer_isolatesDeployers() public { + address deployer2 = makeAddr("deployer2"); + address[] memory proposers = new address[](1); + proposers[0] = proposer; + address[] memory executors = new address[](1); + executors[0] = executor; + ISafeTimelockFactory.TimelockConfig memory config = + ISafeTimelockFactory.TimelockConfig({minDelay: 1 days, proposers: proposers, executors: executors}); + + factory.deployTimelock(config, SALT); + + vm.prank(deployer2); + factory.deployTimelock(config, SALT); + + assertEq(factory.getTimelocksByDeployer(address(this)).length, 1, "deployer1 should have 1"); + assertEq(factory.getTimelocksByDeployer(deployer2).length, 1, "deployer2 should have 1"); + } + + function test_getTimelocksByDeployer_emptyForUnknown() public view { + assertEq(factory.getTimelocksByDeployer(address(0xDEAD)).length, 0, "unknown deployer should return empty"); + } + + function test_getSafesByDeployer_returnsDeployedSafes() public { + address[] memory owners = new address[](1); + owners[0] = makeAddr("owner"); + ISafeTimelockFactory.SafeConfig memory config1 = ISafeTimelockFactory.SafeConfig({owners: owners, threshold: 1}); + + address[] memory owners2 = new address[](1); + owners2[0] = makeAddr("owner2"); + ISafeTimelockFactory.SafeConfig memory config2 = + ISafeTimelockFactory.SafeConfig({owners: owners2, threshold: 1}); + + address safe1 = factory.deploySafe(config1, SALT); + address safe2 = factory.deploySafe(config2, SALT); + + address[] memory result = factory.getSafesByDeployer(address(this)); + assertEq(result.length, 2, "should return 2 safes"); + assertTrue(result[0] == safe1 || result[1] == safe1, "safe1 not in result"); + assertTrue(result[0] == safe2 || result[1] == safe2, "safe2 not in result"); + } + + function test_getSafesByDeployer_isolatesDeployers() public { + address deployer2 = makeAddr("deployer2"); + address[] memory owners = new address[](1); + owners[0] = makeAddr("owner"); + ISafeTimelockFactory.SafeConfig memory config = ISafeTimelockFactory.SafeConfig({owners: owners, threshold: 1}); + + factory.deploySafe(config, SALT); + + address[] memory owners2 = new address[](1); + owners2[0] = makeAddr("owner2"); + ISafeTimelockFactory.SafeConfig memory config2 = + ISafeTimelockFactory.SafeConfig({owners: owners2, threshold: 1}); + vm.prank(deployer2); + factory.deploySafe(config2, SALT); + + assertEq(factory.getSafesByDeployer(address(this)).length, 1, "deployer1 should have 1"); + assertEq(factory.getSafesByDeployer(deployer2).length, 1, "deployer2 should have 1"); + } + + function test_getSafesByDeployer_emptyForUnknown() public view { + assertEq(factory.getSafesByDeployer(address(0xDEAD)).length, 0, "unknown deployer should return empty"); + } } From bd975f877b284a10958d7ec36688a82afe66c84d Mon Sep 17 00:00:00 2001 From: Taras Shchybovyk Date: Wed, 15 Apr 2026 15:42:07 -0700 Subject: [PATCH 23/31] chore: update sepolia-dev deployment output with new contract addresses Full redeploy including SafeTimelockFactory with deployer-indexed registry. All 15 contracts verified on Etherscan. Co-Authored-By: Claude Sonnet 4.6 --- script/deploys/sepolia-dev/output.json | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 script/deploys/sepolia-dev/output.json diff --git a/script/deploys/sepolia-dev/output.json b/script/deploys/sepolia-dev/output.json new file mode 100644 index 0000000..0de1c63 --- /dev/null +++ b/script/deploys/sepolia-dev/output.json @@ -0,0 +1,21 @@ +{ + "addresses": { + "appBeacon": "0xA7323106F6018baCe991946C47e5645cFB8DB7B6", + "appController": "0x84639cE873580a5c19DCCb78f92EFAdCC01019e0", + "appControllerImpl": "0xF91d27fB314F62050212A16a32FD61592bd016db", + "appImpl": "0xf5a395841F1D53A513dBD6191d0bcf29aAaC7Ec0", + "computeAVSRegistrar": "0x662DBE70456Dc43a8aF961F4187eba7B7Db9e56E", + "computeAVSRegistrarImpl": "0x68FBaa90f6F0CBA8f5A8C0DfDe472dcc89c2188B", + "computeOperator": "0x8CA8023360E1f222981f3407f6495E7b6A4B15Ae", + "computeOperatorImpl": "0xdD427c92ec7a593a55dB488F089e6C6BE9195264", + "imageAllowlist": "0xDB7A1A0925bEDdD874537Efc3Fd610644F14B847", + "imageAllowlistImpl": "0x9304f044c69F7D1B66F4aFE5320009fEb58482c5", + "proxyAdmin": "0xefE0f739ADBC93DDC777Bc2Cc5b1CFFea4A89817", + "safeTimelockFactory": "0xb9278168e00878a4365721b3a0250c8e339cb72c", + "safeTimelockFactoryImpl": "0x0876218a3f89bbcec2b22e285b85dc233a67ef84", + "timelockControllerImpl": "0x6d2028ec4330d826e7d990c76249e462ccb1f082" + }, + "chainInfo": { + "chainId": 11155111 + } +} \ No newline at end of file From 04197e8f0ba73e53a1c69cff45f8b7b70c052729 Mon Sep 17 00:00:00 2001 From: Taras Shchybovyk Date: Thu, 16 Apr 2026 11:36:27 -0700 Subject: [PATCH 24/31] fix: pass real Safe addresses to SafeTimelockFactory constructor Deploy.s.sol was hardcoding address(0) for safeSingleton, safeProxyFactory, and safeFallbackHandler, causing all Safe deployments via the factory to revert. Safe addresses are now read from config.json and validated before use. Also adds safeTimelockFactory to the output.json serialization so the address is captured without manual inspection of broadcast logs. --- script/Deploy.s.sol | 12 ++++++++---- script/Parser.s.sol | 9 ++++++++- script/deploys/sepolia-dev/config.json | 17 +++++++++++++++++ script/deploys/sepolia-dev/output.json | 26 ++++++++++++-------------- test/utils/ComputeDeployer.sol | 5 ++++- 5 files changed, 49 insertions(+), 20 deletions(-) create mode 100644 script/deploys/sepolia-dev/config.json diff --git a/script/Deploy.s.sol b/script/Deploy.s.sol index 1132740..d4caece 100644 --- a/script/Deploy.s.sol +++ b/script/Deploy.s.sol @@ -92,11 +92,14 @@ contract Deploy is Parser { // Deploy SafeTimelockFactory if not provided ISafeTimelockFactory safeTimelockFactory = params.safeTimelockFactory; if (address(safeTimelockFactory) == address(0)) { + require(params.safeSingleton != address(0), "safeSingleton must not be zero"); + require(params.safeProxyFactory != address(0), "safeProxyFactory must not be zero"); + require(params.safeFallbackHandler != address(0), "safeFallbackHandler must not be zero"); TimelockControllerImpl timelockImpl = new TimelockControllerImpl(); SafeTimelockFactory factoryImpl = new SafeTimelockFactory({ - _safeSingleton: address(0), - _safeProxyFactory: address(0), - _safeFallbackHandler: address(0), + _safeSingleton: params.safeSingleton, + _safeProxyFactory: params.safeProxyFactory, + _safeFallbackHandler: params.safeFallbackHandler, _timelockImplementation: address(timelockImpl) }); TransparentUpgradeableProxy factoryProxy = new TransparentUpgradeableProxy( @@ -215,7 +218,8 @@ contract Deploy is Parser { vm.serializeAddress(addresses, "computeOperator", address(deployedContracts.computeOperator)); vm.serializeAddress(addresses, "computeOperatorImpl", address(deployedContracts.computeOperatorImpl)); vm.serializeAddress(addresses, "imageAllowlist", address(deployedContracts.imageAllowlist)); - addresses = vm.serializeAddress(addresses, "imageAllowlistImpl", address(deployedContracts.imageAllowlistImpl)); + vm.serializeAddress(addresses, "imageAllowlistImpl", address(deployedContracts.imageAllowlistImpl)); + addresses = vm.serializeAddress(addresses, "safeTimelockFactory", address(deployedContracts.safeTimelockFactory)); // Add the chainInfo object string memory chainInfo = "chainInfo"; diff --git a/script/Parser.s.sol b/script/Parser.s.sol index b33a7b7..3933882 100644 --- a/script/Parser.s.sol +++ b/script/Parser.s.sol @@ -36,7 +36,11 @@ contract Parser is Script { string avsMetadataURI; uint32 maxGlobalActiveApps; uint32 adminMaxActiveApps; - // Optional: if address(0), Deploy will deploy a new SafeTimelockFactory with stub Safe addresses + // Gnosis Safe infrastructure addresses (required for SafeTimelockFactory deployment) + address safeSingleton; + address safeProxyFactory; + address safeFallbackHandler; + // Optional: if address(0), Deploy will deploy a new SafeTimelockFactory ISafeTimelockFactory safeTimelockFactory; } @@ -72,6 +76,9 @@ contract Parser is Script { avsMetadataURI: vm.parseJsonString(json, ".avsMetadataURI"), maxGlobalActiveApps: uint32(vm.parseJsonUint(json, ".maxGlobalActiveApps")), adminMaxActiveApps: uint32(vm.parseJsonUint(json, ".adminMaxActiveApps")), + safeSingleton: vm.parseJsonAddress(json, ".safeSingleton"), + safeProxyFactory: vm.parseJsonAddress(json, ".safeProxyFactory"), + safeFallbackHandler: vm.parseJsonAddress(json, ".safeFallbackHandler"), safeTimelockFactory: ISafeTimelockFactory(address(0)) // Deploy will create one if not in config }); diff --git a/script/deploys/sepolia-dev/config.json b/script/deploys/sepolia-dev/config.json new file mode 100644 index 0000000..2d1b2b7 --- /dev/null +++ b/script/deploys/sepolia-dev/config.json @@ -0,0 +1,17 @@ +{ + "version": "1.4.0", + "delegationManager": "0xD4A7E1Bd8015057293f0D0A557088c286942e84b", + "allocationManager": "0x42583067658071247ec8CE0A516A58f682002d07", + "permissionController": "0x44632dfBdCb6D3E21EF613B0ca8A6A0c618F5a37", + "keyRegistrar": "0xA4dB30D08d8bbcA00D40600bee9F029984dB162a", + "releaseManager": "0x59c8D715DCa616e032B744a753C017c9f3E16bf4", + "proxyAdmin": "0x0000000000000000000000000000000000000000", + "initialOwner": "0x08FEeaEcFeA1Ea0ecd5ee13f7487e0A53aa2f693", + "operatorMetadataURI": "https://eigencloud.xyz", + "avsMetadataURI": "https://eigencloud.xyz", + "maxGlobalActiveApps": 1000, + "adminMaxActiveApps": 100, + "safeSingleton": "0x41675C099F32341bf84BFc5382aF534df5C7461a", + "safeProxyFactory": "0x4e1DCf7AD4e460CfD30791CCC4F9c8a4f820ec67", + "safeFallbackHandler": "0xfd0732Dc9E303f09fCEf3a7388Ad10A83459Ec99" +} diff --git a/script/deploys/sepolia-dev/output.json b/script/deploys/sepolia-dev/output.json index 0de1c63..226acd8 100644 --- a/script/deploys/sepolia-dev/output.json +++ b/script/deploys/sepolia-dev/output.json @@ -1,19 +1,17 @@ { "addresses": { - "appBeacon": "0xA7323106F6018baCe991946C47e5645cFB8DB7B6", - "appController": "0x84639cE873580a5c19DCCb78f92EFAdCC01019e0", - "appControllerImpl": "0xF91d27fB314F62050212A16a32FD61592bd016db", - "appImpl": "0xf5a395841F1D53A513dBD6191d0bcf29aAaC7Ec0", - "computeAVSRegistrar": "0x662DBE70456Dc43a8aF961F4187eba7B7Db9e56E", - "computeAVSRegistrarImpl": "0x68FBaa90f6F0CBA8f5A8C0DfDe472dcc89c2188B", - "computeOperator": "0x8CA8023360E1f222981f3407f6495E7b6A4B15Ae", - "computeOperatorImpl": "0xdD427c92ec7a593a55dB488F089e6C6BE9195264", - "imageAllowlist": "0xDB7A1A0925bEDdD874537Efc3Fd610644F14B847", - "imageAllowlistImpl": "0x9304f044c69F7D1B66F4aFE5320009fEb58482c5", - "proxyAdmin": "0xefE0f739ADBC93DDC777Bc2Cc5b1CFFea4A89817", - "safeTimelockFactory": "0xb9278168e00878a4365721b3a0250c8e339cb72c", - "safeTimelockFactoryImpl": "0x0876218a3f89bbcec2b22e285b85dc233a67ef84", - "timelockControllerImpl": "0x6d2028ec4330d826e7d990c76249e462ccb1f082" + "appBeacon": "0x7cFa9f4a4bEC2940B6CaEB6bE24D3Fb74Bc60DD3", + "appController": "0xf4D36493CE5FFBC5518DC8c0a89C4eBBD2aee009", + "appControllerImpl": "0xA95194BC7479089a22c2aacE24bda1ed83B71902", + "appImpl": "0x5DeD61384DB3b1c32b97F52A9C6e2c40CB3a41B6", + "computeAVSRegistrar": "0xfb8b29cBd7B1768B5F2C040EF80F16A9548c3B5b", + "computeAVSRegistrarImpl": "0x6940aeA1634685411e188B0A0E57681d1Bd7cf3F", + "computeOperator": "0x72504B24E71A3b2A47fa2b031b77843B01EB34D3", + "computeOperatorImpl": "0x8CCB4eBa660f4E299f6ddD7EC5cB27C70119826e", + "imageAllowlist": "0x134AC8409cA0d65763736301b97Eae8Fa78625c5", + "imageAllowlistImpl": "0x2DDb6c99cB8E3Bae98136d613E30f18Dc38CaCA3", + "proxyAdmin": "0xF70434e8608ab551940836A259C49A191a23CDA3", + "safeTimelockFactory": "0xc7577BB90D1B7D1e7eA0F5e3d2647346dabeADdD" }, "chainInfo": { "chainId": 11155111 diff --git a/test/utils/ComputeDeployer.sol b/test/utils/ComputeDeployer.sol index 894a2f7..2968927 100644 --- a/test/utils/ComputeDeployer.sol +++ b/test/utils/ComputeDeployer.sol @@ -62,7 +62,10 @@ contract ComputeDeployer is Test { avsMetadataURI: "https://example.com/avs-metadata", maxGlobalActiveApps: 100, adminMaxActiveApps: 100, - safeTimelockFactory: ISafeTimelockFactory(address(0)) // Deploy will create one with stub Safe addresses + safeSingleton: 0x41675C099F32341bf84BFc5382aF534df5C7461a, + safeProxyFactory: 0x4e1DCf7AD4e460CfD30791CCC4F9c8a4f820ec67, + safeFallbackHandler: 0xfd0732Dc9E303f09fCEf3a7388Ad10A83459Ec99, + safeTimelockFactory: ISafeTimelockFactory(address(0)) // Deploy will create one }); Parser.DeployedContracts memory deployed = deployer.deployForTesting(params); From 349714da5a7f1f5953524c5c40503323bc8f9a61 Mon Sep 17 00:00:00 2001 From: Taras Shchybovyk Date: Thu, 16 Apr 2026 22:58:36 -0700 Subject: [PATCH 25/31] feat: add pending op enumeration to TimelockControllerImpl + redeploy sepolia-dev - TimelockControllerImpl overrides schedule/scheduleBatch/execute/executeBatch/cancel to maintain _pendingIds/_pendingOps storage - getPendingOperations() returns all queued ops with target, calldata, and executableAt without requiring event log scanning or any RPC block range - getPendingOperationIds() returns just the IDs - All existing Timelock clones upgrade automatically via SafeTimelockFactory impl update - Redeploy sepolia-dev at v1.5.0 with new AppController and SafeTimelockFactory --- script/deploys/sepolia-dev/config.json | 2 +- script/deploys/sepolia-dev/output.json | 24 ++--- src/governance/TimelockControllerImpl.sol | 122 +++++++++++++++++++++- 3 files changed, 134 insertions(+), 14 deletions(-) diff --git a/script/deploys/sepolia-dev/config.json b/script/deploys/sepolia-dev/config.json index 2d1b2b7..8fe7782 100644 --- a/script/deploys/sepolia-dev/config.json +++ b/script/deploys/sepolia-dev/config.json @@ -1,5 +1,5 @@ { - "version": "1.4.0", + "version": "1.5.0", "delegationManager": "0xD4A7E1Bd8015057293f0D0A557088c286942e84b", "allocationManager": "0x42583067658071247ec8CE0A516A58f682002d07", "permissionController": "0x44632dfBdCb6D3E21EF613B0ca8A6A0c618F5a37", diff --git a/script/deploys/sepolia-dev/output.json b/script/deploys/sepolia-dev/output.json index 226acd8..f01b9de 100644 --- a/script/deploys/sepolia-dev/output.json +++ b/script/deploys/sepolia-dev/output.json @@ -1,17 +1,17 @@ { "addresses": { - "appBeacon": "0x7cFa9f4a4bEC2940B6CaEB6bE24D3Fb74Bc60DD3", - "appController": "0xf4D36493CE5FFBC5518DC8c0a89C4eBBD2aee009", - "appControllerImpl": "0xA95194BC7479089a22c2aacE24bda1ed83B71902", - "appImpl": "0x5DeD61384DB3b1c32b97F52A9C6e2c40CB3a41B6", - "computeAVSRegistrar": "0xfb8b29cBd7B1768B5F2C040EF80F16A9548c3B5b", - "computeAVSRegistrarImpl": "0x6940aeA1634685411e188B0A0E57681d1Bd7cf3F", - "computeOperator": "0x72504B24E71A3b2A47fa2b031b77843B01EB34D3", - "computeOperatorImpl": "0x8CCB4eBa660f4E299f6ddD7EC5cB27C70119826e", - "imageAllowlist": "0x134AC8409cA0d65763736301b97Eae8Fa78625c5", - "imageAllowlistImpl": "0x2DDb6c99cB8E3Bae98136d613E30f18Dc38CaCA3", - "proxyAdmin": "0xF70434e8608ab551940836A259C49A191a23CDA3", - "safeTimelockFactory": "0xc7577BB90D1B7D1e7eA0F5e3d2647346dabeADdD" + "appBeacon": "0x253fcbd8FBfaE91A6d27284D571f60a816b4152F", + "appController": "0x6A56214b79d24469f066AdfD1F28bB929824daCE", + "appControllerImpl": "0x9f795569F0216E2a769D75fc0004AaA4A89f1319", + "appImpl": "0xC7179bc84c44cF19C4779011B6d45Ef80F7a875f", + "computeAVSRegistrar": "0x29d02CF22A14f467Edaf1C874A21F7eB7c5774a8", + "computeAVSRegistrarImpl": "0xb5Dba04Bf4A14FC6D2556523a05e1c7D522dbf21", + "computeOperator": "0x68CAC9Ed5484992215C66486aEB9eb5B2982e07D", + "computeOperatorImpl": "0xaAe57b73382B7Df50B43042331564bF7d154775e", + "imageAllowlist": "0x7f3385c4061b64d8aaDe500A7D09080b81dc89C6", + "imageAllowlistImpl": "0xa13cf9a6D2246Cd7086D8fBB4276e0f25174b7E9", + "proxyAdmin": "0xd53cABe0A39d5c6D5C659852168DD9d45Eb9D326", + "safeTimelockFactory": "0xD2D8e5085179287365678628077f891810F17108" }, "chainInfo": { "chainId": 11155111 diff --git a/src/governance/TimelockControllerImpl.sol b/src/governance/TimelockControllerImpl.sol index 966e38e..aa3ae1c 100644 --- a/src/governance/TimelockControllerImpl.sol +++ b/src/governance/TimelockControllerImpl.sol @@ -8,9 +8,26 @@ import { /** * @title TimelockControllerImpl * @notice Implementation contract for TimelockController minimal proxies - * @dev Wraps TimelockControllerUpgradeable to expose a public initialize function + * @dev Wraps TimelockControllerUpgradeable and adds on-chain pending operation enumeration. + * Overrides schedule/scheduleBatch/execute/executeBatch/cancel to maintain a set of + * pending operation IDs, enabling clients to enumerate queued operations without + * requiring event log scanning. */ contract TimelockControllerImpl is TimelockControllerUpgradeable { + struct PendingOp { + bytes32 id; + address target; + bytes data; + uint256 executableAt; + } + + // Append-only array of pending operation IDs (swap-and-pop on removal). + bytes32[] private _pendingIds; + // id => 1-based index into _pendingIds (0 means not in set). + mapping(bytes32 => uint256) private _pendingIndex; + // id => stored op metadata for enumeration + mapping(bytes32 => PendingOp) private _pendingOps; + constructor() { _disableInitializers(); } @@ -28,4 +45,107 @@ contract TimelockControllerImpl is TimelockControllerUpgradeable { { __TimelockController_init(minDelay, proposers, executors, admin); } + + // ── Overrides ──────────────────────────────────────────────────────────── + + function schedule( + address target, + uint256 value, + bytes calldata data, + bytes32 predecessor, + bytes32 salt, + uint256 delay + ) public override { + super.schedule(target, value, data, predecessor, salt, delay); + bytes32 id = hashOperation(target, value, data, predecessor, salt); + _addPending(id, target, data, block.timestamp + delay); + } + + function scheduleBatch( + address[] calldata targets, + uint256[] calldata values, + bytes[] calldata payloads, + bytes32 predecessor, + bytes32 salt, + uint256 delay + ) public override { + super.scheduleBatch(targets, values, payloads, predecessor, salt, delay); + // For batch ops store empty data — callers should use getPendingOperationIds and decode individually + bytes32 id = hashOperationBatch(targets, values, payloads, predecessor, salt); + _addPending(id, address(0), "", block.timestamp + delay); + } + + function execute( + address target, + uint256 value, + bytes calldata payload, + bytes32 predecessor, + bytes32 salt + ) public payable override { + bytes32 id = hashOperation(target, value, payload, predecessor, salt); + super.execute(target, value, payload, predecessor, salt); + _removePending(id); + } + + function executeBatch( + address[] calldata targets, + uint256[] calldata values, + bytes[] calldata payloads, + bytes32 predecessor, + bytes32 salt + ) public payable override { + bytes32 id = hashOperationBatch(targets, values, payloads, predecessor, salt); + super.executeBatch(targets, values, payloads, predecessor, salt); + _removePending(id); + } + + function cancel(bytes32 id) public override { + super.cancel(id); + _removePending(id); + } + + // ── Enumeration ────────────────────────────────────────────────────────── + + /** + * @notice Returns all currently pending operation IDs. + */ + function getPendingOperationIds() external view returns (bytes32[] memory) { + return _pendingIds; + } + + /** + * @notice Returns all currently pending operations with metadata. + * @dev For single-call ops, target and data are populated. + * For batch ops, target is address(0) and data is empty. + */ + function getPendingOperations() external view returns (PendingOp[] memory ops) { + ops = new PendingOp[](_pendingIds.length); + for (uint256 i = 0; i < _pendingIds.length; i++) { + ops[i] = _pendingOps[_pendingIds[i]]; + } + } + + // ── Internal helpers ───────────────────────────────────────────────────── + + function _addPending(bytes32 id, address target, bytes memory data, uint256 executableAt) private { + if (_pendingIndex[id] != 0) return; // already tracked + _pendingIds.push(id); + _pendingIndex[id] = _pendingIds.length; // 1-based + _pendingOps[id] = PendingOp({ id: id, target: target, data: data, executableAt: executableAt }); + } + + function _removePending(bytes32 id) private { + uint256 idx = _pendingIndex[id]; + if (idx == 0) return; // not tracked (pre-upgrade op) + uint256 i = idx - 1; + uint256 last = _pendingIds.length - 1; + if (i != last) { + bytes32 lastId = _pendingIds[last]; + _pendingIds[i] = lastId; + _pendingIndex[lastId] = idx; // keep 1-based + } + _pendingIds.pop(); + delete _pendingIndex[id]; + delete _pendingOps[id]; + } } From 1a045562ecf79385b0eb7af712c7ce7cb8e80001 Mon Sep 17 00:00:00 2001 From: Taras Shchybovyk Date: Fri, 17 Apr 2026 14:35:24 -0700 Subject: [PATCH 26/31] fix: include factory address in _deriveSalt to prevent cross-factory address collisions --- src/factories/SafeTimelockFactory.sol | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/factories/SafeTimelockFactory.sol b/src/factories/SafeTimelockFactory.sol index ceb4eee..d92ce95 100644 --- a/src/factories/SafeTimelockFactory.sol +++ b/src/factories/SafeTimelockFactory.sol @@ -132,7 +132,7 @@ contract SafeTimelockFactory is Initializable, SafeTimelockFactoryStorage { TimelockControllerImpl(payable(timelock)).initialize(config.minDelay, config.proposers, config.executors, address(0)); } - function _deriveSalt(address deployer, bytes32 salt) internal pure returns (bytes32) { - return keccak256(abi.encodePacked(deployer, salt)); + function _deriveSalt(address deployer, bytes32 salt) internal view returns (bytes32) { + return keccak256(abi.encodePacked(address(this), deployer, salt)); } } From ce741bac9a2d6f729f4ecf9fc6c3633b2a88346b Mon Sep 17 00:00:00 2001 From: Taras Shchybovyk Date: Mon, 20 Apr 2026 11:01:21 -0700 Subject: [PATCH 27/31] feat: validate Timelock targets at schedule-time via ICallValidator MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit TimelockControllerImpl.schedule/scheduleBatch now calls canCall(address(this), data) on the target before queuing. If the target implements ICallValidator and returns false, the schedule reverts immediately — preventing operations that would always fail at execute-time from entering the queue. AppController implements ICallValidator.canCall: - App-scoped ops (upgrade, transfer, terminate, start, stop, updateMetadata): requires caller has ADMIN on the app's owner team - Team-scoped ops (createAppForTeam, grantTeamRole, revokeTeamRole): requires caller is team or has ADMIN on team - createApp: always allowed (runtime quota checks apply) - Everything else: returns false (blocked from scheduling) --- src/AppController.sol | 40 ++++++++++++++++++++++- src/governance/TimelockControllerImpl.sol | 20 ++++++++++++ src/interfaces/ICallValidator.sol | 16 +++++++++ 3 files changed, 75 insertions(+), 1 deletion(-) create mode 100644 src/interfaces/ICallValidator.sol diff --git a/src/AppController.sol b/src/AppController.sol index 40155e0..7f75540 100644 --- a/src/AppController.sol +++ b/src/AppController.sol @@ -24,13 +24,15 @@ import {BeaconProxy} from "@openzeppelin/contracts/proxy/beacon/BeaconProxy.sol" import {IBeacon} from "@openzeppelin/contracts/proxy/beacon/IBeacon.sol"; import {IApp} from "./interfaces/IApp.sol"; import {ISafeTimelockFactory} from "./interfaces/ISafeTimelockFactory.sol"; +import {ICallValidator} from "./interfaces/ICallValidator.sol"; contract AppController is Initializable, SignatureUtilsMixin, PermissionControllerMixin, AppControllerStorage, - AccessControlEnumerableUpgradeable + AccessControlEnumerableUpgradeable, + ICallValidator { using EnumerableSet for EnumerableSet.AddressSet; @@ -571,6 +573,42 @@ contract AppController is /// VIEW FUNCTIONS + /// @inheritdoc ICallValidator + function canCall(address caller, bytes calldata data) external view override returns (bool) { + if (data.length < 4) return false; + bytes4 selector = bytes4(data[:4]); + + // App-scoped: first arg is app address, caller must be admin on the app's owner team + if ( + selector == this.upgradeApp.selector || selector == this.transferOwnership.selector + || selector == this.terminateApp.selector || selector == this.startApp.selector + || selector == this.stopApp.selector || selector == this.updateAppMetadataURI.selector + ) { + if (data.length < 36) return false; + address app = abi.decode(data[4:36], (address)); + AppConfig storage config = _appConfigs[IApp(app)]; + if (!_exists(config.status)) return false; + return _hasTeamRole(config.owner, caller, TeamRole.ADMIN); + } + + // Team-scoped: first arg is team address, caller must be admin on the team + if ( + selector == this.createAppForTeam.selector || selector == this.grantTeamRole.selector + || selector == this.revokeTeamRole.selector + ) { + if (data.length < 36) return false; + address team = abi.decode(data[4:36], (address)); + return team == caller || hasRole(_teamRole(team, TeamRole.ADMIN), caller); + } + + // Self-referencing: createApp uses msg.sender as team, so the Timelock itself must have quota + if (selector == this.createApp.selector) { + return true; + } + + return false; + } + /// @inheritdoc IAppController function getMaxActiveAppsPerUser(address user) external view returns (uint32) { return _userConfigs[user].maxActiveApps; diff --git a/src/governance/TimelockControllerImpl.sol b/src/governance/TimelockControllerImpl.sol index aa3ae1c..bead874 100644 --- a/src/governance/TimelockControllerImpl.sol +++ b/src/governance/TimelockControllerImpl.sol @@ -4,6 +4,7 @@ pragma solidity ^0.8.27; import { TimelockControllerUpgradeable } from "@openzeppelin-upgrades/contracts/governance/TimelockControllerUpgradeable.sol"; +import {ICallValidator} from "../interfaces/ICallValidator.sol"; /** * @title TimelockControllerImpl @@ -12,6 +13,9 @@ import { * Overrides schedule/scheduleBatch/execute/executeBatch/cancel to maintain a set of * pending operation IDs, enabling clients to enumerate queued operations without * requiring event log scanning. + * + * Also validates targets at schedule-time: if a target implements ICallValidator, + * canCall(address(this), data) must return true or the schedule is rejected. */ contract TimelockControllerImpl is TimelockControllerUpgradeable { struct PendingOp { @@ -56,6 +60,7 @@ contract TimelockControllerImpl is TimelockControllerUpgradeable { bytes32 salt, uint256 delay ) public override { + _validateTarget(target, data); super.schedule(target, value, data, predecessor, salt, delay); bytes32 id = hashOperation(target, value, data, predecessor, salt); _addPending(id, target, data, block.timestamp + delay); @@ -69,6 +74,9 @@ contract TimelockControllerImpl is TimelockControllerUpgradeable { bytes32 salt, uint256 delay ) public override { + for (uint256 i = 0; i < targets.length; i++) { + _validateTarget(targets[i], payloads[i]); + } super.scheduleBatch(targets, values, payloads, predecessor, salt, delay); // For batch ops store empty data — callers should use getPendingOperationIds and decode individually bytes32 id = hashOperationBatch(targets, values, payloads, predecessor, salt); @@ -127,6 +135,18 @@ contract TimelockControllerImpl is TimelockControllerUpgradeable { // ── Internal helpers ───────────────────────────────────────────────────── + /** + * @dev If `target` implements ICallValidator, ask whether this Timelock may execute `data`. + * Targets that do not implement the interface are allowed through (backwards compatible). + */ + function _validateTarget(address target, bytes calldata data) private view { + try ICallValidator(target).canCall(address(this), data) returns (bool allowed) { + require(allowed, "TimelockController: target rejected the call"); + } catch { + // Target does not implement canCall — allow + } + } + function _addPending(bytes32 id, address target, bytes memory data, uint256 executableAt) private { if (_pendingIndex[id] != 0) return; // already tracked _pendingIds.push(id); diff --git a/src/interfaces/ICallValidator.sol b/src/interfaces/ICallValidator.sol new file mode 100644 index 0000000..8625e2f --- /dev/null +++ b/src/interfaces/ICallValidator.sol @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.27; + +/** + * @title ICallValidator + * @notice Optional interface that Timelock targets can implement to reject + * operations at schedule-time rather than waiting until execute-time. + */ +interface ICallValidator { + /** + * @notice Returns true if `caller` is authorized to execute `data` on this contract. + * @param caller The address that will ultimately call (e.g., the Timelock). + * @param data The calldata that will be forwarded to the target. + */ + function canCall(address caller, bytes calldata data) external view returns (bool); +} From b98bfded34e56242835a8304f2dedbd03db099f2 Mon Sep 17 00:00:00 2001 From: Taras Shchybovyk Date: Mon, 20 Apr 2026 12:07:45 -0700 Subject: [PATCH 28/31] chore: run forge fmt --- script/Deploy.s.sol | 3 ++- src/governance/TimelockControllerImpl.sol | 14 ++++++-------- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/script/Deploy.s.sol b/script/Deploy.s.sol index d4caece..e3a1054 100644 --- a/script/Deploy.s.sol +++ b/script/Deploy.s.sol @@ -219,7 +219,8 @@ contract Deploy is Parser { vm.serializeAddress(addresses, "computeOperatorImpl", address(deployedContracts.computeOperatorImpl)); vm.serializeAddress(addresses, "imageAllowlist", address(deployedContracts.imageAllowlist)); vm.serializeAddress(addresses, "imageAllowlistImpl", address(deployedContracts.imageAllowlistImpl)); - addresses = vm.serializeAddress(addresses, "safeTimelockFactory", address(deployedContracts.safeTimelockFactory)); + addresses = + vm.serializeAddress(addresses, "safeTimelockFactory", address(deployedContracts.safeTimelockFactory)); // Add the chainInfo object string memory chainInfo = "chainInfo"; diff --git a/src/governance/TimelockControllerImpl.sol b/src/governance/TimelockControllerImpl.sol index bead874..8a139a9 100644 --- a/src/governance/TimelockControllerImpl.sol +++ b/src/governance/TimelockControllerImpl.sol @@ -83,13 +83,11 @@ contract TimelockControllerImpl is TimelockControllerUpgradeable { _addPending(id, address(0), "", block.timestamp + delay); } - function execute( - address target, - uint256 value, - bytes calldata payload, - bytes32 predecessor, - bytes32 salt - ) public payable override { + function execute(address target, uint256 value, bytes calldata payload, bytes32 predecessor, bytes32 salt) + public + payable + override + { bytes32 id = hashOperation(target, value, payload, predecessor, salt); super.execute(target, value, payload, predecessor, salt); _removePending(id); @@ -151,7 +149,7 @@ contract TimelockControllerImpl is TimelockControllerUpgradeable { if (_pendingIndex[id] != 0) return; // already tracked _pendingIds.push(id); _pendingIndex[id] = _pendingIds.length; // 1-based - _pendingOps[id] = PendingOp({ id: id, target: target, data: data, executableAt: executableAt }); + _pendingOps[id] = PendingOp({id: id, target: target, data: data, executableAt: executableAt}); } function _removePending(bytes32 id) private { From 2153dbee42f8812d4e2110a2cf16a19a62053d73 Mon Sep 17 00:00:00 2001 From: Taras Shchybovyk Date: Mon, 20 Apr 2026 12:08:41 -0700 Subject: [PATCH 29/31] chore: regenerate Go bindings --- pkg/bindings/v1/AppController/binding.go | 33 +++++++- .../v1/TimelockControllerImpl/binding.go | 72 ++++++++++++++++- pkg/bindings/v2/AppController/binding.go | 37 ++++++++- .../v2/TimelockControllerImpl/binding.go | 80 ++++++++++++++++++- 4 files changed, 218 insertions(+), 4 deletions(-) diff --git a/pkg/bindings/v1/AppController/binding.go b/pkg/bindings/v1/AppController/binding.go index 83a0827..8a69556 100644 --- a/pkg/bindings/v1/AppController/binding.go +++ b/pkg/bindings/v1/AppController/binding.go @@ -66,7 +66,7 @@ type IReleaseManagerTypesRelease struct { // AppControllerMetaData contains all meta data concerning the AppController contract. var AppControllerMetaData = &bind.MetaData{ - ABI: "[{\"type\":\"constructor\",\"inputs\":[{\"name\":\"_version\",\"type\":\"string\",\"internalType\":\"string\"},{\"name\":\"_permissionController\",\"type\":\"address\",\"internalType\":\"contractIPermissionController\"},{\"name\":\"_releaseManager\",\"type\":\"address\",\"internalType\":\"contractIReleaseManager\"},{\"name\":\"_computeAVSRegistrar\",\"type\":\"address\",\"internalType\":\"contractIComputeAVSRegistrar\"},{\"name\":\"_computeOperator\",\"type\":\"address\",\"internalType\":\"contractIComputeOperator\"},{\"name\":\"_appBeacon\",\"type\":\"address\",\"internalType\":\"contractIBeacon\"},{\"name\":\"_safeTimelockFactory\",\"type\":\"address\",\"internalType\":\"contractISafeTimelockFactory\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"API_PERMISSION_TYPEHASH\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"DEFAULT_ADMIN_ROLE\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"appBeacon\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIBeacon\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"calculateApiPermissionDigestHash\",\"inputs\":[{\"name\":\"permission\",\"type\":\"bytes4\",\"internalType\":\"bytes4\"},{\"name\":\"expiry\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"calculateAppId\",\"inputs\":[{\"name\":\"deployer\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"salt\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"computeAVSRegistrar\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIComputeAVSRegistrar\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"computeOperator\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIComputeOperator\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"createApp\",\"inputs\":[{\"name\":\"salt\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"release\",\"type\":\"tuple\",\"internalType\":\"structIAppController.Release\",\"components\":[{\"name\":\"rmsRelease\",\"type\":\"tuple\",\"internalType\":\"structIReleaseManagerTypes.Release\",\"components\":[{\"name\":\"artifacts\",\"type\":\"tuple[]\",\"internalType\":\"structIReleaseManagerTypes.Artifact[]\",\"components\":[{\"name\":\"digest\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"registry\",\"type\":\"string\",\"internalType\":\"string\"}]},{\"name\":\"upgradeByTime\",\"type\":\"uint32\",\"internalType\":\"uint32\"}]},{\"name\":\"publicEnv\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"encryptedEnv\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]}],\"outputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"createAppForTeam\",\"inputs\":[{\"name\":\"team\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"salt\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"release\",\"type\":\"tuple\",\"internalType\":\"structIAppController.Release\",\"components\":[{\"name\":\"rmsRelease\",\"type\":\"tuple\",\"internalType\":\"structIReleaseManagerTypes.Release\",\"components\":[{\"name\":\"artifacts\",\"type\":\"tuple[]\",\"internalType\":\"structIReleaseManagerTypes.Artifact[]\",\"components\":[{\"name\":\"digest\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"registry\",\"type\":\"string\",\"internalType\":\"string\"}]},{\"name\":\"upgradeByTime\",\"type\":\"uint32\",\"internalType\":\"uint32\"}]},{\"name\":\"publicEnv\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"encryptedEnv\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]}],\"outputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"domainSeparator\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getActiveAppCount\",\"inputs\":[{\"name\":\"user\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getAppLatestReleaseBlockNumber\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getAppOperatorSetId\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getAppOwner\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getAppStatus\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint8\",\"internalType\":\"enumIAppController.AppStatus\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getAppTimelocked\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getApps\",\"inputs\":[{\"name\":\"offset\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"limit\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"apps\",\"type\":\"address[]\",\"internalType\":\"contractIApp[]\"},{\"name\":\"appConfigsMem\",\"type\":\"tuple[]\",\"internalType\":\"structIAppController.AppConfig[]\",\"components\":[{\"name\":\"owner\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"operatorSetId\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"latestReleaseBlockNumber\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"status\",\"type\":\"uint8\",\"internalType\":\"enumIAppController.AppStatus\"},{\"name\":\"timelocked\",\"type\":\"bool\",\"internalType\":\"bool\"}]}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getAppsByCreator\",\"inputs\":[{\"name\":\"creator\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"offset\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"limit\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"apps\",\"type\":\"address[]\",\"internalType\":\"contractIApp[]\"},{\"name\":\"appConfigsMem\",\"type\":\"tuple[]\",\"internalType\":\"structIAppController.AppConfig[]\",\"components\":[{\"name\":\"owner\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"operatorSetId\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"latestReleaseBlockNumber\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"status\",\"type\":\"uint8\",\"internalType\":\"enumIAppController.AppStatus\"},{\"name\":\"timelocked\",\"type\":\"bool\",\"internalType\":\"bool\"}]}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getAppsByDeveloper\",\"inputs\":[{\"name\":\"developer\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"offset\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"limit\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"apps\",\"type\":\"address[]\",\"internalType\":\"contractIApp[]\"},{\"name\":\"appConfigsMem\",\"type\":\"tuple[]\",\"internalType\":\"structIAppController.AppConfig[]\",\"components\":[{\"name\":\"owner\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"operatorSetId\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"latestReleaseBlockNumber\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"status\",\"type\":\"uint8\",\"internalType\":\"enumIAppController.AppStatus\"},{\"name\":\"timelocked\",\"type\":\"bool\",\"internalType\":\"bool\"}]}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getAppsForAccount\",\"inputs\":[{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"offset\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"limit\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"appRoles\",\"type\":\"tuple[]\",\"internalType\":\"structIAppController.AppRoles[]\",\"components\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"},{\"name\":\"isOwner\",\"type\":\"bool\",\"internalType\":\"bool\"},{\"name\":\"roles\",\"type\":\"uint8[]\",\"internalType\":\"enumIAppController.TeamRole[]\"}]}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getMaxActiveAppsPerUser\",\"inputs\":[{\"name\":\"user\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getRoleAdmin\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getRoleMember\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"index\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getRoleMemberCount\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getTeamRoleMember\",\"inputs\":[{\"name\":\"team\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"role\",\"type\":\"uint8\",\"internalType\":\"enumIAppController.TeamRole\"},{\"name\":\"index\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getTeamRoleMemberCount\",\"inputs\":[{\"name\":\"team\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"role\",\"type\":\"uint8\",\"internalType\":\"enumIAppController.TeamRole\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getTeamRoleMembers\",\"inputs\":[{\"name\":\"team\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"role\",\"type\":\"uint8\",\"internalType\":\"enumIAppController.TeamRole\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address[]\",\"internalType\":\"address[]\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"globalActiveAppCount\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"grantRole\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"grantTeamRole\",\"inputs\":[{\"name\":\"team\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"role\",\"type\":\"uint8\",\"internalType\":\"enumIAppController.TeamRole\"},{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"hasRole\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"hasTeamRole\",\"inputs\":[{\"name\":\"team\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"role\",\"type\":\"uint8\",\"internalType\":\"enumIAppController.TeamRole\"},{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"initialize\",\"inputs\":[{\"name\":\"admin\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"maxGlobalActiveApps\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"migrateAdmins\",\"inputs\":[{\"name\":\"apps\",\"type\":\"address[]\",\"internalType\":\"contractIApp[]\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"permissionController\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIPermissionController\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"releaseManager\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIReleaseManager\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"renounceRole\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"renounceTeamRole\",\"inputs\":[{\"name\":\"team\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"role\",\"type\":\"uint8\",\"internalType\":\"enumIAppController.TeamRole\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"revokeRole\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"revokeTeamRole\",\"inputs\":[{\"name\":\"team\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"role\",\"type\":\"uint8\",\"internalType\":\"enumIAppController.TeamRole\"},{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"safeTimelockFactory\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractISafeTimelockFactory\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"setMaxActiveAppsPerUser\",\"inputs\":[{\"name\":\"user\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"limit\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"setMaxGlobalActiveApps\",\"inputs\":[{\"name\":\"limit\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"startApp\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"stopApp\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"supportsInterface\",\"inputs\":[{\"name\":\"interfaceId\",\"type\":\"bytes4\",\"internalType\":\"bytes4\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"suspend\",\"inputs\":[{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"apps\",\"type\":\"address[]\",\"internalType\":\"contractIApp[]\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"terminateApp\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"terminateAppByAdmin\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"transferOwnership\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"},{\"name\":\"newOwner\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"updateAppMetadataURI\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"},{\"name\":\"metadataURI\",\"type\":\"string\",\"internalType\":\"string\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"upgradeApp\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"},{\"name\":\"release\",\"type\":\"tuple\",\"internalType\":\"structIAppController.Release\",\"components\":[{\"name\":\"rmsRelease\",\"type\":\"tuple\",\"internalType\":\"structIReleaseManagerTypes.Release\",\"components\":[{\"name\":\"artifacts\",\"type\":\"tuple[]\",\"internalType\":\"structIReleaseManagerTypes.Artifact[]\",\"components\":[{\"name\":\"digest\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"registry\",\"type\":\"string\",\"internalType\":\"string\"}]},{\"name\":\"upgradeByTime\",\"type\":\"uint32\",\"internalType\":\"uint32\"}]},{\"name\":\"publicEnv\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"encryptedEnv\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"version\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"string\",\"internalType\":\"string\"}],\"stateMutability\":\"view\"},{\"type\":\"event\",\"name\":\"AppCreated\",\"inputs\":[{\"name\":\"owner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"app\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"contractIApp\"},{\"name\":\"operatorSetId\",\"type\":\"uint32\",\"indexed\":false,\"internalType\":\"uint32\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"AppMetadataURIUpdated\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"contractIApp\"},{\"name\":\"metadataURI\",\"type\":\"string\",\"indexed\":false,\"internalType\":\"string\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"AppOwnershipTransferred\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"contractIApp\"},{\"name\":\"previousOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"newOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"AppStarted\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"contractIApp\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"AppStopped\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"contractIApp\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"AppSuspended\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"contractIApp\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"AppTerminated\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"contractIApp\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"AppTerminatedByAdmin\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"contractIApp\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"AppUpgraded\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"contractIApp\"},{\"name\":\"rmsReleaseId\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"release\",\"type\":\"tuple\",\"indexed\":false,\"internalType\":\"structIAppController.Release\",\"components\":[{\"name\":\"rmsRelease\",\"type\":\"tuple\",\"internalType\":\"structIReleaseManagerTypes.Release\",\"components\":[{\"name\":\"artifacts\",\"type\":\"tuple[]\",\"internalType\":\"structIReleaseManagerTypes.Artifact[]\",\"components\":[{\"name\":\"digest\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"registry\",\"type\":\"string\",\"internalType\":\"string\"}]},{\"name\":\"upgradeByTime\",\"type\":\"uint32\",\"internalType\":\"uint32\"}]},{\"name\":\"publicEnv\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"encryptedEnv\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"GlobalMaxActiveAppsSet\",\"inputs\":[{\"name\":\"limit\",\"type\":\"uint32\",\"indexed\":false,\"internalType\":\"uint32\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Initialized\",\"inputs\":[{\"name\":\"version\",\"type\":\"uint8\",\"indexed\":false,\"internalType\":\"uint8\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"MaxActiveAppsSet\",\"inputs\":[{\"name\":\"user\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"limit\",\"type\":\"uint32\",\"indexed\":false,\"internalType\":\"uint32\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"RoleAdminChanged\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"previousAdminRole\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"newAdminRole\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"RoleGranted\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"account\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"sender\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"RoleRevoked\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"account\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"sender\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"error\",\"name\":\"AccountHasActiveApps\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"AppAlreadyExists\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"AppDoesNotExist\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"CannotRevokeLastAdmin\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"GlobalMaxActiveAppsExceeded\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidAppStatus\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidPermissions\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidReleaseMetadataURI\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidShortString\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidSignature\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"MaxActiveAppsExceeded\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"MoreThanOneArtifact\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"SignatureExpired\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"StringTooLong\",\"inputs\":[{\"name\":\"str\",\"type\":\"string\",\"internalType\":\"string\"}]}]", + ABI: "[{\"type\":\"constructor\",\"inputs\":[{\"name\":\"_version\",\"type\":\"string\",\"internalType\":\"string\"},{\"name\":\"_permissionController\",\"type\":\"address\",\"internalType\":\"contractIPermissionController\"},{\"name\":\"_releaseManager\",\"type\":\"address\",\"internalType\":\"contractIReleaseManager\"},{\"name\":\"_computeAVSRegistrar\",\"type\":\"address\",\"internalType\":\"contractIComputeAVSRegistrar\"},{\"name\":\"_computeOperator\",\"type\":\"address\",\"internalType\":\"contractIComputeOperator\"},{\"name\":\"_appBeacon\",\"type\":\"address\",\"internalType\":\"contractIBeacon\"},{\"name\":\"_safeTimelockFactory\",\"type\":\"address\",\"internalType\":\"contractISafeTimelockFactory\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"API_PERMISSION_TYPEHASH\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"DEFAULT_ADMIN_ROLE\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"appBeacon\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIBeacon\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"calculateApiPermissionDigestHash\",\"inputs\":[{\"name\":\"permission\",\"type\":\"bytes4\",\"internalType\":\"bytes4\"},{\"name\":\"expiry\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"calculateAppId\",\"inputs\":[{\"name\":\"deployer\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"salt\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"canCall\",\"inputs\":[{\"name\":\"caller\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"data\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"computeAVSRegistrar\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIComputeAVSRegistrar\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"computeOperator\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIComputeOperator\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"createApp\",\"inputs\":[{\"name\":\"salt\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"release\",\"type\":\"tuple\",\"internalType\":\"structIAppController.Release\",\"components\":[{\"name\":\"rmsRelease\",\"type\":\"tuple\",\"internalType\":\"structIReleaseManagerTypes.Release\",\"components\":[{\"name\":\"artifacts\",\"type\":\"tuple[]\",\"internalType\":\"structIReleaseManagerTypes.Artifact[]\",\"components\":[{\"name\":\"digest\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"registry\",\"type\":\"string\",\"internalType\":\"string\"}]},{\"name\":\"upgradeByTime\",\"type\":\"uint32\",\"internalType\":\"uint32\"}]},{\"name\":\"publicEnv\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"encryptedEnv\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]}],\"outputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"createAppForTeam\",\"inputs\":[{\"name\":\"team\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"salt\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"release\",\"type\":\"tuple\",\"internalType\":\"structIAppController.Release\",\"components\":[{\"name\":\"rmsRelease\",\"type\":\"tuple\",\"internalType\":\"structIReleaseManagerTypes.Release\",\"components\":[{\"name\":\"artifacts\",\"type\":\"tuple[]\",\"internalType\":\"structIReleaseManagerTypes.Artifact[]\",\"components\":[{\"name\":\"digest\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"registry\",\"type\":\"string\",\"internalType\":\"string\"}]},{\"name\":\"upgradeByTime\",\"type\":\"uint32\",\"internalType\":\"uint32\"}]},{\"name\":\"publicEnv\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"encryptedEnv\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]}],\"outputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"domainSeparator\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getActiveAppCount\",\"inputs\":[{\"name\":\"user\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getAppLatestReleaseBlockNumber\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getAppOperatorSetId\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getAppOwner\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getAppStatus\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint8\",\"internalType\":\"enumIAppController.AppStatus\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getAppTimelocked\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getApps\",\"inputs\":[{\"name\":\"offset\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"limit\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"apps\",\"type\":\"address[]\",\"internalType\":\"contractIApp[]\"},{\"name\":\"appConfigsMem\",\"type\":\"tuple[]\",\"internalType\":\"structIAppController.AppConfig[]\",\"components\":[{\"name\":\"owner\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"operatorSetId\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"latestReleaseBlockNumber\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"status\",\"type\":\"uint8\",\"internalType\":\"enumIAppController.AppStatus\"},{\"name\":\"timelocked\",\"type\":\"bool\",\"internalType\":\"bool\"}]}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getAppsByCreator\",\"inputs\":[{\"name\":\"creator\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"offset\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"limit\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"apps\",\"type\":\"address[]\",\"internalType\":\"contractIApp[]\"},{\"name\":\"appConfigsMem\",\"type\":\"tuple[]\",\"internalType\":\"structIAppController.AppConfig[]\",\"components\":[{\"name\":\"owner\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"operatorSetId\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"latestReleaseBlockNumber\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"status\",\"type\":\"uint8\",\"internalType\":\"enumIAppController.AppStatus\"},{\"name\":\"timelocked\",\"type\":\"bool\",\"internalType\":\"bool\"}]}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getAppsByDeveloper\",\"inputs\":[{\"name\":\"developer\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"offset\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"limit\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"apps\",\"type\":\"address[]\",\"internalType\":\"contractIApp[]\"},{\"name\":\"appConfigsMem\",\"type\":\"tuple[]\",\"internalType\":\"structIAppController.AppConfig[]\",\"components\":[{\"name\":\"owner\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"operatorSetId\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"latestReleaseBlockNumber\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"status\",\"type\":\"uint8\",\"internalType\":\"enumIAppController.AppStatus\"},{\"name\":\"timelocked\",\"type\":\"bool\",\"internalType\":\"bool\"}]}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getAppsForAccount\",\"inputs\":[{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"offset\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"limit\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"appRoles\",\"type\":\"tuple[]\",\"internalType\":\"structIAppController.AppRoles[]\",\"components\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"},{\"name\":\"isOwner\",\"type\":\"bool\",\"internalType\":\"bool\"},{\"name\":\"roles\",\"type\":\"uint8[]\",\"internalType\":\"enumIAppController.TeamRole[]\"}]}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getMaxActiveAppsPerUser\",\"inputs\":[{\"name\":\"user\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getRoleAdmin\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getRoleMember\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"index\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getRoleMemberCount\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getTeamRoleMember\",\"inputs\":[{\"name\":\"team\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"role\",\"type\":\"uint8\",\"internalType\":\"enumIAppController.TeamRole\"},{\"name\":\"index\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getTeamRoleMemberCount\",\"inputs\":[{\"name\":\"team\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"role\",\"type\":\"uint8\",\"internalType\":\"enumIAppController.TeamRole\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getTeamRoleMembers\",\"inputs\":[{\"name\":\"team\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"role\",\"type\":\"uint8\",\"internalType\":\"enumIAppController.TeamRole\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address[]\",\"internalType\":\"address[]\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"globalActiveAppCount\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"grantRole\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"grantTeamRole\",\"inputs\":[{\"name\":\"team\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"role\",\"type\":\"uint8\",\"internalType\":\"enumIAppController.TeamRole\"},{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"hasRole\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"hasTeamRole\",\"inputs\":[{\"name\":\"team\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"role\",\"type\":\"uint8\",\"internalType\":\"enumIAppController.TeamRole\"},{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"initialize\",\"inputs\":[{\"name\":\"admin\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"maxGlobalActiveApps\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"migrateAdmins\",\"inputs\":[{\"name\":\"apps\",\"type\":\"address[]\",\"internalType\":\"contractIApp[]\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"permissionController\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIPermissionController\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"releaseManager\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIReleaseManager\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"renounceRole\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"renounceTeamRole\",\"inputs\":[{\"name\":\"team\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"role\",\"type\":\"uint8\",\"internalType\":\"enumIAppController.TeamRole\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"revokeRole\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"revokeTeamRole\",\"inputs\":[{\"name\":\"team\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"role\",\"type\":\"uint8\",\"internalType\":\"enumIAppController.TeamRole\"},{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"safeTimelockFactory\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractISafeTimelockFactory\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"setMaxActiveAppsPerUser\",\"inputs\":[{\"name\":\"user\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"limit\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"setMaxGlobalActiveApps\",\"inputs\":[{\"name\":\"limit\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"startApp\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"stopApp\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"supportsInterface\",\"inputs\":[{\"name\":\"interfaceId\",\"type\":\"bytes4\",\"internalType\":\"bytes4\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"suspend\",\"inputs\":[{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"apps\",\"type\":\"address[]\",\"internalType\":\"contractIApp[]\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"terminateApp\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"terminateAppByAdmin\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"transferOwnership\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"},{\"name\":\"newOwner\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"updateAppMetadataURI\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"},{\"name\":\"metadataURI\",\"type\":\"string\",\"internalType\":\"string\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"upgradeApp\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"},{\"name\":\"release\",\"type\":\"tuple\",\"internalType\":\"structIAppController.Release\",\"components\":[{\"name\":\"rmsRelease\",\"type\":\"tuple\",\"internalType\":\"structIReleaseManagerTypes.Release\",\"components\":[{\"name\":\"artifacts\",\"type\":\"tuple[]\",\"internalType\":\"structIReleaseManagerTypes.Artifact[]\",\"components\":[{\"name\":\"digest\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"registry\",\"type\":\"string\",\"internalType\":\"string\"}]},{\"name\":\"upgradeByTime\",\"type\":\"uint32\",\"internalType\":\"uint32\"}]},{\"name\":\"publicEnv\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"encryptedEnv\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"version\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"string\",\"internalType\":\"string\"}],\"stateMutability\":\"view\"},{\"type\":\"event\",\"name\":\"AppCreated\",\"inputs\":[{\"name\":\"owner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"app\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"contractIApp\"},{\"name\":\"operatorSetId\",\"type\":\"uint32\",\"indexed\":false,\"internalType\":\"uint32\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"AppMetadataURIUpdated\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"contractIApp\"},{\"name\":\"metadataURI\",\"type\":\"string\",\"indexed\":false,\"internalType\":\"string\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"AppOwnershipTransferred\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"contractIApp\"},{\"name\":\"previousOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"newOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"AppStarted\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"contractIApp\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"AppStopped\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"contractIApp\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"AppSuspended\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"contractIApp\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"AppTerminated\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"contractIApp\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"AppTerminatedByAdmin\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"contractIApp\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"AppUpgraded\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"contractIApp\"},{\"name\":\"rmsReleaseId\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"release\",\"type\":\"tuple\",\"indexed\":false,\"internalType\":\"structIAppController.Release\",\"components\":[{\"name\":\"rmsRelease\",\"type\":\"tuple\",\"internalType\":\"structIReleaseManagerTypes.Release\",\"components\":[{\"name\":\"artifacts\",\"type\":\"tuple[]\",\"internalType\":\"structIReleaseManagerTypes.Artifact[]\",\"components\":[{\"name\":\"digest\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"registry\",\"type\":\"string\",\"internalType\":\"string\"}]},{\"name\":\"upgradeByTime\",\"type\":\"uint32\",\"internalType\":\"uint32\"}]},{\"name\":\"publicEnv\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"encryptedEnv\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"GlobalMaxActiveAppsSet\",\"inputs\":[{\"name\":\"limit\",\"type\":\"uint32\",\"indexed\":false,\"internalType\":\"uint32\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Initialized\",\"inputs\":[{\"name\":\"version\",\"type\":\"uint8\",\"indexed\":false,\"internalType\":\"uint8\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"MaxActiveAppsSet\",\"inputs\":[{\"name\":\"user\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"limit\",\"type\":\"uint32\",\"indexed\":false,\"internalType\":\"uint32\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"RoleAdminChanged\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"previousAdminRole\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"newAdminRole\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"RoleGranted\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"account\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"sender\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"RoleRevoked\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"account\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"sender\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"error\",\"name\":\"AccountHasActiveApps\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"AppAlreadyExists\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"AppDoesNotExist\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"CannotRevokeLastAdmin\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"GlobalMaxActiveAppsExceeded\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidAppStatus\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidPermissions\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidReleaseMetadataURI\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidShortString\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidSignature\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"MaxActiveAppsExceeded\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"MoreThanOneArtifact\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"SignatureExpired\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"StringTooLong\",\"inputs\":[{\"name\":\"str\",\"type\":\"string\",\"internalType\":\"string\"}]}]", } // AppControllerABI is the input ABI used to generate the binding from. @@ -370,6 +370,37 @@ func (_AppController *AppControllerCallerSession) CalculateAppId(deployer common return _AppController.Contract.CalculateAppId(&_AppController.CallOpts, deployer, salt) } +// CanCall is a free data retrieval call binding the contract method 0x9614801b. +// +// Solidity: function canCall(address caller, bytes data) view returns(bool) +func (_AppController *AppControllerCaller) CanCall(opts *bind.CallOpts, caller common.Address, data []byte) (bool, error) { + var out []interface{} + err := _AppController.contract.Call(opts, &out, "canCall", caller, data) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +// CanCall is a free data retrieval call binding the contract method 0x9614801b. +// +// Solidity: function canCall(address caller, bytes data) view returns(bool) +func (_AppController *AppControllerSession) CanCall(caller common.Address, data []byte) (bool, error) { + return _AppController.Contract.CanCall(&_AppController.CallOpts, caller, data) +} + +// CanCall is a free data retrieval call binding the contract method 0x9614801b. +// +// Solidity: function canCall(address caller, bytes data) view returns(bool) +func (_AppController *AppControllerCallerSession) CanCall(caller common.Address, data []byte) (bool, error) { + return _AppController.Contract.CanCall(&_AppController.CallOpts, caller, data) +} + // ComputeAVSRegistrar is a free data retrieval call binding the contract method 0xef6d92c6. // // Solidity: function computeAVSRegistrar() view returns(address) diff --git a/pkg/bindings/v1/TimelockControllerImpl/binding.go b/pkg/bindings/v1/TimelockControllerImpl/binding.go index 01fedc7..fd36112 100644 --- a/pkg/bindings/v1/TimelockControllerImpl/binding.go +++ b/pkg/bindings/v1/TimelockControllerImpl/binding.go @@ -29,9 +29,17 @@ var ( _ = abi.ConvertType ) +// TimelockControllerImplPendingOp is an auto generated low-level Go binding around an user-defined struct. +type TimelockControllerImplPendingOp struct { + Id [32]byte + Target common.Address + Data []byte + ExecutableAt *big.Int +} + // TimelockControllerImplMetaData contains all meta data concerning the TimelockControllerImpl contract. var TimelockControllerImplMetaData = &bind.MetaData{ - ABI: "[{\"type\":\"constructor\",\"inputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"receive\",\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"CANCELLER_ROLE\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"DEFAULT_ADMIN_ROLE\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"EXECUTOR_ROLE\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"PROPOSER_ROLE\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"TIMELOCK_ADMIN_ROLE\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"cancel\",\"inputs\":[{\"name\":\"id\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"execute\",\"inputs\":[{\"name\":\"target\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"value\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"payload\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"predecessor\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"salt\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"executeBatch\",\"inputs\":[{\"name\":\"targets\",\"type\":\"address[]\",\"internalType\":\"address[]\"},{\"name\":\"values\",\"type\":\"uint256[]\",\"internalType\":\"uint256[]\"},{\"name\":\"payloads\",\"type\":\"bytes[]\",\"internalType\":\"bytes[]\"},{\"name\":\"predecessor\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"salt\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"getMinDelay\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getRoleAdmin\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getTimestamp\",\"inputs\":[{\"name\":\"id\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"grantRole\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"hasRole\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"hashOperation\",\"inputs\":[{\"name\":\"target\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"value\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"data\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"predecessor\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"salt\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"pure\"},{\"type\":\"function\",\"name\":\"hashOperationBatch\",\"inputs\":[{\"name\":\"targets\",\"type\":\"address[]\",\"internalType\":\"address[]\"},{\"name\":\"values\",\"type\":\"uint256[]\",\"internalType\":\"uint256[]\"},{\"name\":\"payloads\",\"type\":\"bytes[]\",\"internalType\":\"bytes[]\"},{\"name\":\"predecessor\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"salt\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"pure\"},{\"type\":\"function\",\"name\":\"initialize\",\"inputs\":[{\"name\":\"minDelay\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"proposers\",\"type\":\"address[]\",\"internalType\":\"address[]\"},{\"name\":\"executors\",\"type\":\"address[]\",\"internalType\":\"address[]\"},{\"name\":\"admin\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"isOperation\",\"inputs\":[{\"name\":\"id\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"isOperationDone\",\"inputs\":[{\"name\":\"id\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"isOperationPending\",\"inputs\":[{\"name\":\"id\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"isOperationReady\",\"inputs\":[{\"name\":\"id\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"onERC1155BatchReceived\",\"inputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"\",\"type\":\"uint256[]\",\"internalType\":\"uint256[]\"},{\"name\":\"\",\"type\":\"uint256[]\",\"internalType\":\"uint256[]\"},{\"name\":\"\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes4\",\"internalType\":\"bytes4\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"onERC1155Received\",\"inputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes4\",\"internalType\":\"bytes4\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"onERC721Received\",\"inputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes4\",\"internalType\":\"bytes4\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"renounceRole\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"revokeRole\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"schedule\",\"inputs\":[{\"name\":\"target\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"value\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"data\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"predecessor\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"salt\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"delay\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"scheduleBatch\",\"inputs\":[{\"name\":\"targets\",\"type\":\"address[]\",\"internalType\":\"address[]\"},{\"name\":\"values\",\"type\":\"uint256[]\",\"internalType\":\"uint256[]\"},{\"name\":\"payloads\",\"type\":\"bytes[]\",\"internalType\":\"bytes[]\"},{\"name\":\"predecessor\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"salt\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"delay\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"supportsInterface\",\"inputs\":[{\"name\":\"interfaceId\",\"type\":\"bytes4\",\"internalType\":\"bytes4\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"updateDelay\",\"inputs\":[{\"name\":\"newDelay\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"event\",\"name\":\"CallExecuted\",\"inputs\":[{\"name\":\"id\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"index\",\"type\":\"uint256\",\"indexed\":true,\"internalType\":\"uint256\"},{\"name\":\"target\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"},{\"name\":\"value\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"data\",\"type\":\"bytes\",\"indexed\":false,\"internalType\":\"bytes\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"CallSalt\",\"inputs\":[{\"name\":\"id\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"salt\",\"type\":\"bytes32\",\"indexed\":false,\"internalType\":\"bytes32\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"CallScheduled\",\"inputs\":[{\"name\":\"id\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"index\",\"type\":\"uint256\",\"indexed\":true,\"internalType\":\"uint256\"},{\"name\":\"target\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"},{\"name\":\"value\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"data\",\"type\":\"bytes\",\"indexed\":false,\"internalType\":\"bytes\"},{\"name\":\"predecessor\",\"type\":\"bytes32\",\"indexed\":false,\"internalType\":\"bytes32\"},{\"name\":\"delay\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Cancelled\",\"inputs\":[{\"name\":\"id\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Initialized\",\"inputs\":[{\"name\":\"version\",\"type\":\"uint8\",\"indexed\":false,\"internalType\":\"uint8\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"MinDelayChange\",\"inputs\":[{\"name\":\"oldDuration\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"newDuration\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"RoleAdminChanged\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"previousAdminRole\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"newAdminRole\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"RoleGranted\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"account\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"sender\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"RoleRevoked\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"account\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"sender\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false}]", + ABI: "[{\"type\":\"constructor\",\"inputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"receive\",\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"CANCELLER_ROLE\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"DEFAULT_ADMIN_ROLE\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"EXECUTOR_ROLE\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"PROPOSER_ROLE\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"TIMELOCK_ADMIN_ROLE\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"cancel\",\"inputs\":[{\"name\":\"id\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"execute\",\"inputs\":[{\"name\":\"target\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"value\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"payload\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"predecessor\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"salt\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"executeBatch\",\"inputs\":[{\"name\":\"targets\",\"type\":\"address[]\",\"internalType\":\"address[]\"},{\"name\":\"values\",\"type\":\"uint256[]\",\"internalType\":\"uint256[]\"},{\"name\":\"payloads\",\"type\":\"bytes[]\",\"internalType\":\"bytes[]\"},{\"name\":\"predecessor\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"salt\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"getMinDelay\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getPendingOperationIds\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32[]\",\"internalType\":\"bytes32[]\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getPendingOperations\",\"inputs\":[],\"outputs\":[{\"name\":\"ops\",\"type\":\"tuple[]\",\"internalType\":\"structTimelockControllerImpl.PendingOp[]\",\"components\":[{\"name\":\"id\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"target\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"data\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"executableAt\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getRoleAdmin\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getTimestamp\",\"inputs\":[{\"name\":\"id\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"grantRole\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"hasRole\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"hashOperation\",\"inputs\":[{\"name\":\"target\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"value\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"data\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"predecessor\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"salt\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"pure\"},{\"type\":\"function\",\"name\":\"hashOperationBatch\",\"inputs\":[{\"name\":\"targets\",\"type\":\"address[]\",\"internalType\":\"address[]\"},{\"name\":\"values\",\"type\":\"uint256[]\",\"internalType\":\"uint256[]\"},{\"name\":\"payloads\",\"type\":\"bytes[]\",\"internalType\":\"bytes[]\"},{\"name\":\"predecessor\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"salt\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"pure\"},{\"type\":\"function\",\"name\":\"initialize\",\"inputs\":[{\"name\":\"minDelay\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"proposers\",\"type\":\"address[]\",\"internalType\":\"address[]\"},{\"name\":\"executors\",\"type\":\"address[]\",\"internalType\":\"address[]\"},{\"name\":\"admin\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"isOperation\",\"inputs\":[{\"name\":\"id\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"isOperationDone\",\"inputs\":[{\"name\":\"id\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"isOperationPending\",\"inputs\":[{\"name\":\"id\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"isOperationReady\",\"inputs\":[{\"name\":\"id\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"onERC1155BatchReceived\",\"inputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"\",\"type\":\"uint256[]\",\"internalType\":\"uint256[]\"},{\"name\":\"\",\"type\":\"uint256[]\",\"internalType\":\"uint256[]\"},{\"name\":\"\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes4\",\"internalType\":\"bytes4\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"onERC1155Received\",\"inputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes4\",\"internalType\":\"bytes4\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"onERC721Received\",\"inputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes4\",\"internalType\":\"bytes4\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"renounceRole\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"revokeRole\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"schedule\",\"inputs\":[{\"name\":\"target\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"value\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"data\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"predecessor\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"salt\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"delay\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"scheduleBatch\",\"inputs\":[{\"name\":\"targets\",\"type\":\"address[]\",\"internalType\":\"address[]\"},{\"name\":\"values\",\"type\":\"uint256[]\",\"internalType\":\"uint256[]\"},{\"name\":\"payloads\",\"type\":\"bytes[]\",\"internalType\":\"bytes[]\"},{\"name\":\"predecessor\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"salt\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"delay\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"supportsInterface\",\"inputs\":[{\"name\":\"interfaceId\",\"type\":\"bytes4\",\"internalType\":\"bytes4\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"updateDelay\",\"inputs\":[{\"name\":\"newDelay\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"event\",\"name\":\"CallExecuted\",\"inputs\":[{\"name\":\"id\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"index\",\"type\":\"uint256\",\"indexed\":true,\"internalType\":\"uint256\"},{\"name\":\"target\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"},{\"name\":\"value\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"data\",\"type\":\"bytes\",\"indexed\":false,\"internalType\":\"bytes\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"CallSalt\",\"inputs\":[{\"name\":\"id\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"salt\",\"type\":\"bytes32\",\"indexed\":false,\"internalType\":\"bytes32\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"CallScheduled\",\"inputs\":[{\"name\":\"id\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"index\",\"type\":\"uint256\",\"indexed\":true,\"internalType\":\"uint256\"},{\"name\":\"target\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"},{\"name\":\"value\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"data\",\"type\":\"bytes\",\"indexed\":false,\"internalType\":\"bytes\"},{\"name\":\"predecessor\",\"type\":\"bytes32\",\"indexed\":false,\"internalType\":\"bytes32\"},{\"name\":\"delay\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Cancelled\",\"inputs\":[{\"name\":\"id\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Initialized\",\"inputs\":[{\"name\":\"version\",\"type\":\"uint8\",\"indexed\":false,\"internalType\":\"uint8\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"MinDelayChange\",\"inputs\":[{\"name\":\"oldDuration\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"newDuration\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"RoleAdminChanged\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"previousAdminRole\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"newAdminRole\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"RoleGranted\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"account\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"sender\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"RoleRevoked\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"account\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"sender\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false}]", } // TimelockControllerImplABI is the input ABI used to generate the binding from. @@ -366,6 +374,68 @@ func (_TimelockControllerImpl *TimelockControllerImplCallerSession) GetMinDelay( return _TimelockControllerImpl.Contract.GetMinDelay(&_TimelockControllerImpl.CallOpts) } +// GetPendingOperationIds is a free data retrieval call binding the contract method 0x7b146198. +// +// Solidity: function getPendingOperationIds() view returns(bytes32[]) +func (_TimelockControllerImpl *TimelockControllerImplCaller) GetPendingOperationIds(opts *bind.CallOpts) ([][32]byte, error) { + var out []interface{} + err := _TimelockControllerImpl.contract.Call(opts, &out, "getPendingOperationIds") + + if err != nil { + return *new([][32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([][32]byte)).(*[][32]byte) + + return out0, err + +} + +// GetPendingOperationIds is a free data retrieval call binding the contract method 0x7b146198. +// +// Solidity: function getPendingOperationIds() view returns(bytes32[]) +func (_TimelockControllerImpl *TimelockControllerImplSession) GetPendingOperationIds() ([][32]byte, error) { + return _TimelockControllerImpl.Contract.GetPendingOperationIds(&_TimelockControllerImpl.CallOpts) +} + +// GetPendingOperationIds is a free data retrieval call binding the contract method 0x7b146198. +// +// Solidity: function getPendingOperationIds() view returns(bytes32[]) +func (_TimelockControllerImpl *TimelockControllerImplCallerSession) GetPendingOperationIds() ([][32]byte, error) { + return _TimelockControllerImpl.Contract.GetPendingOperationIds(&_TimelockControllerImpl.CallOpts) +} + +// GetPendingOperations is a free data retrieval call binding the contract method 0x64440ce5. +// +// Solidity: function getPendingOperations() view returns((bytes32,address,bytes,uint256)[] ops) +func (_TimelockControllerImpl *TimelockControllerImplCaller) GetPendingOperations(opts *bind.CallOpts) ([]TimelockControllerImplPendingOp, error) { + var out []interface{} + err := _TimelockControllerImpl.contract.Call(opts, &out, "getPendingOperations") + + if err != nil { + return *new([]TimelockControllerImplPendingOp), err + } + + out0 := *abi.ConvertType(out[0], new([]TimelockControllerImplPendingOp)).(*[]TimelockControllerImplPendingOp) + + return out0, err + +} + +// GetPendingOperations is a free data retrieval call binding the contract method 0x64440ce5. +// +// Solidity: function getPendingOperations() view returns((bytes32,address,bytes,uint256)[] ops) +func (_TimelockControllerImpl *TimelockControllerImplSession) GetPendingOperations() ([]TimelockControllerImplPendingOp, error) { + return _TimelockControllerImpl.Contract.GetPendingOperations(&_TimelockControllerImpl.CallOpts) +} + +// GetPendingOperations is a free data retrieval call binding the contract method 0x64440ce5. +// +// Solidity: function getPendingOperations() view returns((bytes32,address,bytes,uint256)[] ops) +func (_TimelockControllerImpl *TimelockControllerImplCallerSession) GetPendingOperations() ([]TimelockControllerImplPendingOp, error) { + return _TimelockControllerImpl.Contract.GetPendingOperations(&_TimelockControllerImpl.CallOpts) +} + // GetRoleAdmin is a free data retrieval call binding the contract method 0x248a9ca3. // // Solidity: function getRoleAdmin(bytes32 role) view returns(bytes32) diff --git a/pkg/bindings/v2/AppController/binding.go b/pkg/bindings/v2/AppController/binding.go index 46906e1..3d3805d 100644 --- a/pkg/bindings/v2/AppController/binding.go +++ b/pkg/bindings/v2/AppController/binding.go @@ -61,7 +61,7 @@ type IReleaseManagerTypesRelease struct { // AppControllerMetaData contains all meta data concerning the AppController contract. var AppControllerMetaData = bind.MetaData{ - ABI: "[{\"type\":\"constructor\",\"inputs\":[{\"name\":\"_version\",\"type\":\"string\",\"internalType\":\"string\"},{\"name\":\"_permissionController\",\"type\":\"address\",\"internalType\":\"contractIPermissionController\"},{\"name\":\"_releaseManager\",\"type\":\"address\",\"internalType\":\"contractIReleaseManager\"},{\"name\":\"_computeAVSRegistrar\",\"type\":\"address\",\"internalType\":\"contractIComputeAVSRegistrar\"},{\"name\":\"_computeOperator\",\"type\":\"address\",\"internalType\":\"contractIComputeOperator\"},{\"name\":\"_appBeacon\",\"type\":\"address\",\"internalType\":\"contractIBeacon\"},{\"name\":\"_safeTimelockFactory\",\"type\":\"address\",\"internalType\":\"contractISafeTimelockFactory\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"API_PERMISSION_TYPEHASH\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"DEFAULT_ADMIN_ROLE\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"appBeacon\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIBeacon\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"calculateApiPermissionDigestHash\",\"inputs\":[{\"name\":\"permission\",\"type\":\"bytes4\",\"internalType\":\"bytes4\"},{\"name\":\"expiry\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"calculateAppId\",\"inputs\":[{\"name\":\"deployer\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"salt\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"computeAVSRegistrar\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIComputeAVSRegistrar\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"computeOperator\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIComputeOperator\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"createApp\",\"inputs\":[{\"name\":\"salt\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"release\",\"type\":\"tuple\",\"internalType\":\"structIAppController.Release\",\"components\":[{\"name\":\"rmsRelease\",\"type\":\"tuple\",\"internalType\":\"structIReleaseManagerTypes.Release\",\"components\":[{\"name\":\"artifacts\",\"type\":\"tuple[]\",\"internalType\":\"structIReleaseManagerTypes.Artifact[]\",\"components\":[{\"name\":\"digest\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"registry\",\"type\":\"string\",\"internalType\":\"string\"}]},{\"name\":\"upgradeByTime\",\"type\":\"uint32\",\"internalType\":\"uint32\"}]},{\"name\":\"publicEnv\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"encryptedEnv\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]}],\"outputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"createAppForTeam\",\"inputs\":[{\"name\":\"team\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"salt\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"release\",\"type\":\"tuple\",\"internalType\":\"structIAppController.Release\",\"components\":[{\"name\":\"rmsRelease\",\"type\":\"tuple\",\"internalType\":\"structIReleaseManagerTypes.Release\",\"components\":[{\"name\":\"artifacts\",\"type\":\"tuple[]\",\"internalType\":\"structIReleaseManagerTypes.Artifact[]\",\"components\":[{\"name\":\"digest\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"registry\",\"type\":\"string\",\"internalType\":\"string\"}]},{\"name\":\"upgradeByTime\",\"type\":\"uint32\",\"internalType\":\"uint32\"}]},{\"name\":\"publicEnv\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"encryptedEnv\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]}],\"outputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"domainSeparator\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getActiveAppCount\",\"inputs\":[{\"name\":\"user\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getAppLatestReleaseBlockNumber\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getAppOperatorSetId\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getAppOwner\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getAppStatus\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint8\",\"internalType\":\"enumIAppController.AppStatus\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getAppTimelocked\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getApps\",\"inputs\":[{\"name\":\"offset\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"limit\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"apps\",\"type\":\"address[]\",\"internalType\":\"contractIApp[]\"},{\"name\":\"appConfigsMem\",\"type\":\"tuple[]\",\"internalType\":\"structIAppController.AppConfig[]\",\"components\":[{\"name\":\"owner\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"operatorSetId\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"latestReleaseBlockNumber\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"status\",\"type\":\"uint8\",\"internalType\":\"enumIAppController.AppStatus\"},{\"name\":\"timelocked\",\"type\":\"bool\",\"internalType\":\"bool\"}]}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getAppsByCreator\",\"inputs\":[{\"name\":\"creator\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"offset\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"limit\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"apps\",\"type\":\"address[]\",\"internalType\":\"contractIApp[]\"},{\"name\":\"appConfigsMem\",\"type\":\"tuple[]\",\"internalType\":\"structIAppController.AppConfig[]\",\"components\":[{\"name\":\"owner\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"operatorSetId\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"latestReleaseBlockNumber\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"status\",\"type\":\"uint8\",\"internalType\":\"enumIAppController.AppStatus\"},{\"name\":\"timelocked\",\"type\":\"bool\",\"internalType\":\"bool\"}]}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getAppsByDeveloper\",\"inputs\":[{\"name\":\"developer\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"offset\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"limit\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"apps\",\"type\":\"address[]\",\"internalType\":\"contractIApp[]\"},{\"name\":\"appConfigsMem\",\"type\":\"tuple[]\",\"internalType\":\"structIAppController.AppConfig[]\",\"components\":[{\"name\":\"owner\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"operatorSetId\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"latestReleaseBlockNumber\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"status\",\"type\":\"uint8\",\"internalType\":\"enumIAppController.AppStatus\"},{\"name\":\"timelocked\",\"type\":\"bool\",\"internalType\":\"bool\"}]}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getAppsForAccount\",\"inputs\":[{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"offset\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"limit\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"appRoles\",\"type\":\"tuple[]\",\"internalType\":\"structIAppController.AppRoles[]\",\"components\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"},{\"name\":\"isOwner\",\"type\":\"bool\",\"internalType\":\"bool\"},{\"name\":\"roles\",\"type\":\"uint8[]\",\"internalType\":\"enumIAppController.TeamRole[]\"}]}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getMaxActiveAppsPerUser\",\"inputs\":[{\"name\":\"user\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getRoleAdmin\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getRoleMember\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"index\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getRoleMemberCount\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getTeamRoleMember\",\"inputs\":[{\"name\":\"team\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"role\",\"type\":\"uint8\",\"internalType\":\"enumIAppController.TeamRole\"},{\"name\":\"index\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getTeamRoleMemberCount\",\"inputs\":[{\"name\":\"team\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"role\",\"type\":\"uint8\",\"internalType\":\"enumIAppController.TeamRole\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getTeamRoleMembers\",\"inputs\":[{\"name\":\"team\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"role\",\"type\":\"uint8\",\"internalType\":\"enumIAppController.TeamRole\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address[]\",\"internalType\":\"address[]\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"globalActiveAppCount\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"grantRole\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"grantTeamRole\",\"inputs\":[{\"name\":\"team\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"role\",\"type\":\"uint8\",\"internalType\":\"enumIAppController.TeamRole\"},{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"hasRole\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"hasTeamRole\",\"inputs\":[{\"name\":\"team\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"role\",\"type\":\"uint8\",\"internalType\":\"enumIAppController.TeamRole\"},{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"initialize\",\"inputs\":[{\"name\":\"admin\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"maxGlobalActiveApps\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"migrateAdmins\",\"inputs\":[{\"name\":\"apps\",\"type\":\"address[]\",\"internalType\":\"contractIApp[]\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"permissionController\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIPermissionController\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"releaseManager\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIReleaseManager\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"renounceRole\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"renounceTeamRole\",\"inputs\":[{\"name\":\"team\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"role\",\"type\":\"uint8\",\"internalType\":\"enumIAppController.TeamRole\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"revokeRole\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"revokeTeamRole\",\"inputs\":[{\"name\":\"team\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"role\",\"type\":\"uint8\",\"internalType\":\"enumIAppController.TeamRole\"},{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"safeTimelockFactory\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractISafeTimelockFactory\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"setMaxActiveAppsPerUser\",\"inputs\":[{\"name\":\"user\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"limit\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"setMaxGlobalActiveApps\",\"inputs\":[{\"name\":\"limit\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"startApp\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"stopApp\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"supportsInterface\",\"inputs\":[{\"name\":\"interfaceId\",\"type\":\"bytes4\",\"internalType\":\"bytes4\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"suspend\",\"inputs\":[{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"apps\",\"type\":\"address[]\",\"internalType\":\"contractIApp[]\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"terminateApp\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"terminateAppByAdmin\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"transferOwnership\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"},{\"name\":\"newOwner\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"updateAppMetadataURI\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"},{\"name\":\"metadataURI\",\"type\":\"string\",\"internalType\":\"string\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"upgradeApp\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"},{\"name\":\"release\",\"type\":\"tuple\",\"internalType\":\"structIAppController.Release\",\"components\":[{\"name\":\"rmsRelease\",\"type\":\"tuple\",\"internalType\":\"structIReleaseManagerTypes.Release\",\"components\":[{\"name\":\"artifacts\",\"type\":\"tuple[]\",\"internalType\":\"structIReleaseManagerTypes.Artifact[]\",\"components\":[{\"name\":\"digest\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"registry\",\"type\":\"string\",\"internalType\":\"string\"}]},{\"name\":\"upgradeByTime\",\"type\":\"uint32\",\"internalType\":\"uint32\"}]},{\"name\":\"publicEnv\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"encryptedEnv\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"version\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"string\",\"internalType\":\"string\"}],\"stateMutability\":\"view\"},{\"type\":\"event\",\"name\":\"AppCreated\",\"inputs\":[{\"name\":\"owner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"app\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"contractIApp\"},{\"name\":\"operatorSetId\",\"type\":\"uint32\",\"indexed\":false,\"internalType\":\"uint32\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"AppMetadataURIUpdated\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"contractIApp\"},{\"name\":\"metadataURI\",\"type\":\"string\",\"indexed\":false,\"internalType\":\"string\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"AppOwnershipTransferred\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"contractIApp\"},{\"name\":\"previousOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"newOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"AppStarted\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"contractIApp\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"AppStopped\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"contractIApp\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"AppSuspended\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"contractIApp\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"AppTerminated\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"contractIApp\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"AppTerminatedByAdmin\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"contractIApp\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"AppUpgraded\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"contractIApp\"},{\"name\":\"rmsReleaseId\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"release\",\"type\":\"tuple\",\"indexed\":false,\"internalType\":\"structIAppController.Release\",\"components\":[{\"name\":\"rmsRelease\",\"type\":\"tuple\",\"internalType\":\"structIReleaseManagerTypes.Release\",\"components\":[{\"name\":\"artifacts\",\"type\":\"tuple[]\",\"internalType\":\"structIReleaseManagerTypes.Artifact[]\",\"components\":[{\"name\":\"digest\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"registry\",\"type\":\"string\",\"internalType\":\"string\"}]},{\"name\":\"upgradeByTime\",\"type\":\"uint32\",\"internalType\":\"uint32\"}]},{\"name\":\"publicEnv\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"encryptedEnv\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"GlobalMaxActiveAppsSet\",\"inputs\":[{\"name\":\"limit\",\"type\":\"uint32\",\"indexed\":false,\"internalType\":\"uint32\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Initialized\",\"inputs\":[{\"name\":\"version\",\"type\":\"uint8\",\"indexed\":false,\"internalType\":\"uint8\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"MaxActiveAppsSet\",\"inputs\":[{\"name\":\"user\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"limit\",\"type\":\"uint32\",\"indexed\":false,\"internalType\":\"uint32\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"RoleAdminChanged\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"previousAdminRole\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"newAdminRole\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"RoleGranted\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"account\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"sender\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"RoleRevoked\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"account\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"sender\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"error\",\"name\":\"AccountHasActiveApps\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"AppAlreadyExists\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"AppDoesNotExist\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"CannotRevokeLastAdmin\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"GlobalMaxActiveAppsExceeded\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidAppStatus\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidPermissions\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidReleaseMetadataURI\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidShortString\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidSignature\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"MaxActiveAppsExceeded\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"MoreThanOneArtifact\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"SignatureExpired\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"StringTooLong\",\"inputs\":[{\"name\":\"str\",\"type\":\"string\",\"internalType\":\"string\"}]}]", + ABI: "[{\"type\":\"constructor\",\"inputs\":[{\"name\":\"_version\",\"type\":\"string\",\"internalType\":\"string\"},{\"name\":\"_permissionController\",\"type\":\"address\",\"internalType\":\"contractIPermissionController\"},{\"name\":\"_releaseManager\",\"type\":\"address\",\"internalType\":\"contractIReleaseManager\"},{\"name\":\"_computeAVSRegistrar\",\"type\":\"address\",\"internalType\":\"contractIComputeAVSRegistrar\"},{\"name\":\"_computeOperator\",\"type\":\"address\",\"internalType\":\"contractIComputeOperator\"},{\"name\":\"_appBeacon\",\"type\":\"address\",\"internalType\":\"contractIBeacon\"},{\"name\":\"_safeTimelockFactory\",\"type\":\"address\",\"internalType\":\"contractISafeTimelockFactory\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"API_PERMISSION_TYPEHASH\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"DEFAULT_ADMIN_ROLE\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"appBeacon\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIBeacon\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"calculateApiPermissionDigestHash\",\"inputs\":[{\"name\":\"permission\",\"type\":\"bytes4\",\"internalType\":\"bytes4\"},{\"name\":\"expiry\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"calculateAppId\",\"inputs\":[{\"name\":\"deployer\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"salt\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"canCall\",\"inputs\":[{\"name\":\"caller\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"data\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"computeAVSRegistrar\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIComputeAVSRegistrar\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"computeOperator\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIComputeOperator\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"createApp\",\"inputs\":[{\"name\":\"salt\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"release\",\"type\":\"tuple\",\"internalType\":\"structIAppController.Release\",\"components\":[{\"name\":\"rmsRelease\",\"type\":\"tuple\",\"internalType\":\"structIReleaseManagerTypes.Release\",\"components\":[{\"name\":\"artifacts\",\"type\":\"tuple[]\",\"internalType\":\"structIReleaseManagerTypes.Artifact[]\",\"components\":[{\"name\":\"digest\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"registry\",\"type\":\"string\",\"internalType\":\"string\"}]},{\"name\":\"upgradeByTime\",\"type\":\"uint32\",\"internalType\":\"uint32\"}]},{\"name\":\"publicEnv\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"encryptedEnv\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]}],\"outputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"createAppForTeam\",\"inputs\":[{\"name\":\"team\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"salt\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"release\",\"type\":\"tuple\",\"internalType\":\"structIAppController.Release\",\"components\":[{\"name\":\"rmsRelease\",\"type\":\"tuple\",\"internalType\":\"structIReleaseManagerTypes.Release\",\"components\":[{\"name\":\"artifacts\",\"type\":\"tuple[]\",\"internalType\":\"structIReleaseManagerTypes.Artifact[]\",\"components\":[{\"name\":\"digest\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"registry\",\"type\":\"string\",\"internalType\":\"string\"}]},{\"name\":\"upgradeByTime\",\"type\":\"uint32\",\"internalType\":\"uint32\"}]},{\"name\":\"publicEnv\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"encryptedEnv\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]}],\"outputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"domainSeparator\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getActiveAppCount\",\"inputs\":[{\"name\":\"user\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getAppLatestReleaseBlockNumber\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getAppOperatorSetId\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getAppOwner\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getAppStatus\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint8\",\"internalType\":\"enumIAppController.AppStatus\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getAppTimelocked\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getApps\",\"inputs\":[{\"name\":\"offset\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"limit\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"apps\",\"type\":\"address[]\",\"internalType\":\"contractIApp[]\"},{\"name\":\"appConfigsMem\",\"type\":\"tuple[]\",\"internalType\":\"structIAppController.AppConfig[]\",\"components\":[{\"name\":\"owner\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"operatorSetId\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"latestReleaseBlockNumber\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"status\",\"type\":\"uint8\",\"internalType\":\"enumIAppController.AppStatus\"},{\"name\":\"timelocked\",\"type\":\"bool\",\"internalType\":\"bool\"}]}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getAppsByCreator\",\"inputs\":[{\"name\":\"creator\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"offset\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"limit\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"apps\",\"type\":\"address[]\",\"internalType\":\"contractIApp[]\"},{\"name\":\"appConfigsMem\",\"type\":\"tuple[]\",\"internalType\":\"structIAppController.AppConfig[]\",\"components\":[{\"name\":\"owner\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"operatorSetId\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"latestReleaseBlockNumber\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"status\",\"type\":\"uint8\",\"internalType\":\"enumIAppController.AppStatus\"},{\"name\":\"timelocked\",\"type\":\"bool\",\"internalType\":\"bool\"}]}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getAppsByDeveloper\",\"inputs\":[{\"name\":\"developer\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"offset\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"limit\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"apps\",\"type\":\"address[]\",\"internalType\":\"contractIApp[]\"},{\"name\":\"appConfigsMem\",\"type\":\"tuple[]\",\"internalType\":\"structIAppController.AppConfig[]\",\"components\":[{\"name\":\"owner\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"operatorSetId\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"latestReleaseBlockNumber\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"status\",\"type\":\"uint8\",\"internalType\":\"enumIAppController.AppStatus\"},{\"name\":\"timelocked\",\"type\":\"bool\",\"internalType\":\"bool\"}]}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getAppsForAccount\",\"inputs\":[{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"offset\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"limit\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"appRoles\",\"type\":\"tuple[]\",\"internalType\":\"structIAppController.AppRoles[]\",\"components\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"},{\"name\":\"isOwner\",\"type\":\"bool\",\"internalType\":\"bool\"},{\"name\":\"roles\",\"type\":\"uint8[]\",\"internalType\":\"enumIAppController.TeamRole[]\"}]}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getMaxActiveAppsPerUser\",\"inputs\":[{\"name\":\"user\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getRoleAdmin\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getRoleMember\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"index\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getRoleMemberCount\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getTeamRoleMember\",\"inputs\":[{\"name\":\"team\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"role\",\"type\":\"uint8\",\"internalType\":\"enumIAppController.TeamRole\"},{\"name\":\"index\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getTeamRoleMemberCount\",\"inputs\":[{\"name\":\"team\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"role\",\"type\":\"uint8\",\"internalType\":\"enumIAppController.TeamRole\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getTeamRoleMembers\",\"inputs\":[{\"name\":\"team\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"role\",\"type\":\"uint8\",\"internalType\":\"enumIAppController.TeamRole\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address[]\",\"internalType\":\"address[]\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"globalActiveAppCount\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"grantRole\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"grantTeamRole\",\"inputs\":[{\"name\":\"team\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"role\",\"type\":\"uint8\",\"internalType\":\"enumIAppController.TeamRole\"},{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"hasRole\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"hasTeamRole\",\"inputs\":[{\"name\":\"team\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"role\",\"type\":\"uint8\",\"internalType\":\"enumIAppController.TeamRole\"},{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"initialize\",\"inputs\":[{\"name\":\"admin\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"maxGlobalActiveApps\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"migrateAdmins\",\"inputs\":[{\"name\":\"apps\",\"type\":\"address[]\",\"internalType\":\"contractIApp[]\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"permissionController\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIPermissionController\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"releaseManager\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIReleaseManager\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"renounceRole\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"renounceTeamRole\",\"inputs\":[{\"name\":\"team\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"role\",\"type\":\"uint8\",\"internalType\":\"enumIAppController.TeamRole\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"revokeRole\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"revokeTeamRole\",\"inputs\":[{\"name\":\"team\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"role\",\"type\":\"uint8\",\"internalType\":\"enumIAppController.TeamRole\"},{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"safeTimelockFactory\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractISafeTimelockFactory\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"setMaxActiveAppsPerUser\",\"inputs\":[{\"name\":\"user\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"limit\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"setMaxGlobalActiveApps\",\"inputs\":[{\"name\":\"limit\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"startApp\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"stopApp\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"supportsInterface\",\"inputs\":[{\"name\":\"interfaceId\",\"type\":\"bytes4\",\"internalType\":\"bytes4\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"suspend\",\"inputs\":[{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"apps\",\"type\":\"address[]\",\"internalType\":\"contractIApp[]\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"terminateApp\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"terminateAppByAdmin\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"transferOwnership\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"},{\"name\":\"newOwner\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"updateAppMetadataURI\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"},{\"name\":\"metadataURI\",\"type\":\"string\",\"internalType\":\"string\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"upgradeApp\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"internalType\":\"contractIApp\"},{\"name\":\"release\",\"type\":\"tuple\",\"internalType\":\"structIAppController.Release\",\"components\":[{\"name\":\"rmsRelease\",\"type\":\"tuple\",\"internalType\":\"structIReleaseManagerTypes.Release\",\"components\":[{\"name\":\"artifacts\",\"type\":\"tuple[]\",\"internalType\":\"structIReleaseManagerTypes.Artifact[]\",\"components\":[{\"name\":\"digest\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"registry\",\"type\":\"string\",\"internalType\":\"string\"}]},{\"name\":\"upgradeByTime\",\"type\":\"uint32\",\"internalType\":\"uint32\"}]},{\"name\":\"publicEnv\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"encryptedEnv\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"version\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"string\",\"internalType\":\"string\"}],\"stateMutability\":\"view\"},{\"type\":\"event\",\"name\":\"AppCreated\",\"inputs\":[{\"name\":\"owner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"app\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"contractIApp\"},{\"name\":\"operatorSetId\",\"type\":\"uint32\",\"indexed\":false,\"internalType\":\"uint32\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"AppMetadataURIUpdated\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"contractIApp\"},{\"name\":\"metadataURI\",\"type\":\"string\",\"indexed\":false,\"internalType\":\"string\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"AppOwnershipTransferred\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"contractIApp\"},{\"name\":\"previousOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"newOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"AppStarted\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"contractIApp\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"AppStopped\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"contractIApp\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"AppSuspended\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"contractIApp\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"AppTerminated\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"contractIApp\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"AppTerminatedByAdmin\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"contractIApp\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"AppUpgraded\",\"inputs\":[{\"name\":\"app\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"contractIApp\"},{\"name\":\"rmsReleaseId\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"release\",\"type\":\"tuple\",\"indexed\":false,\"internalType\":\"structIAppController.Release\",\"components\":[{\"name\":\"rmsRelease\",\"type\":\"tuple\",\"internalType\":\"structIReleaseManagerTypes.Release\",\"components\":[{\"name\":\"artifacts\",\"type\":\"tuple[]\",\"internalType\":\"structIReleaseManagerTypes.Artifact[]\",\"components\":[{\"name\":\"digest\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"registry\",\"type\":\"string\",\"internalType\":\"string\"}]},{\"name\":\"upgradeByTime\",\"type\":\"uint32\",\"internalType\":\"uint32\"}]},{\"name\":\"publicEnv\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"encryptedEnv\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"GlobalMaxActiveAppsSet\",\"inputs\":[{\"name\":\"limit\",\"type\":\"uint32\",\"indexed\":false,\"internalType\":\"uint32\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Initialized\",\"inputs\":[{\"name\":\"version\",\"type\":\"uint8\",\"indexed\":false,\"internalType\":\"uint8\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"MaxActiveAppsSet\",\"inputs\":[{\"name\":\"user\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"limit\",\"type\":\"uint32\",\"indexed\":false,\"internalType\":\"uint32\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"RoleAdminChanged\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"previousAdminRole\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"newAdminRole\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"RoleGranted\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"account\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"sender\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"RoleRevoked\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"account\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"sender\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"error\",\"name\":\"AccountHasActiveApps\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"AppAlreadyExists\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"AppDoesNotExist\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"CannotRevokeLastAdmin\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"GlobalMaxActiveAppsExceeded\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidAppStatus\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidPermissions\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidReleaseMetadataURI\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidShortString\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidSignature\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"MaxActiveAppsExceeded\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"MoreThanOneArtifact\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"SignatureExpired\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"StringTooLong\",\"inputs\":[{\"name\":\"str\",\"type\":\"string\",\"internalType\":\"string\"}]}]", ID: "AppController", } @@ -272,6 +272,41 @@ func (appController *AppController) UnpackCalculateAppId(data []byte) (common.Ad return out0, nil } +// PackCanCall is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x9614801b. This method will panic if any +// invalid/nil inputs are passed. +// +// Solidity: function canCall(address caller, bytes data) view returns(bool) +func (appController *AppController) PackCanCall(caller common.Address, data []byte) []byte { + enc, err := appController.abi.Pack("canCall", caller, data) + if err != nil { + panic(err) + } + return enc +} + +// TryPackCanCall is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x9614801b. This method will return an error +// if any inputs are invalid/nil. +// +// Solidity: function canCall(address caller, bytes data) view returns(bool) +func (appController *AppController) TryPackCanCall(caller common.Address, data []byte) ([]byte, error) { + return appController.abi.Pack("canCall", caller, data) +} + +// UnpackCanCall is the Go binding that unpacks the parameters returned +// from invoking the contract method with ID 0x9614801b. +// +// Solidity: function canCall(address caller, bytes data) view returns(bool) +func (appController *AppController) UnpackCanCall(data []byte) (bool, error) { + out, err := appController.abi.Unpack("canCall", data) + if err != nil { + return *new(bool), err + } + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + return out0, nil +} + // PackComputeAVSRegistrar is the Go binding used to pack the parameters required for calling // the contract method with ID 0xef6d92c6. This method will panic if any // invalid/nil inputs are passed. diff --git a/pkg/bindings/v2/TimelockControllerImpl/binding.go b/pkg/bindings/v2/TimelockControllerImpl/binding.go index 6e4caf6..1be4e1c 100644 --- a/pkg/bindings/v2/TimelockControllerImpl/binding.go +++ b/pkg/bindings/v2/TimelockControllerImpl/binding.go @@ -24,9 +24,17 @@ var ( _ = abi.ConvertType ) +// TimelockControllerImplPendingOp is an auto generated low-level Go binding around an user-defined struct. +type TimelockControllerImplPendingOp struct { + Id [32]byte + Target common.Address + Data []byte + ExecutableAt *big.Int +} + // TimelockControllerImplMetaData contains all meta data concerning the TimelockControllerImpl contract. var TimelockControllerImplMetaData = bind.MetaData{ - ABI: "[{\"type\":\"constructor\",\"inputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"receive\",\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"CANCELLER_ROLE\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"DEFAULT_ADMIN_ROLE\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"EXECUTOR_ROLE\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"PROPOSER_ROLE\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"TIMELOCK_ADMIN_ROLE\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"cancel\",\"inputs\":[{\"name\":\"id\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"execute\",\"inputs\":[{\"name\":\"target\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"value\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"payload\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"predecessor\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"salt\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"executeBatch\",\"inputs\":[{\"name\":\"targets\",\"type\":\"address[]\",\"internalType\":\"address[]\"},{\"name\":\"values\",\"type\":\"uint256[]\",\"internalType\":\"uint256[]\"},{\"name\":\"payloads\",\"type\":\"bytes[]\",\"internalType\":\"bytes[]\"},{\"name\":\"predecessor\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"salt\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"getMinDelay\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getRoleAdmin\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getTimestamp\",\"inputs\":[{\"name\":\"id\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"grantRole\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"hasRole\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"hashOperation\",\"inputs\":[{\"name\":\"target\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"value\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"data\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"predecessor\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"salt\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"pure\"},{\"type\":\"function\",\"name\":\"hashOperationBatch\",\"inputs\":[{\"name\":\"targets\",\"type\":\"address[]\",\"internalType\":\"address[]\"},{\"name\":\"values\",\"type\":\"uint256[]\",\"internalType\":\"uint256[]\"},{\"name\":\"payloads\",\"type\":\"bytes[]\",\"internalType\":\"bytes[]\"},{\"name\":\"predecessor\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"salt\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"pure\"},{\"type\":\"function\",\"name\":\"initialize\",\"inputs\":[{\"name\":\"minDelay\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"proposers\",\"type\":\"address[]\",\"internalType\":\"address[]\"},{\"name\":\"executors\",\"type\":\"address[]\",\"internalType\":\"address[]\"},{\"name\":\"admin\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"isOperation\",\"inputs\":[{\"name\":\"id\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"isOperationDone\",\"inputs\":[{\"name\":\"id\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"isOperationPending\",\"inputs\":[{\"name\":\"id\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"isOperationReady\",\"inputs\":[{\"name\":\"id\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"onERC1155BatchReceived\",\"inputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"\",\"type\":\"uint256[]\",\"internalType\":\"uint256[]\"},{\"name\":\"\",\"type\":\"uint256[]\",\"internalType\":\"uint256[]\"},{\"name\":\"\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes4\",\"internalType\":\"bytes4\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"onERC1155Received\",\"inputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes4\",\"internalType\":\"bytes4\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"onERC721Received\",\"inputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes4\",\"internalType\":\"bytes4\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"renounceRole\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"revokeRole\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"schedule\",\"inputs\":[{\"name\":\"target\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"value\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"data\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"predecessor\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"salt\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"delay\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"scheduleBatch\",\"inputs\":[{\"name\":\"targets\",\"type\":\"address[]\",\"internalType\":\"address[]\"},{\"name\":\"values\",\"type\":\"uint256[]\",\"internalType\":\"uint256[]\"},{\"name\":\"payloads\",\"type\":\"bytes[]\",\"internalType\":\"bytes[]\"},{\"name\":\"predecessor\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"salt\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"delay\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"supportsInterface\",\"inputs\":[{\"name\":\"interfaceId\",\"type\":\"bytes4\",\"internalType\":\"bytes4\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"updateDelay\",\"inputs\":[{\"name\":\"newDelay\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"event\",\"name\":\"CallExecuted\",\"inputs\":[{\"name\":\"id\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"index\",\"type\":\"uint256\",\"indexed\":true,\"internalType\":\"uint256\"},{\"name\":\"target\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"},{\"name\":\"value\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"data\",\"type\":\"bytes\",\"indexed\":false,\"internalType\":\"bytes\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"CallSalt\",\"inputs\":[{\"name\":\"id\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"salt\",\"type\":\"bytes32\",\"indexed\":false,\"internalType\":\"bytes32\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"CallScheduled\",\"inputs\":[{\"name\":\"id\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"index\",\"type\":\"uint256\",\"indexed\":true,\"internalType\":\"uint256\"},{\"name\":\"target\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"},{\"name\":\"value\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"data\",\"type\":\"bytes\",\"indexed\":false,\"internalType\":\"bytes\"},{\"name\":\"predecessor\",\"type\":\"bytes32\",\"indexed\":false,\"internalType\":\"bytes32\"},{\"name\":\"delay\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Cancelled\",\"inputs\":[{\"name\":\"id\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Initialized\",\"inputs\":[{\"name\":\"version\",\"type\":\"uint8\",\"indexed\":false,\"internalType\":\"uint8\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"MinDelayChange\",\"inputs\":[{\"name\":\"oldDuration\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"newDuration\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"RoleAdminChanged\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"previousAdminRole\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"newAdminRole\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"RoleGranted\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"account\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"sender\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"RoleRevoked\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"account\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"sender\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false}]", + ABI: "[{\"type\":\"constructor\",\"inputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"receive\",\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"CANCELLER_ROLE\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"DEFAULT_ADMIN_ROLE\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"EXECUTOR_ROLE\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"PROPOSER_ROLE\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"TIMELOCK_ADMIN_ROLE\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"cancel\",\"inputs\":[{\"name\":\"id\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"execute\",\"inputs\":[{\"name\":\"target\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"value\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"payload\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"predecessor\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"salt\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"executeBatch\",\"inputs\":[{\"name\":\"targets\",\"type\":\"address[]\",\"internalType\":\"address[]\"},{\"name\":\"values\",\"type\":\"uint256[]\",\"internalType\":\"uint256[]\"},{\"name\":\"payloads\",\"type\":\"bytes[]\",\"internalType\":\"bytes[]\"},{\"name\":\"predecessor\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"salt\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"getMinDelay\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getPendingOperationIds\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32[]\",\"internalType\":\"bytes32[]\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getPendingOperations\",\"inputs\":[],\"outputs\":[{\"name\":\"ops\",\"type\":\"tuple[]\",\"internalType\":\"structTimelockControllerImpl.PendingOp[]\",\"components\":[{\"name\":\"id\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"target\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"data\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"executableAt\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getRoleAdmin\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getTimestamp\",\"inputs\":[{\"name\":\"id\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"grantRole\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"hasRole\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"hashOperation\",\"inputs\":[{\"name\":\"target\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"value\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"data\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"predecessor\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"salt\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"pure\"},{\"type\":\"function\",\"name\":\"hashOperationBatch\",\"inputs\":[{\"name\":\"targets\",\"type\":\"address[]\",\"internalType\":\"address[]\"},{\"name\":\"values\",\"type\":\"uint256[]\",\"internalType\":\"uint256[]\"},{\"name\":\"payloads\",\"type\":\"bytes[]\",\"internalType\":\"bytes[]\"},{\"name\":\"predecessor\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"salt\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"pure\"},{\"type\":\"function\",\"name\":\"initialize\",\"inputs\":[{\"name\":\"minDelay\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"proposers\",\"type\":\"address[]\",\"internalType\":\"address[]\"},{\"name\":\"executors\",\"type\":\"address[]\",\"internalType\":\"address[]\"},{\"name\":\"admin\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"isOperation\",\"inputs\":[{\"name\":\"id\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"isOperationDone\",\"inputs\":[{\"name\":\"id\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"isOperationPending\",\"inputs\":[{\"name\":\"id\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"isOperationReady\",\"inputs\":[{\"name\":\"id\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"onERC1155BatchReceived\",\"inputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"\",\"type\":\"uint256[]\",\"internalType\":\"uint256[]\"},{\"name\":\"\",\"type\":\"uint256[]\",\"internalType\":\"uint256[]\"},{\"name\":\"\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes4\",\"internalType\":\"bytes4\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"onERC1155Received\",\"inputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes4\",\"internalType\":\"bytes4\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"onERC721Received\",\"inputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes4\",\"internalType\":\"bytes4\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"renounceRole\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"revokeRole\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"schedule\",\"inputs\":[{\"name\":\"target\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"value\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"data\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"predecessor\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"salt\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"delay\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"scheduleBatch\",\"inputs\":[{\"name\":\"targets\",\"type\":\"address[]\",\"internalType\":\"address[]\"},{\"name\":\"values\",\"type\":\"uint256[]\",\"internalType\":\"uint256[]\"},{\"name\":\"payloads\",\"type\":\"bytes[]\",\"internalType\":\"bytes[]\"},{\"name\":\"predecessor\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"salt\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"delay\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"supportsInterface\",\"inputs\":[{\"name\":\"interfaceId\",\"type\":\"bytes4\",\"internalType\":\"bytes4\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"updateDelay\",\"inputs\":[{\"name\":\"newDelay\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"event\",\"name\":\"CallExecuted\",\"inputs\":[{\"name\":\"id\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"index\",\"type\":\"uint256\",\"indexed\":true,\"internalType\":\"uint256\"},{\"name\":\"target\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"},{\"name\":\"value\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"data\",\"type\":\"bytes\",\"indexed\":false,\"internalType\":\"bytes\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"CallSalt\",\"inputs\":[{\"name\":\"id\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"salt\",\"type\":\"bytes32\",\"indexed\":false,\"internalType\":\"bytes32\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"CallScheduled\",\"inputs\":[{\"name\":\"id\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"index\",\"type\":\"uint256\",\"indexed\":true,\"internalType\":\"uint256\"},{\"name\":\"target\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"},{\"name\":\"value\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"data\",\"type\":\"bytes\",\"indexed\":false,\"internalType\":\"bytes\"},{\"name\":\"predecessor\",\"type\":\"bytes32\",\"indexed\":false,\"internalType\":\"bytes32\"},{\"name\":\"delay\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Cancelled\",\"inputs\":[{\"name\":\"id\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Initialized\",\"inputs\":[{\"name\":\"version\",\"type\":\"uint8\",\"indexed\":false,\"internalType\":\"uint8\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"MinDelayChange\",\"inputs\":[{\"name\":\"oldDuration\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"newDuration\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"RoleAdminChanged\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"previousAdminRole\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"newAdminRole\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"RoleGranted\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"account\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"sender\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"RoleRevoked\",\"inputs\":[{\"name\":\"role\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"account\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"sender\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false}]", ID: "TimelockControllerImpl", } @@ -326,6 +334,76 @@ func (timelockControllerImpl *TimelockControllerImpl) UnpackGetMinDelay(data []b return out0, nil } +// PackGetPendingOperationIds is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x7b146198. This method will panic if any +// invalid/nil inputs are passed. +// +// Solidity: function getPendingOperationIds() view returns(bytes32[]) +func (timelockControllerImpl *TimelockControllerImpl) PackGetPendingOperationIds() []byte { + enc, err := timelockControllerImpl.abi.Pack("getPendingOperationIds") + if err != nil { + panic(err) + } + return enc +} + +// TryPackGetPendingOperationIds is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x7b146198. This method will return an error +// if any inputs are invalid/nil. +// +// Solidity: function getPendingOperationIds() view returns(bytes32[]) +func (timelockControllerImpl *TimelockControllerImpl) TryPackGetPendingOperationIds() ([]byte, error) { + return timelockControllerImpl.abi.Pack("getPendingOperationIds") +} + +// UnpackGetPendingOperationIds is the Go binding that unpacks the parameters returned +// from invoking the contract method with ID 0x7b146198. +// +// Solidity: function getPendingOperationIds() view returns(bytes32[]) +func (timelockControllerImpl *TimelockControllerImpl) UnpackGetPendingOperationIds(data []byte) ([][32]byte, error) { + out, err := timelockControllerImpl.abi.Unpack("getPendingOperationIds", data) + if err != nil { + return *new([][32]byte), err + } + out0 := *abi.ConvertType(out[0], new([][32]byte)).(*[][32]byte) + return out0, nil +} + +// PackGetPendingOperations is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x64440ce5. This method will panic if any +// invalid/nil inputs are passed. +// +// Solidity: function getPendingOperations() view returns((bytes32,address,bytes,uint256)[] ops) +func (timelockControllerImpl *TimelockControllerImpl) PackGetPendingOperations() []byte { + enc, err := timelockControllerImpl.abi.Pack("getPendingOperations") + if err != nil { + panic(err) + } + return enc +} + +// TryPackGetPendingOperations is the Go binding used to pack the parameters required for calling +// the contract method with ID 0x64440ce5. This method will return an error +// if any inputs are invalid/nil. +// +// Solidity: function getPendingOperations() view returns((bytes32,address,bytes,uint256)[] ops) +func (timelockControllerImpl *TimelockControllerImpl) TryPackGetPendingOperations() ([]byte, error) { + return timelockControllerImpl.abi.Pack("getPendingOperations") +} + +// UnpackGetPendingOperations is the Go binding that unpacks the parameters returned +// from invoking the contract method with ID 0x64440ce5. +// +// Solidity: function getPendingOperations() view returns((bytes32,address,bytes,uint256)[] ops) +func (timelockControllerImpl *TimelockControllerImpl) UnpackGetPendingOperations(data []byte) ([]TimelockControllerImplPendingOp, error) { + out, err := timelockControllerImpl.abi.Unpack("getPendingOperations", data) + if err != nil { + return *new([]TimelockControllerImplPendingOp), err + } + out0 := *abi.ConvertType(out[0], new([]TimelockControllerImplPendingOp)).(*[]TimelockControllerImplPendingOp) + return out0, nil +} + // PackGetRoleAdmin is the Go binding used to pack the parameters required for calling // the contract method with ID 0x248a9ca3. This method will panic if any // invalid/nil inputs are passed. From b5fde69461e358f76168501c6efc3f28fa2d7d0e Mon Sep 17 00:00:00 2001 From: Taras Shchybovyk Date: Wed, 22 Apr 2026 20:37:39 -0700 Subject: [PATCH 30/31] chore: bump governance release to v1.5.0 master already ships a v1.4.0 (isolated-billing), so this release must apply on top of v1.4.0. Move the directory to v1.5.0-governance and update upgrade.json: from 1.4.0, to 1.5.0. --- .../1-deployContracts.s.sol | 0 .../2-upgradeAppController.s.sol | 0 .../{v1.4.0-governance => v1.5.0-governance}/upgrade.json | 0 3 files changed, 0 insertions(+), 0 deletions(-) rename script/releases/{v1.4.0-governance => v1.5.0-governance}/1-deployContracts.s.sol (100%) rename script/releases/{v1.4.0-governance => v1.5.0-governance}/2-upgradeAppController.s.sol (100%) rename script/releases/{v1.4.0-governance => v1.5.0-governance}/upgrade.json (100%) diff --git a/script/releases/v1.4.0-governance/1-deployContracts.s.sol b/script/releases/v1.5.0-governance/1-deployContracts.s.sol similarity index 100% rename from script/releases/v1.4.0-governance/1-deployContracts.s.sol rename to script/releases/v1.5.0-governance/1-deployContracts.s.sol diff --git a/script/releases/v1.4.0-governance/2-upgradeAppController.s.sol b/script/releases/v1.5.0-governance/2-upgradeAppController.s.sol similarity index 100% rename from script/releases/v1.4.0-governance/2-upgradeAppController.s.sol rename to script/releases/v1.5.0-governance/2-upgradeAppController.s.sol diff --git a/script/releases/v1.4.0-governance/upgrade.json b/script/releases/v1.5.0-governance/upgrade.json similarity index 100% rename from script/releases/v1.4.0-governance/upgrade.json rename to script/releases/v1.5.0-governance/upgrade.json From 53c13bd0c91466060309bf1fd87fbb50d63c6727 Mon Sep 17 00:00:00 2001 From: Taras Shchybovyk Date: Thu, 23 Apr 2026 10:10:45 -0700 Subject: [PATCH 31/31] fix: set timelocked at app creation + bump release version MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit createAppForTeam only wrote _appConfigs[app].owner but never set _appConfigs[app].timelocked. If the team (and therefore the app's initial owner) is a factory-deployed Timelock, the app was created with timelocked=false — bypassing the runtime guards on upgradeApp, transferOwnership, terminateApp, and grantTeamRole(ADMIN). Any subsequent co-admin the Timelock granted could then perform sensitive ops directly, with no queue delay. Set timelocked = safeTimelockFactory.isTimelock(team) at creation, mirroring the check transferOwnership already performs. Also fix upgrade.json metadata that was committed with the old 1.3.0 → 1.4.0 values; this release must apply on top of v1.4.0 (which is already taken by isolated-billing on master). Added regression tests: - timelockedOwnerSetsTimelockedFlag: Timelock-created app has the flag - timelockedBlocksNonOwnerAdminUpgrade: co-admin upgrade reverts, Timelock upgrade succeeds (exploit path closed) - nonTimelockOwnerDoesNotSetTimelocked: EOA-owned app keeps flag false - safeOwnerDoesNotSetTimelocked: Safe-owned app keeps flag false --- .../releases/v1.5.0-governance/upgrade.json | 4 +- src/AppController.sol | 6 ++ test/AppController.t.sol | 88 +++++++++++++++++++ 3 files changed, 96 insertions(+), 2 deletions(-) diff --git a/script/releases/v1.5.0-governance/upgrade.json b/script/releases/v1.5.0-governance/upgrade.json index cd1c314..310e8d7 100644 --- a/script/releases/v1.5.0-governance/upgrade.json +++ b/script/releases/v1.5.0-governance/upgrade.json @@ -1,7 +1,7 @@ { "name": "governance", - "from": "1.3.0", - "to": "1.4.0", + "from": "1.4.0", + "to": "1.5.0", "phases": [ { "type": "eoa", "filename": "1-deployContracts.s.sol" }, { "type": "multisig", "filename": "2-upgradeAppController.s.sol" } diff --git a/src/AppController.sol b/src/AppController.sol index 7f75540..a584506 100644 --- a/src/AppController.sol +++ b/src/AppController.sol @@ -167,6 +167,12 @@ contract AppController is _appConfigs[app].operatorSetId = operatorSetId; _appConfigs[app].latestReleaseBlockNumber = 0; _appConfigs[app].owner = team; + // If the team is a factory-deployed Timelock, mark the app timelocked at + // creation so sensitive ops (upgrade/terminate/transfer/grantAdmin) go + // through schedule→execute instead of being callable directly by any + // admin the Timelock later grants. Mirrors the same check performed in + // transferOwnership when ownership is handed to a Timelock. + _appConfigs[app].timelocked = safeTimelockFactory.isTimelock(team); _allApps.add(address(app)); emit AppCreated(team, app, operatorSetId); diff --git a/test/AppController.t.sol b/test/AppController.t.sol index f2c562d..e443d37 100644 --- a/test/AppController.t.sol +++ b/test/AppController.t.sol @@ -270,6 +270,94 @@ contract AppControllerTest is ComputeDeployer { appController.createAppForTeam(developer, keccak256("dev_app"), _assembleRelease()); } + // ========== Regression: `timelocked` flag must be set at creation (V-1 / G-1 / A-1) ========== + + function test_createAppForTeam_timelockedOwnerSetsTimelockedFlag() public { + // A factory-registered Timelock creates an app for itself. The app's + // `timelocked` flag MUST be set at creation so that subsequent sensitive + // ops (upgrade, terminate, transferOwnership, grantAdmin) require + // msg.sender == owner (i.e., must go through schedule→execute). + address mockTimelock = makeAddr("mockTimelock"); + _mockIsTimelock(mockTimelock); + _setMaxActiveAppsPerUser(mockTimelock, 10); + + vm.prank(mockTimelock); + IApp app = appController.createAppForTeam(mockTimelock, keccak256("tl_app"), _assembleRelease()); + + assertEq(appController.getAppOwner(app), mockTimelock); + assertTrue( + appController.getAppTimelocked(app), + "Timelock-owned app must be flagged timelocked at creation" + ); + } + + function test_createAppForTeam_timelockedBlocksNonOwnerAdminUpgrade() public { + // Exploit scenario before the fix: + // 1. Timelock creates app for itself → timelocked defaulted to false + // 2. Timelock grants ADMIN to another address (say, via a scheduled op) + // 3. That address calls upgradeApp directly — succeeds with no delay + // + // After the fix, step 3 must revert because timelocked=true forces + // msg.sender == owner. + address mockTimelock = makeAddr("mockTimelock"); + _mockIsTimelock(mockTimelock); + _setMaxActiveAppsPerUser(mockTimelock, 10); + + vm.prank(mockTimelock); + IApp app = appController.createAppForTeam(mockTimelock, keccak256("tl_app"), _assembleRelease()); + + // Timelock grants ADMIN to a co-admin. + address coAdmin = makeAddr("coAdmin"); + vm.prank(mockTimelock); + appController.grantTeamRole(mockTimelock, IAppController.TeamRole.ADMIN, coAdmin); + + // Co-admin attempts direct upgrade — must revert (timelocked gate). + vm.prank(coAdmin); + vm.expectRevert(PermissionControllerMixin.InvalidPermissions.selector); + appController.upgradeApp(app, _assembleRelease()); + + // The Timelock itself can still upgrade directly (i.e., via a scheduled + // operation that results in msg.sender == Timelock at execute time). + vm.prank(mockTimelock); + appController.upgradeApp(app, _assembleRelease()); + } + + function test_createAppForTeam_nonTimelockOwnerDoesNotSetTimelocked() public { + // Sanity check: EOA/team-owned apps must NOT be flagged timelocked. + // Regression guard that the fix in createAppForTeam doesn't + // over-apply the flag. + vm.prank(developer); + IApp app = appController.createAppForTeam(developer, keccak256("eoa_app"), _assembleRelease()); + + assertEq(appController.getAppOwner(app), developer); + assertFalse( + appController.getAppTimelocked(app), + "EOA-owned app must not be flagged timelocked" + ); + + // And direct upgrade by an ADMIN continues to work (pre-fix behavior). + vm.prank(developer); + appController.upgradeApp(app, _assembleRelease()); + } + + function test_createAppForTeam_safeOwnerDoesNotSetTimelocked() public { + // A Safe is NOT a Timelock (even though it's deployed by the same + // factory). Apps owned by a Safe must not be flagged timelocked — + // Safe threshold is handled off-chain, not via schedule→execute. + address mockSafe = makeAddr("mockSafe"); + // Do NOT call _mockIsTimelock — the factory returns false for non-Timelock addresses. + _setMaxActiveAppsPerUser(mockSafe, 10); + + vm.prank(mockSafe); + IApp app = appController.createAppForTeam(mockSafe, keccak256("safe_app"), _assembleRelease()); + + assertEq(appController.getAppOwner(app), mockSafe); + assertFalse( + appController.getAppTimelocked(app), + "Safe-owned app must not be flagged timelocked" + ); + } + function test_createAppForTeam_quotaDeductedFromTeam() public { // Set up team with limited quota _setMaxActiveAppsPerUser(developer, 3);