creation_sourcecode: {{
    "language": "Solidity",
    "sources": {
      "@openzeppelin/contracts/access/AccessControl.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (access/AccessControl.sol)\n\npragma solidity ^0.8.20;\n\nimport {IAccessControl} from \"./IAccessControl.sol\";\nimport {Context} from \"../utils/Context.sol\";\nimport {ERC165} from \"../utils/introspection/ERC165.sol\";\n\n/**\n * @dev Contract module that allows children to implement role-based access\n * control mechanisms. This is a lightweight version that doesn't allow enumerating role\n * members except through off-chain means by accessing the contract event logs. Some\n * applications may benefit from on-chain enumerability, for those cases see\n * {AccessControlEnumerable}.\n *\n * Roles are referred to by their `bytes32` identifier. These should be exposed\n * in the external API and be unique. The best way to achieve this is by\n * using `public constant` hash digests:\n *\n * ```solidity\n * bytes32 public constant MY_ROLE = keccak256(\"MY_ROLE\");\n * ```\n *\n * Roles can be used to represent a set of permissions. To restrict access to a\n * function call, use {hasRole}:\n *\n * ```solidity\n * function foo() public {\n *     require(hasRole(MY_ROLE, msg.sender));\n *     ...\n * }\n * ```\n *\n * Roles can be granted and revoked dynamically via the {grantRole} and\n * {revokeRole} functions. Each role has an associated admin role, and only\n * accounts that have a role's admin role can call {grantRole} and {revokeRole}.\n *\n * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means\n * that only accounts with this role will be able to grant or revoke other\n * roles. More complex role relationships can be created by using\n * {_setRoleAdmin}.\n *\n * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to\n * grant and revoke this role. Extra precautions should be taken to secure\n * accounts that have been granted it. We recommend using {AccessControlDefaultAdminRules}\n * to enforce additional security measures for this role.\n */\nabstract contract AccessControl is Context, IAccessControl, ERC165 {\n    struct RoleData {\n        mapping(address account => bool) hasRole;\n        bytes32 adminRole;\n    }\n\n    mapping(bytes32 role => RoleData) private _roles;\n\n    bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;\n\n    /**\n     * @dev Modifier that checks that an account has a specific role. Reverts\n     * with an {AccessControlUnauthorizedAccount} error including the required role.\n     */\n    modifier onlyRole(bytes32 role) {\n        _checkRole(role);\n        _;\n    }\n\n    /**\n     * @dev See {IERC165-supportsInterface}.\n     */\n    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n        return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId);\n    }\n\n    /**\n     * @dev Returns `true` if `account` has been granted `role`.\n     */\n    function hasRole(bytes32 role, address account) public view virtual returns (bool) {\n        return _roles[role].hasRole[account];\n    }\n\n    /**\n     * @dev Reverts with an {AccessControlUnauthorizedAccount} error if `_msgSender()`\n     * is missing `role`. Overriding this function changes the behavior of the {onlyRole} modifier.\n     */\n    function _checkRole(bytes32 role) internal view virtual {\n        _checkRole(role, _msgSender());\n    }\n\n    /**\n     * @dev Reverts with an {AccessControlUnauthorizedAccount} error if `account`\n     * is missing `role`.\n     */\n    function _checkRole(bytes32 role, address account) internal view virtual {\n        if (!hasRole(role, account)) {\n            revert AccessControlUnauthorizedAccount(account, role);\n        }\n    }\n\n    /**\n     * @dev Returns the admin role that controls `role`. See {grantRole} and\n     * {revokeRole}.\n     *\n     * To change a role's admin, use {_setRoleAdmin}.\n     */\n    function getRoleAdmin(bytes32 role) public view virtual returns (bytes32) {\n        return _roles[role].adminRole;\n    }\n\n    /**\n     * @dev Grants `role` to `account`.\n     *\n     * If `account` had not been already granted `role`, emits a {RoleGranted}\n     * event.\n     *\n     * Requirements:\n     *\n     * - the caller must have ``role``'s admin role.\n     *\n     * May emit a {RoleGranted} event.\n     */\n    function grantRole(bytes32 role, address account) public virtual onlyRole(getRoleAdmin(role)) {\n        _grantRole(role, account);\n    }\n\n    /**\n     * @dev Revokes `role` from `account`.\n     *\n     * If `account` had been granted `role`, emits a {RoleRevoked} event.\n     *\n     * Requirements:\n     *\n     * - the caller must have ``role``'s admin role.\n     *\n     * May emit a {RoleRevoked} event.\n     */\n    function revokeRole(bytes32 role, address account) public virtual onlyRole(getRoleAdmin(role)) {\n        _revokeRole(role, account);\n    }\n\n    /**\n     * @dev Revokes `role` from the calling account.\n     *\n     * Roles are often managed via {grantRole} and {revokeRole}: this function's\n     * purpose is to provide a mechanism for accounts to lose their privileges\n     * if they are compromised (such as when a trusted device is misplaced).\n     *\n     * If the calling account had been revoked `role`, emits a {RoleRevoked}\n     * event.\n     *\n     * Requirements:\n     *\n     * - the caller must be `callerConfirmation`.\n     *\n     * May emit a {RoleRevoked} event.\n     */\n    function renounceRole(bytes32 role, address callerConfirmation) public virtual {\n        if (callerConfirmation != _msgSender()) {\n            revert AccessControlBadConfirmation();\n        }\n\n        _revokeRole(role, callerConfirmation);\n    }\n\n    /**\n     * @dev Sets `adminRole` as ``role``'s admin role.\n     *\n     * Emits a {RoleAdminChanged} event.\n     */\n    function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {\n        bytes32 previousAdminRole = getRoleAdmin(role);\n        _roles[role].adminRole = adminRole;\n        emit RoleAdminChanged(role, previousAdminRole, adminRole);\n    }\n\n    /**\n     * @dev Attempts to grant `role` to `account` and returns a boolean indicating if `role` was granted.\n     *\n     * Internal function without access restriction.\n     *\n     * May emit a {RoleGranted} event.\n     */\n    function _grantRole(bytes32 role, address account) internal virtual returns (bool) {\n        if (!hasRole(role, account)) {\n            _roles[role].hasRole[account] = true;\n            emit RoleGranted(role, account, _msgSender());\n            return true;\n        } else {\n            return false;\n        }\n    }\n\n    /**\n     * @dev Attempts to revoke `role` to `account` and returns a boolean indicating if `role` was revoked.\n     *\n     * Internal function without access restriction.\n     *\n     * May emit a {RoleRevoked} event.\n     */\n    function _revokeRole(bytes32 role, address account) internal virtual returns (bool) {\n        if (hasRole(role, account)) {\n            _roles[role].hasRole[account] = false;\n            emit RoleRevoked(role, account, _msgSender());\n            return true;\n        } else {\n            return false;\n        }\n    }\n}\n"
      },
      "@openzeppelin/contracts/access/IAccessControl.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (access/IAccessControl.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev External interface of AccessControl declared to support ERC165 detection.\n */\ninterface IAccessControl {\n    /**\n     * @dev The `account` is missing a role.\n     */\n    error AccessControlUnauthorizedAccount(address account, bytes32 neededRole);\n\n    /**\n     * @dev The caller of a function is not the expected one.\n     *\n     * NOTE: Don't confuse with {AccessControlUnauthorizedAccount}.\n     */\n    error AccessControlBadConfirmation();\n\n    /**\n     * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`\n     *\n     * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite\n     * {RoleAdminChanged} not being emitted signaling this.\n     */\n    event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);\n\n    /**\n     * @dev Emitted when `account` is granted `role`.\n     *\n     * `sender` is the account that originated the contract call, an admin role\n     * bearer except when using {AccessControl-_setupRole}.\n     */\n    event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);\n\n    /**\n     * @dev Emitted when `account` is revoked `role`.\n     *\n     * `sender` is the account that originated the contract call:\n     *   - if using `revokeRole`, it is the admin role bearer\n     *   - if using `renounceRole`, it is the role bearer (i.e. `account`)\n     */\n    event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);\n\n    /**\n     * @dev Returns `true` if `account` has been granted `role`.\n     */\n    function hasRole(bytes32 role, address account) external view returns (bool);\n\n    /**\n     * @dev Returns the admin role that controls `role`. See {grantRole} and\n     * {revokeRole}.\n     *\n     * To change a role's admin, use {AccessControl-_setRoleAdmin}.\n     */\n    function getRoleAdmin(bytes32 role) external view returns (bytes32);\n\n    /**\n     * @dev Grants `role` to `account`.\n     *\n     * If `account` had not been already granted `role`, emits a {RoleGranted}\n     * event.\n     *\n     * Requirements:\n     *\n     * - the caller must have ``role``'s admin role.\n     */\n    function grantRole(bytes32 role, address account) external;\n\n    /**\n     * @dev Revokes `role` from `account`.\n     *\n     * If `account` had been granted `role`, emits a {RoleRevoked} event.\n     *\n     * Requirements:\n     *\n     * - the caller must have ``role``'s admin role.\n     */\n    function revokeRole(bytes32 role, address account) external;\n\n    /**\n     * @dev Revokes `role` from the calling account.\n     *\n     * Roles are often managed via {grantRole} and {revokeRole}: this function's\n     * purpose is to provide a mechanism for accounts to lose their privileges\n     * if they are compromised (such as when a trusted device is misplaced).\n     *\n     * If the calling account had been granted `role`, emits a {RoleRevoked}\n     * event.\n     *\n     * Requirements:\n     *\n     * - the caller must be `callerConfirmation`.\n     */\n    function renounceRole(bytes32 role, address callerConfirmation) external;\n}\n"
      },
      "@openzeppelin/contracts/token/ERC20/IERC20.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n    /**\n     * @dev Emitted when `value` tokens are moved from one account (`from`) to\n     * another (`to`).\n     *\n     * Note that `value` may be zero.\n     */\n    event Transfer(address indexed from, address indexed to, uint256 value);\n\n    /**\n     * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n     * a call to {approve}. `value` is the new allowance.\n     */\n    event Approval(address indexed owner, address indexed spender, uint256 value);\n\n    /**\n     * @dev Returns the value of tokens in existence.\n     */\n    function totalSupply() external view returns (uint256);\n\n    /**\n     * @dev Returns the value of tokens owned by `account`.\n     */\n    function balanceOf(address account) external view returns (uint256);\n\n    /**\n     * @dev Moves a `value` amount of tokens from the caller's account to `to`.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transfer(address to, uint256 value) external returns (bool);\n\n    /**\n     * @dev Returns the remaining number of tokens that `spender` will be\n     * allowed to spend on behalf of `owner` through {transferFrom}. This is\n     * zero by default.\n     *\n     * This value changes when {approve} or {transferFrom} are called.\n     */\n    function allowance(address owner, address spender) external view returns (uint256);\n\n    /**\n     * @dev Sets a `value` amount of tokens as the allowance of `spender` over the\n     * caller's tokens.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * IMPORTANT: Beware that changing an allowance with this method brings the risk\n     * that someone may use both the old and the new allowance by unfortunate\n     * transaction ordering. One possible solution to mitigate this race\n     * condition is to first reduce the spender's allowance to 0 and set the\n     * desired value afterwards:\n     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n     *\n     * Emits an {Approval} event.\n     */\n    function approve(address spender, uint256 value) external returns (bool);\n\n    /**\n     * @dev Moves a `value` amount of tokens from `from` to `to` using the\n     * allowance mechanism. `value` is then deducted from the caller's\n     * allowance.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transferFrom(address from, address to, uint256 value) external returns (bool);\n}\n"
      },
      "@openzeppelin/contracts/utils/Address.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (utils/Address.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n    /**\n     * @dev The ETH balance of the account is not enough to perform the operation.\n     */\n    error AddressInsufficientBalance(address account);\n\n    /**\n     * @dev There's no code at `target` (it is not a contract).\n     */\n    error AddressEmptyCode(address target);\n\n    /**\n     * @dev A call to an address target failed. The target may have reverted.\n     */\n    error FailedInnerCall();\n\n    /**\n     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n     * `recipient`, forwarding all available gas and reverting on errors.\n     *\n     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n     * of certain opcodes, possibly making contracts go over the 2300 gas limit\n     * imposed by `transfer`, making them unable to receive funds via\n     * `transfer`. {sendValue} removes this limitation.\n     *\n     * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n     *\n     * IMPORTANT: because control is transferred to `recipient`, care must be\n     * taken to not create reentrancy vulnerabilities. Consider using\n     * {ReentrancyGuard} or the\n     * https://solidity.readthedocs.io/en/v0.8.20/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n     */\n    function sendValue(address payable recipient, uint256 amount) internal {\n        if (address(this).balance < amount) {\n            revert AddressInsufficientBalance(address(this));\n        }\n\n        (bool success, ) = recipient.call{value: amount}(\"\");\n        if (!success) {\n            revert FailedInnerCall();\n        }\n    }\n\n    /**\n     * @dev Performs a Solidity function call using a low level `call`. A\n     * plain `call` is an unsafe replacement for a function call: use this\n     * function instead.\n     *\n     * If `target` reverts with a revert reason or custom error, it is bubbled\n     * up by this function (like regular Solidity function calls). However, if\n     * the call reverted with no returned reason, this function reverts with a\n     * {FailedInnerCall} error.\n     *\n     * Returns the raw returned data. To convert to the expected return value,\n     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n     *\n     * Requirements:\n     *\n     * - `target` must be a contract.\n     * - calling `target` with `data` must not revert.\n     */\n    function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n        return functionCallWithValue(target, data, 0);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but also transferring `value` wei to `target`.\n     *\n     * Requirements:\n     *\n     * - the calling contract must have an ETH balance of at least `value`.\n     * - the called Solidity function must be `payable`.\n     */\n    function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\n        if (address(this).balance < value) {\n            revert AddressInsufficientBalance(address(this));\n        }\n        (bool success, bytes memory returndata) = target.call{value: value}(data);\n        return verifyCallResultFromTarget(target, success, returndata);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but performing a static call.\n     */\n    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n        (bool success, bytes memory returndata) = target.staticcall(data);\n        return verifyCallResultFromTarget(target, success, returndata);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but performing a delegate call.\n     */\n    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n        (bool success, bytes memory returndata) = target.delegatecall(data);\n        return verifyCallResultFromTarget(target, success, returndata);\n    }\n\n    /**\n     * @dev Tool to verify that a low level call to smart-contract was successful, and reverts if the target\n     * was not a contract or bubbling up the revert reason (falling back to {FailedInnerCall}) in case of an\n     * unsuccessful call.\n     */\n    function verifyCallResultFromTarget(\n        address target,\n        bool success,\n        bytes memory returndata\n    ) internal view returns (bytes memory) {\n        if (!success) {\n            _revert(returndata);\n        } else {\n            // only check if target is a contract if the call was successful and the return data is empty\n            // otherwise we already know that it was a contract\n            if (returndata.length == 0 && target.code.length == 0) {\n                revert AddressEmptyCode(target);\n            }\n            return returndata;\n        }\n    }\n\n    /**\n     * @dev Tool to verify that a low level call was successful, and reverts if it wasn't, either by bubbling the\n     * revert reason or with a default {FailedInnerCall} error.\n     */\n    function verifyCallResult(bool success, bytes memory returndata) internal pure returns (bytes memory) {\n        if (!success) {\n            _revert(returndata);\n        } else {\n            return returndata;\n        }\n    }\n\n    /**\n     * @dev Reverts with returndata if present. Otherwise reverts with {FailedInnerCall}.\n     */\n    function _revert(bytes memory returndata) private pure {\n        // Look for revert reason and bubble it up if present\n        if (returndata.length > 0) {\n            // The easiest way to bubble the revert reason is using memory via assembly\n            /// @solidity memory-safe-assembly\n            assembly {\n                let returndata_size := mload(returndata)\n                revert(add(32, returndata), returndata_size)\n            }\n        } else {\n            revert FailedInnerCall();\n        }\n    }\n}\n"
      },
      "@openzeppelin/contracts/utils/Context.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (utils/Context.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n    function _msgSender() internal view virtual returns (address) {\n        return msg.sender;\n    }\n\n    function _msgData() internal view virtual returns (bytes calldata) {\n        return msg.data;\n    }\n}\n"
      },
      "@openzeppelin/contracts/utils/introspection/ERC165.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.20;\n\nimport {IERC165} from \"./IERC165.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n *     return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n */\nabstract contract ERC165 is IERC165 {\n    /**\n     * @dev See {IERC165-supportsInterface}.\n     */\n    function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) {\n        return interfaceId == type(IERC165).interfaceId;\n    }\n}\n"
      },
      "@openzeppelin/contracts/utils/introspection/IERC165.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165 {\n    /**\n     * @dev Returns true if this contract implements the interface defined by\n     * `interfaceId`. See the corresponding\n     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n     * to learn more about how these ids are created.\n     *\n     * This function call must use less than 30 000 gas.\n     */\n    function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n"
      },
      "contracts/base/auth/AccessControlDS.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.22;\n\nimport {AccessControl} from \"@openzeppelin/contracts/access/AccessControl.sol\";\nimport {OwnableReadonlyDS} from \"./OwnableReadonlyDS.sol\";\n\nabstract contract AccessControlDS is AccessControl, OwnableReadonlyDS {\n    function hasRole(bytes32 _role, address _account) public view virtual override returns (bool) {\n        return (isOwnerRole(_role) && _owner() == _account) || super.hasRole(_role, _account);\n    }\n\n    function isOwnerRole(bytes32 _role) private pure returns (bool) {\n        return _role == DEFAULT_ADMIN_ROLE;\n    }\n}\n"
      },
      "contracts/base/auth/OwnableReadonly.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.22;\n\nimport {UnauthorizedAccount} from \"contracts/interfaces/base/CommonErrors.sol\";\nimport {Address} from \"contracts/libraries/Address.sol\";\n\n/**\n * @dev We intentionally do not expose \"owner()\" publicly\n * due to possible conflicts with \"OwnershipFacet\"\n * https://github.com/mudgen/diamond-3-hardhat/blob/main/contracts/facets/OwnershipFacet.sol\n */\nabstract contract OwnableReadonly {\n    using Address for bytes32;\n\n    modifier onlyOwner() {\n        enforceIsContractOwner();\n        _;\n    }\n\n    function _owner() internal view returns (address) {\n        return _ownerSlot().get();\n    }\n\n    function _ownerSlot() internal pure virtual returns (bytes32);\n\n    function enforceIsContractOwner() private view {\n        if (msg.sender != _owner()) revert UnauthorizedAccount(msg.sender);\n    }\n}\n"
      },
      "contracts/base/auth/OwnableReadonlyDS.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.22;\n\nimport {DiamondLibrary} from \"contracts/libraries/DiamondLibrary.sol\";\nimport {OwnableReadonly} from \"./OwnableReadonly.sol\";\n\n/**\n * @notice Use DiamondStorage's owner slot for OwnableReadonly\n */\nabstract contract OwnableReadonlyDS is OwnableReadonly {\n    function _ownerSlot() internal pure override returns (bytes32 slot_) {\n        DiamondLibrary.DiamondStorage storage ds = DiamondLibrary.diamondStorage();\n        assembly {\n            // DiamondLib will not change so it's safe to hardcode owner offset here\n            let ownerOffsetInDiamondStorage := 4\n            slot_ := add(ds.slot, ownerOffsetInDiamondStorage)\n        }\n    }\n}\n"
      },
      "contracts/base/StateMachine.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.22;\n\nimport {LibBit} from \"solady/src/utils/LibBit.sol\";\n\ntype State is uint256;\n\nusing {and as &, neq as !=, eq as ==, or as |, includes, isInitialized, isValid} for State global;\n\nfunction and(State self, State value) pure returns (State) {\n    return State.wrap(State.unwrap(self) & State.unwrap(value));\n}\n\nfunction neq(State self, State value) pure returns (bool) {\n    return State.unwrap(self) != State.unwrap(value);\n}\n\nfunction eq(State self, State value) pure returns (bool) {\n    return State.unwrap(self) == State.unwrap(value);\n}\n\nfunction or(State self, State value) pure returns (State) {\n    return State.wrap(State.unwrap(self) | State.unwrap(value));\n}\n\nfunction includes(State bitmap, State state) pure returns (bool) {\n    return State.unwrap(bitmap) & State.unwrap(state) != 0;\n}\n\nfunction isInitialized(State self) pure returns (bool answer_) {\n    return State.unwrap(self) != 0;\n}\n\nfunction isValid(State self) pure returns (bool) {\n    // most significant bit is reserved for the undefined state\n    uint256 mask = 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff;\n    return LibBit.isPo2(State.unwrap(self) & mask);\n}\n\nabstract contract StateMachine {\n    struct Storage {\n        State currentState;\n        mapping(bytes32 transitionId => function(bytes memory) internal transition) transitions;\n    }\n\n    // Undefined state cannot be zero because it will break bitmap comparison math in `onlyState`\n    State internal immutable STATE_UNDEFINED = newStateFromIdUnchecked(STATE_UNDEFINED_ID); // solhint-disable-line immutable-vars-naming\n\n    uint8 private constant STATE_UNDEFINED_ID = type(uint8).max;\n    bytes32 private constant STORAGE_SLOT = keccak256(\"StateMachine storage slot V1\");\n\n    event StateChanged(State from, State to);\n\n    error TransitionAlreadyExists(State from, State to);\n    error TransitionDoesNotExist(State from, State to);\n\n    error UnexpectedState(State expectedStatesBitmap, State currentState);\n    // A valid state must be in form of 2^n, where n ∈ {x | x ∈ uint8, x < STATE_UNDEFINED_ID}.\n    error InvalidState(State);\n    error IdIsReservedForUndefinedState(uint256);\n\n    modifier onlyState(State _expectedStatesBitmap) {\n        if (!_expectedStatesBitmap.includes(currentState()))\n            revert UnexpectedState(_expectedStatesBitmap, currentState());\n        _;\n    }\n\n    function createTransition(\n        State _from,\n        State _to,\n        function(bytes memory) internal _transition\n    ) internal {\n        bytes32 id = getTransitionId(_from, _to);\n        if (isTransitionExists(id)) revert TransitionAlreadyExists(_from, _to);\n\n        _storage().transitions[id] = _transition;\n    }\n\n    function deleteTransition(State _from, State _to) internal {\n        bytes32 id = getTransitionId(_from, _to);\n        if (!isTransitionExists(id)) revert TransitionDoesNotExist(_from, _to);\n\n        delete _storage().transitions[id];\n    }\n\n    function changeState(State _newState) internal {\n        changeState(_newState, \"\");\n    }\n\n    function changeState(State _newState, bytes memory _transitionArgs) internal {\n        if (!_newState.isValid()) revert InvalidState(_newState);\n\n        bytes32 id = getTransitionId(currentState(), _newState);\n        if (!isTransitionExists(id)) revert TransitionDoesNotExist(currentState(), _newState);\n\n        _storage().transitions[id](_transitionArgs);\n\n        emit StateChanged(currentState(), _newState);\n        _storage().currentState = _newState;\n    }\n\n    function isTransitionExists(State _from, State _to) internal view returns (bool) {\n        return isTransitionExists(getTransitionId(_from, _to));\n    }\n\n    function currentState() internal view returns (State currentState_) {\n        currentState_ = _storage().currentState;\n        // We substitute 0 with STATE_UNDEFINED here in order to avoid storage\n        // initialization with default value to save gas\n        if (!currentState_.isInitialized()) return currentState_ = STATE_UNDEFINED;\n    }\n\n    function newStateFromId(uint8 _stateId) internal pure returns (State) {\n        if (_stateId == STATE_UNDEFINED_ID) revert IdIsReservedForUndefinedState(_stateId);\n        return newStateFromIdUnchecked(_stateId);\n    }\n\n    function isTransitionExists(bytes32 _transitionId) private view returns (bool exists_) {\n        mapping(bytes32 => function(bytes memory) internal) storage map = _storage().transitions;\n        assembly {\n            // we won't use this memory location after keccak so it's safe to use 0x00 and 0x20\n            mstore(0x00, _transitionId)\n            mstore(0x20, map.slot)\n            let position := keccak256(0x00, 64)\n            // callback = map[_transition]\n            let callback := sload(position)\n            // exists_ = callback != null\n            exists_ := iszero(iszero(callback))\n        }\n    }\n\n    function getTransitionId(State _from, State _to) private view returns (bytes32) {\n        if (_from != STATE_UNDEFINED && !_from.isValid()) revert InvalidState(_from);\n        if (!_to.isValid()) revert InvalidState(_to);\n        return keccak256(abi.encodePacked(_from, _to));\n    }\n\n    function newStateFromIdUnchecked(uint8 _stateId) private pure returns (State) {\n        return State.wrap(1 << _stateId);\n    }\n\n    function _storage() private pure returns (Storage storage s_) {\n        bytes32 slot = STORAGE_SLOT;\n        assembly {\n            s_.slot := slot\n        }\n    }\n}\n"
      },
      "contracts/interfaces/accountAbstraction/compliance/Asset.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.22;\n\nimport {AssetLibrary} from \"contracts/libraries/AssetLibrary.sol\";\n\n/**\n * @title Asset\n * @dev Represents an asset with its token address and the amount.\n * @param token The address of the asset's token.\n * @param amount The amount of the asset.\n */\nstruct Asset {\n    address token;\n    uint256 amount;\n}\n\nusing AssetLibrary for Asset global;\n"
      },
      "contracts/interfaces/accountAbstraction/compliance/IWhitelistingController.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.22;\n\n/**\n * @title Status\n * @notice Enum representing status of a record (e.g., token, protocol, operator)\n *  used for operation validation.\n * @notice Validators must adhere to the following rules for different operations and contexts:\n *  1) For exchanges: `operator`, `pool`, and `input token` *MAY* be either supported or suspended, but the `output token` *MUST* be supported.\n *  2) For deposits: `operator`, `pool`, and every `token` in the `pool` *MUST* be supported.\n *  3) For withdrawals: `operator`, `pool`, and each `token` *MAY* be either supported or suspended.\n *\n * @dev **Note** that deposit denotes **all** ways of aquiring liquidity such\n * as token deposit, LP tokens stake, NFT mint etc.\n */\nenum Status {\n    Undefined,\n    Supported,\n    Suspended\n}\n\n/**\n * @title WhitelistingAddressRecord\n * @notice A struct to store an address and its support status.\n * @dev This struct stores an address and its support status.\n * @dev `source`: The address to be stored.\n * @dev `supported`: Indicates whether the address is supported or not.\n */\nstruct WhitelistingAddressRecord {\n    address source;\n    bool supported;\n}\n\n/**\n * @title TokenPermission\n * @notice This enum represents different levels of permission for a token, including trading, collateral, leverage, and full access.\n * @dev `None`: Represents no permissions granted for the token.\n * @dev `TradeOnly`: Represents the lowest permission level where you can only trade the token.\n * @dev `Collateral`: Allows you to use the token as collateral.\n * @dev `Leverage`: Allows you to leverage the token.\n * @dev `FullAccess`: Represents the highest permission level where you have full access to trade, use as collateral, and leverage the token.\n */\nenum TokenPermission {\n    None,\n    TradeOnly,\n    Collateral,\n    Leverage,\n    FullAccess\n}\n\n/**\n * @title WhitelistingTokenRecord\n * @notice This struct stores an address and its support status for whitelisting, collateral and leverage.\n * @dev `source`: The address of the token.\n * @dev `supported`: Whether the token can be received from a protocol trades.\n * @dev `permission`: Level of [`TokenPermission`](./enum.TokenPermission.html).\n */\nstruct WhitelistingTokenRecord {\n    address source;\n    bool supported;\n    TokenPermission permission;\n}\n\n/**\n * @notice An error indicating that a token is not supported by the whitelisting controller.\n * @dev This error is thrown when an unsupported token is used.\n * @dev `token`: The address of the unsupported token.\n */\nerror TokenIsNotSupported(address token);\n\n/**\n * @notice An error indicating that a token is suspended by the whitelisting controller.\n * @dev This error is thrown when a suspended token is used.\n * @dev `token`: The address of the suspended token.\n */\nerror TokenIsSuspended(address token);\n\n/**\n * @notice An error indicating that the token's permission level is insufficient for the requested action.\n * @dev This can be thrown at [`IWhitelistingController.enforceTokenHasPermission()`](./interface.IWhitelistingController.html#enforcetokenhaspermission)\n * @param token The address of the token that has insufficient permissions.\n * @param required The required permission level for the action.\n * @param actual The actual permission level of the token.\n */\nerror TokenLevelInsufficient(address token, TokenPermission required, TokenPermission actual);\n\n/**\n * @notice An error indicating that an operator is not supported by the whitelisting controller.\n * @dev This error is thrown when an unsupported operator is used.\n * @dev `operator`: The address of the unsupported operator.\n */\nerror OperatorIsNotSupported(address operator);\n\n/**\n * @notice An error indicating that an operator is suspended by the whitelisting controller.\n * @dev This error is thrown when a suspended operator is used.\n * @dev `operator`: The address of the suspended operator.\n */\nerror OperatorIsSuspended(address operator);\n\n/**\n * @notice An error indicating that a protocol is not supported by the whitelisting controller.\n * @dev This error is thrown when an unsupported protocol is used.\n * @dev `protocol`: The identification string of the unsupported protocol.\n */\nerror ProtocolIsNotSupported(string protocol);\n\n/**\n * @notice An error indicating that a protocol is suspended by the whitelisting controller.\n * @dev This error is thrown when a suspended protocol is used.\n * @dev `protocol`: The identification string of the unsupported protocol.\n */\nerror ProtocolIsSuspended(string protocol);\n\n/**\n * @title IWhitelistingController\n * @notice Interface for managing whitelisting of tokens, protocols, and operators.\n */\ninterface IWhitelistingController {\n    /**\n     * @dev Emitted when the support status of a protocol changes.\n     * @dev `protocol`: The identification string of the protocol.\n     * @dev `supported`: Whether the protocol is supported or not.\n     */\n    event ProtocolSupportChanged(string indexed protocol, bool supported);\n\n    /**\n     * @dev Emitted when the support status of a token changes.\n     * @dev `token`: The address of the token.\n     * @dev `supported`: Whether the token is supported or not.\n     * @dev `permission`: Level of [`TokenPermission`](./enum.TokenPermission.html).\n     */\n    event TokenSupportChanged(address indexed token, bool supported, TokenPermission permission);\n\n    /**\n     * @dev Emitted when the support status of an operator changes for a specific protocol.\n     * @dev `protocol`: The identification string of the protocol.\n     * @dev `operator`: The address of the operator.\n     * @dev `supported`: Whether the operator is supported or not.\n     */\n    event OperatorSupportChanged(string indexed protocol, address indexed operator, bool supported);\n\n    /**\n     * @notice Update the support status of multiple tokens.\n     * @dev Emits a [`TokenSupportChanged()`](#tokensupportchanged) event for each token whose status changed.\n     * @dev Reverts with an [`AlreadyUpToDate()`](/interfaces/base/CommonErrors.sol/error.AlreadyUpToDate.html)\n     *  error if no token status changed.\n     * @param _tokens An array of [`WhitelistingTokenRecord`](./struct.WhitelistingTokenRecord.html)\n     * structs containing token addresses, support statuses and permissions.\n     */\n    function updateTokensSupport(WhitelistingTokenRecord[] calldata _tokens) external;\n\n    /**\n     * @notice Update the support status of a protocol.\n     * @dev Emits a [`ProtocolSupportChanged()`](#protocolsupportchanged) event.\n     * @dev Reverts with an [`AlreadyUpToDate()`](/interfaces/base/CommonErrors.sol/error.AlreadyUpToDate.html)\n     *  error if protocol status is up to date.\n     * @param _protocol The identification string of the protocol.\n     * @param _adapterEvaluator The address of the adapter evaluator for the protocol.\n     * @param _supported Whether the protocol is supported or not.\n     */\n    function updateProtocolSupport(\n        string calldata _protocol,\n        address _adapterEvaluator,\n        bool _supported\n    ) external;\n\n    /**\n     * @notice Update the support status of multiple operators for a specific protocol.\n     * @dev Emits a [`OperatorSupportChanged()`](#operatorsupportchanged) event for each token whose status changed.\n     * @dev Reverts with an [`AlreadyUpToDate()`](/interfaces/base/CommonErrors.sol/error.AlreadyUpToDate.html)\n     *  error if no operator status changed.\n     * @param _protocol The identification string of the protocol.\n     * @param _operators An array of `WhitelistingAddressRecord` structs containing operator addresses and support statuses.\n     */\n    function updateOperatorsSupport(\n        string calldata _protocol,\n        WhitelistingAddressRecord[] calldata _operators\n    ) external;\n\n    /**\n     * @notice Ensures that a token has the specified permission level.\n     * @dev This check does not enforce exact match, but only that level is sufficient.\n     *  So if `permission` is TokenPermission.TradeOnly and the token has TokenPermission.Collateral\n     *  then it assumes that level is sufficient since Collateral level includes both\n     *  TradeOnly and Collateral levels.\n     * @param token The address of the token to check for permission.\n     * @param permission The required [`TokenPermission`](TokenPermission) to be enforced.\n     */\n    function enforceTokenHasPermission(address token, TokenPermission permission) external view;\n\n    /**\n     * @notice Returns the support status of a token as well as it's permissions.\n     * @param _token The address of the token.\n     * @return The [`Status`](./enum.Status.html)\n     * of the token.\n     * @return The [`TokenPermission`](./enum.TokenPermission.html)\n     * of the token.\n     */\n    function getTokenSupport(address _token) external view returns (Status, TokenPermission);\n\n    /**\n     * @notice Returns the support status of a protocol.\n     * @param _protocol The identification string of the protocol.\n     * @return The [`Status`](./enum.Status.html)\n     *  of the protocol.\n     */\n    function getProtocolStatus(string calldata _protocol) external view returns (Status);\n\n    /**\n     * @notice Returns the address of the adapter evaluator for a protocol.\n     * @param _protocol The identification string of the protocol.\n     * @return The address of the adapter evaluator for the protocol.\n     */\n    function getProtocolEvaluator(string calldata _protocol) external view returns (address);\n\n    /**\n     * @notice Returns the support status of an operator for a specific protocol.\n     * @param _operator The address of the operator.\n     * @return operatorStatus_ The [`Status`](./enum.Status.html)\n     *  of the operator.\n     * @return protocolStatus_ The [`Status`](./enum.Status.html)\n     *  of the protocol.\n     */\n    function getOperatorStatus(\n        address _operator\n    ) external view returns (Status operatorStatus_, Status protocolStatus_);\n}\n"
      },
      "contracts/interfaces/accountAbstraction/interpreter/adapters/IDecreasePositionEvaluator.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.22;\n\nimport {Asset} from \"contracts/libraries/AssetLibrary.sol\";\nimport {Command} from \"../Command.sol\";\nimport {PositionDescriptor} from \"./PositionDescriptor.sol\";\n\ninterface IDecreasePositionEvaluator {\n    /**\n     * @notice Request structure for decreasing a position.\n     * @dev `descriptor`: The [`PositionDescriptor`](/interfaces/accountAbstraction/interpreter/adapters/PositionDescriptor.sol/struct.PositionDescriptor.html)\n     *  struct.\n     * @dev `liquidity`: Abstract amount that can be interpreted differently in different protocols (e.g., amount of LP tokens to burn).\n     * @dev `minOutput`: [`Asset`](/interfaces/accountAbstraction/compliance/Asset.sol/struct.Asset.html) array with minimum amounts that must be retrieved from the position.\n     */\n    struct DecreasePositionRequest {\n        PositionDescriptor descriptor;\n        uint256 liquidity;\n        Asset[] minOutput;\n    }\n\n    /**\n     * @notice Evaluate a decrease position request.\n     * @param _operator Address which initiated the request\n     * @param _request The [`DecreasePositionRequest`](#decreasepositionrequest) struct containing decrease position details.\n     * @return cmds_ An array of [`Command`](../../Command.sol/struct.Command.html) to execute the request.\n     */\n    function evaluate(\n        address _operator,\n        DecreasePositionRequest calldata _request\n    ) external returns (Command[] memory cmds_);\n}\n"
      },
      "contracts/interfaces/accountAbstraction/interpreter/adapters/IExchangeEvaluator.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.22;\n\nimport {Command} from \"../Command.sol\";\n\n/**\n * @title IExchangeEvaluator\n * @notice Interface for compiling commands for token exchanges for different protocols.\n */\ninterface IExchangeEvaluator {\n    /**\n     * @notice Structure for an exchange token request.\n     * @dev `path`: Encoded path of tokens to follow in the exchange, including pool identifiers.\n     * 20 bytes(tokenA) + 4 byte(poolId_A_B) + 20 bytes(tokenB) + ...\n     * ... + 4 byte(poolId_N-1_N) + 20 bytes(tokenN).\n     * @dev `extraData`: Additional data specific to a particular protocol, such as the response from a 1Inch Exchange API.\n     * @dev `amountIn`: The amount of tokenA to spend.\n     * @dev `minAmountOut`: The minimum amount of tokenN to receive.\n     * @dev `recipient`: The recipient of tokenN.\n     */\n    struct ExchangeRequest {\n        bytes path;\n        bytes extraData;\n        uint256 amountIn;\n        uint256 minAmountOut;\n        address recipient;\n    }\n\n    /**\n     * @notice Constructs an exchange token request.\n     * @param _operator Address which initiated the request\n     * @param _request The [`ExchangeRequest`](#exchangerequest) struct containing exchange token details.\n     * @return cmds_ An array of [`Command`](../../Command.sol/struct.Command.html) to execute the request.\n     */\n    function evaluate(\n        address _operator,\n        ExchangeRequest calldata _request\n    ) external view returns (Command[] memory cmds_);\n}\n"
      },
      "contracts/interfaces/accountAbstraction/interpreter/adapters/IIncreasePositionEvaluator.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.22;\n\nimport {Asset} from \"contracts/libraries/AssetLibrary.sol\";\nimport {Command} from \"../Command.sol\";\nimport {PositionDescriptor} from \"./PositionDescriptor.sol\";\n\ninterface IIncreasePositionEvaluator {\n    /**\n     * @notice Structure for an increase position request.\n     * @dev `descriptor`: The [`PositionDescriptor`](/interfaces/accountAbstraction/interpreter/adapters/PositionDescriptor.sol/struct.PositionDescriptor.html)\n     *  struct.\n     * @dev `input`: An array of [`Asset`](/interfaces/accountAbstraction/compliance/Asset.sol/struct.Asset.html) representing the token-amounts that will be added to the position.\n     * @dev `minLiquidityOut`: An abstract amount that can be interpreted differently in different protocols (e.g., minimum amount of LP tokens to receive).\n     */\n    struct IncreasePositionRequest {\n        PositionDescriptor descriptor;\n        Asset[] input;\n        uint256 minLiquidityOut;\n    }\n\n    /**\n     * @notice Evaluate a increase position request.\n     * @param _operator Address which initiated the request\n     * @param _request The [`IncreasePositionRequest`](#increasepositionrequest) struct containing increase position details.\n     * @return cmds_ An array of [`Command`](../../Command.sol/struct.Command.html) to execute the request.\n     */\n    function evaluate(\n        address _operator,\n        IncreasePositionRequest calldata _request\n    ) external returns (Command[] memory cmds_);\n}\n"
      },
      "contracts/interfaces/accountAbstraction/interpreter/adapters/PositionDescriptor.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.22;\n\n// TODO CRYPTO-145: Possibly move into appropriate interface?\n/**\n * @notice Used to determine the required position for an operation.\n * @dev `poolId`: An identifier that is unique within a single protocol.\n * @dev `extraData`: Additional data used to specify the position, for example\n * this is used in OneInchV5Evaluator to pass swap tx generated via 1inch API.\n */\nstruct PositionDescriptor {\n    uint256 poolId;\n    bytes extraData;\n}\n"
      },
      "contracts/interfaces/accountAbstraction/interpreter/Command.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.22;\n\nimport {CommandLibrary} from \"contracts/libraries/CommandLibrary.sol\";\n\n/**\n * @title Command\n * @notice Contains arguments for a low-level call.\n * @dev This struct allows deferring the call's execution, suspending it by passing it to another function or contract.\n * @dev `target` The address to be called.\n * @dev `value` Value to send in the call.\n * @dev `payload` Encoded call with function selector and arguments.\n */\nstruct Command {\n    address target;\n    uint256 value;\n    bytes payload;\n}\n\nusing CommandLibrary for Command global;\n"
      },
      "contracts/interfaces/accountAbstraction/interpreter/IJitCompiler.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.22;\n\nimport {IDecreasePositionEvaluator} from \"./adapters/IDecreasePositionEvaluator.sol\";\nimport {IExchangeEvaluator} from \"./adapters/IExchangeEvaluator.sol\";\nimport {IIncreasePositionEvaluator} from \"./adapters/IIncreasePositionEvaluator.sol\";\nimport {Command} from \"./Command.sol\";\nimport {Script} from \"./Script.sol\";\n\n/**\n * @title IJitCompiler\n * @notice Compiles a script or an instruction into an array of [Commands](/interfaces/accountAbstraction/interpreter/Command.sol/struct.Command.html) using protocol evaluator matching `protocol` field in the underlying instruction.\n */\ninterface IJitCompiler {\n    /**\n     * @notice Instruction designed to increase:\n     *  1. Caller's magnitude of the position determined by the [PositionDescriptor](../adapters/PositionDescriptor.sol/struct.PositionDescriptor.html).\n     *  2. Callee's balance of token(s).\n     * @notice and decrease:\n     *  1. Caller's balance of token(s).\n     *  2. (*Optional*) callee's supply of the position determined by the [PositionDescriptor](../adapters/PositionDescriptor.sol/struct.PositionDescriptor.html).\n     * @dev This instruction will be evaluated in [IncreasePositionEvaluator](../adapters/IIncreasePositionEvaluator.sol/interface.IIncreasePositionEvaluator.html).\n     * @dev `protocol` The name of the underlying protocol where instruction should be evaluated. For example: `curvefi`, `oneinchv5`\n     * @dev `request` The [`IncreasePositionRequest`](../adapters/IIncreasePositionEvaluator.sol/interface.IIncreasePositionEvaluator.html#increasepositionrequest) containing all information required for instruction evaluation.\n     */\n    struct IncreasePositionInstruction {\n        string protocol;\n        IIncreasePositionEvaluator.IncreasePositionRequest request;\n    }\n\n    /**\n     * @notice Instruction designed to increase:\n     *  1. Caller's balance of token(s).\n     *  2. (*Optional*) callee's supply of the position determined by the [PositionDescriptor](../adapters/PositionDescriptor.sol/struct.PositionDescriptor.html).\n     * @notice and decrease:\n     *  1. Caller's magnitude of the position determined by the [PositionDescriptor](../adapters/PositionDescriptor.sol/struct.PositionDescriptor.html).\n     *  2. Callee's balance of token(s).\n     * @dev This instruction will be evaluated in [DecreasePositionEvaluator](../adapters/IDecreasePositionEvaluator.sol/interface.IDecreasePositionEvaluator.html).\n     * @dev `protocol` The name of the underlying protocol where instruction should be evaluated. For example: `curvefi`, `oneinchv5`\n     * @dev `request` The [`DecreasePositionRequest`](../adapters/IDecreasePositionEvaluator.sol/interface.IDecreasePositionEvaluator.html#decreasepositionrequest) containing all information required for instruction evaluation.\n     */\n    struct DecreasePositionInstruction {\n        string protocol;\n        IDecreasePositionEvaluator.DecreasePositionRequest request;\n    }\n\n    /**\n     * @notice Instruction designed to increase:\n     *  1. (*Optional*) caller's balance of output token.\n     *  2. Callee's balance of input token.\n     * @notice and decrease:\n     *  1. Caller's balance of input token.\n     *  2. (*Optional*) callee's balance of output token.\n     * @dev This instruction will be evaluated in [ExchangeEvaluator](../adapters/IExchangeEvaluator.sol/interface.IExchangeEvaluator.html).\n     * @dev `protocol` The name of the underlying protocol where instruction should be evaluated. For example: `curvefi`, `oneinchv5`\n     * @dev `request` The [`ExchangeRequest`](../adapters/IExchangeEvaluator.sol/interface.IExchangeEvaluator.html#exchangerequest) containing all information required for instruction evaluation.\n     */\n    struct ExchangeInstruction {\n        string protocol;\n        IExchangeEvaluator.ExchangeRequest request;\n    }\n\n    /**\n     * @notice Instruction designed to increase:\n     *  1. (*Optional*) caller's balance of output token.\n     *  2. Callee's balance of input token.\n     * @notice and decrease:\n     *  1. Caller's balance of input token.\n     *  2. (*Optional*) callee's balance of output token.\n     * @dev This instruction will be evaluated in [ExchangeEvaluator](../adapters/IExchangeEvaluator.sol/interface.IExchangeEvaluator.html).\n     * @dev **Important note:** this instruction has an identical structure to [ExchangeInstruction](#exchangeinstruction), but differs from it in that [ExchangeInstruction](#exchangeinstruction) is static and [ExchangeAllInstruction](#exchangeallinstruction) is dynamic. This means that the `amountIn` field will be set at runtime by the compiler to the caller's balance by the input token.\n     * @dev `protocol` The name of the underlying protocol where instruction should be evaluated. For example: `curvefi`, `oneinchv5`\n     * @dev `request` The [`ExchangeRequest`](../adapters/IExchangeEvaluator.sol/interface.IExchangeEvaluator.html#exchangerequest) containing all information required for instruction evaluation. The `amountIn` field will be set at runtime by the compiler to the caller's balance by the input token.\n     */\n    struct ExchangeAllInstruction {\n        string protocol;\n        IExchangeEvaluator.ExchangeRequest request;\n    }\n\n    /**\n     * @notice Compiles a [Script](../Script.sol/struct.Script.html).\n     * @dev **Important note:** don't put two instructions to the same script if one depend on the other because content of the script will be compiled at once meaning that balance changes will be applied only after the compilation of the entire script. If you have two instructions and one depends on the other, put them into different scripts.\n     * @param script Script to compile\n     * @return An array of [`Commands`](../Command.sol/struct.Command.html) to execute the instruction.\n     */\n    function compile(Script calldata script) external returns (Command[] memory);\n\n    /**\n     * @notice Compiles an increase position instruction.\n     * @param instruction The [`IncreasePositionInstruction`](#increasepositioninstruction) struct.\n     * @return An array of [`Commands`](../Command.sol/struct.Command.html) to execute the instruction.\n     */\n    function compileIncreasePositionInstruction(\n        IncreasePositionInstruction calldata instruction\n    ) external returns (Command[] memory);\n\n    /**\n     * @notice Compiles a decrease position instruction.\n     * @param instruction The [`DecreasePositionInstruction`](#decreasepositioninstruction) struct.\n     * @return An array of [`Commands`](../Command.sol/struct.Command.html) to execute the instruction.\n     */\n    function compileDecreasePositionInstruction(\n        DecreasePositionInstruction calldata instruction\n    ) external returns (Command[] memory);\n\n    /**\n     * @notice Compiles an exchange instruction.\n     * @param instruction The [`ExchangeInstruction`](#exchangeinstruction) struct.\n     * @return An array of [`Commands`](../Command.sol/struct.Command.html) to execute the instruction.\n     */\n    function compileExchangeInstruction(\n        ExchangeInstruction calldata instruction\n    ) external returns (Command[] memory);\n\n    /**\n     * @notice Sets the `amountIn` field to the balance of the caller by the input token and compiles an underlying exchange instruction.\n     * @dev `amountIn` will be overriden with the balance of the caller by the input token.\n     * @param instruction The [`ExchangeAllInstruction`](#exchangeallinstruction) struct.\n     * @return An array of [`Commands`](../Command.sol/struct.Command.html) to execute the instruction.\n     */\n    function compileExchangeAllInstruction(\n        ExchangeAllInstruction calldata instruction\n    ) external returns (Command[] memory);\n}\n"
      },
      "contracts/interfaces/accountAbstraction/interpreter/Script.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.22;\n\nimport {IJitCompiler} from \"./IJitCompiler.sol\";\n\n/**\n * @title Script\n * @notice A structure defining a script with various instructions for a JIT compiler.\n * @notice The [JIT compiler](../IJitCompiler.sol/interface.IJitCompiler.html) will compile it the following way:\n * 1. Flatten content's instructions arrays into a single-dimensional array: `flattened = [...increasePositionInstructions, ...decreasePositionInstructions, ...exchangeInstructions, ...exchangeAllInstructions]`.\n * 2. Execute `flattened[PC]` where `PC = sequence[i]` where `i` is the index of current loop iteration, starting from `i = 0`.\n * 3. Increment current loop interation index: `i = i + 1`.\n * 4. If `i < length(flattened)` go to step 2.\n * @dev `sequence` Auto-incrementing read-only program counter. Determines the order of execution of the instruction within the script.\n * @dev `increasePositionInstructions` An array of [`IncreasePositionInstructions`](../IJitCompiler.sol/interface.IJitCompiler.html#increasepositioninstruction).\n * @dev `decreasePositionInstructions` An array of [`DecreasePositionInstructions`](../IJitCompiler.sol/interface.IJitCompiler.html#decreasepositioninstruction).\n * @dev `exchangeInstructions` An array of [`ExchangeInstructions`](../IJitCompiler.sol/interface.IJitCompiler.html#exchangeinstruction).\n * @dev `exchangeAllInstructions` An array of [`ExchangeAllInstructions`](../IJitCompiler.sol/interface.IJitCompiler.html#exchangeallinstruction).\n */\nstruct Script {\n    uint256[] sequence;\n    IJitCompiler.IncreasePositionInstruction[] increasePositionInstructions;\n    IJitCompiler.DecreasePositionInstruction[] decreasePositionInstructions;\n    IJitCompiler.ExchangeInstruction[] exchangeInstructions;\n    IJitCompiler.ExchangeAllInstruction[] exchangeAllInstructions;\n}\n"
      },
      "contracts/interfaces/accountAbstraction/marginAccount/IAccount.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.22;\n\nimport {State} from \"contracts/base/StateMachine.sol\";\nimport {Asset} from \"contracts/libraries/AssetLibrary.sol\";\n\nimport {Command} from \"../interpreter/Command.sol\";\nimport {Script} from \"../interpreter/Script.sol\";\n\ninterface IAccount {\n    event AccountRegistered(address indexed owner, Asset[] collateral, Asset leverage);\n    event LeverageSupplied(address indexed owner, uint256 supplied, int256 remaining);\n    event AccountOpened(address indexed owner);\n    event AccountSuspended(address indexed owner);\n    event AccountClosed(address indexed previousOwner);\n\n    /**\n     * @notice Receive Ether and log the transaction.\n     * @dev This function is called when the margin account receives Ether without a specific function call.\n     */\n    receive() external payable;\n\n    /**\n     * @notice After calling this function margin account will be in the registered state\n     * Reverts if either not enough assets were transferred before the call\n     * or the account is in an invalid state\n     * @param user Address that will be assigned as an owner of the account\n     * @param collateral Must be transfered to the account beforehand\n     * @param requestedLeverage Asset that has to be supplied to the account\n     * to switch it's state to the opened\n     */\n    function register(\n        address user,\n        Asset[] calldata collateral,\n        Asset calldata requestedLeverage\n    ) external payable;\n\n    /**\n     * @notice This method is a step of the margin account opening.\n     * Once enough leverage supplied, margin account will be switched to\n     * the opened state\n     * @dev Reverts if either too much leverage is supplied\n     * or account is in an invalid state\n     * @param amount Amount to supply\n     * @return allocationSuccess Whether enought leverage has been supplied\n     * and margin account now ready to use by the owner\n     */\n    function supply(uint256 amount) external payable returns (bool allocationSuccess);\n\n    /**\n     * @notice Immediately switches the account to the suspended state and\n     * tries to execute provided scripts\n     * @dev Reverts if either script's compilation failed in [interpreter](/interfaces/accountAbstraction/interpreter/index.html)\n     * or account's state cannot be switched to the suspended state\n     * @param strategy If all scripts will be executed successfully\n     * the account will be switched to the closed state\n     * @return success Whether the account was switched to the closed state\n     */\n    function tryClose(Script[] calldata strategy) external returns (bool success);\n\n    /**\n     * @notice Allows margin account's owner to execute any low level call\n     * @dev Reverts if either validation failed, call failed or account\n     * is in an invalid state\n     * @param cmd Parameters of the call: target, value and payload.\n     * All the parameters will be validated in validation hub before execution.\n     * All the approvals will performed automatically, owner does not need to\n     * do it manually\n     */\n    function execute(Command calldata cmd) external;\n\n    /**\n     * @notice Returns the owner of the margin account.\n     * @return The address of the the margin account owner.\n     */\n    function owner() external view returns (address);\n\n    /**\n     * @notice Leverage asset allocated (or being allocated) to the account\n     */\n    function leverage() external view returns (address, uint256);\n\n    /**\n     * @return currentState In which state the state machine is running now\n     * @return switchTimestamp Time, when state was switched to the underlying state\n     */\n    function stateInfo() external view returns (State currentState, uint256 switchTimestamp);\n\n    function allocationInfo()\n        external\n        view\n        returns (\n            State currentState,\n            uint256 stateSwitchTimestamp,\n            address owner,\n            address leverageToken,\n            uint256 leverageAmount\n        );\n}\n"
      },
      "contracts/interfaces/accountAbstraction/marginAccount/IAccountFactory.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.22;\n\ninterface IAccountFactory {\n    /// @notice Logged when new margin account is deployed\n    event AccountDeployed(address indexed account);\n    /// @notice Logged every time a margin account being assigned to a new owner\n    event AccountBorrowed(address indexed account);\n    /// @notice Logged every time a margin account being unassigned from the previous owner\n    event AccountReturned(address indexed account);\n\n    /**\n     * @notice Allows *Margin Engine* to borrow an account for registration.\n     * @return Address of the borrowed account.\n     */\n    function borrowAccount() external returns (address);\n\n    /**\n     * @notice After account was closed or liquidated *Margin Engine* returns it to the factory for later reuse.\n     * @param account Address of the account to return.\n     */\n    function returnAccount(address account) external;\n\n    /**\n     * @notice Utility to deploy multiple margin accounts for future use\n     * @param count Number of margin accounts to deploy\n     */\n    function deployMarginAccounts(uint256 count) external;\n}\n"
      },
      "contracts/interfaces/base/CommonErrors.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.22;\n\n/**\n * @notice An error indicating that the amount for the specified token is zero.\n * @param token The address of the token with a zero amount.\n */\nerror AmountMustNotBeZero(address token);\n\n/**\n * @notice An error indicating that an address must not be zero.\n */\nerror AddressMustNotBeZero();\n\n/**\n * @notice An error indicating that an array must not be empty.\n */\nerror ArrayMustNotBeEmpty();\n\n/**\n * @notice An error indicating storage is already up to date and doesn't need further processing.\n * @dev This error is thrown when attempting to update an entity(s) that is(are) already up to date.\n */\nerror AlreadyUpToDate();\n\n/**\n * @notice An error indicating that an action is unauthorized for the specified account.\n * @param account The address of the unauthorized account.\n */\nerror UnauthorizedAccount(address account);\n"
      },
      "contracts/interfaces/marginEngine/Envelope.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.22;\n\nimport {Script} from \"contracts/interfaces/accountAbstraction/interpreter/Script.sol\";\nimport {EnvelopeRunner} from \"contracts/marginEngine/libraries/EnvelopeRunner.sol\";\n\n/**\n * @title Route\n * @notice Part of the [envelope](/interfaces/marginEngine/Envelope.sol/struct.Envelope.html)\n * @notice At **routing** level we define `protocol` name where **content**\n * should be executed as well as through which `protocol` **content** should\n * be delivered to the target ledger if chain did not matched.\n * @dev The `protocol` through which **content** should be delivered.\n * @dev The `destination` chain of the **content**.\n */\nstruct Route {\n    string protocol;\n    string destination;\n}\n\n/**\n * @title Envelope\n * @notice Part of the [syntax tree](/interfaces/marginEngine/index.html#syntax-tree-for-allocation--liquidation)\n * @notice Along with **routing** this struct holds **content** containing\n * [scripts](/interfaces/accountAbstraction/interpreter/Script.sol/struct.Script.html)\n * with actual business logic.\n * @dev The [route](/interfaces/marginEngine/Envelope.sol/struct.Route.html) of the **content**\n * @dev The `content` field holds an array of [`Scripts`](/interfaces/accountAbstraction/interpreter/Script.sol/struct.Script.html)\n * that should be executed at the `route.destination`.\n */\nstruct Envelope {\n    Route route;\n    Script[] content;\n}\n\nusing EnvelopeRunner for Envelope global;\n\n/**\n * @dev Error indicating that cross-chain actions are forbidden.\n */\nerror CrossChainActionIsForbidden();\n"
      },
      "contracts/interfaces/marginEngine/IDispatcher.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.22;\n\nimport {Asset} from \"contracts/libraries/AssetLibrary.sol\";\nimport {Package} from \"./Package.sol\";\n\n/**\n * @title Dispatcher\n * @notice The facade for communication between margin engine backend and margin engine smart contracts module.\n * @notice This contract is responsible for handling [account registration](#registermarginaccount), [leverage allocation](#submitplan), [account close](#tryclosemarginaccount) and [account liquidation](#tryclosemarginaccount).\n */\ninterface IDispatcher {\n    /// @notice Throwed when asset, supplied to a margin account, does not corresponds the account's leverage\n    error InvalidLeverageSupplied(address actual, address expected);\n\n    /**\n     * @notice Ether may be received from _Asset Manager_ during registration and from [`IPool`](/interfaces/liquidityManagement/liquidityPool/IPool.sol/interface.IPool.html) during the allocation.\n     */\n    receive() external payable;\n\n    /**\n     * @notice Assigns and registers a new margin account to the caller.\n     * @notice Collateral will be transferred from `msg.sender` to the account immediately.\n     * After the call the account will be in the `registered` state.\n     * Will revert if either thresholds are not met,\n     * whitelists validation failed, or collateral tokens are not approved to this contract.\n     * @dev [AccountFactory](/interfaces/accountAbstraction/marginAccount/IAccountFactory.sol/interface.IAccountFactory.html)\n     * emits [AccountBorrowed](/interfaces/accountAbstraction/marginAccount/IAccountFactory.sol/interface.IAccountFactory.html#accountborrowed)\n     * (and [AccountDeployed](http://localhost:3000/interfaces/accountAbstraction/marginAccount/IAccountFactory.sol/interface.IAccountFactory.html#accountdeployed) if object pool is empty).\n     * @dev [Account](/interfaces/accountAbstraction/marginAccount/IAccount.sol/interface.IAccount.html) emits\n     * [AccountRegistered](/interfaces/accountAbstraction/marginAccount/IAccount.sol/interface.IAccount.html#accountregistered).\n     */\n    function registerMarginAccount(\n        Asset[] calldata _collateral,\n        Asset calldata _leverage\n    ) external payable returns (address account);\n\n    /**\n     * @notice Executes provided syntax tree.\n     * @dev Will revert **ONLY IF** [script](/interfaces/accountAbstraction/interpreter/Script.sol/struct.Script.html) compilation failed.\n     * @dev Will **NOT** revert if execution of compiled instruction failed.\n     * @param syntaxTree Deterministic set of scripts wrapped in routing envelopes.\n     * `onComplete` callback will be run only if `action` execution was successful.\n     */\n    function submitPlan(Package[] calldata syntaxTree) external;\n\n    /**\n     * @notice Supplies registered margin account with leverage.\n     * @dev Will revert if either account already opened, [invalid leverage token supplied](/interfaces/marginEngine/IDispatcher.sol/interface.IDispatcher.html#invalidleveragesupplied) or too much supplied\n     * @param partialLeverage Full or partial amount of leverage to supply.\n     */\n    function supplyMarginAccount(\n        address payable account,\n        Asset calldata partialLeverage\n    ) external payable;\n\n    /**\n     * @notice Switchs margin account to the `suspended` state and\n     * tries to execute provided plan's action on the account. Can be called\n     * multiple times if the account's closing was not successful\n     * @dev Will not revert if action execution on margin account failed\n     * therefore all the changes from successful scripts will be applied\n     * after transaction. Account will remain in the suspended state and\n     * will wait till successful closing.\n     * @param liquidationPlan `action` will be executed on the account and\n     * `onComplete` callback will be run on this contract (if `action` succeeded).\n     */\n    function tryCloseMarginAccount(\n        address payable account,\n        Package calldata liquidationPlan\n    ) external returns (bool success);\n}\n"
      },
      "contracts/interfaces/marginEngine/Package.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.22;\n\nimport {PackageRunner} from \"contracts/marginEngine/libraries/PackageRunner.sol\";\nimport {Envelope} from \"./Envelope.sol\";\n\n/**\n * @title Package\n * @notice Part of the [syntax tree](/interfaces/marginEngine/index.html#syntax-tree-for-allocation--liquidation)\n * @notice **Automation** part of the syntax tree which defines an `action` with attached to it callback `onComplete`.\n * The callback will only be run if action succeeded.\n * @dev The `action` field represents the primary action in the [`Envelope`](../Envelope.sol/struct.Envelope.html) struct to be executed.\n * @dev The `onComplete` array is composed of [`Envelope`](../Envelope.sol/struct.Envelope.html) structs that will be executed after the primary action completes.\n */\nstruct Package {\n    Envelope action;\n    Envelope[] onComplete;\n}\n\nusing PackageRunner for Package global;\n"
      },
      "contracts/libraries/Address.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.22;\n\nlibrary Address {\n    address internal constant ETH = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;\n\n    function set(bytes32 _slot, address _value) internal {\n        assembly {\n            sstore(_slot, _value)\n        }\n    }\n\n    function get(bytes32 _slot) internal view returns (address result_) {\n        assembly {\n            result_ := sload(_slot)\n        }\n    }\n\n    function isEth(address _token) internal pure returns (bool) {\n        return _token == ETH || _token == address(0);\n    }\n\n    function sort(address _a, address _b) internal pure returns (address, address) {\n        return _a < _b ? (_a, _b) : (_b, _a);\n    }\n\n    function sort(address[4] memory _array) internal pure returns (address[4] memory _sorted) {\n        // Sorting network for the array of length 4\n        (_sorted[0], _sorted[1]) = sort(_array[0], _array[1]);\n        (_sorted[2], _sorted[3]) = sort(_array[2], _array[3]);\n\n        (_sorted[0], _sorted[2]) = sort(_sorted[0], _sorted[2]);\n        (_sorted[1], _sorted[3]) = sort(_sorted[1], _sorted[3]);\n        (_sorted[1], _sorted[2]) = sort(_sorted[1], _sorted[2]);\n    }\n}\n"
      },
      "contracts/libraries/AssetLibrary.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.22;\n\nimport {SafeTransferLib} from \"solady/src/utils/SafeTransferLib.sol\";\n\nimport {Asset} from \"contracts/interfaces/accountAbstraction/compliance/Asset.sol\";\nimport {AmountMustNotBeZero} from \"contracts/interfaces/base/CommonErrors.sol\";\n\nimport {Address} from \"./Address.sol\";\n\nlibrary AssetLibrary {\n    using SafeTransferLib for address;\n    using Address for address;\n\n    error NotEnoughReceived(address token, uint256 expected, uint256 received);\n\n    function forward(Asset calldata _self, address _to) internal {\n        if (_self.amount == 0) revert AmountMustNotBeZero(_self.token);\n\n        if (_self.token.isEth()) _to.safeTransferETH(_self.amount);\n        else _self.token.safeTransferFrom(msg.sender, _to, _self.amount);\n    }\n\n    function enforceReceived(Asset calldata _self) internal view {\n        if (_self.amount == 0) revert AmountMustNotBeZero(_self.token);\n\n        uint256 balance = _self.token.isEth()\n            ? address(this).balance\n            : _self.token.balanceOf(address(this));\n\n        if (balance < _self.amount) revert NotEnoughReceived(_self.token, _self.amount, balance);\n    }\n}\n"
      },
      "contracts/libraries/CommandLibrary.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.22;\n\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport {Command} from \"contracts/interfaces/accountAbstraction/interpreter/Command.sol\";\nimport {SafeCall} from \"contracts/libraries/SafeCall.sol\";\n\n/**\n * @notice Utility to convert often-used methods into a Command object\n */\nlibrary CommandPresets {\n    function approve(\n        address _token,\n        address _to,\n        uint256 _amount\n    ) internal pure returns (Command memory cmd_) {\n        cmd_.target = _token;\n        cmd_.payload = abi.encodeCall(IERC20.approve, (_to, _amount));\n    }\n\n    function transfer(\n        address _token,\n        address _to,\n        uint256 _amount\n    ) internal pure returns (Command memory cmd_) {\n        cmd_.target = _token;\n        cmd_.payload = abi.encodeCall(IERC20.transfer, (_to, _amount));\n    }\n}\n\nlibrary CommandExecutor {\n    using SafeCall for Command[];\n\n    function execute(Command[] calldata _cmds) external {\n        _cmds.safeCallAll();\n    }\n}\n\nlibrary CommandLibrary {\n    using CommandLibrary for Command[];\n\n    function last(Command[] memory _self) internal pure returns (Command memory) {\n        return _self[_self.length - 1];\n    }\n\n    function asArray(Command memory _self) internal pure returns (Command[] memory result_) {\n        result_ = new Command[](1);\n        result_[0] = _self;\n    }\n\n    function concat(\n        Command memory _self,\n        Command memory _cmd\n    ) internal pure returns (Command[] memory result_) {\n        result_ = new Command[](2);\n        result_[0] = _self;\n        result_[1] = _cmd;\n    }\n\n    function concat(\n        Command memory _self,\n        Command[] memory _cmds\n    ) internal pure returns (Command[] memory result_) {\n        result_ = new Command[](_cmds.length + 1);\n        result_[0] = _self;\n        for (uint256 i = 1; i < result_.length; i++) {\n            result_[i] = _cmds[i - 1];\n        }\n    }\n\n    function append(\n        Command[] memory _self,\n        Command[] memory _cmds\n    ) internal pure returns (Command[] memory result_) {\n        result_ = new Command[](_self.length + _cmds.length);\n        uint256 i;\n        for (; i < _self.length; i++) {\n            result_[i] = _self[i];\n        }\n        for (; i < result_.length; i++) {\n            result_[i] = _cmds[i - _self.length];\n        }\n    }\n\n    function push(\n        Command[] memory _self,\n        Command memory _cmd\n    ) internal pure returns (Command[] memory result_) {\n        result_ = new Command[](_self.length + 1);\n        for (uint256 i; i < _self.length; i++) {\n            result_[i] = _self[i];\n        }\n        result_[_self.length] = _cmd;\n    }\n\n    function unshift(\n        Command[] memory _self,\n        Command memory _cmd\n    ) internal pure returns (Command[] memory result_) {\n        result_ = new Command[](1 + _self.length);\n        result_[0] = _cmd;\n        for (uint256 i = 1; i < result_.length; i++) {\n            result_[i] = _self[i - 1];\n        }\n    }\n\n    function unshift(\n        Command[] memory _self,\n        Command[] memory _cmds\n    ) internal pure returns (Command[] memory result_) {\n        result_ = new Command[](_cmds.length + _self.length);\n        uint256 i;\n        for (; i < _cmds.length; i++) {\n            result_[i] = _cmds[i];\n        }\n        for (; i < result_.length; i++) {\n            result_[i] = _self[i - _cmds.length];\n        }\n    }\n\n    function populateWithApprove(\n        Command memory _self,\n        address _token,\n        uint256 _amount\n    ) internal pure returns (Command[] memory result_) {\n        if (_amount != 0) {\n            result_ = CommandPresets.approve(_token, _self.target, _amount).concat(_self);\n        } else {\n            result_ = _self.asArray();\n        }\n    }\n\n    function populateWithRevokeAndApprove(\n        Command memory _self,\n        address _token,\n        uint256 _amount\n    ) internal pure returns (Command[] memory result_) {\n        return\n            CommandPresets.approve(_token, _self.target, 0).concat(\n                _self.populateWithApprove(_token, _amount)\n            );\n    }\n\n    function populateWithApprove(\n        Command[] memory _self,\n        address _token,\n        uint256 _amount\n    ) internal pure returns (Command[] memory result_) {\n        if (_amount != 0) {\n            result_ = _self.unshift(\n                CommandPresets.approve(_token, _self[_self.length - 1].target, _amount)\n            );\n        } else {\n            result_ = _self;\n        }\n    }\n\n    function populateWithApprove(\n        Command memory _self,\n        address[2] memory _tokens,\n        uint256[2] memory _amounts\n    ) internal pure returns (Command[] memory result_) {\n        if (_amounts[0] != 0 && _amounts[1] != 0) {\n            result_ = CommandPresets\n                .approve(_tokens[0], _self.target, _amounts[0])\n                .concat(CommandPresets.approve(_tokens[1], _self.target, _amounts[1]))\n                .push(_self);\n        } else {\n            if (_amounts[0] != 0) {\n                result_ = populateWithApprove(_self, _tokens[0], _amounts[0]);\n            } else {\n                result_ = populateWithApprove(_self, _tokens[1], _amounts[1]);\n            }\n        }\n    }\n\n    function populateWithApprove(\n        Command memory _self,\n        address[3] memory _tokens,\n        uint256[3] memory _amounts\n    ) internal pure returns (Command[] memory result_) {\n        if (_amounts[0] != 0 && _amounts[1] != 0 && _amounts[2] != 0) {\n            result_ = CommandPresets\n                .approve(_tokens[0], _self.target, _amounts[0])\n                .concat(CommandPresets.approve(_tokens[1], _self.target, _amounts[1]))\n                .push(CommandPresets.approve(_tokens[2], _self.target, _amounts[2]))\n                .push(_self);\n        } else {\n            if (_amounts[0] == 0) {\n                result_ = populateWithApprove(\n                    _self,\n                    [_tokens[1], _tokens[2]],\n                    [_amounts[1], _amounts[2]]\n                );\n            } else if (_amounts[1] == 0) {\n                result_ = populateWithApprove(\n                    _self,\n                    [_tokens[0], _tokens[2]],\n                    [_amounts[0], _amounts[2]]\n                );\n            } else {\n                result_ = populateWithApprove(\n                    _self,\n                    [_tokens[0], _tokens[1]],\n                    [_amounts[0], _amounts[1]]\n                );\n            }\n        }\n    }\n\n    function populateWithApprove(\n        Command memory _self,\n        address[4] memory _tokens,\n        uint256[4] memory _amounts\n    ) internal pure returns (Command[] memory result_) {\n        if (_amounts[0] != 0 && _amounts[1] != 0 && _amounts[2] != 0 && _amounts[3] != 0) {\n            result_ = CommandPresets\n                .approve(_tokens[0], _self.target, _amounts[0])\n                .concat(CommandPresets.approve(_tokens[1], _self.target, _amounts[1]))\n                .push(CommandPresets.approve(_tokens[2], _self.target, _amounts[2]))\n                .push(CommandPresets.approve(_tokens[3], _self.target, _amounts[3]))\n                .push(_self);\n        } else {\n            if (_amounts[0] == 0) {\n                result_ = populateWithApprove(\n                    _self,\n                    [_tokens[1], _tokens[2], _tokens[3]],\n                    [_amounts[1], _amounts[2], _amounts[3]]\n                );\n            } else if (_amounts[1] == 0) {\n                result_ = populateWithApprove(\n                    _self,\n                    [_tokens[0], _tokens[2], _tokens[3]],\n                    [_amounts[0], _amounts[2], _amounts[3]]\n                );\n            } else if (_amounts[2] == 0) {\n                result_ = populateWithApprove(\n                    _self,\n                    [_tokens[0], _tokens[1], _tokens[3]],\n                    [_amounts[0], _amounts[1], _amounts[3]]\n                );\n            } else {\n                result_ = populateWithApprove(\n                    _self,\n                    [_tokens[0], _tokens[1], _tokens[2]],\n                    [_amounts[0], _amounts[1], _amounts[2]]\n                );\n            }\n        }\n    }\n}\n"
      },
      "contracts/libraries/DiamondLibrary.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.22;\n\nlibrary DiamondLibrary {\n    struct FacetAddressAndPosition {\n        address facetAddress;\n        uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\n    }\n\n    struct FacetFunctionSelectors {\n        bytes4[] functionSelectors;\n        uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\n    }\n\n    struct DiamondStorage {\n        // maps function selector to the facet address and\n        // the position of the selector in the facetFunctionSelectors.selectors array\n        mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\n        // maps facet addresses to function selectors\n        mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\n        // facet addresses\n        address[] facetAddresses;\n        // Used to query if a contract implements an interface.\n        // Used to implement ERC-165.\n        mapping(bytes4 => bool) supportedInterfaces;\n        // owner of the contract\n        address contractOwner;\n    }\n\n    bytes32 private constant DIAMOND_STORAGE_POSITION =\n        keccak256(\"diamond.standard.diamond.storage\");\n\n    function diamondStorage() internal pure returns (DiamondStorage storage ds_) {\n        bytes32 position = DIAMOND_STORAGE_POSITION;\n        assembly {\n            ds_.slot := position\n        }\n    }\n}\n"
      },
      "contracts/libraries/SafeCall.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.22;\n\nimport {Address} from \"@openzeppelin/contracts/utils/Address.sol\";\nimport {Command} from \"contracts/interfaces/accountAbstraction/interpreter/Command.sol\";\n\n/**\n * @notice Safe methods performing a low-level calls that revert\n * if the call was not successful\n */\nlibrary SafeCall {\n    using Address for address;\n\n    function safeCallAll(Command[] memory _cmds) internal {\n        for (uint256 i; i < _cmds.length; i++) {\n            safeCall(_cmds[i]);\n        }\n    }\n\n    function safeCall(Command memory _cmd) internal returns (bytes memory result_) {\n        result_ = safeCall(_cmd.target, _cmd.value, _cmd.payload);\n    }\n\n    function safeCall(address _target, bytes memory _data) internal returns (bytes memory result_) {\n        result_ = safeCall(_target, 0, _data);\n    }\n\n    function safeCall(\n        address _target,\n        uint256 _value,\n        bytes memory _data\n    ) internal returns (bytes memory result_) {\n        result_ = _target.functionCallWithValue(_data, _value);\n    }\n\n    function safeDelegateCall(\n        address _target,\n        bytes memory _data\n    ) internal returns (bytes memory result_) {\n        result_ = _target.functionDelegateCall(_data);\n    }\n}\n"
      },
      "contracts/marginEngine/base/ThresholdsVerifier.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.22;\n\nimport {\n    IWhitelistingController,\n    TokenPermission\n} from \"contracts/interfaces/accountAbstraction/compliance/IWhitelistingController.sol\";\nimport {AmountMustNotBeZero, ArrayMustNotBeEmpty} from \"contracts/interfaces/base/CommonErrors.sol\";\nimport {Asset} from \"contracts/libraries/AssetLibrary.sol\";\n\nabstract contract ThresholdsVerifier {\n    IWhitelistingController internal immutable compliance;\n\n    constructor(address _compliance) {\n        compliance = IWhitelistingController(_compliance);\n    }\n\n    function verifyThresholds(\n        Asset[] calldata _collateral,\n        Asset calldata _leverage\n    ) internal view {\n        compliance.enforceTokenHasPermission(_leverage.token, TokenPermission.Leverage);\n        if (_leverage.amount == 0) revert AmountMustNotBeZero(_leverage.token);\n\n        if (_collateral.length == 0) revert ArrayMustNotBeEmpty();\n\n        for (uint256 i; i < _collateral.length; i++) {\n            Asset calldata c = _collateral[i];\n            compliance.enforceTokenHasPermission(c.token, TokenPermission.Collateral);\n            if (c.amount == 0) revert AmountMustNotBeZero(c.token);\n        }\n    }\n}\n"
      },
      "contracts/marginEngine/Dispatcher.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.22;\n\nimport {IAccount} from \"contracts/interfaces/accountAbstraction/marginAccount/IAccount.sol\";\nimport {\n    IAccountFactory\n} from \"contracts/interfaces/accountAbstraction/marginAccount/IAccountFactory.sol\";\nimport {Asset, IDispatcher} from \"contracts/interfaces/marginEngine/IDispatcher.sol\";\n\nimport {AccessControlDS} from \"contracts/base/auth/AccessControlDS.sol\";\n\nimport {ThresholdsVerifier} from \"./base/ThresholdsVerifier.sol\";\nimport {\n    CrossChainActionIsForbidden,\n    Envelope,\n    EnvelopeRunner,\n    Package\n} from \"./libraries/PackageRunner.sol\";\n\ncontract Dispatcher is IDispatcher, AccessControlDS, ThresholdsVerifier {\n    using EnvelopeRunner for Envelope[];\n\n    address private immutable interpreter;\n    bytes32 private immutable chainNameHash;\n    IAccountFactory private immutable factory;\n\n    bytes32 public constant MARGIN_ENGINE_AUTHORITY = keccak256(\"Margin Engine Authority\");\n    bytes32 public constant MARGIN_ACCOUNT_SUPPLIER = keccak256(\"Margin Account Supplier\");\n\n    constructor(\n        address _interpreter,\n        address _factory,\n        string memory _chainName\n    ) ThresholdsVerifier(_interpreter) {\n        interpreter = _interpreter;\n        chainNameHash = keccak256(bytes(_chainName));\n        factory = IAccountFactory(_factory);\n    }\n\n    receive() external payable override {}\n\n    function registerMarginAccount(\n        Asset[] calldata _collateral,\n        Asset calldata _leverage\n    ) external payable override returns (address account) {\n        verifyThresholds(_collateral, _leverage);\n\n        account = factory.borrowAccount();\n\n        for (uint256 i; i < _collateral.length; i++) {\n            _collateral[i].forward(account);\n        }\n\n        IAccount(payable(account)).register(msg.sender, _collateral, _leverage);\n    }\n\n    function submitPlan(\n        Package[] calldata _plan\n    ) external override onlyRole(MARGIN_ENGINE_AUTHORITY) {\n        for (uint256 i; i < _plan.length; i++) {\n            _plan[i].run(interpreter, chainNameHash);\n        }\n    }\n\n    function supplyMarginAccount(\n        address payable _account,\n        Asset calldata partialLeverage\n    ) external payable override onlyRole(MARGIN_ACCOUNT_SUPPLIER) {\n        IAccount account = IAccount(_account);\n\n        (address expected, ) = account.leverage();\n        address supplying = partialLeverage.token;\n        if (supplying != expected) revert InvalidLeverageSupplied(supplying, expected);\n\n        partialLeverage.forward(_account);\n        account.supply(partialLeverage.amount);\n    }\n\n    function tryCloseMarginAccount(\n        address payable _account,\n        Package calldata _liquidationPlan\n    ) external override onlyRole(MARGIN_ENGINE_AUTHORITY) returns (bool success_) {\n        if (!_liquidationPlan.action.isChainEq(chainNameHash)) revert CrossChainActionIsForbidden();\n\n        IAccount account = IAccount(_account);\n\n        if (success_ = account.tryClose(_liquidationPlan.action.content)) {\n            factory.returnAccount(address(account));\n            success_ = _liquidationPlan.onComplete.run(interpreter, chainNameHash) == 0;\n        }\n    }\n}\n"
      },
      "contracts/marginEngine/libraries/EnvelopeRunner.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.22;\n\nimport {\n    IJitCompiler,\n    Script\n} from \"contracts/interfaces/accountAbstraction/interpreter/IJitCompiler.sol\";\nimport {\n    CrossChainActionIsForbidden,\n    Envelope\n} from \"contracts/interfaces/marginEngine/Envelope.sol\";\nimport {Command, CommandExecutor} from \"contracts/libraries/CommandLibrary.sol\";\n\nlibrary EnvelopeRunner {\n    using CommandExecutor for Command[];\n\n    /**\n     * @dev This error should never happen, it is needed\n     * for preventing underestimation on \"eth_estimateGas\".\n     */\n    error OutOfGas();\n\n    function run(\n        Envelope[] calldata self,\n        address jitCompiler,\n        bytes32 chainNameHash\n    ) internal returns (uint256 numberOfFailures) {\n        for (uint256 i; i < self.length; i++) {\n            numberOfFailures += self[i].run(jitCompiler, chainNameHash) ? 0 : 1;\n        }\n    }\n\n    function run(\n        Envelope calldata self,\n        address jitCompiler,\n        bytes32 chainNameHash\n    ) internal returns (bool success) {\n        IJitCompiler compiler = IJitCompiler(jitCompiler);\n\n        if (self.isChainEq(chainNameHash)) {\n            for (uint256 i; i < self.content.length; i++) {\n                Script calldata script = self.content[i];\n                Command[] memory cmds = compiler.compile(script);\n                uint256 gasBefore = gasleft();\n                // solhint-disable-next-line no-empty-blocks\n                try cmds.execute() {} catch {\n                    // NOTE: Since we allow silent fail here, this revert is\n                    // required to prevent the underestimation of gas in the\n                    // context of EIP-150. The \"all but one 64th\" rule, along\n                    // with the way most clients estimate gas, may produce an\n                    // out-of-gas error at the callee contract but success at\n                    // the caller contract. For example, if we have a single\n                    // instruction to execute, and after executing this\n                    // instruction, the remaining work will consume 5000 gas,\n                    // the instruction will only receive at most 5000*63 gas.\n                    // Therefore, if the actual requirements are higher, it\n                    // will fail at the random opcode. The remaining work\n                    // will be finished (since we still have at least 5000*1\n                    // gas), and overall transaction success will be achieved,\n                    // making the gas estimator happy.\n                    //\n                    // The proportion for comparing the gasleft (to check that\n                    // the call has not consumed all the gas passed) is in practice\n                    // 1 to 16-32, but we take twice as much just in case.\n                    if (gasleft() < gasBefore / 8) revert OutOfGas();\n                    return success = false;\n                }\n            }\n        } else {\n            revert CrossChainActionIsForbidden();\n        }\n\n        return success = true;\n    }\n\n    function isChainEq(Envelope calldata self, bytes32 chainNameHash) internal pure returns (bool) {\n        return keccak256(bytes(self.route.destination)) == chainNameHash;\n    }\n}\n"
      },
      "contracts/marginEngine/libraries/PackageRunner.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.22;\n\nimport {Package} from \"contracts/interfaces/marginEngine/Package.sol\";\nimport {Command, SafeCall} from \"contracts/libraries/SafeCall.sol\";\nimport {CrossChainActionIsForbidden, Envelope, EnvelopeRunner} from \"./EnvelopeRunner.sol\";\n\nlibrary PackageRunner {\n    using SafeCall for Command[];\n    using EnvelopeRunner for Envelope[];\n\n    function run(\n        Package calldata self,\n        address compiler,\n        bytes32 chainNameHash\n    ) internal returns (uint256 numberOfFailures) {\n        if (self.action.isChainEq(chainNameHash)) {\n            bool actionSuccess = self.action.run(compiler, chainNameHash);\n            if (actionSuccess) {\n                numberOfFailures += self.onComplete.run(compiler, chainNameHash);\n            } else {\n                numberOfFailures++;\n            }\n        } else {\n            revert CrossChainActionIsForbidden();\n        }\n    }\n}\n"
      },
      "solady/src/utils/LibBit.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\n/// @notice Library for bit twiddling and boolean operations.\n/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/LibBit.sol)\n/// @author Inspired by (https://graphics.stanford.edu/~seander/bithacks.html)\nlibrary LibBit {\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                  BIT TWIDDLING OPERATIONS                  */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev Find last set.\n    /// Returns the index of the most significant bit of `x`,\n    /// counting from the least significant bit position.\n    /// If `x` is zero, returns 256.\n    /// Equivalent to `log2(x)`, but without reverting for the zero case.\n    function fls(uint256 x) internal pure returns (uint256 r) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            r := shl(8, iszero(x))\n\n            r := or(r, shl(7, lt(0xffffffffffffffffffffffffffffffff, x)))\n            r := or(r, shl(6, lt(0xffffffffffffffff, shr(r, x))))\n            r := or(r, shl(5, lt(0xffffffff, shr(r, x))))\n\n            // For the remaining 32 bits, use a De Bruijn lookup.\n            x := shr(r, x)\n            x := or(x, shr(1, x))\n            x := or(x, shr(2, x))\n            x := or(x, shr(4, x))\n            x := or(x, shr(8, x))\n            x := or(x, shr(16, x))\n\n            // forgefmt: disable-next-item\n            r := or(r, byte(shr(251, mul(x, shl(224, 0x07c4acdd))),\n                0x0009010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f))\n        }\n    }\n\n    /// @dev Count leading zeros.\n    /// Returns the number of zeros preceding the most significant one bit.\n    /// If `x` is zero, returns 256.\n    function clz(uint256 x) internal pure returns (uint256 r) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            let t := add(iszero(x), 255)\n\n            r := shl(7, lt(0xffffffffffffffffffffffffffffffff, x))\n            r := or(r, shl(6, lt(0xffffffffffffffff, shr(r, x))))\n            r := or(r, shl(5, lt(0xffffffff, shr(r, x))))\n\n            // For the remaining 32 bits, use a De Bruijn lookup.\n            x := shr(r, x)\n            x := or(x, shr(1, x))\n            x := or(x, shr(2, x))\n            x := or(x, shr(4, x))\n            x := or(x, shr(8, x))\n            x := or(x, shr(16, x))\n\n            // forgefmt: disable-next-item\n            r := sub(t, or(r, byte(shr(251, mul(x, shl(224, 0x07c4acdd))),\n                0x0009010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f)))\n        }\n    }\n\n    /// @dev Find first set.\n    /// Returns the index of the least significant bit of `x`,\n    /// counting from the least significant bit position.\n    /// If `x` is zero, returns 256.\n    /// Equivalent to `ctz` (count trailing zeros), which gives\n    /// the number of zeros following the least significant one bit.\n    function ffs(uint256 x) internal pure returns (uint256 r) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            r := shl(8, iszero(x))\n\n            // Isolate the least significant bit.\n            x := and(x, add(not(x), 1))\n\n            r := or(r, shl(7, lt(0xffffffffffffffffffffffffffffffff, x)))\n            r := or(r, shl(6, lt(0xffffffffffffffff, shr(r, x))))\n            r := or(r, shl(5, lt(0xffffffff, shr(r, x))))\n\n            // For the remaining 32 bits, use a De Bruijn lookup.\n            // forgefmt: disable-next-item\n            r := or(r, byte(shr(251, mul(shr(r, x), shl(224, 0x077cb531))), \n                0x00011c021d0e18031e16140f191104081f1b0d17151310071a0c12060b050a09))\n        }\n    }\n\n    /// @dev Returns the number of set bits in `x`.\n    function popCount(uint256 x) internal pure returns (uint256 c) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            let max := not(0)\n            let isMax := eq(x, max)\n            x := sub(x, and(shr(1, x), div(max, 3)))\n            x := add(and(x, div(max, 5)), and(shr(2, x), div(max, 5)))\n            x := and(add(x, shr(4, x)), div(max, 17))\n            c := or(shl(8, isMax), shr(248, mul(x, div(max, 255))))\n        }\n    }\n\n    /// @dev Returns whether `x` is a power of 2.\n    function isPo2(uint256 x) internal pure returns (bool result) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            // Equivalent to `x && !(x & (x - 1))`.\n            result := iszero(add(and(x, sub(x, 1)), iszero(x)))\n        }\n    }\n\n    /// @dev Returns `x` reversed at the bit level.\n    function reverseBits(uint256 x) internal pure returns (uint256 r) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            // Computing masks on-the-fly reduces bytecode size by about 500 bytes.\n            let m := not(0)\n            r := x\n            for { let s := 128 } 1 {} {\n                m := xor(m, shl(s, m))\n                r := or(and(shr(s, r), m), and(shl(s, r), not(m)))\n                s := shr(1, s)\n                if iszero(s) { break }\n            }\n        }\n    }\n\n    /// @dev Returns `x` reversed at the byte level.\n    function reverseBytes(uint256 x) internal pure returns (uint256 r) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            // Computing masks on-the-fly reduces bytecode size by about 200 bytes.\n            let m := not(0)\n            r := x\n            for { let s := 128 } 1 {} {\n                m := xor(m, shl(s, m))\n                r := or(and(shr(s, r), m), and(shl(s, r), not(m)))\n                s := shr(1, s)\n                if eq(s, 4) { break }\n            }\n        }\n    }\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                     BOOLEAN OPERATIONS                     */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev Returns `x & y`.\n    function and(bool x, bool y) internal pure returns (bool z) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            z := and(x, y)\n        }\n    }\n\n    /// @dev Returns `x | y`.\n    function or(bool x, bool y) internal pure returns (bool z) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            z := or(x, y)\n        }\n    }\n\n    /// @dev Returns a non-zero number if `b` is true, else 0.\n    /// If `b` is from plain Solidity, the non-zero number will be 1.\n    function toUint(bool b) internal pure returns (uint256 z) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            z := b\n        }\n    }\n}\n"
      },
      "solady/src/utils/SafeTransferLib.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\n/// @notice Safe ETH and ERC20 transfer library that gracefully handles missing return values.\n/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/SafeTransferLib.sol)\n/// @author Modified from Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/SafeTransferLib.sol)\n/// @dev Caution! This library won't check that a token has code, responsibility is delegated to the caller.\nlibrary SafeTransferLib {\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                       CUSTOM ERRORS                        */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev The ETH transfer has failed.\n    error ETHTransferFailed();\n\n    /// @dev The ERC20 `transferFrom` has failed.\n    error TransferFromFailed();\n\n    /// @dev The ERC20 `transfer` has failed.\n    error TransferFailed();\n\n    /// @dev The ERC20 `approve` has failed.\n    error ApproveFailed();\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                         CONSTANTS                          */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev Suggested gas stipend for contract receiving ETH\n    /// that disallows any storage writes.\n    uint256 internal constant _GAS_STIPEND_NO_STORAGE_WRITES = 2300;\n\n    /// @dev Suggested gas stipend for contract receiving ETH to perform a few\n    /// storage reads and writes, but low enough to prevent griefing.\n    /// Multiply by a small constant (e.g. 2), if needed.\n    uint256 internal constant _GAS_STIPEND_NO_GRIEF = 100000;\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                       ETH OPERATIONS                       */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev Sends `amount` (in wei) ETH to `to`.\n    /// Reverts upon failure.\n    function safeTransferETH(address to, uint256 amount) internal {\n        /// @solidity memory-safe-assembly\n        assembly {\n            // Transfer the ETH and check if it succeeded or not.\n            if iszero(call(gas(), to, amount, 0, 0, 0, 0)) {\n                // Store the function selector of `ETHTransferFailed()`.\n                mstore(0x00, 0xb12d13eb)\n                // Revert with (offset, size).\n                revert(0x1c, 0x04)\n            }\n        }\n    }\n\n    /// @dev Force sends `amount` (in wei) ETH to `to`, with a `gasStipend`.\n    /// The `gasStipend` can be set to a low enough value to prevent\n    /// storage writes or gas griefing.\n    ///\n    /// If sending via the normal procedure fails, force sends the ETH by\n    /// creating a temporary contract which uses `SELFDESTRUCT` to force send the ETH.\n    ///\n    /// Reverts if the current contract has insufficient balance.\n    function forceSafeTransferETH(address to, uint256 amount, uint256 gasStipend) internal {\n        /// @solidity memory-safe-assembly\n        assembly {\n            // If insufficient balance, revert.\n            if lt(selfbalance(), amount) {\n                // Store the function selector of `ETHTransferFailed()`.\n                mstore(0x00, 0xb12d13eb)\n                // Revert with (offset, size).\n                revert(0x1c, 0x04)\n            }\n            // Transfer the ETH and check if it succeeded or not.\n            if iszero(call(gasStipend, to, amount, 0, 0, 0, 0)) {\n                mstore(0x00, to) // Store the address in scratch space.\n                mstore8(0x0b, 0x73) // Opcode `PUSH20`.\n                mstore8(0x20, 0xff) // Opcode `SELFDESTRUCT`.\n                // We can directly use `SELFDESTRUCT` in the contract creation.\n                // Compatible with `SENDALL`: https://eips.ethereum.org/EIPS/eip-4758\n                if iszero(create(amount, 0x0b, 0x16)) {\n                    // For better gas estimation.\n                    if iszero(gt(gas(), 1000000)) { revert(0, 0) }\n                }\n            }\n        }\n    }\n\n    /// @dev Force sends `amount` (in wei) ETH to `to`, with a gas stipend\n    /// equal to `_GAS_STIPEND_NO_GRIEF`. This gas stipend is a reasonable default\n    /// for 99% of cases and can be overriden with the three-argument version of this\n    /// function if necessary.\n    ///\n    /// If sending via the normal procedure fails, force sends the ETH by\n    /// creating a temporary contract which uses `SELFDESTRUCT` to force send the ETH.\n    ///\n    /// Reverts if the current contract has insufficient balance.\n    function forceSafeTransferETH(address to, uint256 amount) internal {\n        // Manually inlined because the compiler doesn't inline functions with branches.\n        /// @solidity memory-safe-assembly\n        assembly {\n            // If insufficient balance, revert.\n            if lt(selfbalance(), amount) {\n                // Store the function selector of `ETHTransferFailed()`.\n                mstore(0x00, 0xb12d13eb)\n                // Revert with (offset, size).\n                revert(0x1c, 0x04)\n            }\n            // Transfer the ETH and check if it succeeded or not.\n            if iszero(call(_GAS_STIPEND_NO_GRIEF, to, amount, 0, 0, 0, 0)) {\n                mstore(0x00, to) // Store the address in scratch space.\n                mstore8(0x0b, 0x73) // Opcode `PUSH20`.\n                mstore8(0x20, 0xff) // Opcode `SELFDESTRUCT`.\n                // We can directly use `SELFDESTRUCT` in the contract creation.\n                // Compatible with `SENDALL`: https://eips.ethereum.org/EIPS/eip-4758\n                if iszero(create(amount, 0x0b, 0x16)) {\n                    // For better gas estimation.\n                    if iszero(gt(gas(), 1000000)) { revert(0, 0) }\n                }\n            }\n        }\n    }\n\n    /// @dev Sends `amount` (in wei) ETH to `to`, with a `gasStipend`.\n    /// The `gasStipend` can be set to a low enough value to prevent\n    /// storage writes or gas griefing.\n    ///\n    /// Simply use `gasleft()` for `gasStipend` if you don't need a gas stipend.\n    ///\n    /// Note: Does NOT revert upon failure.\n    /// Returns whether the transfer of ETH is successful instead.\n    function trySafeTransferETH(address to, uint256 amount, uint256 gasStipend)\n        internal\n        returns (bool success)\n    {\n        /// @solidity memory-safe-assembly\n        assembly {\n            // Transfer the ETH and check if it succeeded or not.\n            success := call(gasStipend, to, amount, 0, 0, 0, 0)\n        }\n    }\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                      ERC20 OPERATIONS                      */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev Sends `amount` of ERC20 `token` from `from` to `to`.\n    /// Reverts upon failure.\n    ///\n    /// The `from` account must have at least `amount` approved for\n    /// the current contract to manage.\n    function safeTransferFrom(address token, address from, address to, uint256 amount) internal {\n        /// @solidity memory-safe-assembly\n        assembly {\n            let m := mload(0x40) // Cache the free memory pointer.\n\n            mstore(0x60, amount) // Store the `amount` argument.\n            mstore(0x40, to) // Store the `to` argument.\n            mstore(0x2c, shl(96, from)) // Store the `from` argument.\n            // Store the function selector of `transferFrom(address,address,uint256)`.\n            mstore(0x0c, 0x23b872dd000000000000000000000000)\n\n            if iszero(\n                and( // The arguments of `and` are evaluated from right to left.\n                    // Set success to whether the call reverted, if not we check it either\n                    // returned exactly 1 (can't just be non-zero data), or had no return data.\n                    or(eq(mload(0x00), 1), iszero(returndatasize())),\n                    call(gas(), token, 0, 0x1c, 0x64, 0x00, 0x20)\n                )\n            ) {\n                // Store the function selector of `TransferFromFailed()`.\n                mstore(0x00, 0x7939f424)\n                // Revert with (offset, size).\n                revert(0x1c, 0x04)\n            }\n\n            mstore(0x60, 0) // Restore the zero slot to zero.\n            mstore(0x40, m) // Restore the free memory pointer.\n        }\n    }\n\n    /// @dev Sends all of ERC20 `token` from `from` to `to`.\n    /// Reverts upon failure.\n    ///\n    /// The `from` account must have at least `amount` approved for\n    /// the current contract to manage.\n    function safeTransferAllFrom(address token, address from, address to)\n        internal\n        returns (uint256 amount)\n    {\n        /// @solidity memory-safe-assembly\n        assembly {\n            let m := mload(0x40) // Cache the free memory pointer.\n\n            mstore(0x40, to) // Store the `to` argument.\n            mstore(0x2c, shl(96, from)) // Store the `from` argument.\n            // Store the function selector of `balanceOf(address)`.\n            mstore(0x0c, 0x70a08231000000000000000000000000)\n            if iszero(\n                and( // The arguments of `and` are evaluated from right to left.\n                    gt(returndatasize(), 0x1f), // At least 32 bytes returned.\n                    staticcall(gas(), token, 0x1c, 0x24, 0x60, 0x20)\n                )\n            ) {\n                // Store the function selector of `TransferFromFailed()`.\n                mstore(0x00, 0x7939f424)\n                // Revert with (offset, size).\n                revert(0x1c, 0x04)\n            }\n\n            // Store the function selector of `transferFrom(address,address,uint256)`.\n            mstore(0x00, 0x23b872dd)\n            // The `amount` argument is already written to the memory word at 0x6c.\n            amount := mload(0x60)\n\n            if iszero(\n                and( // The arguments of `and` are evaluated from right to left.\n                    // Set success to whether the call reverted, if not we check it either\n                    // returned exactly 1 (can't just be non-zero data), or had no return data.\n                    or(eq(mload(0x00), 1), iszero(returndatasize())),\n                    call(gas(), token, 0, 0x1c, 0x64, 0x00, 0x20)\n                )\n            ) {\n                // Store the function selector of `TransferFromFailed()`.\n                mstore(0x00, 0x7939f424)\n                // Revert with (offset, size).\n                revert(0x1c, 0x04)\n            }\n\n            mstore(0x60, 0) // Restore the zero slot to zero.\n            mstore(0x40, m) // Restore the free memory pointer.\n        }\n    }\n\n    /// @dev Sends `amount` of ERC20 `token` from the current contract to `to`.\n    /// Reverts upon failure.\n    function safeTransfer(address token, address to, uint256 amount) internal {\n        /// @solidity memory-safe-assembly\n        assembly {\n            mstore(0x14, to) // Store the `to` argument.\n            mstore(0x34, amount) // Store the `amount` argument.\n            // Store the function selector of `transfer(address,uint256)`.\n            mstore(0x00, 0xa9059cbb000000000000000000000000)\n\n            if iszero(\n                and( // The arguments of `and` are evaluated from right to left.\n                    // Set success to whether the call reverted, if not we check it either\n                    // returned exactly 1 (can't just be non-zero data), or had no return data.\n                    or(eq(mload(0x00), 1), iszero(returndatasize())),\n                    call(gas(), token, 0, 0x10, 0x44, 0x00, 0x20)\n                )\n            ) {\n                // Store the function selector of `TransferFailed()`.\n                mstore(0x00, 0x90b8ec18)\n                // Revert with (offset, size).\n                revert(0x1c, 0x04)\n            }\n            // Restore the part of the free memory pointer that was overwritten.\n            mstore(0x34, 0)\n        }\n    }\n\n    /// @dev Sends all of ERC20 `token` from the current contract to `to`.\n    /// Reverts upon failure.\n    function safeTransferAll(address token, address to) internal returns (uint256 amount) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            mstore(0x00, 0x70a08231) // Store the function selector of `balanceOf(address)`.\n            mstore(0x20, address()) // Store the address of the current contract.\n            if iszero(\n                and( // The arguments of `and` are evaluated from right to left.\n                    gt(returndatasize(), 0x1f), // At least 32 bytes returned.\n                    staticcall(gas(), token, 0x1c, 0x24, 0x34, 0x20)\n                )\n            ) {\n                // Store the function selector of `TransferFailed()`.\n                mstore(0x00, 0x90b8ec18)\n                // Revert with (offset, size).\n                revert(0x1c, 0x04)\n            }\n\n            mstore(0x14, to) // Store the `to` argument.\n            // The `amount` argument is already written to the memory word at 0x34.\n            amount := mload(0x34)\n            // Store the function selector of `transfer(address,uint256)`.\n            mstore(0x00, 0xa9059cbb000000000000000000000000)\n\n            if iszero(\n                and( // The arguments of `and` are evaluated from right to left.\n                    // Set success to whether the call reverted, if not we check it either\n                    // returned exactly 1 (can't just be non-zero data), or had no return data.\n                    or(eq(mload(0x00), 1), iszero(returndatasize())),\n                    call(gas(), token, 0, 0x10, 0x44, 0x00, 0x20)\n                )\n            ) {\n                // Store the function selector of `TransferFailed()`.\n                mstore(0x00, 0x90b8ec18)\n                // Revert with (offset, size).\n                revert(0x1c, 0x04)\n            }\n            // Restore the part of the free memory pointer that was overwritten.\n            mstore(0x34, 0)\n        }\n    }\n\n    /// @dev Sets `amount` of ERC20 `token` for `to` to manage on behalf of the current contract.\n    /// Reverts upon failure.\n    function safeApprove(address token, address to, uint256 amount) internal {\n        /// @solidity memory-safe-assembly\n        assembly {\n            mstore(0x14, to) // Store the `to` argument.\n            mstore(0x34, amount) // Store the `amount` argument.\n            // Store the function selector of `approve(address,uint256)`.\n            mstore(0x00, 0x095ea7b3000000000000000000000000)\n\n            if iszero(\n                and( // The arguments of `and` are evaluated from right to left.\n                    // Set success to whether the call reverted, if not we check it either\n                    // returned exactly 1 (can't just be non-zero data), or had no return data.\n                    or(eq(mload(0x00), 1), iszero(returndatasize())),\n                    call(gas(), token, 0, 0x10, 0x44, 0x00, 0x20)\n                )\n            ) {\n                // Store the function selector of `ApproveFailed()`.\n                mstore(0x00, 0x3e3f8f73)\n                // Revert with (offset, size).\n                revert(0x1c, 0x04)\n            }\n            // Restore the part of the free memory pointer that was overwritten.\n            mstore(0x34, 0)\n        }\n    }\n\n    /// @dev Returns the amount of ERC20 `token` owned by `account`.\n    /// Returns zero if the `token` does not exist.\n    function balanceOf(address token, address account) internal view returns (uint256 amount) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            mstore(0x14, account) // Store the `account` argument.\n            // Store the function selector of `balanceOf(address)`.\n            mstore(0x00, 0x70a08231000000000000000000000000)\n            amount :=\n                mul(\n                    mload(0x20),\n                    and( // The arguments of `and` are evaluated from right to left.\n                        gt(returndatasize(), 0x1f), // At least 32 bytes returned.\n                        staticcall(gas(), token, 0x10, 0x24, 0x20, 0x20)\n                    )\n                )\n        }\n    }\n}\n"
      }
    },
    "settings": {
      "viaIR": false,
      "optimizer": {
        "enabled": true,
        "runs": 1000000
      },
      "evmVersion": "paris",
      "outputSelection": {
        "*": {
          "*": [
            "evm.bytecode",
            "evm.deployedBytecode",
            "devdoc",
            "userdoc",
            "metadata",
            "abi"
          ]
        }
      },
      "metadata": {
        "useLiteralContent": true
      },
      "libraries": {
        "contracts/libraries/CommandLibrary.sol": {
          "CommandExecutor": "0x776197c47823dd8a2dd318d81a0556a9e4fb3b95"
        }
      }
    }
  }}