creation_sourcecode: {{
    "language": "Solidity",
    "sources": {
      "lib/openzeppelin-contracts/contracts/access/Ownable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol)\n\npragma solidity ^0.8.20;\n\nimport {Context} from \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * The initial owner is set to the address provided by the deployer. This can\n * later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n    address private _owner;\n\n    /**\n     * @dev The caller account is not authorized to perform an operation.\n     */\n    error OwnableUnauthorizedAccount(address account);\n\n    /**\n     * @dev The owner is not a valid owner account. (eg. `address(0)`)\n     */\n    error OwnableInvalidOwner(address owner);\n\n    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n    /**\n     * @dev Initializes the contract setting the address provided by the deployer as the initial owner.\n     */\n    constructor(address initialOwner) {\n        if (initialOwner == address(0)) {\n            revert OwnableInvalidOwner(address(0));\n        }\n        _transferOwnership(initialOwner);\n    }\n\n    /**\n     * @dev Throws if called by any account other than the owner.\n     */\n    modifier onlyOwner() {\n        _checkOwner();\n        _;\n    }\n\n    /**\n     * @dev Returns the address of the current owner.\n     */\n    function owner() public view virtual returns (address) {\n        return _owner;\n    }\n\n    /**\n     * @dev Throws if the sender is not the owner.\n     */\n    function _checkOwner() internal view virtual {\n        if (owner() != _msgSender()) {\n            revert OwnableUnauthorizedAccount(_msgSender());\n        }\n    }\n\n    /**\n     * @dev Leaves the contract without owner. It will not be possible to call\n     * `onlyOwner` functions. Can only be called by the current owner.\n     *\n     * NOTE: Renouncing ownership will leave the contract without an owner,\n     * thereby disabling any functionality that is only available to the owner.\n     */\n    function renounceOwnership() public virtual onlyOwner {\n        _transferOwnership(address(0));\n    }\n\n    /**\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\n     * Can only be called by the current owner.\n     */\n    function transferOwnership(address newOwner) public virtual onlyOwner {\n        if (newOwner == address(0)) {\n            revert OwnableInvalidOwner(address(0));\n        }\n        _transferOwnership(newOwner);\n    }\n\n    /**\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\n     * Internal function without access restriction.\n     */\n    function _transferOwnership(address newOwner) internal virtual {\n        address oldOwner = _owner;\n        _owner = newOwner;\n        emit OwnershipTransferred(oldOwner, newOwner);\n    }\n}\n"
      },
      "lib/openzeppelin-contracts/contracts/access/Ownable2Step.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable2Step.sol)\n\npragma solidity ^0.8.20;\n\nimport {Ownable} from \"./Ownable.sol\";\n\n/**\n * @dev Contract module which provides access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * The initial owner is specified at deployment time in the constructor for `Ownable`. This\n * can later be changed with {transferOwnership} and {acceptOwnership}.\n *\n * This module is used through inheritance. It will make available all functions\n * from parent (Ownable).\n */\nabstract contract Ownable2Step is Ownable {\n    address private _pendingOwner;\n\n    event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner);\n\n    /**\n     * @dev Returns the address of the pending owner.\n     */\n    function pendingOwner() public view virtual returns (address) {\n        return _pendingOwner;\n    }\n\n    /**\n     * @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one.\n     * Can only be called by the current owner.\n     */\n    function transferOwnership(address newOwner) public virtual override onlyOwner {\n        _pendingOwner = newOwner;\n        emit OwnershipTransferStarted(owner(), newOwner);\n    }\n\n    /**\n     * @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner.\n     * Internal function without access restriction.\n     */\n    function _transferOwnership(address newOwner) internal virtual override {\n        delete _pendingOwner;\n        super._transferOwnership(newOwner);\n    }\n\n    /**\n     * @dev The new owner accepts the ownership transfer.\n     */\n    function acceptOwnership() public virtual {\n        address sender = _msgSender();\n        if (pendingOwner() != sender) {\n            revert OwnableUnauthorizedAccount(sender);\n        }\n        _transferOwnership(sender);\n    }\n}\n"
      },
      "lib/openzeppelin-contracts/contracts/utils/Context.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.1) (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    function _contextSuffixLength() internal view virtual returns (uint256) {\n        return 0;\n    }\n}\n"
      },
      "src/beacons/InfinexProtocolConfigBeacon.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.21;\n\nimport { Ownable2Step, Ownable } from \"@openzeppelin/contracts/access/Ownable2Step.sol\";\n\nimport { IInfinexProtocolConfigBeacon } from \"src/interfaces/beacons/IInfinexProtocolConfigBeacon.sol\";\n\nimport { Error } from \"src/libraries/Error.sol\";\n\ncontract InfinexProtocolConfigBeacon is IInfinexProtocolConfigBeacon, Ownable2Step {\n    /// @notice The timestamp the beacon is initialised.\n    uint256 public immutable CREATED_AT;\n    /// @notice Gets the trusted forwarder address for the account EIP712 context\n    address public immutable TRUSTED_FORWARDER;\n    mapping(address => bool) public trustedRecoveryKeepers;\n    bool public fundsRecoveryActive;\n    address public revenuePool;\n    uint256 public withdrawalFeeUSDC;\n\n    // the required parameters for accepting and bridging USDC\n    address public USDC;\n    BridgeConfiguration public bridgeConfiguration;\n\n    // the required parameters to handle any Solana-related transaction\n    SolanaConfiguration public solanaConfiguration;\n\n    ImplementationAddresses public implementationAddresses;\n\n    mapping(uint16 wormholeChainId => bool isSupported) public supportedWormholeChainIds;\n\n    uint32 public solanaCCTPDestinationDomain;\n\n    /**\n     * @notice constructor function\n     * @param _owner The owner of the contract\n     * @param _infinexBeaconArgs The constructor arguments struct\n     * @dev Circle Destination Domain can be 0 - Ethereum\n     */\n    constructor(address _owner, InfinexBeaconConstructorArgs memory _infinexBeaconArgs) Ownable(_owner) {\n        if (_infinexBeaconArgs.trustedForwarder == address(0)) revert Error.NullAddress();\n        if (_infinexBeaconArgs.latestAccountImplementation == address(0)) revert Error.NullAddress();\n        if (_infinexBeaconArgs.initialProxyImplementation == address(0)) revert Error.NullAddress();\n\n        if (_infinexBeaconArgs.USDC == address(0)) revert Error.NullAddress();\n\n        if (_infinexBeaconArgs.circleBridge == address(0)) revert Error.NullAddress();\n        if (_infinexBeaconArgs.circleMinter == address(0)) revert Error.NullAddress();\n        if (_infinexBeaconArgs.wormholeCircleBridge == address(0)) revert Error.NullAddress();\n        if (_infinexBeaconArgs.defaultDestinationWormholeChainId == 0) revert Error.ZeroValue();\n        if (_infinexBeaconArgs.supportedWormholeChainIds.length == 0) revert Error.ZeroValue();\n\n        if (_infinexBeaconArgs.solanaWalletProgramAddress == bytes32(0)) revert Error.ZeroValue();\n        if (_infinexBeaconArgs.solanaTokenMintAddress == bytes32(0)) revert Error.ZeroValue();\n        if (_infinexBeaconArgs.solanaTokenProgramAddress == bytes32(0)) revert Error.ZeroValue();\n        if (_infinexBeaconArgs.solanaAssociatedTokenProgramAddress == bytes32(0)) revert Error.ZeroValue();\n\n        if (_infinexBeaconArgs.solanaWalletProgramAddress == bytes32(0)) revert Error.ZeroValue();\n        if (_infinexBeaconArgs.solanaTokenMintAddress == bytes32(0)) revert Error.ZeroValue();\n        if (_infinexBeaconArgs.solanaTokenProgramAddress == bytes32(0)) revert Error.ZeroValue();\n        if (_infinexBeaconArgs.solanaAssociatedTokenProgramAddress == bytes32(0)) revert Error.ZeroValue();\n\n        CREATED_AT = block.timestamp;\n        TRUSTED_FORWARDER = _infinexBeaconArgs.trustedForwarder;\n\n        implementationAddresses.latestAccountImplementation = _infinexBeaconArgs.latestAccountImplementation;\n        implementationAddresses.initialProxyImplementation = _infinexBeaconArgs.initialProxyImplementation;\n        implementationAddresses.latestInfinexProtocolConfigBeacon = address(this);\n\n        revenuePool = _infinexBeaconArgs.revenuePool;\n        USDC = _infinexBeaconArgs.USDC;\n\n        for (uint256 i; i < _infinexBeaconArgs.supportedWormholeChainIds.length; i++) {\n            supportedWormholeChainIds[_infinexBeaconArgs.supportedWormholeChainIds[i]] = true;\n        }\n\n        // setting the bridge configuration\n        bridgeConfiguration = BridgeConfiguration({\n            minimumUSDCBridgeAmount: _infinexBeaconArgs.minimumUSDCBridgeAmount,\n            circleBridge: _infinexBeaconArgs.circleBridge,\n            circleMinter: _infinexBeaconArgs.circleMinter,\n            wormholeCircleBridge: _infinexBeaconArgs.wormholeCircleBridge,\n            defaultDestinationCCTPDomain: _infinexBeaconArgs.defaultDestinationCCTPDomain,\n            defaultDestinationWormholeChainId: _infinexBeaconArgs.defaultDestinationWormholeChainId\n        });\n\n        solanaCCTPDestinationDomain = _infinexBeaconArgs.solanaCCTPDestinationDomain;\n\n        // setting the Solana configuration\n        solanaConfiguration = SolanaConfiguration({\n            walletSeed: _infinexBeaconArgs.solanaWalletSeed,\n            fixedPDASeed: _infinexBeaconArgs.solanaFixedPDASeed,\n            walletProgramAddress: _infinexBeaconArgs.solanaWalletProgramAddress,\n            tokenMintAddress: _infinexBeaconArgs.solanaTokenMintAddress,\n            tokenProgramAddress: _infinexBeaconArgs.solanaTokenProgramAddress,\n            associatedTokenProgramAddress: _infinexBeaconArgs.solanaAssociatedTokenProgramAddress\n        });\n    }\n\n    /*///////////////////////////////////////////////////////////////\n                    \t\t\tVIEW FUNCTIONS\n    ///////////////////////////////////////////////////////////////*/\n\n    /**\n     * @notice Retrieves supported wormhole chain ids.\n     * @param _wormholeChainId the chain id to check\n     * @return bool if the chain is supported or not.\n     */\n    function isSupportedWormholeChainId(uint16 _wormholeChainId) external view returns (bool) {\n        return supportedWormholeChainIds[_wormholeChainId];\n    }\n\n    /**\n     * @notice Retrieves the minimum USDC amount that can be bridged.\n     * @return The minimum USDC bridge amount.\n     */\n    function getMinimumUSDCBridgeAmount() external view returns (uint256) {\n        return bridgeConfiguration.minimumUSDCBridgeAmount;\n    }\n\n    /**\n     * @notice Retrieves the Circle Bridge parameters.\n     * @return circleBridge The address of the Circle Bridge contract.\n     * @return circleMinter The address of the TokenMinter contract.\n     * @return defaultDestinationCCTPDomain The CCTP domain of the default destination chain.\n     */\n    function getCircleBridgeParams()\n        external\n        view\n        returns (address circleBridge, address circleMinter, uint32 defaultDestinationCCTPDomain)\n    {\n        return (bridgeConfiguration.circleBridge, bridgeConfiguration.circleMinter, bridgeConfiguration.defaultDestinationCCTPDomain);\n    }\n\n    /**\n     * @notice Retrieves the Circle Bridge address.\n     * @return The address of the Circle Bridge contract.\n     */\n    function getCircleBridge() external view returns (address) {\n        return bridgeConfiguration.circleBridge;\n    }\n\n    /**\n     * @notice Retrieves the Circle TokenMinter address.\n     * @return The address of the Circle TokenMinter contract.\n     */\n    function getCircleMinter() external view returns (address) {\n        return bridgeConfiguration.circleMinter;\n    }\n\n    /**\n     * @notice Retrieves the CCTP domain of the destination chain.\n     * @return The CCTP domain of the default destination chain.\n     */\n    function getDefaultDestinationCCTPDomain() external view returns (uint32) {\n        return bridgeConfiguration.defaultDestinationCCTPDomain;\n    }\n\n    /**\n     * @notice Retrieves the circle CCTP destination domain for solana.\n     * @return The CCTP destination domain for solana.\n     */\n    function getSolanaCCTPDestinationDomain() external view returns (uint32) {\n        return solanaCCTPDestinationDomain;\n    }\n\n    /**\n     * @notice Retrieves the parameters required for Wormhole bridging.\n     * @return The address of the Wormhole Circle Bridge contract.\n     * @return The default wormhole destination domain for the circle bridge contract.\n     */\n    function getWormholeCircleBridgeParams() external view returns (address, uint16) {\n        return (bridgeConfiguration.wormholeCircleBridge, bridgeConfiguration.defaultDestinationWormholeChainId);\n    }\n\n    /**\n     * @notice Retrieves the Wormhole Circle Bridge address.\n     * @return The address of the Wormhole Circle Bridge contract.\n     */\n    function getWormholeCircleBridge() external view returns (address) {\n        return bridgeConfiguration.wormholeCircleBridge;\n    }\n\n    /**\n     * @notice Retrieves the Wormhole chain id for the default destination chain.\n     * @return The Wormhole chain id of the default destination chain.\n     */\n    function getDefaultDestinationWormholeChainId() external view returns (uint16) {\n        return bridgeConfiguration.defaultDestinationWormholeChainId;\n    }\n\n    /**\n     * @notice Gets the latest account implementation address.\n     * @return The address of the latest account implementation.\n     */\n    function getLatestAccountImplementation() external view returns (address) {\n        return implementationAddresses.latestAccountImplementation;\n    }\n\n    /**\n     * @notice Gets the initial proxy implementation address.\n     * @return The address of the initial proxy implementation.\n     */\n    function getInitialProxyImplementation() external view returns (address) {\n        return implementationAddresses.initialProxyImplementation;\n    }\n\n    /**\n     * @notice The latest Infinex Protocol config beacon address, used for pointing account updates to the latest beacon.\n     * @return The address of the latest Infinex Protocol config beacon.\n     */\n    function getLatestInfinexProtocolConfigBeacon() external view returns (address) {\n        return implementationAddresses.latestInfinexProtocolConfigBeacon;\n    }\n\n    /**\n     * @notice Checks if an address is a trusted recovery keeper.\n     * @param _address The address to check.\n     * @return True if the address is a trusted recovery keeper, false otherwise.\n     */\n    function isTrustedRecoveryKeeper(address _address) external view returns (bool) {\n        return trustedRecoveryKeepers[_address];\n    }\n\n    /**\n     * @notice Returns the Solana configuration\n     * @param walletSeed The salt used to generate the Solana account (fixed seed \"wallet\")\n     * @param fixedPDASeed The salt used to generate the PDA (Program Derived Address)\n     * @param walletProgramAddress The Solana Wallet Program Address\n     * @param tokenMintAddress The Solana token mint address\n     * @param tokenProgramAddress The Solana token address\n     * @param associatedTokenProgramAddress The Solana ATA program address\n     */\n    function getSolanaConfiguration()\n        external\n        view\n        returns (\n            bytes memory walletSeed,\n            bytes memory fixedPDASeed,\n            bytes32 walletProgramAddress,\n            bytes32 tokenMintAddress,\n            bytes32 tokenProgramAddress,\n            bytes32 associatedTokenProgramAddress\n        )\n    {\n        return (\n            solanaConfiguration.walletSeed,\n            solanaConfiguration.fixedPDASeed,\n            solanaConfiguration.walletProgramAddress,\n            solanaConfiguration.tokenMintAddress,\n            solanaConfiguration.tokenProgramAddress,\n            solanaConfiguration.associatedTokenProgramAddress\n        );\n    }\n\n    /*///////////////////////////////////////////////////////////////\n                    \t\t\tMUTATIVE FUNCTIONS\n    ///////////////////////////////////////////////////////////////*/\n\n    /**\n     * @notice Sets or unsets a supported wormhole chain id.\n     * @param _wormholeChainId the wormhole chain id to add or remove.\n     * @param _status the status of the chain id.\n     */\n    function setSupportedWormholeChainId(uint16 _wormholeChainId, bool _status) external onlyOwner {\n        emit SupportedWormholeChainIdSet(_wormholeChainId, _status);\n        supportedWormholeChainIds[_wormholeChainId] = _status;\n    }\n\n    /**\n     * @notice Sets the Solana CCTP destination domain\n     * @param _solanaCCTPDestinationDomain the destination domain for circles CCTP USDC bridge.\n     */\n    function setSolanaCCTPDestinationDomain(uint32 _solanaCCTPDestinationDomain) external onlyOwner {\n        emit SolanaCCTPDestinationDomainSet(_solanaCCTPDestinationDomain);\n        solanaCCTPDestinationDomain = _solanaCCTPDestinationDomain;\n    }\n\n    /**\n     * @notice Sets or unsets an address as a trusted recovery keeper.\n     * @param _address The address to set or unset.\n     * @param _isTrusted Boolean indicating whether to set or unset the address as a trusted recovery keeper.\n     */\n    function setTrustedRecoveryKeeper(address _address, bool _isTrusted) external onlyOwner {\n        if (_address == address(0)) revert Error.NullAddress();\n        emit TrustedRecoveryKeeperSet(_address, _isTrusted);\n        trustedRecoveryKeepers[_address] = _isTrusted;\n    }\n\n    /**\n     * @notice Sets the funds recovery flag to active.\n     * @dev Initially only the owner can call this. After 90 days, it can be activated by anyone.\n     */\n    function setFundsRecoveryActive() external {\n        if (owner() != _msgSender()) {\n            if (block.timestamp - CREATED_AT < 90 days) {\n                revert Error.FundsRecoveryActivationDeadlinePending();\n            }\n        }\n        emit FundsRecoveryStatusSet(true);\n        fundsRecoveryActive = true;\n    }\n\n    /**\n     * @notice Sets the revenue pool address.\n     * @param _revenuePool The revenue pool address.\n     */\n    function setRevenuePool(address _revenuePool) external onlyOwner {\n        if (_revenuePool == address(0)) revert Error.NullAddress();\n        emit RevenuePoolSet(_revenuePool);\n        revenuePool = _revenuePool;\n    }\n\n    /**\n     * @notice Sets the USDC amount to charge as withdrawal fee.\n     * @param _withdrawalFeeUSDC The withdrawal fee in USDC's decimals.\n     */\n    function setWithdrawalFeeUSDC(uint256 _withdrawalFeeUSDC) external onlyOwner {\n        _setWithdrawalFeeUSDC(_withdrawalFeeUSDC);\n    }\n\n    /**\n     * @notice Sets the address of the USDC token contract.\n     * @param _USDC The address of the USDC token contract.\n     * @dev Only the contract owner can call this function.\n     * @dev Throws an error if the provided address is the zero address.\n     */\n    function setUSDCAddress(address _USDC) external onlyOwner {\n        if (_USDC == address(0)) revert Error.NullAddress();\n        emit USDCAddressSet(_USDC);\n        USDC = _USDC;\n    }\n\n    /**\n     * @notice Sets the minimum USDC amount that can be bridged, in 6 decimals.\n     * @param _amount The minimum USDC bridge amount.\n     */\n    function setMinimumUSDCBridgeAmount(uint256 _amount) external onlyOwner {\n        emit MinimumUSDCBridgeAmountSet(_amount);\n        bridgeConfiguration.minimumUSDCBridgeAmount = _amount;\n    }\n\n    /**\n     * @notice Sets the parameters for Circle bridging.\n     * @param _circleBridge The address of the Circle Bridge contract.\n     * @param _circleMinter The address of the Circle TokenMinter contract.\n     * @param _defaultDestinationCCTPDomain The CCTP domain of the default destination chain.\n     * @dev Circle Destination Domain can be 0 - Ethereum.\n     */\n    function setCircleBridgeParams(address _circleBridge, address _circleMinter, uint32 _defaultDestinationCCTPDomain)\n        external\n        onlyOwner\n    {\n        if (_circleBridge == address(0)) revert Error.NullAddress();\n        if (_circleMinter == address(0)) revert Error.NullAddress();\n        emit CircleBridgeParamsSet(_circleBridge, _circleMinter, _defaultDestinationCCTPDomain);\n        bridgeConfiguration.circleBridge = _circleBridge;\n        bridgeConfiguration.circleMinter = _circleMinter;\n        bridgeConfiguration.defaultDestinationCCTPDomain = _defaultDestinationCCTPDomain;\n    }\n\n    /**\n     * @notice Sets the parameters for Wormhole bridging.\n     * @param _wormholeCircleBridge The address of the Wormhole Circle Bridge contract.\n     * @param _defaultDestinationWormholeChainId The wormhole domain of the default destination chain.\n     */\n    function setWormholeCircleBridgeParams(address _wormholeCircleBridge, uint16 _defaultDestinationWormholeChainId)\n        external\n        onlyOwner\n    {\n        if (_wormholeCircleBridge == address(0)) revert Error.NullAddress();\n        if (_defaultDestinationWormholeChainId == 0) revert Error.ZeroValue();\n        emit WormholeCircleBridgeParamsSet(_wormholeCircleBridge, _defaultDestinationWormholeChainId);\n        bridgeConfiguration.wormholeCircleBridge = _wormholeCircleBridge;\n        bridgeConfiguration.defaultDestinationWormholeChainId = _defaultDestinationWormholeChainId;\n    }\n\n    /**\n     * @notice Sets the initial proxy implementation address.\n     * @param _initialProxyImplementation The initial proxy implementation address.\n     */\n    function setInitialProxyImplementation(address _initialProxyImplementation) external onlyOwner {\n        if (_initialProxyImplementation == address(0)) revert Error.NullAddress();\n        emit InitialProxyImplementationSet(_initialProxyImplementation);\n        implementationAddresses.initialProxyImplementation = _initialProxyImplementation;\n    }\n\n    /**\n     * @notice Sets the latest account implementation address.\n     * @param _latestAccountImplementation The latest account implementation address.\n     */\n    function setLatestAccountImplementation(address _latestAccountImplementation) external onlyOwner {\n        if (_latestAccountImplementation == address(0)) revert Error.NullAddress();\n        emit LatestAccountImplementationSet(_latestAccountImplementation);\n        implementationAddresses.latestAccountImplementation = _latestAccountImplementation;\n    }\n\n    /**\n     * @notice Sets the latest Infinex Protocol Config Beacon.\n     * @param _latestInfinexProtocolConfigBeacon The address of the Infinex Protocol Config Beacon.\n     */\n    function setLatestInfinexProtocolConfigBeacon(address _latestInfinexProtocolConfigBeacon) external onlyOwner {\n        if (_latestInfinexProtocolConfigBeacon == address(0)) revert Error.NullAddress();\n        emit LatestInfinexProtocolConfigBeaconSet(_latestInfinexProtocolConfigBeacon);\n        implementationAddresses.latestInfinexProtocolConfigBeacon = _latestInfinexProtocolConfigBeacon;\n    }\n\n    /*///////////////////////////////////////////////////////////////\n                    \t\t\tINTERNAL FUNCTIONS\n    ///////////////////////////////////////////////////////////////*/\n\n    function _setWithdrawalFeeUSDC(uint256 _withdrawalFeeUSDC) internal {\n        emit WithdrawalFeeUSDCSet(_withdrawalFeeUSDC);\n        withdrawalFeeUSDC = _withdrawalFeeUSDC;\n    }\n}\n"
      },
      "src/interfaces/beacons/IInfinexProtocolConfigBeacon.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.21;\n\n/**\n * @title IInfinexProtocolConfigBeacon\n * @notice Interface for the Infinex Protocol Config Beacon contract.\n */\ninterface IInfinexProtocolConfigBeacon {\n    /*///////////////////////////////////////////////////////////////\n    \t \t\t\t\t\t\t\t\t\t\tSTRUCTS\n    ///////////////////////////////////////////////////////////////*/\n\n    /**\n     * @notice Struct containing the constructor arguments for the InfinexProtocolConfigBeacon contract\n     * @param trustedForwarder Address of the trusted forwarder contract\n     * @param latestAccountImplementation Address of the latest account implementation contract\n     * @param initialProxyImplementation Address of the initial proxy implementation contract\n     * @param revenuePool Address of the revenue pool contract\n     * @param USDC Address of the USDC token contract\n     * @param minimumUSDCBridgeAmount Minimum amount of USDC required to bridge\n     * @param circleBridge Address of the Circle bridge contract\n     * @param circleMinter Address of the Circle minter contract, used for checking the maximum bridge amount\n     * @param wormholeCircleBridge Address of the Wormhole Circle bridge contract\n     * @param defaultDestinationCCTPDomain the CCTP domain of the default destination chain.\n     * @param defaultDestinationWormholeChainId the Wormhole chain id of the default destination chain.\n     * @param solanaWalletSeed The salt used to generate the Solana account (fixed seed \"wallet\")\n     * @param solanaFixedPDASeed The salt used to generate the PDA (Program Derived Address)\n     * @param solanaWalletProgramAddress The Solana Wallet Program Address\n     * @param solanaTokenMintAddress The Solana token mint address\n     * @param solanaTokenProgramAddress The Solana token program address\n     * @param solanaAssociatedTokenProgramAddress The Solana ATA program address\n     */\n    struct InfinexBeaconConstructorArgs {\n        address trustedForwarder;\n        address latestAccountImplementation;\n        address initialProxyImplementation;\n        address revenuePool;\n        address USDC;\n        uint256 minimumUSDCBridgeAmount;\n        address circleBridge;\n        address circleMinter;\n        address wormholeCircleBridge;\n        uint32 defaultDestinationCCTPDomain;\n        uint16 defaultDestinationWormholeChainId;\n        uint16[] supportedWormholeChainIds;\n        uint32 solanaCCTPDestinationDomain;\n        bytes solanaWalletSeed;\n        bytes solanaFixedPDASeed;\n        bytes32 solanaWalletProgramAddress;\n        bytes32 solanaTokenMintAddress;\n        bytes32 solanaTokenProgramAddress;\n        bytes32 solanaAssociatedTokenProgramAddress;\n    }\n\n    /**\n     * @notice Struct containing both Circle and Wormhole bridge configuration\n     * @param minimumUSDCBridgeAmount Minimum amount of USDC required to bridge\n     * @param circleBridge Address of the Circle bridge contract\n     * @param circleMinter Address of the Circle minter contract, used for checking the maximum bridge amount\n     * @param wormholeCircleBridge Address of the Wormhole Circle bridge contract\n     * @param defaultDestinationCCTPDomain the CCTP domain of the default destination chain.\n     * @param defaultDestinationWormholeChainId the Wormhole chain id of the default destination chain.\n     * @dev Chain id is the official chain id for evm chains and documented one for non evm chains.\n     */\n    struct BridgeConfiguration {\n        uint256 minimumUSDCBridgeAmount;\n        address circleBridge;\n        address circleMinter;\n        address wormholeCircleBridge;\n        uint32 defaultDestinationCCTPDomain;\n        uint16 defaultDestinationWormholeChainId;\n    }\n\n    /**\n     * @notice The addresses for implementations referenced by the beacon\n     * @param initialProxyImplementation The initial proxy implementation address used for account creation to ensure identical cross chain addresses\n     * @param latestAccountImplementation The latest account implementation address, used for account upgrades and new accounts\n     * @param latestInfinexProtocolConfigBeacon The latest Infinex Protocol config beacon address, used for pointing account updates to the latest beacon\n     */\n    struct ImplementationAddresses {\n        address initialProxyImplementation;\n        address latestAccountImplementation;\n        address latestInfinexProtocolConfigBeacon;\n    }\n\n    /**\n     * @notice Struct containing the Solana configuration needed to verify addresses\n     * @param walletSeed The salt used to generate the Solana account (fixed seed \"wallet\")\n     * @param fixedPDASeed The salt used to generate the PDA (Program Derived Address)\n     * @param walletProgramAddress The Solana Wallet Program Address\n     * @param tokenMintAddress The Solana token mint address\n     * @param tokenProgramAddress The Solana token address\n     * @param associatedTokenProgramAddress The Solana ATA program address\n     */\n    struct SolanaConfiguration {\n        bytes walletSeed;\n        bytes fixedPDASeed;\n        bytes32 walletProgramAddress;\n        bytes32 tokenMintAddress;\n        bytes32 tokenProgramAddress;\n        bytes32 associatedTokenProgramAddress;\n    }\n\n    /*///////////////////////////////////////////////////////////////\n    \t \t\t\t\t\t\t\t\t\t\tEVENTS\n    ///////////////////////////////////////////////////////////////*/\n\n    event LatestAccountImplementationSet(address latestAccountImplementation);\n    event InitialProxyImplementationSet(address initialProxyImplementation);\n    event RevenuePoolSet(address revenuePool);\n    event USDCAddressSet(address USDC);\n    event CircleBridgeParamsSet(address circleBridge, address circleMinter, uint32 defaultDestinationCCTPDomain);\n    event WormholeCircleBridgeParamsSet(address wormholeCircleBridge, uint16 defaultDestinationWormholeChainId);\n    event LatestInfinexProtocolConfigBeaconSet(address latestInfinexProtocolConfigBeacon);\n    event WithdrawalFeeUSDCSet(uint256 withdrawalFee);\n    event FundsRecoveryStatusSet(bool status);\n    event MinimumUSDCBridgeAmountSet(uint256 amount);\n    event WormholeDestinationDomainSet(uint256 indexed chainId, uint16 destinationDomain);\n    event CircleDestinationDomainSet(uint256 indexed chainId, uint32 destinationDomain);\n    event TrustedRecoveryKeeperSet(address indexed trustedRecoveryKeeper, bool isTrusted);\n    event SupportedWormholeChainIdSet(uint16 wormholeChainId, bool status);\n    event SolanaCCTPDestinationDomainSet(uint32 solanaCCTPDestinationDomain);\n\n    /*///////////////////////////////////////////////////////////////\n    \t \t\t\t\t\t\t\t\t\tVARIABLES\n    ///////////////////////////////////////////////////////////////*/\n\n    /**\n     * @notice Gets the timestamp the beacon was deployed\n     * @return The timestamp the beacon was deployed\n     */\n    function CREATED_AT() external view returns (uint256);\n\n    /**\n     * @notice Gets the trusted forwarder address\n     * @return The address of the trusted forwarder\n     */\n    function TRUSTED_FORWARDER() external view returns (address);\n\n    /**\n     * @notice A platform wide feature flag to enable or disable funds recovery, false by default\n     * @return True if funds recovery is active\n     */\n    function fundsRecoveryActive() external view returns (bool);\n\n    /**\n     * @notice Gets the revenue pool address\n     * @return The address of the revenue pool\n     */\n    function revenuePool() external view returns (address);\n\n    /**\n     * @notice Gets the USDC amount to charge as withdrawal fee\n     * @return The withdrawal fee in USDC's decimals\n     */\n    function withdrawalFeeUSDC() external view returns (uint256);\n\n    /**\n     * @notice Retrieves the USDC address.\n     * @return The address of the USDC token\n     */\n    function USDC() external view returns (address);\n\n    /*///////////////////////////////////////////////////////////////\n    \t \t\t\t\t\t\t\t\tVIEW FUNCTIONS\n    ///////////////////////////////////////////////////////////////*/\n\n    /**\n     * @notice Retrieves supported wormhole chain ids.\n     * @param _wormholeChainId the chain id to check\n     * @return bool if the chain is supported or not.\n     */\n    function isSupportedWormholeChainId(uint16 _wormholeChainId) external view returns (bool);\n\n    /**\n     * @notice Retrieves the minimum USDC amount that can be bridged.\n     * @return The minimum USDC bridge amount.\n     */\n    function getMinimumUSDCBridgeAmount() external view returns (uint256);\n\n    /**\n     * @notice Retrieves the Circle Bridge parameters.\n     * @return circleBridge The address of the Circle Bridge contract.\n     * @return circleMinter The address of the TokenMinter contract.\n     * @return defaultDestinationCCTPDomain The CCTP domain of the default destination chain.\n     */\n    function getCircleBridgeParams()\n        external\n        view\n        returns (address circleBridge, address circleMinter, uint32 defaultDestinationCCTPDomain);\n\n    /**\n     * @notice Retrieves the Circle Bridge address.\n     * @return The address of the Circle Bridge contract.\n     */\n    function getCircleBridge() external view returns (address);\n\n    /**\n     * @notice Retrieves the Circle TokenMinter address.\n     * @return The address of the Circle TokenMinter contract.\n     */\n    function getCircleMinter() external view returns (address);\n\n    /**\n     * @notice Retrieves the CCTP domain of the destination chain.\n     * @return The CCTP domain of the default destination chain.\n     */\n    function getDefaultDestinationCCTPDomain() external view returns (uint32);\n\n    /**\n     * @notice Retrieves the parameters required for Wormhole bridging.\n     * @return The address of the Wormhole Circle Bridge contract.\n     * @return The default wormhole destination domain for the circle bridge contract.\n     */\n    function getWormholeCircleBridgeParams() external view returns (address, uint16);\n\n    /**\n     * @notice Retrieves the Wormhole Circle Bridge address.\n     * @return The address of the Wormhole Circle Bridge contract.\n     */\n    function getWormholeCircleBridge() external view returns (address);\n\n    /**\n     * @notice Retrieves the Wormhole chain id for Base, or Ethereum Mainnet if deployed on Base.\n     * @return The Wormhole chain id of the default destination chain.\n     */\n    function getDefaultDestinationWormholeChainId() external view returns (uint16);\n\n    /**\n     * @notice Retrieves the circle CCTP destination domain for solana.\n     * @return The CCTP destination domain for solana.\n     */\n    function getSolanaCCTPDestinationDomain() external view returns (uint32);\n\n    /**\n     * @notice Gets the latest account implementation address.\n     * @return The address of the latest account implementation.\n     */\n    function getLatestAccountImplementation() external view returns (address);\n\n    /**\n     * @notice Gets the initial proxy implementation address.\n     * @return The address of the initial proxy implementation.\n     */\n    function getInitialProxyImplementation() external view returns (address);\n\n    /**\n     * @notice The latest Infinex Protocol config beacon address, used for pointing account updates to the latest beacon.\n     * @return The address of the latest Infinex Protocol config beacon.\n     */\n    function getLatestInfinexProtocolConfigBeacon() external view returns (address);\n\n    /**\n     * @notice Checks if an address is a trusted recovery keeper.\n     * @param _address The address to check.\n     * @return True if the address is a trusted recovery keeper, false otherwise.\n     */\n    function isTrustedRecoveryKeeper(address _address) external view returns (bool);\n\n    /**\n     * @notice Returns the Solana configuration\n     * @param walletSeed The salt used to generate the Solana account (fixed seed \"wallet\")\n     * @param fixedPDASeed The salt used to generate the PDA (Program Derived Address)\n     * @param walletProgramAddress The Solana Wallet Program Address\n     * @param tokenMintAddress The Solana token mint address\n     * @param tokenProgramAddress The Solana token program address\n     * @param associatedTokenProgramAddress The Solana ATA program address\n     */\n    function getSolanaConfiguration()\n        external\n        view\n        returns (\n            bytes memory walletSeed,\n            bytes memory fixedPDASeed,\n            bytes32 walletProgramAddress,\n            bytes32 tokenMintAddress,\n            bytes32 tokenProgramAddress,\n            bytes32 associatedTokenProgramAddress\n        );\n\n    /*///////////////////////////////////////////////////////////////\n    \t \t\t\t\t\t\t\tMUTATIVE FUNCTIONS\n    ///////////////////////////////////////////////////////////////*/\n\n    /**\n     * @notice Sets or unsets a supported wormhole chain id.\n     * @param _wormholeChainId the wormhole chain id to add or remove.\n     * @param _status the status of the chain id.\n     */\n    function setSupportedWormholeChainId(uint16 _wormholeChainId, bool _status) external;\n\n    /**\n     * @notice Sets the solana CCTP destination domain\n     * @param _solanaCCTPDestinationDomain the destination domain for circles CCTP USDC bridge.\n     */\n    function setSolanaCCTPDestinationDomain(uint32 _solanaCCTPDestinationDomain) external;\n\n    /**\n     * @notice Sets or unsets an address as a trusted recovery keeper.\n     * @param _address The address to set or unset.\n     * @param _isTrusted Boolean indicating whether to set or unset the address as a trusted recovery keeper.\n     */\n    function setTrustedRecoveryKeeper(address _address, bool _isTrusted) external;\n\n    /**\n     * @notice Sets the funds recovery flag to active.\n     * @dev Initially only the owner can call this. After 90 days, it can be activated by anyone.\n     */\n    function setFundsRecoveryActive() external;\n\n    /**\n     * @notice Sets the revenue pool address.\n     * @param _revenuePool The revenue pool address.\n     */\n    function setRevenuePool(address _revenuePool) external;\n\n    /**\n     * @notice Sets the USDC amount to charge as withdrawal fee.\n     * @param _withdrawalFeeUSDC The withdrawal fee in USDC's decimals.\n     */\n    function setWithdrawalFeeUSDC(uint256 _withdrawalFeeUSDC) external;\n\n    /**\n     * @notice Sets the address of the USDC token contract.\n     * @param _USDC The address of the USDC token contract.\n     * @dev Only the contract owner can call this function.\n     * @dev Throws an error if the provided address is the zero address.\n     */\n    function setUSDCAddress(address _USDC) external;\n\n    /**\n     * @notice Sets the minimum USDC amount that can be bridged, in 6 decimals.\n     * @param _amount The minimum USDC bridge amount.\n     */\n    function setMinimumUSDCBridgeAmount(uint256 _amount) external;\n\n    /**\n     * @notice Sets the parameters for Circle bridging.\n     * @param _circleBridge The address of the Circle Bridge contract.\n     * @param _circleMinter The address of the Circle TokenMinter contract.\n     * @param _defaultDestinationCCTPDomain The CCTP domain of the default destination chain.\n     * @dev Circle Destination Domain can be 0 - Ethereum.\n     */\n    function setCircleBridgeParams(address _circleBridge, address _circleMinter, uint32 _defaultDestinationCCTPDomain) external;\n\n    /**\n     * @notice Sets the parameters for Wormhole bridging.\n     * @param _wormholeCircleBridge The address of the Wormhole Circle Bridge contract.\n     * @param _defaultDestinationWormholeChainId The wormhole domain of the default destination chain.\n     */\n    function setWormholeCircleBridgeParams(address _wormholeCircleBridge, uint16 _defaultDestinationWormholeChainId) external;\n\n    /**\n     * @notice Sets the initial proxy implementation address.\n     * @param _initialProxyImplementation The initial proxy implementation address.\n     * @dev Throws an error if the provided address is the zero address.\n     */\n    function setInitialProxyImplementation(address _initialProxyImplementation) external;\n\n    /**\n     * @notice Sets the latest account implementation address.\n     * @param _latestAccountImplementation The latest account implementation address.\n     * @dev Throws an error if the provided address is the zero address.\n     */\n    function setLatestAccountImplementation(address _latestAccountImplementation) external;\n\n    /**\n     * @notice Sets the latest Infinex Protocol Config Beacon.\n     * @param _latestInfinexProtocolConfigBeacon The address of the Infinex Protocol Config Beacon.\n     * @dev Throws an error if the provided address is the zero address.\n     */\n    function setLatestInfinexProtocolConfigBeacon(address _latestInfinexProtocolConfigBeacon) external;\n}\n"
      },
      "src/libraries/Error.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.21;\n\nlibrary Error {\n    /*///////////////////////////////////////////////////////////////\n                                            GENERIC\n    ///////////////////////////////////////////////////////////////*/\n\n    error AlreadyExists();\n\n    error DoesNotExist();\n\n    error Unauthorized();\n\n    error InvalidLength();\n\n    error NotOwner();\n\n    error InvalidWormholeChainId();\n\n    /*///////////////////////////////////////////////////////////////\n                                            ADDRESS\n    ///////////////////////////////////////////////////////////////*/\n\n    error ImplementationMismatch(address implementation, address latestImplementation);\n\n    error InvalidWithdrawalAddress(address to);\n\n    error NullAddress();\n\n    error SameAddress();\n\n    error InvalidSolanaAddress();\n\n    error AddressAlreadySet();\n\n    /*///////////////////////////////////////////////////////////////\n                                    AMOUNT / BALANCE\n    ///////////////////////////////////////////////////////////////*/\n\n    error InsufficientBalance();\n\n    error InsufficientWithdrawalAmount(uint256 amount);\n\n    error InsufficientBalanceForFee(uint256 balance, uint256 fee);\n\n    error InvalidNonce(bytes32 nonce);\n\n    error ZeroValue();\n\n    error AmountDeltaZeroValue();\n\n    error DecimalsMoreThan18(uint256 decimals);\n\n    error InsufficientBridgeAmount();\n\n    error BridgeMaxAmountExceeded();\n\n    /*///////////////////////////////////////////////////////////////\n                                            ACCOUNT\n    ///////////////////////////////////////////////////////////////*/\n\n    error CreateAccountDisabled();\n\n    error InvalidKeysForSalt();\n\n    error PredictAddressDisabled();\n\n    error FundsRecoveryActivationDeadlinePending();\n\n    /*///////////////////////////////////////////////////////////////\n                                        KEY MANAGEMENT\n    ///////////////////////////////////////////////////////////////*/\n\n    error InvalidRequest();\n\n    error InvalidKeySignature(address from);\n\n    error KeyAlreadyInvalid();\n\n    error KeyAlreadyValid();\n\n    error KeyNotFound();\n\n    error CannotRemoveLastKey();\n\n    /*///////////////////////////////////////////////////////////////\n                                     GAS FEE REBATE\n    ///////////////////////////////////////////////////////////////*/\n\n    error InvalidDeductGasFunction(bytes4 sig);\n\n    /*///////////////////////////////////////////////////////////////\n                                FEATURE FLAGS\n    ///////////////////////////////////////////////////////////////*/\n\n    error FundsRecoveryNotActive();\n}\n"
      }
    },
    "settings": {
      "optimizer": {
        "enabled": true,
        "runs": 200
      },
      "evmVersion": "paris",
      "remappings": [
        "@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/",
        "@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/",
        "@synthetixio/core-contracts/=node_modules/@synthetixio/core-contracts/",
        "@synthetixio/core-modules/=node_modules/@synthetixio/core-modules/",
        "@synthetixio/main/=node_modules/@synthetixio/main/",
        "@synthetixio/oracle-manager/=node_modules/@synthetixio/oracle-manager/",
        "@synthetixio/perps-market/=node_modules/@synthetixio/perps-market/",
        "@synthetixio/spot-market/=node_modules/@synthetixio/spot-market/",
        "cannon-std/=lib/cannon-std/src/",
        "ds-test/=lib/forge-std/lib/ds-test/src/",
        "erc4626-tests/=lib/openzeppelin-contracts-upgradeable/lib/erc4626-tests/",
        "forge-std/=lib/forge-std/src/",
        "openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/",
        "openzeppelin-contracts/=lib/openzeppelin-contracts/",
        "src/=src/",
        "test/=test/",
        "wormhole-circle-integration/=lib/wormhole-circle-integration/evm/src/",
        "wormhole/=lib/wormhole-circle-integration/evm/src/"
      ],
      "outputSelection": {
        "*": {
          "*": [
            "evm.bytecode",
            "evm.deployedBytecode",
            "devdoc",
            "userdoc",
            "metadata",
            "abi"
          ]
        }
      },
      "libraries": {}
    }
  }}