From f0c8d1c1803141601e702d561ca483f278316141 Mon Sep 17 00:00:00 2001 From: adu Date: Thu, 25 Jul 2024 17:44:15 +0800 Subject: [PATCH 1/4] refactor: remove isActivated check --- input.json | 1 + src/core/ExoCapsule.sol | 4 ---- 2 files changed, 1 insertion(+), 4 deletions(-) create mode 100644 input.json diff --git a/input.json b/input.json new file mode 100644 index 00000000..9feac0a5 --- /dev/null +++ b/input.json @@ -0,0 +1 @@ +{"language":"Solidity","sources":{"src/core/ExocoreGateway.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {IExocoreGateway} from \"../interfaces/IExocoreGateway.sol\";\n\nimport {ASSETS_CONTRACT, ASSETS_PRECOMPILE_ADDRESS} from \"../interfaces/precompiles/IAssets.sol\";\nimport {CLAIM_REWARD_CONTRACT, CLAIM_REWARD_PRECOMPILE_ADDRESS} from \"../interfaces/precompiles/IClaimReward.sol\";\nimport {DELEGATION_CONTRACT, DELEGATION_PRECOMPILE_ADDRESS} from \"../interfaces/precompiles/IDelegation.sol\";\n\nimport {\n MessagingFee,\n MessagingReceipt,\n OAppReceiverUpgradeable,\n OAppUpgradeable,\n Origin\n} from \"../lzApp/OAppUpgradeable.sol\";\nimport {ExocoreGatewayStorage} from \"../storage/ExocoreGatewayStorage.sol\";\n\nimport {Errors} from \"../libraries/Errors.sol\";\nimport {OAppCoreUpgradeable} from \"../lzApp/OAppCoreUpgradeable.sol\";\nimport {IOAppCore} from \"@layerzero-v2/oapp/contracts/oapp/interfaces/IOAppCore.sol\";\nimport {OptionsBuilder} from \"@layerzero-v2/oapp/contracts/oapp/libs/OptionsBuilder.sol\";\nimport {ILayerZeroReceiver} from \"@layerzero-v2/protocol/contracts/interfaces/ILayerZeroReceiver.sol\";\nimport {OwnableUpgradeable} from \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport {Initializable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport {PausableUpgradeable} from \"@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol\";\nimport {ReentrancyGuardUpgradeable} from \"@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol\";\n\n/// @title ExocoreGateway\n/// @author ExocoreNetwork\n/// @notice The gateway contract deployed on Exocore chain for client chain operations.\n/// @dev This contract address must be registered in the `x/assets` module for the precompile operations to go through.\ncontract ExocoreGateway is\n Initializable,\n PausableUpgradeable,\n OwnableUpgradeable,\n ReentrancyGuardUpgradeable,\n IExocoreGateway,\n ExocoreGatewayStorage,\n OAppUpgradeable\n{\n\n using OptionsBuilder for bytes;\n\n /// @dev Ensures that the function is called only from this contract via low-level call.\n modifier onlyCalledFromThis() {\n if (msg.sender != address(this)) {\n revert Errors.ExocoreGatewayOnlyCalledFromThis();\n }\n _;\n }\n\n /// @notice Creates the ExocoreGateway contract.\n /// @param endpoint_ The LayerZero endpoint address deployed on this chain\n constructor(address endpoint_) OAppUpgradeable(endpoint_) {\n _disableInitializers();\n }\n\n receive() external payable {}\n\n /// @notice Initializes the ExocoreGateway contract.\n /// @param owner_ The address of the contract owner.\n function initialize(address owner_) external initializer {\n if (owner_ == address(0)) {\n revert Errors.ZeroAddress();\n }\n\n _initializeWhitelistFunctionSelectors();\n _transferOwnership(owner_);\n __OAppCore_init_unchained(owner_);\n __Pausable_init_unchained();\n __ReentrancyGuard_init_unchained();\n }\n\n /// @dev Initializes the whitelist function selectors.\n function _initializeWhitelistFunctionSelectors() private {\n _whiteListFunctionSelectors[Action.REQUEST_DEPOSIT] = this.requestDeposit.selector;\n _whiteListFunctionSelectors[Action.REQUEST_DELEGATE_TO] = this.requestDelegateTo.selector;\n _whiteListFunctionSelectors[Action.REQUEST_UNDELEGATE_FROM] = this.requestUndelegateFrom.selector;\n _whiteListFunctionSelectors[Action.REQUEST_WITHDRAW_PRINCIPAL_FROM_EXOCORE] =\n this.requestWithdrawPrincipal.selector;\n _whiteListFunctionSelectors[Action.REQUEST_WITHDRAW_REWARD_FROM_EXOCORE] = this.requestWithdrawReward.selector;\n _whiteListFunctionSelectors[Action.REQUEST_DEPOSIT_THEN_DELEGATE_TO] =\n this.requestDepositThenDelegateTo.selector;\n }\n\n /// @notice Pauses the contract.\n function pause() external onlyOwner {\n _pause();\n }\n\n /// @notice Unpauses the contract.\n function unpause() external onlyOwner {\n _unpause();\n }\n\n /// @notice Marks the bootstrap on all chains.\n /// @dev This function obtains a list of client chain ids from the precompile, and then\n /// sends a `REQUEST_MARK_BOOTSTRAP` to all of them. In response, the Bootstrap contract\n /// on those chains should upgrade itself to the ClientChainGateway contract.\n /// This function should be the first to be called after the LZ infrastructure is ready.\n // TODO: call this function automatically, either within the initializer (which requires\n // setPeer) or be triggered by Golang after the contract is deployed.\n // For manual calls, this function should be called immediately after deployment and\n // then never needs to be called again.\n function markBootstrapOnAllChains() public whenNotPaused nonReentrant {\n (bool success, bytes memory result) =\n ASSETS_PRECOMPILE_ADDRESS.staticcall(abi.encodeWithSelector(ASSETS_CONTRACT.getClientChains.selector));\n if (!success) {\n revert Errors.ExocoreGatewayFailedToGetClientChainIds();\n }\n (bool ok, uint32[] memory clientChainIds) = abi.decode(result, (bool, uint32[]));\n if (!ok) {\n revert Errors.ExocoreGatewayFailedToDecodeClientChainIds();\n }\n for (uint256 i = 0; i < clientChainIds.length; i++) {\n uint32 clientChainId = clientChainIds[i];\n if (!chainToBootstrapped[clientChainId]) {\n _sendInterchainMsg(clientChainId, Action.REQUEST_MARK_BOOTSTRAP, \"\", true);\n // TODO: should this be marked only upon receiving a response?\n chainToBootstrapped[clientChainId] = true;\n }\n }\n }\n\n /// @inheritdoc IExocoreGateway\n function registerOrUpdateClientChain(\n uint32 clientChainId,\n bytes32 peer,\n uint8 addressLength,\n string calldata name,\n string calldata metaInfo,\n string calldata signatureType\n ) public onlyOwner whenNotPaused {\n if (\n clientChainId == uint32(0) || peer == bytes32(0) || addressLength == 0 || bytes(name).length == 0\n || bytes(metaInfo).length == 0\n ) {\n revert Errors.ZeroValue();\n }\n // signature type could be left as empty for current implementation\n _registerClientChain(clientChainId, addressLength, name, metaInfo, signatureType);\n super.setPeer(clientChainId, peer);\n\n if (!isRegisteredClientChain[clientChainId]) {\n isRegisteredClientChain[clientChainId] = true;\n emit ClientChainRegistered(clientChainId);\n } else {\n emit ClientChainUpdated(clientChainId);\n }\n }\n\n /// @notice Sets a peer on the destination chain for this contract.\n /// @dev This is the LayerZero peer.\n /// @param clientChainId The id of the client chain.\n /// @param clientChainGateway The address of the peer as bytes32.\n function setPeer(uint32 clientChainId, bytes32 clientChainGateway)\n public\n override(IOAppCore, OAppCoreUpgradeable)\n onlyOwner\n whenNotPaused\n {\n if (!isRegisteredClientChain[clientChainId]) {\n revert Errors.ExocoreGatewayNotRegisteredClientChainId();\n }\n\n super.setPeer(clientChainId, clientChainGateway);\n }\n\n /// @inheritdoc IExocoreGateway\n function addWhitelistTokens(\n uint32 clientChainId,\n bytes32[] calldata tokens,\n uint8[] calldata decimals,\n uint256[] calldata tvlLimits,\n string[] calldata names,\n string[] calldata metaData\n ) external payable onlyOwner whenNotPaused nonReentrant {\n _addOrUpdateWhitelistTokens(clientChainId, tokens, decimals, tvlLimits, names, metaData, true);\n }\n\n /// @inheritdoc IExocoreGateway\n function updateWhitelistedTokens(\n uint32 clientChainId,\n bytes32[] calldata tokens,\n uint8[] calldata decimals,\n uint256[] calldata tvlLimits,\n string[] calldata names,\n string[] calldata metaData\n ) external onlyOwner whenNotPaused {\n _addOrUpdateWhitelistTokens(clientChainId, tokens, decimals, tvlLimits, names, metaData, false);\n }\n\n /// @dev The internal version of addWhitelistTokens and updateWhitelistedTokens.\n /// @param clientChainId Source client chain id\n /// @param tokens List of token addresses\n /// @param decimals List of token decimals (like 18)\n /// @param tvlLimits List of TVL limits (like max supply)\n /// @param names List of token names\n /// @param metaData List of arbitrary meta data for each token\n /// @param add Whether to add or update the tokens\n /// @dev Validates that lengths are equal, <= 255, and that the chain is registered.\n // Though this function would call precompiled contract, all precompiled contracts belong to Exocore\n // and we could make sure its implementation does not have dangerous behavior like reentrancy.\n // slither-disable-next-line reentrancy-no-eth\n function _addOrUpdateWhitelistTokens(\n uint32 clientChainId,\n bytes32[] calldata tokens,\n uint8[] calldata decimals,\n uint256[] calldata tvlLimits,\n string[] calldata names,\n string[] calldata metaData,\n bool add\n ) internal {\n _validateWhitelistTokensInput(clientChainId, tokens, decimals, tvlLimits, names, metaData);\n\n for (uint256 i; i < tokens.length; i++) {\n require(tokens[i] != bytes32(0), \"ExocoreGateway: token cannot be zero address\");\n if (!add) {\n require(isWhitelistedToken[tokens[i]], \"ExocoreGateway: token has not been added to whitelist before\");\n }\n require(tvlLimits[i] > 0, \"ExocoreGateway: tvl limit should not be zero\");\n require(bytes(names[i]).length != 0, \"ExocoreGateway: name cannot be empty\");\n require(bytes(metaData[i]).length != 0, \"ExocoreGateway: meta data cannot be empty\");\n\n bool success = ASSETS_CONTRACT.registerToken(\n clientChainId, abi.encodePacked(tokens[i]), decimals[i], tvlLimits[i], names[i], metaData[i]\n );\n\n if (success) {\n if (add) {\n isWhitelistedToken[tokens[i]] = true;\n emit WhitelistTokenAdded(clientChainId, tokens[i]);\n } else {\n emit WhitelistTokenUpdated(clientChainId, tokens[i]);\n }\n } else {\n if (add) {\n revert AddWhitelistTokenFailed(tokens[i]);\n } else {\n revert UpdateWhitelistTokenFailed(tokens[i]);\n }\n }\n }\n if (add) {\n _sendInterchainMsg(\n clientChainId,\n Action.REQUEST_ADD_WHITELIST_TOKENS,\n abi.encodePacked(uint8(tokens.length), tokens),\n false\n );\n }\n }\n\n /// @dev Validates the input for whitelist tokens.\n /// @param clientChainId The client chain id, which must have been previously registered.\n /// @param tokens The list of token addresses, length must be <= 255.\n /// @param decimals The list of token decimals, length must be equal to that of @param tokens.\n /// @param tvlLimits The list of token TVL limits, length must be equal to that of @param tokens.\n /// @param names The list of token names, length must be equal to that of @param tokens.\n /// @param metaData The list of token meta data, length must be equal to that of @param tokens.\n function _validateWhitelistTokensInput(\n uint32 clientChainId,\n bytes32[] calldata tokens,\n uint8[] calldata decimals,\n uint256[] calldata tvlLimits,\n string[] calldata names,\n string[] calldata metaData\n ) internal view {\n if (!isRegisteredClientChain[clientChainId]) {\n revert ClientChainIDNotRegisteredBefore(clientChainId);\n }\n\n uint256 expectedLength = tokens.length;\n if (expectedLength > type(uint8).max) {\n revert WhitelistTokensListTooLong();\n }\n\n if (\n decimals.length != expectedLength || tvlLimits.length != expectedLength || names.length != expectedLength\n || metaData.length != expectedLength\n ) {\n revert InvalidWhitelistTokensInput();\n }\n }\n\n /// @dev The internal version of registerClientChain.\n /// @param clientChainId The client chain id.\n /// @param addressLength The length of the address type on the client chain.\n /// @param name The name of the client chain.\n /// @param metaInfo The arbitrary metadata for the client chain.\n /// @param signatureType The signature type supported by the client chain.\n function _registerClientChain(\n uint32 clientChainId,\n uint8 addressLength,\n string calldata name,\n string calldata metaInfo,\n string calldata signatureType\n ) internal {\n bool success = ASSETS_CONTRACT.registerClientChain(clientChainId, addressLength, name, metaInfo, signatureType);\n if (!success) {\n revert RegisterClientChainToExocoreFailed(clientChainId);\n }\n }\n\n /// @inheritdoc OAppReceiverUpgradeable\n function _lzReceive(Origin calldata _origin, bytes calldata payload)\n internal\n virtual\n override\n whenNotPaused\n nonReentrant\n {\n _verifyAndUpdateNonce(_origin.srcEid, _origin.sender, _origin.nonce);\n\n Action act = Action(uint8(payload[0]));\n bytes4 selector_ = _whiteListFunctionSelectors[act];\n if (selector_ == bytes4(0)) {\n revert UnsupportedRequest(act);\n }\n\n (bool success, bytes memory responseOrReason) =\n address(this).call(abi.encodePacked(selector_, abi.encode(_origin.srcEid, _origin.nonce, payload[1:])));\n if (!success) {\n revert RequestExecuteFailed(act, _origin.nonce, responseOrReason);\n }\n }\n\n /// @notice Responds to a deposit request from a client chain.\n /// @dev Can only be called from this contract via low-level call.\n /// @param srcChainId The source chain id.\n /// @param lzNonce The layer zero nonce.\n /// @param payload The request payload.\n function requestDeposit(uint32 srcChainId, uint64 lzNonce, bytes calldata payload) public onlyCalledFromThis {\n _validatePayloadLength(payload, DEPOSIT_REQUEST_LENGTH, Action.REQUEST_DEPOSIT);\n\n bytes memory token = payload[:32];\n bytes memory depositor = payload[32:64];\n uint256 amount = uint256(bytes32(payload[64:96]));\n\n (bool success, uint256 updatedBalance) = ASSETS_CONTRACT.depositTo(srcChainId, token, depositor, amount);\n if (!success) {\n revert DepositRequestShouldNotFail(srcChainId, lzNonce);\n }\n\n _sendInterchainMsg(srcChainId, Action.RESPOND, abi.encodePacked(lzNonce, success, updatedBalance), true);\n\n emit DepositResult(true, bytes32(token), bytes32(depositor), amount);\n }\n\n /// @notice Responds to a withdraw-principal request from a client chain.\n /// @dev Can only be called from this contract via low-level call.\n /// @param srcChainId The source chain id.\n /// @param lzNonce The layer zero nonce.\n /// @param payload The request payload.\n function requestWithdrawPrincipal(uint32 srcChainId, uint64 lzNonce, bytes calldata payload)\n public\n onlyCalledFromThis\n {\n _validatePayloadLength(\n payload, WITHDRAW_PRINCIPAL_REQUEST_LENGTH, Action.REQUEST_WITHDRAW_PRINCIPAL_FROM_EXOCORE\n );\n\n bytes memory token = payload[:32];\n bytes memory withdrawer = payload[32:64];\n uint256 amount = uint256(bytes32(payload[64:96]));\n\n bool result = false;\n try ASSETS_CONTRACT.withdrawPrincipal(srcChainId, token, withdrawer, amount) returns (\n bool success, uint256 updatedBalance\n ) {\n result = success;\n _sendInterchainMsg(srcChainId, Action.RESPOND, abi.encodePacked(lzNonce, success, updatedBalance), true);\n } catch {\n emit ExocorePrecompileError(ASSETS_PRECOMPILE_ADDRESS, lzNonce);\n\n _sendInterchainMsg(srcChainId, Action.RESPOND, abi.encodePacked(lzNonce, false, uint256(0)), true);\n }\n\n emit WithdrawPrincipalResult(result, bytes32(token), bytes32(withdrawer), amount);\n }\n\n /// @notice Responds to a withdraw-reward request from a client chain.\n /// @dev Can only be called from this contract via low-level call.\n /// @param srcChainId The source chain id.\n /// @param lzNonce The layer zero nonce.\n /// @param payload The request payload.\n function requestWithdrawReward(uint32 srcChainId, uint64 lzNonce, bytes calldata payload)\n public\n onlyCalledFromThis\n {\n _validatePayloadLength(payload, CLAIM_REWARD_REQUEST_LENGTH, Action.REQUEST_WITHDRAW_REWARD_FROM_EXOCORE);\n\n bytes memory token = payload[:32];\n bytes memory withdrawer = payload[32:64];\n uint256 amount = uint256(bytes32(payload[64:96]));\n\n bool result = false;\n try CLAIM_REWARD_CONTRACT.claimReward(srcChainId, token, withdrawer, amount) returns (\n bool success, uint256 updatedBalance\n ) {\n result = success;\n _sendInterchainMsg(srcChainId, Action.RESPOND, abi.encodePacked(lzNonce, success, updatedBalance), true);\n } catch {\n emit ExocorePrecompileError(CLAIM_REWARD_PRECOMPILE_ADDRESS, lzNonce);\n\n _sendInterchainMsg(srcChainId, Action.RESPOND, abi.encodePacked(lzNonce, false, uint256(0)), true);\n }\n\n emit WithdrawRewardResult(result, bytes32(token), bytes32(withdrawer), amount);\n }\n\n /// @notice Responds to a delegate request from a client chain.\n /// @dev Can only be called from this contract via low-level call.\n /// @param srcChainId The source chain id.\n /// @param lzNonce The layer zero nonce.\n /// @param payload The request payload.\n function requestDelegateTo(uint32 srcChainId, uint64 lzNonce, bytes calldata payload) public onlyCalledFromThis {\n _validatePayloadLength(payload, DELEGATE_REQUEST_LENGTH, Action.REQUEST_DELEGATE_TO);\n\n bytes memory token = payload[:32];\n bytes memory delegator = payload[32:64];\n bytes memory operator = payload[64:106];\n uint256 amount = uint256(bytes32(payload[106:138]));\n\n bool result = false;\n try DELEGATION_CONTRACT.delegateToThroughClientChain(srcChainId, lzNonce, token, delegator, operator, amount)\n returns (bool success) {\n result = success;\n _sendInterchainMsg(srcChainId, Action.RESPOND, abi.encodePacked(lzNonce, success), true);\n } catch {\n emit ExocorePrecompileError(DELEGATION_PRECOMPILE_ADDRESS, lzNonce);\n\n _sendInterchainMsg(srcChainId, Action.RESPOND, abi.encodePacked(lzNonce, false), true);\n }\n\n emit DelegateResult(result, bytes32(token), bytes32(delegator), string(operator), amount);\n }\n\n /// @notice Responds to an undelegate request from a client chain.\n /// @dev Can only be called from this contract via low-level call.\n /// @param srcChainId The source chain id.\n /// @param lzNonce The layer zero nonce.\n /// @param payload The request payload.\n function requestUndelegateFrom(uint32 srcChainId, uint64 lzNonce, bytes calldata payload)\n public\n onlyCalledFromThis\n {\n _validatePayloadLength(payload, UNDELEGATE_REQUEST_LENGTH, Action.REQUEST_UNDELEGATE_FROM);\n\n bytes memory token = payload[:32];\n bytes memory delegator = payload[32:64];\n bytes memory operator = payload[64:106];\n uint256 amount = uint256(bytes32(payload[106:138]));\n\n bool result = false;\n try DELEGATION_CONTRACT.undelegateFromThroughClientChain(\n srcChainId, lzNonce, token, delegator, operator, amount\n ) returns (bool success) {\n result = success;\n _sendInterchainMsg(srcChainId, Action.RESPOND, abi.encodePacked(lzNonce, success), true);\n } catch {\n emit ExocorePrecompileError(DELEGATION_PRECOMPILE_ADDRESS, lzNonce);\n\n _sendInterchainMsg(srcChainId, Action.RESPOND, abi.encodePacked(lzNonce, false), true);\n }\n\n emit UndelegateResult(result, bytes32(token), bytes32(delegator), string(operator), amount);\n }\n\n /// @notice Responds to a deposit-then-delegate request from a client chain.\n /// @dev Can only be called from this contract via low-level call.\n /// @param srcChainId The source chain id.\n /// @param lzNonce The layer zero nonce.\n /// @param payload The request payload.\n function requestDepositThenDelegateTo(uint32 srcChainId, uint64 lzNonce, bytes calldata payload)\n public\n onlyCalledFromThis\n {\n _validatePayloadLength(payload, DEPOSIT_THEN_DELEGATE_REQUEST_LENGTH, Action.REQUEST_DEPOSIT_THEN_DELEGATE_TO);\n\n bytes memory token = payload[:32];\n bytes memory depositor = payload[32:64];\n bytes memory operator = payload[64:106];\n uint256 amount = uint256(bytes32(payload[106:138]));\n\n // while some of the code from requestDeposit and requestDelegateTo is duplicated here,\n // it is done intentionally to work around Solidity's limitations with regards to\n // function calls, error handling and indexing the return data of memory type.\n // for example, you cannot index a bytes memory result from the requestDepositTo call,\n // if you were to modify it to return bytes and then process them here.\n\n bool result = false;\n (bool success, uint256 updatedBalance) = ASSETS_CONTRACT.depositTo(srcChainId, token, depositor, amount);\n if (!success) {\n revert DepositRequestShouldNotFail(srcChainId, lzNonce);\n }\n emit DepositResult(true, bytes32(token), bytes32(depositor), amount);\n\n try DELEGATION_CONTRACT.delegateToThroughClientChain(srcChainId, lzNonce, token, depositor, operator, amount)\n returns (bool delegateSuccess) {\n result = delegateSuccess;\n _sendInterchainMsg(\n srcChainId, Action.RESPOND, abi.encodePacked(lzNonce, delegateSuccess, updatedBalance), true\n );\n } catch {\n emit ExocorePrecompileError(DELEGATION_PRECOMPILE_ADDRESS, lzNonce);\n _sendInterchainMsg(srcChainId, Action.RESPOND, abi.encodePacked(lzNonce, false, updatedBalance), true);\n }\n emit DelegateResult(result, bytes32(token), bytes32(depositor), string(operator), amount);\n }\n\n /// @dev Validates the payload length, that it matches the expected length.\n /// @param payload The payload to validate.\n /// @param expectedLength The expected length of the payload.\n /// @param action The action that the payload is for.\n function _validatePayloadLength(bytes calldata payload, uint256 expectedLength, Action action) private pure {\n if (payload.length != expectedLength) {\n revert InvalidRequestLength(action, expectedLength, payload.length);\n }\n }\n\n /// @dev Sends an interchain message to the client chain.\n /// @param srcChainId The chain id of the source chain, from which a message was received, and to which a response\n /// is being sent.\n /// @param act The action to be performed.\n /// @param actionArgs The arguments for the action.\n /// @param payByApp If the source for the transaction funds is this contract.\n function _sendInterchainMsg(uint32 srcChainId, Action act, bytes memory actionArgs, bool payByApp)\n internal\n whenNotPaused\n {\n bytes memory payload = abi.encodePacked(act, actionArgs);\n bytes memory options = OptionsBuilder.newOptions().addExecutorLzReceiveOption(\n DESTINATION_GAS_LIMIT, DESTINATION_MSG_VALUE\n ).addExecutorOrderedExecutionOption();\n MessagingFee memory fee = _quote(srcChainId, payload, options, false);\n\n MessagingReceipt memory receipt =\n _lzSend(srcChainId, payload, options, MessagingFee(fee.nativeFee, 0), msg.sender, payByApp);\n emit MessageSent(act, receipt.guid, receipt.nonce, receipt.fee.nativeFee);\n }\n\n /// @inheritdoc IExocoreGateway\n function quote(uint32 srcChainid, bytes memory _message) public view returns (uint256 nativeFee) {\n bytes memory options = OptionsBuilder.newOptions().addExecutorLzReceiveOption(\n DESTINATION_GAS_LIMIT, DESTINATION_MSG_VALUE\n ).addExecutorOrderedExecutionOption();\n MessagingFee memory fee = _quote(srcChainid, _message, options, false);\n return fee.nativeFee;\n }\n\n /// @inheritdoc OAppReceiverUpgradeable\n function nextNonce(uint32 srcEid, bytes32 sender)\n public\n view\n virtual\n override(ILayerZeroReceiver, OAppReceiverUpgradeable)\n returns (uint64)\n {\n return inboundNonce[srcEid][sender] + 1;\n }\n\n}\n"},"src/interfaces/IExocoreGateway.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {IOAppCore} from \"@layerzero-v2/oapp/contracts/oapp/interfaces/IOAppCore.sol\";\nimport {IOAppReceiver} from \"@layerzero-v2/oapp/contracts/oapp/interfaces/IOAppReceiver.sol\";\n\n/// @title IExocoreGateway\n/// @author ExocoreNetwork\n/// @notice IExocoreGateway is the interface for the ExocoreGateway contract. It provides a set of functions for\n/// ExocoreGateway operations.\n/// @dev It is deployed on the Exocore end and is designed to interact with other chains,\n/// as well as precompiles on the Exocore chain in response to messages from other chains.\ninterface IExocoreGateway is IOAppReceiver, IOAppCore {\n\n /// @notice Calculates the native fee for sending a message with specific options.\n /// @param srcChainid The chain id of the source chain, from which a message was received,\n /// and to which a response is being sent.\n /// @param _message The message for which the fee is being calculated.\n /// @return nativeFee The calculated native fee for the given message.\n function quote(uint32 srcChainid, bytes memory _message) external view returns (uint256 nativeFee);\n\n /// @notice Registers the @param clientChainId and other meta data to Exocore native module or update the client\n /// chain's meta data, if a chain identified by @param clientChainId already exists. Sets trusted @param peer to\n /// enable cross-chain communication.\n /// @param clientChainId The endpoint ID for client chain.\n /// @param peer The trusted remote contract address to be associated with the corresponding endpoint or some\n /// authorized signer that would be trusted for sending messages from/to source chain to/from this contract.\n /// @param addressLength The bytes length of address type on that client chain.\n /// @param name The name of client chain.\n /// @param metaInfo The arbitrary metadata for client chain.\n /// @param signatureType The cryptographic signature type that client chain supports.\n /// @dev Only the owner/admin of the OApp can call this function.\n /// @dev Indicates that the peer is trusted to send LayerZero messages to this OApp.\n /// @dev Peer is a bytes32 to accommodate non-evm chains.\n function registerOrUpdateClientChain(\n uint32 clientChainId,\n bytes32 peer,\n uint8 addressLength,\n string calldata name,\n string calldata metaInfo,\n string calldata signatureType\n ) external;\n\n /// @notice Adds a list of whitelisted tokens to the client chain.\n /// @param clientChainId The LayerZero chain id of the client chain.\n /// @param tokens The list of token addresses to be whitelisted.\n /// @param decimals The list of token decimals, in the same order as the tokens list.\n /// @param tvlLimits The list of token TVL limits (typically max supply),in the same order as the tokens list.\n /// @param names The names of the tokens, in the same order as the tokens list.\n /// @param metaData The meta information of the tokens, in the same order as the tokens list.\n /// @dev The chain must be registered before adding tokens.\n function addWhitelistTokens(\n uint32 clientChainId,\n bytes32[] calldata tokens,\n uint8[] calldata decimals,\n uint256[] calldata tvlLimits,\n string[] calldata names,\n string[] calldata metaData\n ) external payable;\n\n /// @notice Updates a list of whitelisted tokens to the client chain.\n /// @param clientChainId The LayerZero chain id of the client chain.\n /// @param tokens The list of token addresses to be whitelisted.\n /// @param decimals The list of token decimals, in the same order as the tokens list.\n /// @param tvlLimits The list of token TVL limits (typically max supply),in the same order as the tokens list.\n /// @param names The names of the tokens, in the same order as the tokens list.\n /// @param metaData The meta information of the tokens, in the same order as the tokens list.\n /// @dev The chain must be registered before updating tokens, and the token as well.\n function updateWhitelistedTokens(\n uint32 clientChainId,\n bytes32[] calldata tokens,\n uint8[] calldata decimals,\n uint256[] calldata tvlLimits,\n string[] calldata names,\n string[] calldata metaData\n ) external;\n\n}\n"},"src/interfaces/precompiles/IAssets.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity >=0.8.17;\n\n/// @dev The Assets contract's address.\naddress constant ASSETS_PRECOMPILE_ADDRESS = 0x0000000000000000000000000000000000000804;\n\n/// @dev The Assets contract's instance.\nIAssets constant ASSETS_CONTRACT = IAssets(ASSETS_PRECOMPILE_ADDRESS);\n\n/// @author Exocore Team\n/// @title Assets Precompile Contract\n/// @dev The interface through which solidity contracts will interact with assets module\n/// @custom:address 0x0000000000000000000000000000000000000804\ninterface IAssets {\n\n /// TRANSACTIONS\n /// @dev deposit the client chain assets for the staker,\n /// that will change the state in deposit module\n /// Note that this address cannot be a module account.\n /// @param clientChainLzID The LzID of client chain\n /// @param assetsAddress The client chain asset address\n /// @param stakerAddress The staker address\n /// @param opAmount The amount to deposit\n function depositTo(uint32 clientChainLzID, bytes memory assetsAddress, bytes memory stakerAddress, uint256 opAmount)\n external\n returns (bool success, uint256 latestAssetState);\n\n /// TRANSACTIONS\n /// @dev withdraw To the staker, that will change the state in withdraw module\n /// Note that this address cannot be a module account.\n /// @param clientChainLzID The LzID of client chain\n /// @param assetsAddress The client chain asset Address\n /// @param withdrawAddress The withdraw address\n /// @param opAmount The withdraw amount\n function withdrawPrincipal(\n uint32 clientChainLzID,\n bytes memory assetsAddress,\n bytes memory withdrawAddress,\n uint256 opAmount\n ) external returns (bool success, uint256 latestAssetState);\n\n /// QUERIES\n /// @dev Returns the chain indices of the client chains.\n function getClientChains() external view returns (bool, uint32[] memory);\n\n /// TRANSACTIONS\n /// @dev register some client chain to allow token registration from that chain, staking\n /// from that chain, and other operations from that chain.\n /// @param clientChainID is the layerZero chainID if it is supported.\n // It might be allocated by Exocore when the client chain isn't supported\n // by layerZero\n function registerClientChain(\n uint32 clientChainID,\n uint8 addressLength,\n string calldata name,\n string calldata metaInfo,\n string calldata signatureType\n ) external returns (bool success);\n\n /// TRANSACTIONS\n /// @dev register unwhitelisted token address to exocore assets module\n /// @param clientChainID is the layerZero chainID if it is supported.\n // It might be allocated by Exocore when the client chain isn't supported\n // by layerZero\n /// @param token The token address that would be registered to exocore\n function registerToken(\n uint32 clientChainID,\n bytes calldata token,\n uint8 decimals,\n uint256 tvlLimit,\n string calldata name,\n string calldata metaData\n ) external returns (bool success);\n\n}\n"},"src/interfaces/precompiles/IClaimReward.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity >=0.8.17;\n\n/// TODO: we might remove this precompile contract and merge it into assets precompile\n/// if we decide to handle reward withdrawal request by assets precompile\n\n/// @dev The claimReward contract's address.\naddress constant CLAIM_REWARD_PRECOMPILE_ADDRESS = 0x0000000000000000000000000000000000000806;\n\n/// @dev The claimReward contract's instance.\nIClaimReward constant CLAIM_REWARD_CONTRACT = IClaimReward(CLAIM_REWARD_PRECOMPILE_ADDRESS);\n\n/// @author Exocore Team\n/// @title ClaimReward Precompile Contract\n/// @dev The interface through which solidity contracts will interact with ClaimReward\n/// @custom:address 0x0000000000000000000000000000000000000806\ninterface IClaimReward {\n\n /// TRANSACTIONS\n /// @dev ClaimReward To the staker, that will change the state in reward module\n /// Note that this address cannot be a module account.\n /// @param clientChainLzId The lzId of client chain\n /// @param assetsAddress The client chain asset Address\n /// @param withdrawRewardAddress The claim reward address\n /// @param opAmount The reward amount\n function claimReward(\n uint32 clientChainLzId,\n bytes memory assetsAddress,\n bytes memory withdrawRewardAddress,\n uint256 opAmount\n ) external returns (bool success, uint256 latestAssetState);\n\n}\n"},"src/interfaces/precompiles/IDelegation.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity >=0.8.17;\n\n/// @dev The delegation contract's address.\naddress constant DELEGATION_PRECOMPILE_ADDRESS = 0x0000000000000000000000000000000000000805;\n\n/// @dev The delegation contract's instance.\nIDelegation constant DELEGATION_CONTRACT = IDelegation(DELEGATION_PRECOMPILE_ADDRESS);\n\n/// @author Exocore Team\n/// @title delegation Precompile Contract\n/// @dev The interface through which solidity contracts will interact with delegation\n/// @custom:address 0x0000000000000000000000000000000000000805\ninterface IDelegation {\n\n /// TRANSACTIONS\n /// @dev delegate the client chain assets to the operator through client chain, that will change the states in\n /// delegation and assets module.\n /// Note that this address cannot be a module account.\n /// @param clientChainLzId The lzId of client chain\n /// @param lzNonce The cross chain tx layerZero nonce\n /// @param assetsAddress The client chain asset Address\n /// @param stakerAddress The staker address\n /// @param operatorAddr The operator address that wants to be delegated to\n /// @param opAmount The delegation amount\n function delegateToThroughClientChain(\n uint32 clientChainLzId,\n uint64 lzNonce,\n bytes memory assetsAddress,\n bytes memory stakerAddress,\n bytes memory operatorAddr,\n uint256 opAmount\n ) external returns (bool success);\n\n /// TRANSACTIONS\n /// @dev undelegate the client chain assets from the operator through client chain, that will change the states in\n /// delegation and assets module\n /// Note that this address cannot be a module account.\n /// @param clientChainLzId The lzId of client chain\n /// @param lzNonce The cross chain tx layerZero nonce\n /// @param assetsAddress The client chain asset Address\n /// @param stakerAddress The staker address\n /// @param operatorAddr The operator address that wants to unDelegate from\n /// @param opAmount The Undelegation amount\n function undelegateFromThroughClientChain(\n uint32 clientChainLzId,\n uint64 lzNonce,\n bytes memory assetsAddress,\n bytes memory stakerAddress,\n bytes memory operatorAddr,\n uint256 opAmount\n ) external returns (bool success);\n\n}\n"},"src/lzApp/OAppUpgradeable.sol":{"content":"// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.20;\n\n// @dev Import the 'MessagingFee' and 'MessagingReceipt' so it's exposed to OApp implementers\n// solhint-disable-next-line no-unused-import\nimport {MessagingFee, MessagingReceipt, OAppSenderUpgradeable} from \"./OAppSenderUpgradeable.sol\";\n// @dev Import the 'Origin' so it's exposed to OApp implementers\n// solhint-disable-next-line no-unused-import\n\nimport {OAppCoreUpgradeable} from \"./OAppCoreUpgradeable.sol\";\nimport {OAppReceiverUpgradeable, Origin} from \"./OAppReceiverUpgradeable.sol\";\n\n/**\n * @title OApp\n * @dev Abstract contract serving as the base for OApp implementation, combining OAppSender and OAppReceiver\n * functionality.\n */\nabstract contract OAppUpgradeable is OAppSenderUpgradeable, OAppReceiverUpgradeable {\n\n /**\n * @dev Constructor to initialize the OApp with the provided endpoint.\n * @param _endpoint The address of the LOCAL LayerZero endpoint.\n */\n constructor(address _endpoint) OAppCoreUpgradeable(_endpoint) {}\n\n /**\n * @dev Initialize delegate\n * @param _delegate The delegate capable of making OApp configurations inside of the endpoint.\n */\n function __OApp_init(address _delegate) internal onlyInitializing {\n __OAppCore_init(_delegate);\n }\n\n function __OApp_init_unchained(address _delegate) internal onlyInitializing {\n __OAppCore_init_unchained(_delegate);\n }\n\n /**\n * @notice Retrieves the OApp version information.\n * @return senderVersion The version of the OAppSender.sol implementation.\n * @return receiverVersion The version of the OAppReceiver.sol implementation.\n */\n function oAppVersion()\n public\n pure\n virtual\n override(OAppSenderUpgradeable, OAppReceiverUpgradeable)\n returns (uint64 senderVersion, uint64 receiverVersion)\n {\n return (SENDER_VERSION, RECEIVER_VERSION);\n }\n\n}\n"},"src/storage/ExocoreGatewayStorage.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {GatewayStorage} from \"./GatewayStorage.sol\";\n\n/// @title ExocoreGatewayStorage\n/// @notice Storage used by the ExocoreGateway contract.\n/// @author ExocoreNetwork\ncontract ExocoreGatewayStorage is GatewayStorage {\n\n /// @dev The length of a deposit request, in bytes.\n // bytes32 token + bytes32 depositor + uint256 amount\n uint256 internal constant DEPOSIT_REQUEST_LENGTH = 96;\n\n /// @dev The length of a delegate request, in bytes.\n // bytes32 token + bytes32 delegator + bytes(42) operator + uint256 amount\n uint256 internal constant DELEGATE_REQUEST_LENGTH = 138;\n\n /// @dev The length of an undelegate request, in bytes.\n // bytes32 token + bytes32 delegator + bytes(42) operator + uint256 amount\n uint256 internal constant UNDELEGATE_REQUEST_LENGTH = 138;\n\n /// @dev The length of a withdraw principal request, in bytes.\n // bytes32 token + bytes32 withdrawer + uint256 amount\n uint256 internal constant WITHDRAW_PRINCIPAL_REQUEST_LENGTH = 96;\n\n /// @dev The length of a claim reward request, in bytes.\n // bytes32 token + bytes32 withdrawer + uint256 amount\n uint256 internal constant CLAIM_REWARD_REQUEST_LENGTH = 96;\n\n /// @dev The length of a deposit-then-delegate request, in bytes.\n // bytes32 token + bytes32 delegator + bytes(42) operator + uint256 amount\n uint256 internal constant DEPOSIT_THEN_DELEGATE_REQUEST_LENGTH = DELEGATE_REQUEST_LENGTH;\n\n // constants used for layerzero messaging\n /// @dev The gas limit for all the destination chains.\n uint128 internal constant DESTINATION_GAS_LIMIT = 500_000;\n\n /// @dev The msg.value for all the destination chains.\n uint128 internal constant DESTINATION_MSG_VALUE = 0;\n\n /// @notice A mapping from client chain IDs to whether the chain has been bootstrapped.\n /// @dev Used to ensure no repeated bootstrap requests are sent.\n mapping(uint32 clienChainId => bool) public chainToBootstrapped;\n\n /// @notice A mapping from client chain IDs to whether the chain has been registered.\n /// @dev Used to ensure that only registered client chains can interact with the gateway.\n mapping(uint32 clienChainId => bool registered) public isRegisteredClientChain;\n\n /// @notice A mapping from token address to whether the token is whitelisted.\n /// @dev Used to ensure no duplicate tokens are added to the whitelist.\n mapping(bytes32 token => bool whitelisted) public isWhitelistedToken;\n\n /// @notice Emitted when a precompile call fails.\n /// @param precompile Address of the precompile contract.\n /// @param nonce The LayerZero nonce\n event ExocorePrecompileError(address indexed precompile, uint64 nonce);\n\n /// @notice Emitted upon the registration of a new client chain.\n /// @param clientChainId The LayerZero chain ID of the client chain.\n event ClientChainRegistered(uint32 clientChainId);\n\n /// @notice Emitted upon the update of a client chain.\n /// @param clientChainId The LayerZero chain ID of the client chain.\n event ClientChainUpdated(uint32 clientChainId);\n\n /// @notice Emitted when a token is added to the whitelist.\n /// @param clientChainId The LayerZero chain ID of the client chain.\n /// @param token The address of the token.\n event WhitelistTokenAdded(uint32 clientChainId, bytes32 token);\n\n /// @notice Emitted when a token is updated in the whitelist.\n /// @param clientChainId The LayerZero chain ID of the client chain.\n /// @param token The address of the token.\n event WhitelistTokenUpdated(uint32 clientChainId, bytes32 token);\n\n /* --------- asset operations results and staking operations results -------- */\n /// @notice Emitted when reward is withdrawn.\n /// @param success Whether the withdrawal was successful.\n /// @param token The address of the token.\n /// @param withdrawer The address of the withdrawer.\n /// @param amount The amount of the token withdrawn.\n event WithdrawRewardResult(bool indexed success, bytes32 indexed token, bytes32 indexed withdrawer, uint256 amount);\n\n /// @notice Emitted when a deposit happens.\n /// @param success Whether the deposit was successful.\n /// @param token The address of the token.\n /// @param depositor The address of the depositor.\n /// @param amount The amount of the token deposited.\n event DepositResult(bool indexed success, bytes32 indexed token, bytes32 indexed depositor, uint256 amount);\n\n /// @notice Emitted when principal is withdrawn.\n /// @param success Whether the withdrawal was successful.\n /// @param token The address of the token.\n /// @param withdrawer The address of the withdrawer.\n /// @param amount The amount of the token withdrawn.\n event WithdrawPrincipalResult(\n bool indexed success, bytes32 indexed token, bytes32 indexed withdrawer, uint256 amount\n );\n\n /// @notice Emitted upon delegation.\n /// @param success Whether the delegation was successful.\n /// @param token The address of the token.\n /// @param delegator The address of the delegator.\n /// @param operator The Exo account address of the operator.\n /// @param amount The amount of the token delegated.\n event DelegateResult(\n bool indexed success, bytes32 indexed token, bytes32 indexed delegator, string operator, uint256 amount\n );\n\n /// @notice Emitted upon undelegation\n /// @param success Whether the undelegation was successful.\n /// @param token The address of the token.\n /// @param undelegator The address of the undelegator.\n /// @param operator The Exo account address of the operator.\n /// @param amount The amount of the token undelegated.\n event UndelegateResult(\n bool indexed success, bytes32 indexed token, bytes32 indexed undelegator, string operator, uint256 amount\n );\n\n /// @notice Thrown when the execution of a request fails\n /// @param act The action that failed.\n /// @param nonce The LayerZero nonce.\n /// @param reason The reason for the failure.\n error RequestExecuteFailed(Action act, uint64 nonce, bytes reason);\n\n /// @notice Thrown when the execution of a precompile call fails.\n /// @param selector_ The function selector of the precompile call.\n /// @param reason The reason for the failure.\n error PrecompileCallFailed(bytes4 selector_, bytes reason);\n\n /// @notice Thrown when the request length is invalid.\n /// @param act The action that failed.\n /// @param expectedLength The expected length of the request.\n /// @param actualLength The actual length of the request.\n error InvalidRequestLength(Action act, uint256 expectedLength, uint256 actualLength);\n\n /// @notice Thrown when a deposit request fails.\n /// @param srcChainId The source chain ID.\n /// @param lzNonce The LayerZero nonce.\n /// @dev This is considered a critical error.\n error DepositRequestShouldNotFail(uint32 srcChainId, uint64 lzNonce);\n\n /// @notice Thrown when a client chain registration fails\n /// @param clientChainId The LayerZero chain ID of the client chain.\n error RegisterClientChainToExocoreFailed(uint32 clientChainId);\n\n /// @notice Thrown when a whitelist token addition fails\n /// @param token The address of the token.\n error AddWhitelistTokenFailed(bytes32 token);\n\n /// @notice Thrown when a whitelist token update fails\n /// @param token The address of the token.\n error UpdateWhitelistTokenFailed(bytes32 token);\n\n /// @notice Thrown when the whitelist tokens input is invalid.\n error InvalidWhitelistTokensInput();\n\n /// @notice Thrown when the client chain ID is not registered.\n /// @param clientChainId The LayerZero chain ID of the client chain.\n error ClientChainIDNotRegisteredBefore(uint32 clientChainId);\n\n /// @notice Thrown when the whitelist tokens list is too long.\n error WhitelistTokensListTooLong();\n\n /// @dev Storage gap to allow for future upgrades.\n uint256[40] private __gap;\n\n}\n"},"src/libraries/Errors.sol":{"content":"pragma solidity ^0.8.19;\n\n/// @dev @title Errors library\n/// @dev @notice A library for all errors that can be thrown in the Exocore contracts\n/// @dev All errors in Exocore follow the following syntax: 'error ContractNameErrorName(arg1, arg2, ...)', where\n/// @dev 'ContractName' is the name of the contract\n/// @dev that the error originates from and 'ErrorName' is the name of the error. The arguments are optional and are\n/// used to\n/// @dev provide additional context to the error\n/// @dev 'Global' errors are those that are thrown from various contracts throughout the protocol and do not have a\n/// @dev 'ContractName' prefix\n\nlibrary Errors {\n\n /////////////////////\n // Global Errors //\n /////////////////////\n\n /// @dev Thrown when the passed-in address is the zero address, i.e. address(0)\n error ZeroAddress();\n\n /// @dev Thrown when passed-in amount is zero\n error ZeroAmount();\n\n /// @dev Thrown wehn the passed-in value is zero\n /// @dev This is used when the value in question is not an amount\n error ZeroValue();\n\n /// @dev Index out of array bounds\n error IndexOutOfBounds();\n\n ////////////////////////\n // Bootstrap Errors //\n ////////////////////////\n\n /// @dev Bootstrap: spawn time should be in the future\n error BootstrapSpawnTimeAlreadyPast();\n\n /// @dev Bootstrap: spawn time should be greater than offset duration\n error BootstrapSpawnTimeLessThanDuration();\n\n /// @dev Bootstrap: lock time should be in the future\n error BootstrapLockTimeAlreadyPast();\n\n /// @dev Bootstrap: operation not allowed after lock time\n error BootstrapBeforeLocked();\n\n /// @dev Bootstrap: token should be not whitelisted before\n /// @param token The address of the token already whitelisted\n error BootstrapAlreadyWhitelisted(address token);\n\n /// @dev Bootstrap: Ethereum address already linked to a validator\n /// @param validator The Ethereum address of the validator\n error BootstrapValidatorAlreadyHasAddress(address validator);\n\n /// @dev Bootstrap: Validator with this Exocore address is already registered\n error BootstrapValidatorAlreadyRegistered();\n\n /// @dev Bootstrap: Consensus public key already in use\n /// @param publicKey The public key that is already in use\n error BootstrapConsensusPubkeyAlreadyUsed(bytes32 publicKey);\n\n /// @dev Bootstrap: Validator name already in use\n error BootstrapValidatorNameAlreadyUsed();\n\n /// @dev Bootstrap: Invalid commission\n error BootstrapInvalidCommission();\n\n /// @dev Bootstrap: validator does not exist\n error BootstrapValidatorNotExist();\n\n /// @dev Bootstrap: Commission already edited once\n error BootstrapComissionAlreadyEdited();\n\n /// @dev Bootstrap: Rate exceeds max rate\n error BootstrapRateExceedsMaxRate();\n\n /// @dev Bootstrap: Rate change exceeds max change rate\n error BootstrapRateChangeExceedsMaxChangeRate();\n\n /// @dev Bootstrap: insufficient deposited balance\n error BootstrapInsufficientDepositedBalance();\n\n /// @dev Bootstrap: insufficient withdrawable balance\n error BootstrapInsufficientWithdrawableBalance();\n\n /// @dev Bootstrap: insufficient delegated balance\n error BootstrapInsufficientDelegatedBalance();\n\n /// @dev Bootstrap: no ether required for delegation/undelegation\n error BootstrapNoEtherForDelegation();\n\n /// @dev Bootstrap: not yet in the bootstrap time\n error BootstrapNotSpawnTime();\n\n /// @dev Bootstrap: not yet bootstrapped\n error BootstrapAlreadyBootstrapped();\n\n /// @dev Bootstrap: client chain initialization data is malformed\n error BootstrapClientChainDataMalformed();\n\n //////////////////////////////////\n // BootstrapLzReceiver Errors //\n //////////////////////////////////\n\n /// @dev BootstrapLzReceiver: could only be called from this contract itself with low level call\n error BootstrapLzReceiverOnlyCalledFromThis();\n\n /// @dev BootstrapLzReceiver: invalid action\n error BootstrapLzReceiverInvalidAction();\n\n /////////////////////////////////\n // ClientChainGateway Errors //\n /////////////////////////////////\n\n /// @dev ClientChainGateway: tokens length should not execeed 255\n error ClientChainGatewayAddWhitelistTooManyTokens();\n\n /// @dev ClientChainGateway: token should not be whitelisted before\n error ClientChainGatewayAlreadyWhitelisted();\n\n //////////////////////////////////////\n // ClientGatewayLzReceiver Errors //\n //////////////////////////////////////\n\n /// @dev ClientChainLzReceiver: could only be called from this contract itself with low level call\n error ClientGatewayLzReceiverOnlyCalledFromThis();\n\n ///////////////////////////////\n // CustomProxyAdmin Errors //\n ///////////////////////////////\n\n /// @dev CustomProxyAdmin: sender must be bootstrapper\n error CustomProxyAdminOnlyCalledFromBootstrapper();\n\n /// @dev CustomProxyAdmin: sender must be the proxy itself\n error CustomProxyAdminOnlyCalledFromProxy();\n\n /////////////////////////\n // ExoCapsule Errors //\n /////////////////////////\n\n /// @dev ExoCapsule: withdrawal amount is larger than staker's withdrawable balance\n error ExoCapsuleWithdrawalAmountExceeds();\n\n /// @dev ExoCapsule: withdrawNonBeaconChainETHBalance: amountToWithdraw is greater than nonBeaconChainETHBalance\n error ExoCapsuleNonBeaconChainWithdrawalAmountExceeds();\n\n /// @dev ExoCapsule: timestamp should be greater than beacon chain genesis timestamp\n error ExoCapsuleTimestampBeforeGenesis();\n\n /////////////////////////////\n // ExocoreGateway Errors //\n /////////////////////////////\n\n /// @dev ExocoreGateway: can only be called from this contract itself with a low-level call\n error ExocoreGatewayOnlyCalledFromThis();\n\n /// @dev ExocoreGateway: failed to get client chain ids\n error ExocoreGatewayFailedToGetClientChainIds();\n\n /// @dev ExocoreGateway: failed to decode client chain ids\n error ExocoreGatewayFailedToDecodeClientChainIds();\n\n /// @dev ExocoreGateway: client chain should be registered before setting peer to change peer address\n error ExocoreGatewayNotRegisteredClientChainId();\n\n ////////////////////////////////////////\n // NativeRestakingController Errors //\n ////////////////////////////////////////\n\n /// @dev NativeRestakingController: native restaking is not enabled\n error NativeRestakingControllerNotWhitelisted();\n\n /// @dev NativeRestakingController: stake value must be exactly 32 ether\n error NativeRestakingControllerInvalidStakeValue();\n\n /// @dev NativeRestakingController: message sender has already created the capsule\n error NativeRestakingControllerCapsuleAlreadyCreated();\n\n ////////////////////\n // Vault Errors //\n ////////////////////\n\n /// @dev Vault: caller is not the gateway\n error VaultCallerIsNotGateway();\n\n /// @dev Vault: withdrawal amount is larger than depositor's withdrawable balance\n error VaultWithdrawalAmountExceeds();\n\n /// @dev Vault: total principal unlock amount is larger than the total deposited amount\n error VaultPrincipalExceedsTotalDeposit();\n\n /// @dev Vault: total principal unlock amount is larger than the total deposited amount\n error VaultTotalUnlockPrincipalExceedsDeposit();\n\n}\n"},"src/lzApp/OAppCoreUpgradeable.sol":{"content":"// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.20;\n\nimport {ILayerZeroEndpointV2, IOAppCore} from \"@layerzero-v2/oapp/contracts/oapp/interfaces/IOAppCore.sol\";\nimport {OwnableUpgradeable} from \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\n\n/**\n * @title OAppCoreUpgradeable\n * @dev Abstract contract implementing the IOAppCore interface with basic OApp configurations.\n */\nabstract contract OAppCoreUpgradeable is IOAppCore, OwnableUpgradeable {\n\n // The LayerZero endpoint associated with the given OApp\n ILayerZeroEndpointV2 public immutable endpoint;\n\n // Mapping to store peers associated with corresponding endpoints\n mapping(uint32 eid => bytes32 peer) public peers;\n\n /**\n * @dev Constructor to initialize the OAppCore with the provided endpoint and delegate.\n * @param _endpoint The address of the LOCAL Layer Zero endpoint.\n */\n constructor(address _endpoint) {\n require(_endpoint != address(0), \"layerzero endpoint should not be empty\");\n endpoint = ILayerZeroEndpointV2(_endpoint);\n\n _disableInitializers();\n }\n\n /**\n * @dev The delegate typically should be set as the owner of the contract.\n * @param _delegate The delegate capable of making OApp configurations inside of the endpoint.\n */\n function __OAppCore_init(address _delegate) internal onlyInitializing {\n if (_delegate == address(0)) {\n revert InvalidDelegate();\n }\n endpoint.setDelegate(_delegate);\n _transferOwnership(_delegate);\n }\n\n /**\n * @dev The delegate typically should be set as the owner of the contract.\n * @param _delegate The delegate capable of making OApp configurations inside of the endpoint.\n */\n function __OAppCore_init_unchained(address _delegate) internal onlyInitializing {\n if (_delegate == address(0)) {\n revert InvalidDelegate();\n }\n endpoint.setDelegate(_delegate);\n }\n\n /**\n * @notice Sets the peer address (OApp instance) for a corresponding endpoint.\n * @param _eid The endpoint ID.\n * @param _peer The address of the peer to be associated with the corresponding endpoint.\n *\n * @dev Only the owner/admin of the OApp can call this function.\n * @dev Indicates that the peer is trusted to send LayerZero messages to this OApp.\n * @dev Set this to bytes32(0) to remove the peer address.\n * @dev Peer is a bytes32 to accommodate non-evm chains.\n */\n function setPeer(uint32 _eid, bytes32 _peer) public virtual onlyOwner {\n peers[_eid] = _peer;\n emit PeerSet(_eid, _peer);\n }\n\n /**\n * @notice Internal function to get the peer address associated with a specific endpoint; reverts if NOT set.\n * ie. the peer is set to bytes32(0).\n * @param _eid The endpoint ID.\n * @return peer The address of the peer associated with the specified endpoint.\n */\n function _getPeerOrRevert(uint32 _eid) internal view virtual returns (bytes32) {\n bytes32 peer = peers[_eid];\n if (peer == bytes32(0)) {\n revert NoPeer(_eid);\n }\n return peer;\n }\n\n /**\n * @notice Sets the delegate address for the OApp.\n * @param _delegate The address of the delegate to be set.\n *\n * @dev Only the owner/admin of the OApp can call this function.\n * @dev Provides the ability for a delegate to set configs, on behalf of the OApp, directly on the Endpoint\n * contract.\n */\n function setDelegate(address _delegate) public onlyOwner {\n endpoint.setDelegate(_delegate);\n }\n\n}\n"},"lib/LayerZero-v2/oapp/contracts/oapp/interfaces/IOAppCore.sol":{"content":"// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.20;\n\nimport { ILayerZeroEndpointV2 } from \"@layerzerolabs/lz-evm-protocol-v2/contracts/interfaces/ILayerZeroEndpointV2.sol\";\n\n/**\n * @title IOAppCore\n */\ninterface IOAppCore {\n // Custom error messages\n error OnlyPeer(uint32 eid, bytes32 sender);\n error NoPeer(uint32 eid);\n error InvalidEndpointCall();\n error InvalidDelegate();\n\n // Event emitted when a peer (OApp) is set for a corresponding endpoint\n event PeerSet(uint32 eid, bytes32 peer);\n\n /**\n * @notice Retrieves the OApp version information.\n * @return senderVersion The version of the OAppSender.sol contract.\n * @return receiverVersion The version of the OAppReceiver.sol contract.\n */\n function oAppVersion() external view returns (uint64 senderVersion, uint64 receiverVersion);\n\n /**\n * @notice Retrieves the LayerZero endpoint associated with the OApp.\n * @return iEndpoint The LayerZero endpoint as an interface.\n */\n function endpoint() external view returns (ILayerZeroEndpointV2 iEndpoint);\n\n /**\n * @notice Retrieves the peer (OApp) associated with a corresponding endpoint.\n * @param _eid The endpoint ID.\n * @return peer The peer address (OApp instance) associated with the corresponding endpoint.\n */\n function peers(uint32 _eid) external view returns (bytes32 peer);\n\n /**\n * @notice Sets the peer address (OApp instance) for a corresponding endpoint.\n * @param _eid The endpoint ID.\n * @param _peer The address of the peer to be associated with the corresponding endpoint.\n */\n function setPeer(uint32 _eid, bytes32 _peer) external;\n\n /**\n * @notice Sets the delegate address for the OApp Core.\n * @param _delegate The address of the delegate to be set.\n */\n function setDelegate(address _delegate) external;\n}\n"},"lib/LayerZero-v2/oapp/contracts/oapp/libs/OptionsBuilder.sol":{"content":"// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.20;\n\nimport { BytesLib } from \"solidity-bytes-utils/contracts/BytesLib.sol\";\nimport { SafeCast } from \"@openzeppelin/contracts/utils/math/SafeCast.sol\";\n\nimport { ExecutorOptions } from \"@layerzerolabs/lz-evm-protocol-v2/contracts/messagelib/libs/ExecutorOptions.sol\";\nimport { DVNOptions } from \"@layerzerolabs/lz-evm-messagelib-v2/contracts/uln/libs/DVNOptions.sol\";\n\n/**\n * @title OptionsBuilder\n * @dev Library for building and encoding various message options.\n */\nlibrary OptionsBuilder {\n using SafeCast for uint256;\n using BytesLib for bytes;\n\n // Constants for options types\n uint16 internal constant TYPE_1 = 1; // legacy options type 1\n uint16 internal constant TYPE_2 = 2; // legacy options type 2\n uint16 internal constant TYPE_3 = 3;\n\n // Custom error message\n error InvalidSize(uint256 max, uint256 actual);\n error InvalidOptionType(uint16 optionType);\n\n // Modifier to ensure only options of type 3 are used\n modifier onlyType3(bytes memory _options) {\n if (_options.toUint16(0) != TYPE_3) revert InvalidOptionType(_options.toUint16(0));\n _;\n }\n\n /**\n * @dev Creates a new options container with type 3.\n * @return options The newly created options container.\n */\n function newOptions() internal pure returns (bytes memory) {\n return abi.encodePacked(TYPE_3);\n }\n\n /**\n * @dev Adds an executor LZ receive option to the existing options.\n * @param _options The existing options container.\n * @param _gas The gasLimit used on the lzReceive() function in the OApp.\n * @param _value The msg.value passed to the lzReceive() function in the OApp.\n * @return options The updated options container.\n *\n * @dev When multiples of this option are added, they are summed by the executor\n * eg. if (_gas: 200k, and _value: 1 ether) AND (_gas: 100k, _value: 0.5 ether) are sent in an option to the LayerZeroEndpoint,\n * that becomes (300k, 1.5 ether) when the message is executed on the remote lzReceive() function.\n */\n function addExecutorLzReceiveOption(\n bytes memory _options,\n uint128 _gas,\n uint128 _value\n ) internal pure onlyType3(_options) returns (bytes memory) {\n bytes memory option = ExecutorOptions.encodeLzReceiveOption(_gas, _value);\n return addExecutorOption(_options, ExecutorOptions.OPTION_TYPE_LZRECEIVE, option);\n }\n\n /**\n * @dev Adds an executor native drop option to the existing options.\n * @param _options The existing options container.\n * @param _amount The amount for the native value that is airdropped to the 'receiver'.\n * @param _receiver The receiver address for the native drop option.\n * @return options The updated options container.\n *\n * @dev When multiples of this option are added, they are summed by the executor on the remote chain.\n */\n function addExecutorNativeDropOption(\n bytes memory _options,\n uint128 _amount,\n bytes32 _receiver\n ) internal pure onlyType3(_options) returns (bytes memory) {\n bytes memory option = ExecutorOptions.encodeNativeDropOption(_amount, _receiver);\n return addExecutorOption(_options, ExecutorOptions.OPTION_TYPE_NATIVE_DROP, option);\n }\n\n /**\n * @dev Adds an executor LZ compose option to the existing options.\n * @param _options The existing options container.\n * @param _index The index for the lzCompose() function call.\n * @param _gas The gasLimit for the lzCompose() function call.\n * @param _value The msg.value for the lzCompose() function call.\n * @return options The updated options container.\n *\n * @dev When multiples of this option are added, they are summed PER index by the executor on the remote chain.\n * @dev If the OApp sends N lzCompose calls on the remote, you must provide N incremented indexes starting with 0.\n * ie. When your remote OApp composes (N = 3) messages, you must set this option for index 0,1,2\n */\n function addExecutorLzComposeOption(\n bytes memory _options,\n uint16 _index,\n uint128 _gas,\n uint128 _value\n ) internal pure onlyType3(_options) returns (bytes memory) {\n bytes memory option = ExecutorOptions.encodeLzComposeOption(_index, _gas, _value);\n return addExecutorOption(_options, ExecutorOptions.OPTION_TYPE_LZCOMPOSE, option);\n }\n\n /**\n * @dev Adds an executor ordered execution option to the existing options.\n * @param _options The existing options container.\n * @return options The updated options container.\n */\n function addExecutorOrderedExecutionOption(\n bytes memory _options\n ) internal pure onlyType3(_options) returns (bytes memory) {\n return addExecutorOption(_options, ExecutorOptions.OPTION_TYPE_ORDERED_EXECUTION, bytes(\"\"));\n }\n\n /**\n * @dev Adds a DVN pre-crime option to the existing options.\n * @param _options The existing options container.\n * @param _dvnIdx The DVN index for the pre-crime option.\n * @return options The updated options container.\n */\n function addDVNPreCrimeOption(\n bytes memory _options,\n uint8 _dvnIdx\n ) internal pure onlyType3(_options) returns (bytes memory) {\n return addDVNOption(_options, _dvnIdx, DVNOptions.OPTION_TYPE_PRECRIME, bytes(\"\"));\n }\n\n /**\n * @dev Adds an executor option to the existing options.\n * @param _options The existing options container.\n * @param _optionType The type of the executor option.\n * @param _option The encoded data for the executor option.\n * @return options The updated options container.\n */\n function addExecutorOption(\n bytes memory _options,\n uint8 _optionType,\n bytes memory _option\n ) internal pure onlyType3(_options) returns (bytes memory) {\n return\n abi.encodePacked(\n _options,\n ExecutorOptions.WORKER_ID,\n _option.length.toUint16() + 1, // +1 for optionType\n _optionType,\n _option\n );\n }\n\n /**\n * @dev Adds a DVN option to the existing options.\n * @param _options The existing options container.\n * @param _dvnIdx The DVN index for the DVN option.\n * @param _optionType The type of the DVN option.\n * @param _option The encoded data for the DVN option.\n * @return options The updated options container.\n */\n function addDVNOption(\n bytes memory _options,\n uint8 _dvnIdx,\n uint8 _optionType,\n bytes memory _option\n ) internal pure onlyType3(_options) returns (bytes memory) {\n return\n abi.encodePacked(\n _options,\n DVNOptions.WORKER_ID,\n _option.length.toUint16() + 2, // +2 for optionType and dvnIdx\n _dvnIdx,\n _optionType,\n _option\n );\n }\n\n /**\n * @dev Encodes legacy options of type 1.\n * @param _executionGas The gasLimit value passed to lzReceive().\n * @return legacyOptions The encoded legacy options.\n */\n function encodeLegacyOptionsType1(uint256 _executionGas) internal pure returns (bytes memory) {\n if (_executionGas > type(uint128).max) revert InvalidSize(type(uint128).max, _executionGas);\n return abi.encodePacked(TYPE_1, _executionGas);\n }\n\n /**\n * @dev Encodes legacy options of type 2.\n * @param _executionGas The gasLimit value passed to lzReceive().\n * @param _nativeForDst The amount of native air dropped to the receiver.\n * @param _receiver The _nativeForDst receiver address.\n * @return legacyOptions The encoded legacy options of type 2.\n */\n function encodeLegacyOptionsType2(\n uint256 _executionGas,\n uint256 _nativeForDst,\n bytes memory _receiver // @dev Use bytes instead of bytes32 in legacy type 2 for _receiver.\n ) internal pure returns (bytes memory) {\n if (_executionGas > type(uint128).max) revert InvalidSize(type(uint128).max, _executionGas);\n if (_nativeForDst > type(uint128).max) revert InvalidSize(type(uint128).max, _nativeForDst);\n if (_receiver.length > 32) revert InvalidSize(32, _receiver.length);\n return abi.encodePacked(TYPE_2, _executionGas, _nativeForDst, _receiver);\n }\n}\n"},"lib/LayerZero-v2/protocol/contracts/interfaces/ILayerZeroReceiver.sol":{"content":"// SPDX-License-Identifier: MIT\n\npragma solidity >=0.8.0;\n\nimport { Origin } from \"./ILayerZeroEndpointV2.sol\";\n\ninterface ILayerZeroReceiver {\n function allowInitializePath(Origin calldata _origin) external view returns (bool);\n\n function nextNonce(uint32 _eid, bytes32 _sender) external view returns (uint64);\n\n function lzReceive(\n Origin calldata _origin,\n bytes32 _guid,\n bytes calldata _message,\n address _executor,\n bytes calldata _extraData\n ) external payable;\n}\n"},"lib/openzeppelin-contracts-upgradeable/contracts/access/OwnableUpgradeable.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/ContextUpgradeable.sol\";\nimport {Initializable} from \"../proxy/utils/Initializable.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 * By default, the owner account will be the one that deploys the contract. This\n * can 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 OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\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 require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\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 require(newOwner != address(0), \"Ownable: new owner is the zero address\");\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 /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n"},"lib/openzeppelin-contracts-upgradeable/contracts/proxy/utils/Initializable.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../../utils/AddressUpgradeable.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```solidity\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n *\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts.\n *\n * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a\n * constructor.\n *\n * Emits an {Initialized} event.\n */\n modifier initializer() {\n bool isTopLevelCall = !_initializing;\n require(\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\n \"Initializable: contract is already initialized\"\n );\n _initialized = 1;\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * A reinitializer may be used after the original initialization step. This is essential to configure modules that\n * are added through upgrades and that require initialization.\n *\n * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`\n * cannot be nested. If one is invoked in the context of another, execution will revert.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n *\n * WARNING: setting the version to 255 will prevent any future reinitialization.\n *\n * Emits an {Initialized} event.\n */\n modifier reinitializer(uint8 version) {\n require(!_initializing && _initialized < version, \"Initializable: contract is already initialized\");\n _initialized = version;\n _initializing = true;\n _;\n _initializing = false;\n emit Initialized(version);\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n *\n * Emits an {Initialized} event the first time it is successfully executed.\n */\n function _disableInitializers() internal virtual {\n require(!_initializing, \"Initializable: contract is initializing\");\n if (_initialized != type(uint8).max) {\n _initialized = type(uint8).max;\n emit Initialized(type(uint8).max);\n }\n }\n\n /**\n * @dev Returns the highest version that has been initialized. See {reinitializer}.\n */\n function _getInitializedVersion() internal view returns (uint8) {\n return _initialized;\n }\n\n /**\n * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.\n */\n function _isInitializing() internal view returns (bool) {\n return _initializing;\n }\n}\n"},"lib/openzeppelin-contracts-upgradeable/contracts/security/PausableUpgradeable.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (security/Pausable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/ContextUpgradeable.sol\";\nimport {Initializable} from \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module which allows children to implement an emergency stop\n * mechanism that can be triggered by an authorized account.\n *\n * This module is used through inheritance. It will make available the\n * modifiers `whenNotPaused` and `whenPaused`, which can be applied to\n * the functions of your contract. Note that they will not be pausable by\n * simply including this module, only once the modifiers are put in place.\n */\nabstract contract PausableUpgradeable is Initializable, ContextUpgradeable {\n /**\n * @dev Emitted when the pause is triggered by `account`.\n */\n event Paused(address account);\n\n /**\n * @dev Emitted when the pause is lifted by `account`.\n */\n event Unpaused(address account);\n\n bool private _paused;\n\n /**\n * @dev Initializes the contract in unpaused state.\n */\n function __Pausable_init() internal onlyInitializing {\n __Pausable_init_unchained();\n }\n\n function __Pausable_init_unchained() internal onlyInitializing {\n _paused = false;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is not paused.\n *\n * Requirements:\n *\n * - The contract must not be paused.\n */\n modifier whenNotPaused() {\n _requireNotPaused();\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is paused.\n *\n * Requirements:\n *\n * - The contract must be paused.\n */\n modifier whenPaused() {\n _requirePaused();\n _;\n }\n\n /**\n * @dev Returns true if the contract is paused, and false otherwise.\n */\n function paused() public view virtual returns (bool) {\n return _paused;\n }\n\n /**\n * @dev Throws if the contract is paused.\n */\n function _requireNotPaused() internal view virtual {\n require(!paused(), \"Pausable: paused\");\n }\n\n /**\n * @dev Throws if the contract is not paused.\n */\n function _requirePaused() internal view virtual {\n require(paused(), \"Pausable: not paused\");\n }\n\n /**\n * @dev Triggers stopped state.\n *\n * Requirements:\n *\n * - The contract must not be paused.\n */\n function _pause() internal virtual whenNotPaused {\n _paused = true;\n emit Paused(_msgSender());\n }\n\n /**\n * @dev Returns to normal state.\n *\n * Requirements:\n *\n * - The contract must be paused.\n */\n function _unpause() internal virtual whenPaused {\n _paused = false;\n emit Unpaused(_msgSender());\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n"},"lib/openzeppelin-contracts-upgradeable/contracts/security/ReentrancyGuardUpgradeable.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (security/ReentrancyGuard.sol)\n\npragma solidity ^0.8.0;\nimport {Initializable} from \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module that helps prevent reentrant calls to a function.\n *\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\n * available, which can be applied to functions to make sure there are no nested\n * (reentrant) calls to them.\n *\n * Note that because there is a single `nonReentrant` guard, functions marked as\n * `nonReentrant` may not call one another. This can be worked around by making\n * those functions `private`, and then adding `external` `nonReentrant` entry\n * points to them.\n *\n * TIP: If you would like to learn more about reentrancy and alternative ways\n * to protect against it, check out our blog post\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\n */\nabstract contract ReentrancyGuardUpgradeable is Initializable {\n // Booleans are more expensive than uint256 or any type that takes up a full\n // word because each write operation emits an extra SLOAD to first read the\n // slot's contents, replace the bits taken up by the boolean, and then write\n // back. This is the compiler's defense against contract upgrades and\n // pointer aliasing, and it cannot be disabled.\n\n // The values being non-zero value makes deployment a bit more expensive,\n // but in exchange the refund on every call to nonReentrant will be lower in\n // amount. Since refunds are capped to a percentage of the total\n // transaction's gas, it is best to keep them low in cases like this one, to\n // increase the likelihood of the full refund coming into effect.\n uint256 private constant _NOT_ENTERED = 1;\n uint256 private constant _ENTERED = 2;\n\n uint256 private _status;\n\n function __ReentrancyGuard_init() internal onlyInitializing {\n __ReentrancyGuard_init_unchained();\n }\n\n function __ReentrancyGuard_init_unchained() internal onlyInitializing {\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n * Calling a `nonReentrant` function from another `nonReentrant`\n * function is not supported. It is possible to prevent this from happening\n * by making the `nonReentrant` function external, and making it call a\n * `private` function that does the actual work.\n */\n modifier nonReentrant() {\n _nonReentrantBefore();\n _;\n _nonReentrantAfter();\n }\n\n function _nonReentrantBefore() private {\n // On the first call to nonReentrant, _status will be _NOT_ENTERED\n require(_status != _ENTERED, \"ReentrancyGuard: reentrant call\");\n\n // Any calls to nonReentrant after this point will fail\n _status = _ENTERED;\n }\n\n function _nonReentrantAfter() private {\n // By storing the original value once again, a refund is triggered (see\n // https://eips.ethereum.org/EIPS/eip-2200)\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Returns true if the reentrancy guard is currently set to \"entered\", which indicates there is a\n * `nonReentrant` function in the call stack.\n */\n function _reentrancyGuardEntered() internal view returns (bool) {\n return _status == _ENTERED;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n"},"lib/LayerZero-v2/oapp/contracts/oapp/interfaces/IOAppReceiver.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.20;\n\nimport { ILayerZeroReceiver, Origin } from \"@layerzerolabs/lz-evm-protocol-v2/contracts/interfaces/ILayerZeroReceiver.sol\";\n\ninterface IOAppReceiver is ILayerZeroReceiver {\n /**\n * @notice Retrieves the address responsible for 'sending' composeMsg's to the Endpoint.\n * @return sender The address responsible for 'sending' composeMsg's to the Endpoint.\n *\n * @dev Applications can optionally choose to implement a separate composeMsg sender that is NOT the bridging layer.\n * @dev The default sender IS the OApp implementer.\n */\n function composeMsgSender() external view returns (address sender);\n}\n"},"src/lzApp/OAppSenderUpgradeable.sol":{"content":"// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.20;\n\nimport {OAppCoreUpgradeable} from \"./OAppCoreUpgradeable.sol\";\nimport {\n MessagingFee,\n MessagingParams,\n MessagingReceipt\n} from \"@layerzero-v2/protocol/contracts/interfaces/ILayerZeroEndpointV2.sol\";\nimport {IERC20, SafeERC20} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\n/**\n * @title OAppSenderUpgradeable\n * @dev Abstract contract implementing the OAppSender functionality for sending messages to a LayerZero endpoint.\n */\nabstract contract OAppSenderUpgradeable is OAppCoreUpgradeable {\n\n using SafeERC20 for IERC20;\n\n // Custom error messages\n error NotExactNativeFee(uint256 msgValue);\n error LzTokenUnavailable();\n\n // @dev The version of the OAppSender implementation.\n // @dev Version is bumped when changes are made to this contract.\n uint64 internal constant SENDER_VERSION = 1;\n\n /**\n * @notice Retrieves the OApp version information.\n * @return senderVersion The version of the OAppSender.sol contract.\n * @return receiverVersion The version of the OAppReceiver.sol contract.\n *\n * @dev Providing 0 as the default for OAppReceiver version. Indicates that the OAppReceiver is not implemented.\n * ie. this is a SEND only OApp.\n * @dev If the OApp uses both OAppSender and OAppReceiver, then this needs to be override returning the correct\n * versions\n */\n function oAppVersion() public view virtual returns (uint64 senderVersion, uint64 receiverVersion) {\n return (SENDER_VERSION, 0);\n }\n\n /**\n * @dev Internal function to interact with the LayerZero EndpointV2.quote() for fee calculation.\n * @param _dstEid The destination endpoint ID.\n * @param _message The message payload.\n * @param _options Additional options for the message.\n * @param _payInLzToken Flag indicating whether to pay the fee in LZ tokens.\n * @return fee The calculated MessagingFee for the message.\n * - nativeFee: The native fee for the message.\n * - lzTokenFee: The LZ token fee for the message.\n */\n function _quote(uint32 _dstEid, bytes memory _message, bytes memory _options, bool _payInLzToken)\n internal\n view\n virtual\n returns (MessagingFee memory fee)\n {\n return endpoint.quote(\n MessagingParams(_dstEid, _getPeerOrRevert(_dstEid), _message, _options, _payInLzToken), address(this)\n );\n }\n\n /**\n * @dev Internal function to interact with the LayerZero EndpointV2.send() for sending a message.\n * @param _dstEid The destination endpoint ID.\n * @param _message The message payload.\n * @param _options Additional options for the message.\n * @param _fee The calculated LayerZero fee for the message.\n * - nativeFee: The native fee.\n * - lzTokenFee: The lzToken fee.\n * @param _refundAddress The address to receive any excess fee values sent to the endpoint.\n * @param byApp Whether the native fee is paid by the app itself or by the app caller,\n * if byApp is true, app caller does not need to specify msg.value to pay for the native fee.\n * @return receipt The receipt for the sent message.\n * - guid: The unique identifier for the sent message.\n * - nonce: The nonce of the sent message.\n * - fee: The LayerZero fee incurred for the message.\n */\n function _lzSend(\n uint32 _dstEid,\n bytes memory _message,\n bytes memory _options,\n MessagingFee memory _fee,\n address _refundAddress,\n bool byApp\n ) internal virtual returns (MessagingReceipt memory receipt) {\n // @dev Push corresponding fees to the endpoint, any excess is sent back to the _refundAddress from the\n // endpoint.\n uint256 messageValue = _payNative(_fee.nativeFee, byApp);\n if (_fee.lzTokenFee > 0) {\n _payLzToken(_fee.lzTokenFee);\n }\n\n return endpoint.send{value: messageValue}(\n // solhint-disable-next-line check-send-result\n MessagingParams(_dstEid, _getPeerOrRevert(_dstEid), _message, _options, _fee.lzTokenFee > 0),\n _refundAddress\n );\n }\n\n /**\n * @dev Internal function to pay the native fee associated with the message.\n * @param _nativeFee The native fee to be paid.\n * @param byApp Whether the native fee is paid by the app itself or by the app caller,\n * if byApp is true, do not check that the msg.value is equal to nativeFee.\n * @return nativeFee The amount of native currency paid.\n *\n * @dev If the OApp needs to initiate MULTIPLE LayerZero messages in a single transaction,\n * this will need to be overridden because msg.value would contain multiple lzFees.\n * @dev Should be overridden in the event the LayerZero endpoint requires a different native currency.\n * @dev Some EVMs use an ERC20 as a method for paying transactions/gasFees.\n * @dev The endpoint is EITHER/OR, ie. it will NOT support both types of native payment at a time.\n */\n function _payNative(uint256 _nativeFee, bool byApp) internal virtual returns (uint256 nativeFee) {\n if (!byApp && msg.value != _nativeFee) {\n revert NotExactNativeFee(msg.value);\n }\n return _nativeFee;\n }\n\n /**\n * @dev Internal function to pay the LZ token fee associated with the message.\n * @param _lzTokenFee The LZ token fee to be paid.\n *\n * @dev If the caller is trying to pay in the specified lzToken, then the lzTokenFee is passed to the endpoint.\n * @dev Any excess sent, is passed back to the specified _refundAddress in the _lzSend().\n */\n function _payLzToken(uint256 _lzTokenFee) internal virtual {\n // @dev Cannot cache the token because it is not immutable in the endpoint.\n address lzToken = endpoint.lzToken();\n if (lzToken == address(0)) {\n revert LzTokenUnavailable();\n }\n\n // Pay LZ token fee by sending tokens to the endpoint.\n IERC20(lzToken).safeTransferFrom(msg.sender, address(endpoint), _lzTokenFee);\n }\n\n}\n"},"src/lzApp/OAppReceiverUpgradeable.sol":{"content":"// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.20;\n\nimport {OAppCoreUpgradeable} from \"./OAppCoreUpgradeable.sol\";\nimport {IOAppReceiver, Origin} from \"@layerzero-v2/oapp/contracts/oapp/interfaces/IOAppReceiver.sol\";\n\n/**\n * @title OAppReceiverUpgradeable\n * @dev Abstract contract implementing the ILayerZeroReceiver interface and extending OAppCore for OApp receivers.\n */\nabstract contract OAppReceiverUpgradeable is IOAppReceiver, OAppCoreUpgradeable {\n\n // Custom error message for when the caller is not the registered endpoint/\n error OnlyEndpoint(address addr);\n\n // @dev The version of the OAppReceiver implementation.\n // @dev Version is bumped when changes are made to this contract.\n uint64 internal constant RECEIVER_VERSION = 1;\n\n /**\n * @notice Retrieves the OApp version information.\n * @return senderVersion The version of the OAppSender.sol contract.\n * @return receiverVersion The version of the OAppReceiver.sol contract.\n *\n * @dev Providing 0 as the default for OAppSender version. Indicates that the OAppSender is not implemented.\n * ie. this is a RECEIVE only OApp.\n * @dev If the OApp uses both OAppSender and OAppReceiver, then this needs to be override returning the correct\n * versions.\n */\n function oAppVersion() public view virtual returns (uint64 senderVersion, uint64 receiverVersion) {\n return (0, RECEIVER_VERSION);\n }\n\n /**\n * @notice Retrieves the address responsible for 'sending' composeMsg's to the Endpoint.\n * @return sender The address responsible for 'sending' composeMsg's to the Endpoint.\n *\n * @dev Applications can optionally choose to implement a separate composeMsg sender that is NOT the bridging layer.\n * @dev The default sender IS the OApp implementer.\n */\n function composeMsgSender() public view virtual returns (address sender) {\n return address(this);\n }\n\n /**\n * @notice Checks if the path initialization is allowed based on the provided origin.\n * @param origin The origin information containing the source endpoint and sender address.\n * @return Whether the path has been initialized.\n *\n * @dev This indicates to the endpoint that the OApp has enabled msgs for this particular path to be received.\n * @dev This defaults to assuming if a peer has been set, its initialized.\n * Can be overridden by the OApp if there is other logic to determine this.\n */\n function allowInitializePath(Origin calldata origin) public view virtual returns (bool) {\n return peers[origin.srcEid] == origin.sender;\n }\n\n /**\n * @notice Retrieves the next nonce for a given source endpoint and sender address.\n * @dev _srcEid The source endpoint ID.\n * @dev _sender The sender address.\n * @return nonce The next nonce.\n *\n * @dev The path nonce starts from 1. If 0 is returned it means that there is NO nonce ordered enforcement.\n * @dev Is required by the off-chain executor to determine the OApp expects msg execution is ordered.\n * @dev This is also enforced by the OApp.\n * @dev By default this is NOT enabled. ie. nextNonce is hardcoded to return 0.\n */\n function nextNonce(uint32, /*_srcEid*/ bytes32 /*_sender*/ ) public view virtual returns (uint64 nonce) {\n return 0;\n }\n\n /**\n * @dev Entry point for receiving messages or packets from the endpoint.\n * @param _origin The origin information containing the source endpoint and sender address.\n * - srcEid: The source chain endpoint ID.\n * - sender: The sender address on the src chain.\n * - nonce: The nonce of the message.\n * @param _guid The unique identifier for the received LayerZero message.\n * @param _message The payload of the received message.\n * @param _executor The address of the executor for the received message.\n * @param _extraData Additional arbitrary data provided by the corresponding executor.\n *\n * @dev Entry point for receiving msg/packet from the LayerZero endpoint.\n */\n function lzReceive(\n Origin calldata _origin,\n bytes32 _guid,\n bytes calldata _message,\n address _executor,\n bytes calldata _extraData\n ) public payable virtual {\n // Ensures that only the endpoint can attempt to lzReceive() messages to this OApp.\n if (address(endpoint) != msg.sender) {\n revert OnlyEndpoint(msg.sender);\n }\n\n // Ensure that the sender matches the expected peer for the source endpoint.\n if (_getPeerOrRevert(_origin.srcEid) != _origin.sender) {\n revert OnlyPeer(_origin.srcEid, _origin.sender);\n }\n\n // Call the internal OApp implementation of lzReceive.\n _lzReceive(_origin, _message);\n }\n\n /**\n * @dev Internal function to implement lzReceive logic without needing to copy the basic parameter validation.\n */\n function _lzReceive(Origin calldata _origin, bytes calldata _message) internal virtual;\n\n}\n"},"src/storage/GatewayStorage.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\n/// @title GatewayStorage\n/// @notice Storage used by both ends of the gateway contract.\n/// @dev This contract is used as the base storage and is inherited by the storage for Bootstrap and ExocoreGateway.\ncontract GatewayStorage {\n\n /// @notice Enum representing various actions that can be performed.\n enum Action {\n REQUEST_DEPOSIT,\n REQUEST_WITHDRAW_PRINCIPAL_FROM_EXOCORE,\n REQUEST_WITHDRAW_REWARD_FROM_EXOCORE,\n REQUEST_DELEGATE_TO,\n REQUEST_UNDELEGATE_FROM,\n REQUEST_DEPOSIT_THEN_DELEGATE_TO,\n REQUEST_MARK_BOOTSTRAP,\n REQUEST_ADD_WHITELIST_TOKENS,\n RESPOND\n }\n\n /// @dev Mapping of actions to their corresponding function selectors.\n mapping(Action => bytes4) internal _whiteListFunctionSelectors;\n\n /// @dev Mapping to track inbound nonces for each chain and sender.\n mapping(uint32 eid => mapping(bytes32 sender => uint64 nonce)) public inboundNonce;\n\n /// @dev Storage gap to allow for future upgrades.\n uint256[40] private __gap;\n\n /// @notice Emitted when a message is sent through the gateway.\n /// @param act The action being performed.\n /// @param packetId The unique identifier for the packet.\n /// @param nonce The nonce associated with the message.\n /// @param nativeFee The native fee paid for the message.\n event MessageSent(Action indexed act, bytes32 packetId, uint64 nonce, uint256 nativeFee);\n\n /// @notice Error thrown when an unsupported request is made.\n /// @param act The unsupported action.\n error UnsupportedRequest(Action act);\n\n /// @notice Error thrown when a message is received from an unexpected source chain.\n /// @param unexpectedSrcEndpointId The unexpected source chain ID.\n error UnexpectedSourceChain(uint32 unexpectedSrcEndpointId);\n\n /// @notice Error thrown when the inbound nonce is not as expected.\n /// @param expectedNonce The expected nonce.\n /// @param actualNonce The actual nonce received.\n error UnexpectedInboundNonce(uint64 expectedNonce, uint64 actualNonce);\n\n /// @notice Verifies and updates the inbound nonce for a given source chain and address.\n /// @dev This function reverts if the nonce is not as expected.\n /// @param srcChainId The ID of the source chain.\n /// @param srcAddress The address of the sender on the source chain.\n /// @param nonce The nonce to be verified and updated.\n function _verifyAndUpdateNonce(uint32 srcChainId, bytes32 srcAddress, uint64 nonce) internal {\n uint64 expectedNonce = inboundNonce[srcChainId][srcAddress] + 1;\n if (nonce != expectedNonce) {\n revert UnexpectedInboundNonce(expectedNonce, nonce);\n }\n inboundNonce[srcChainId][srcAddress] = nonce;\n }\n\n}\n"},"lib/LayerZero-v2/protocol/contracts/interfaces/ILayerZeroEndpointV2.sol":{"content":"// SPDX-License-Identifier: MIT\n\npragma solidity >=0.8.0;\n\nimport { IMessageLibManager } from \"./IMessageLibManager.sol\";\nimport { IMessagingComposer } from \"./IMessagingComposer.sol\";\nimport { IMessagingChannel } from \"./IMessagingChannel.sol\";\nimport { IMessagingContext } from \"./IMessagingContext.sol\";\n\nstruct MessagingParams {\n uint32 dstEid;\n bytes32 receiver;\n bytes message;\n bytes options;\n bool payInLzToken;\n}\n\nstruct MessagingReceipt {\n bytes32 guid;\n uint64 nonce;\n MessagingFee fee;\n}\n\nstruct MessagingFee {\n uint256 nativeFee;\n uint256 lzTokenFee;\n}\n\nstruct Origin {\n uint32 srcEid;\n bytes32 sender;\n uint64 nonce;\n}\n\ninterface ILayerZeroEndpointV2 is IMessageLibManager, IMessagingComposer, IMessagingChannel, IMessagingContext {\n event PacketSent(bytes encodedPayload, bytes options, address sendLibrary);\n\n event PacketVerified(Origin origin, address receiver, bytes32 payloadHash);\n\n event PacketDelivered(Origin origin, address receiver);\n\n event LzReceiveAlert(\n address indexed receiver,\n address indexed executor,\n Origin origin,\n bytes32 guid,\n uint256 gas,\n uint256 value,\n bytes message,\n bytes extraData,\n bytes reason\n );\n\n event LzTokenSet(address token);\n\n event DelegateSet(address sender, address delegate);\n\n function quote(MessagingParams calldata _params, address _sender) external view returns (MessagingFee memory);\n\n function send(\n MessagingParams calldata _params,\n address _refundAddress\n ) external payable returns (MessagingReceipt memory);\n\n function verify(Origin calldata _origin, address _receiver, bytes32 _payloadHash) external;\n\n function verifiable(Origin calldata _origin, address _receiver) external view returns (bool);\n\n function initializable(Origin calldata _origin, address _receiver) external view returns (bool);\n\n function lzReceive(\n Origin calldata _origin,\n address _receiver,\n bytes32 _guid,\n bytes calldata _message,\n bytes calldata _extraData\n ) external payable;\n\n // oapp can burn messages partially by calling this function with its own business logic if messages are verified in order\n function clear(address _oapp, Origin calldata _origin, bytes32 _guid, bytes calldata _message) external;\n\n function setLzToken(address _lzToken) external;\n\n function lzToken() external view returns (address);\n\n function nativeToken() external view returns (address);\n\n function setDelegate(address _delegate) external;\n}\n"},"lib/solidity-bytes-utils/contracts/BytesLib.sol":{"content":"// SPDX-License-Identifier: Unlicense\n/*\n * @title Solidity Bytes Arrays Utils\n * @author Gonçalo Sá \n *\n * @dev Bytes tightly packed arrays utility library for ethereum contracts written in Solidity.\n * The library lets you concatenate, slice and type cast bytes arrays both in memory and storage.\n */\npragma solidity >=0.8.0 <0.9.0;\n\n\nlibrary BytesLib {\n function concat(\n bytes memory _preBytes,\n bytes memory _postBytes\n )\n internal\n pure\n returns (bytes memory)\n {\n bytes memory tempBytes;\n\n assembly {\n // Get a location of some free memory and store it in tempBytes as\n // Solidity does for memory variables.\n tempBytes := mload(0x40)\n\n // Store the length of the first bytes array at the beginning of\n // the memory for tempBytes.\n let length := mload(_preBytes)\n mstore(tempBytes, length)\n\n // Maintain a memory counter for the current write location in the\n // temp bytes array by adding the 32 bytes for the array length to\n // the starting location.\n let mc := add(tempBytes, 0x20)\n // Stop copying when the memory counter reaches the length of the\n // first bytes array.\n let end := add(mc, length)\n\n for {\n // Initialize a copy counter to the start of the _preBytes data,\n // 32 bytes into its memory.\n let cc := add(_preBytes, 0x20)\n } lt(mc, end) {\n // Increase both counters by 32 bytes each iteration.\n mc := add(mc, 0x20)\n cc := add(cc, 0x20)\n } {\n // Write the _preBytes data into the tempBytes memory 32 bytes\n // at a time.\n mstore(mc, mload(cc))\n }\n\n // Add the length of _postBytes to the current length of tempBytes\n // and store it as the new length in the first 32 bytes of the\n // tempBytes memory.\n length := mload(_postBytes)\n mstore(tempBytes, add(length, mload(tempBytes)))\n\n // Move the memory counter back from a multiple of 0x20 to the\n // actual end of the _preBytes data.\n mc := end\n // Stop copying when the memory counter reaches the new combined\n // length of the arrays.\n end := add(mc, length)\n\n for {\n let cc := add(_postBytes, 0x20)\n } lt(mc, end) {\n mc := add(mc, 0x20)\n cc := add(cc, 0x20)\n } {\n mstore(mc, mload(cc))\n }\n\n // Update the free-memory pointer by padding our last write location\n // to 32 bytes: add 31 bytes to the end of tempBytes to move to the\n // next 32 byte block, then round down to the nearest multiple of\n // 32. If the sum of the length of the two arrays is zero then add\n // one before rounding down to leave a blank 32 bytes (the length block with 0).\n mstore(0x40, and(\n add(add(end, iszero(add(length, mload(_preBytes)))), 31),\n not(31) // Round down to the nearest 32 bytes.\n ))\n }\n\n return tempBytes;\n }\n\n function concatStorage(bytes storage _preBytes, bytes memory _postBytes) internal {\n assembly {\n // Read the first 32 bytes of _preBytes storage, which is the length\n // of the array. (We don't need to use the offset into the slot\n // because arrays use the entire slot.)\n let fslot := sload(_preBytes.slot)\n // Arrays of 31 bytes or less have an even value in their slot,\n // while longer arrays have an odd value. The actual length is\n // the slot divided by two for odd values, and the lowest order\n // byte divided by two for even values.\n // If the slot is even, bitwise and the slot with 255 and divide by\n // two to get the length. If the slot is odd, bitwise and the slot\n // with -1 and divide by two.\n let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2)\n let mlength := mload(_postBytes)\n let newlength := add(slength, mlength)\n // slength can contain both the length and contents of the array\n // if length < 32 bytes so let's prepare for that\n // v. http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage\n switch add(lt(slength, 32), lt(newlength, 32))\n case 2 {\n // Since the new array still fits in the slot, we just need to\n // update the contents of the slot.\n // uint256(bytes_storage) = uint256(bytes_storage) + uint256(bytes_memory) + new_length\n sstore(\n _preBytes.slot,\n // all the modifications to the slot are inside this\n // next block\n add(\n // we can just add to the slot contents because the\n // bytes we want to change are the LSBs\n fslot,\n add(\n mul(\n div(\n // load the bytes from memory\n mload(add(_postBytes, 0x20)),\n // zero all bytes to the right\n exp(0x100, sub(32, mlength))\n ),\n // and now shift left the number of bytes to\n // leave space for the length in the slot\n exp(0x100, sub(32, newlength))\n ),\n // increase length by the double of the memory\n // bytes length\n mul(mlength, 2)\n )\n )\n )\n }\n case 1 {\n // The stored value fits in the slot, but the combined value\n // will exceed it.\n // get the keccak hash to get the contents of the array\n mstore(0x0, _preBytes.slot)\n let sc := add(keccak256(0x0, 0x20), div(slength, 32))\n\n // save new length\n sstore(_preBytes.slot, add(mul(newlength, 2), 1))\n\n // The contents of the _postBytes array start 32 bytes into\n // the structure. Our first read should obtain the `submod`\n // bytes that can fit into the unused space in the last word\n // of the stored array. To get this, we read 32 bytes starting\n // from `submod`, so the data we read overlaps with the array\n // contents by `submod` bytes. Masking the lowest-order\n // `submod` bytes allows us to add that value directly to the\n // stored value.\n\n let submod := sub(32, slength)\n let mc := add(_postBytes, submod)\n let end := add(_postBytes, mlength)\n let mask := sub(exp(0x100, submod), 1)\n\n sstore(\n sc,\n add(\n and(\n fslot,\n 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00\n ),\n and(mload(mc), mask)\n )\n )\n\n for {\n mc := add(mc, 0x20)\n sc := add(sc, 1)\n } lt(mc, end) {\n sc := add(sc, 1)\n mc := add(mc, 0x20)\n } {\n sstore(sc, mload(mc))\n }\n\n mask := exp(0x100, sub(mc, end))\n\n sstore(sc, mul(div(mload(mc), mask), mask))\n }\n default {\n // get the keccak hash to get the contents of the array\n mstore(0x0, _preBytes.slot)\n // Start copying to the last used word of the stored array.\n let sc := add(keccak256(0x0, 0x20), div(slength, 32))\n\n // save new length\n sstore(_preBytes.slot, add(mul(newlength, 2), 1))\n\n // Copy over the first `submod` bytes of the new data as in\n // case 1 above.\n let slengthmod := mod(slength, 32)\n let mlengthmod := mod(mlength, 32)\n let submod := sub(32, slengthmod)\n let mc := add(_postBytes, submod)\n let end := add(_postBytes, mlength)\n let mask := sub(exp(0x100, submod), 1)\n\n sstore(sc, add(sload(sc), and(mload(mc), mask)))\n\n for {\n sc := add(sc, 1)\n mc := add(mc, 0x20)\n } lt(mc, end) {\n sc := add(sc, 1)\n mc := add(mc, 0x20)\n } {\n sstore(sc, mload(mc))\n }\n\n mask := exp(0x100, sub(mc, end))\n\n sstore(sc, mul(div(mload(mc), mask), mask))\n }\n }\n }\n\n function slice(\n bytes memory _bytes,\n uint256 _start,\n uint256 _length\n )\n internal\n pure\n returns (bytes memory)\n {\n require(_length + 31 >= _length, \"slice_overflow\");\n require(_bytes.length >= _start + _length, \"slice_outOfBounds\");\n\n bytes memory tempBytes;\n\n assembly {\n switch iszero(_length)\n case 0 {\n // Get a location of some free memory and store it in tempBytes as\n // Solidity does for memory variables.\n tempBytes := mload(0x40)\n\n // The first word of the slice result is potentially a partial\n // word read from the original array. To read it, we calculate\n // the length of that partial word and start copying that many\n // bytes into the array. The first word we copy will start with\n // data we don't care about, but the last `lengthmod` bytes will\n // land at the beginning of the contents of the new array. When\n // we're done copying, we overwrite the full first word with\n // the actual length of the slice.\n let lengthmod := and(_length, 31)\n\n // The multiplication in the next line is necessary\n // because when slicing multiples of 32 bytes (lengthmod == 0)\n // the following copy loop was copying the origin's length\n // and then ending prematurely not copying everything it should.\n let mc := add(add(tempBytes, lengthmod), mul(0x20, iszero(lengthmod)))\n let end := add(mc, _length)\n\n for {\n // The multiplication in the next line has the same exact purpose\n // as the one above.\n let cc := add(add(add(_bytes, lengthmod), mul(0x20, iszero(lengthmod))), _start)\n } lt(mc, end) {\n mc := add(mc, 0x20)\n cc := add(cc, 0x20)\n } {\n mstore(mc, mload(cc))\n }\n\n mstore(tempBytes, _length)\n\n //update free-memory pointer\n //allocating the array padded to 32 bytes like the compiler does now\n mstore(0x40, and(add(mc, 31), not(31)))\n }\n //if we want a zero-length slice let's just return a zero-length array\n default {\n tempBytes := mload(0x40)\n //zero out the 32 bytes slice we are about to return\n //we need to do it because Solidity does not garbage collect\n mstore(tempBytes, 0)\n\n mstore(0x40, add(tempBytes, 0x20))\n }\n }\n\n return tempBytes;\n }\n\n function toAddress(bytes memory _bytes, uint256 _start) internal pure returns (address) {\n require(_bytes.length >= _start + 20, \"toAddress_outOfBounds\");\n address tempAddress;\n\n assembly {\n tempAddress := div(mload(add(add(_bytes, 0x20), _start)), 0x1000000000000000000000000)\n }\n\n return tempAddress;\n }\n\n function toUint8(bytes memory _bytes, uint256 _start) internal pure returns (uint8) {\n require(_bytes.length >= _start + 1 , \"toUint8_outOfBounds\");\n uint8 tempUint;\n\n assembly {\n tempUint := mload(add(add(_bytes, 0x1), _start))\n }\n\n return tempUint;\n }\n\n function toUint16(bytes memory _bytes, uint256 _start) internal pure returns (uint16) {\n require(_bytes.length >= _start + 2, \"toUint16_outOfBounds\");\n uint16 tempUint;\n\n assembly {\n tempUint := mload(add(add(_bytes, 0x2), _start))\n }\n\n return tempUint;\n }\n\n function toUint32(bytes memory _bytes, uint256 _start) internal pure returns (uint32) {\n require(_bytes.length >= _start + 4, \"toUint32_outOfBounds\");\n uint32 tempUint;\n\n assembly {\n tempUint := mload(add(add(_bytes, 0x4), _start))\n }\n\n return tempUint;\n }\n\n function toUint64(bytes memory _bytes, uint256 _start) internal pure returns (uint64) {\n require(_bytes.length >= _start + 8, \"toUint64_outOfBounds\");\n uint64 tempUint;\n\n assembly {\n tempUint := mload(add(add(_bytes, 0x8), _start))\n }\n\n return tempUint;\n }\n\n function toUint96(bytes memory _bytes, uint256 _start) internal pure returns (uint96) {\n require(_bytes.length >= _start + 12, \"toUint96_outOfBounds\");\n uint96 tempUint;\n\n assembly {\n tempUint := mload(add(add(_bytes, 0xc), _start))\n }\n\n return tempUint;\n }\n\n function toUint128(bytes memory _bytes, uint256 _start) internal pure returns (uint128) {\n require(_bytes.length >= _start + 16, \"toUint128_outOfBounds\");\n uint128 tempUint;\n\n assembly {\n tempUint := mload(add(add(_bytes, 0x10), _start))\n }\n\n return tempUint;\n }\n\n function toUint256(bytes memory _bytes, uint256 _start) internal pure returns (uint256) {\n require(_bytes.length >= _start + 32, \"toUint256_outOfBounds\");\n uint256 tempUint;\n\n assembly {\n tempUint := mload(add(add(_bytes, 0x20), _start))\n }\n\n return tempUint;\n }\n\n function toBytes32(bytes memory _bytes, uint256 _start) internal pure returns (bytes32) {\n require(_bytes.length >= _start + 32, \"toBytes32_outOfBounds\");\n bytes32 tempBytes32;\n\n assembly {\n tempBytes32 := mload(add(add(_bytes, 0x20), _start))\n }\n\n return tempBytes32;\n }\n\n function equal(bytes memory _preBytes, bytes memory _postBytes) internal pure returns (bool) {\n bool success = true;\n\n assembly {\n let length := mload(_preBytes)\n\n // if lengths don't match the arrays are not equal\n switch eq(length, mload(_postBytes))\n case 1 {\n // cb is a circuit breaker in the for loop since there's\n // no said feature for inline assembly loops\n // cb = 1 - don't breaker\n // cb = 0 - break\n let cb := 1\n\n let mc := add(_preBytes, 0x20)\n let end := add(mc, length)\n\n for {\n let cc := add(_postBytes, 0x20)\n // the next line is the loop condition:\n // while(uint256(mc < end) + cb == 2)\n } eq(add(lt(mc, end), cb), 2) {\n mc := add(mc, 0x20)\n cc := add(cc, 0x20)\n } {\n // if any of these checks fails then arrays are not equal\n if iszero(eq(mload(mc), mload(cc))) {\n // unsuccess:\n success := 0\n cb := 0\n }\n }\n }\n default {\n // unsuccess:\n success := 0\n }\n }\n\n return success;\n }\n\n function equal_nonAligned(bytes memory _preBytes, bytes memory _postBytes) internal pure returns (bool) {\n bool success = true;\n\n assembly {\n let length := mload(_preBytes)\n\n // if lengths don't match the arrays are not equal\n switch eq(length, mload(_postBytes))\n case 1 {\n // cb is a circuit breaker in the for loop since there's\n // no said feature for inline assembly loops\n // cb = 1 - don't breaker\n // cb = 0 - break\n let cb := 1\n\n let endMinusWord := add(_preBytes, length)\n let mc := add(_preBytes, 0x20)\n let cc := add(_postBytes, 0x20)\n\n for {\n // the next line is the loop condition:\n // while(uint256(mc < endWord) + cb == 2)\n } eq(add(lt(mc, endMinusWord), cb), 2) {\n mc := add(mc, 0x20)\n cc := add(cc, 0x20)\n } {\n // if any of these checks fails then arrays are not equal\n if iszero(eq(mload(mc), mload(cc))) {\n // unsuccess:\n success := 0\n cb := 0\n }\n }\n\n // Only if still successful\n // For <1 word tail bytes\n if gt(success, 0) {\n // Get the remainder of length/32\n // length % 32 = AND(length, 32 - 1)\n let numTailBytes := and(length, 0x1f)\n let mcRem := mload(mc)\n let ccRem := mload(cc)\n for {\n let i := 0\n // the next line is the loop condition:\n // while(uint256(i < numTailBytes) + cb == 2)\n } eq(add(lt(i, numTailBytes), cb), 2) {\n i := add(i, 1)\n } {\n if iszero(eq(byte(i, mcRem), byte(i, ccRem))) {\n // unsuccess:\n success := 0\n cb := 0\n }\n }\n }\n }\n default {\n // unsuccess:\n success := 0\n }\n }\n\n return success;\n }\n\n function equalStorage(\n bytes storage _preBytes,\n bytes memory _postBytes\n )\n internal\n view\n returns (bool)\n {\n bool success = true;\n\n assembly {\n // we know _preBytes_offset is 0\n let fslot := sload(_preBytes.slot)\n // Decode the length of the stored array like in concatStorage().\n let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2)\n let mlength := mload(_postBytes)\n\n // if lengths don't match the arrays are not equal\n switch eq(slength, mlength)\n case 1 {\n // slength can contain both the length and contents of the array\n // if length < 32 bytes so let's prepare for that\n // v. http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage\n if iszero(iszero(slength)) {\n switch lt(slength, 32)\n case 1 {\n // blank the last byte which is the length\n fslot := mul(div(fslot, 0x100), 0x100)\n\n if iszero(eq(fslot, mload(add(_postBytes, 0x20)))) {\n // unsuccess:\n success := 0\n }\n }\n default {\n // cb is a circuit breaker in the for loop since there's\n // no said feature for inline assembly loops\n // cb = 1 - don't breaker\n // cb = 0 - break\n let cb := 1\n\n // get the keccak hash to get the contents of the array\n mstore(0x0, _preBytes.slot)\n let sc := keccak256(0x0, 0x20)\n\n let mc := add(_postBytes, 0x20)\n let end := add(mc, mlength)\n\n // the next line is the loop condition:\n // while(uint256(mc < end) + cb == 2)\n for {} eq(add(lt(mc, end), cb), 2) {\n sc := add(sc, 1)\n mc := add(mc, 0x20)\n } {\n if iszero(eq(sload(sc), mload(mc))) {\n // unsuccess:\n success := 0\n cb := 0\n }\n }\n }\n }\n }\n default {\n // unsuccess:\n success := 0\n }\n }\n\n return success;\n }\n}\n"},"lib/openzeppelin-contracts/contracts/utils/math/SafeCast.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SafeCast.sol)\n// This file was procedurally generated from scripts/generate/templates/SafeCast.js.\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\n * checks.\n *\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\n * easily result in undesired exploitation or bugs, since developers usually\n * assume that overflows raise errors. `SafeCast` restores this intuition by\n * reverting the transaction when such an operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n *\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\n * all math on `uint256` and `int256` and then downcasting.\n */\nlibrary SafeCast {\n /**\n * @dev Returns the downcasted uint248 from uint256, reverting on\n * overflow (when the input is greater than largest uint248).\n *\n * Counterpart to Solidity's `uint248` operator.\n *\n * Requirements:\n *\n * - input must fit into 248 bits\n *\n * _Available since v4.7._\n */\n function toUint248(uint256 value) internal pure returns (uint248) {\n require(value <= type(uint248).max, \"SafeCast: value doesn't fit in 248 bits\");\n return uint248(value);\n }\n\n /**\n * @dev Returns the downcasted uint240 from uint256, reverting on\n * overflow (when the input is greater than largest uint240).\n *\n * Counterpart to Solidity's `uint240` operator.\n *\n * Requirements:\n *\n * - input must fit into 240 bits\n *\n * _Available since v4.7._\n */\n function toUint240(uint256 value) internal pure returns (uint240) {\n require(value <= type(uint240).max, \"SafeCast: value doesn't fit in 240 bits\");\n return uint240(value);\n }\n\n /**\n * @dev Returns the downcasted uint232 from uint256, reverting on\n * overflow (when the input is greater than largest uint232).\n *\n * Counterpart to Solidity's `uint232` operator.\n *\n * Requirements:\n *\n * - input must fit into 232 bits\n *\n * _Available since v4.7._\n */\n function toUint232(uint256 value) internal pure returns (uint232) {\n require(value <= type(uint232).max, \"SafeCast: value doesn't fit in 232 bits\");\n return uint232(value);\n }\n\n /**\n * @dev Returns the downcasted uint224 from uint256, reverting on\n * overflow (when the input is greater than largest uint224).\n *\n * Counterpart to Solidity's `uint224` operator.\n *\n * Requirements:\n *\n * - input must fit into 224 bits\n *\n * _Available since v4.2._\n */\n function toUint224(uint256 value) internal pure returns (uint224) {\n require(value <= type(uint224).max, \"SafeCast: value doesn't fit in 224 bits\");\n return uint224(value);\n }\n\n /**\n * @dev Returns the downcasted uint216 from uint256, reverting on\n * overflow (when the input is greater than largest uint216).\n *\n * Counterpart to Solidity's `uint216` operator.\n *\n * Requirements:\n *\n * - input must fit into 216 bits\n *\n * _Available since v4.7._\n */\n function toUint216(uint256 value) internal pure returns (uint216) {\n require(value <= type(uint216).max, \"SafeCast: value doesn't fit in 216 bits\");\n return uint216(value);\n }\n\n /**\n * @dev Returns the downcasted uint208 from uint256, reverting on\n * overflow (when the input is greater than largest uint208).\n *\n * Counterpart to Solidity's `uint208` operator.\n *\n * Requirements:\n *\n * - input must fit into 208 bits\n *\n * _Available since v4.7._\n */\n function toUint208(uint256 value) internal pure returns (uint208) {\n require(value <= type(uint208).max, \"SafeCast: value doesn't fit in 208 bits\");\n return uint208(value);\n }\n\n /**\n * @dev Returns the downcasted uint200 from uint256, reverting on\n * overflow (when the input is greater than largest uint200).\n *\n * Counterpart to Solidity's `uint200` operator.\n *\n * Requirements:\n *\n * - input must fit into 200 bits\n *\n * _Available since v4.7._\n */\n function toUint200(uint256 value) internal pure returns (uint200) {\n require(value <= type(uint200).max, \"SafeCast: value doesn't fit in 200 bits\");\n return uint200(value);\n }\n\n /**\n * @dev Returns the downcasted uint192 from uint256, reverting on\n * overflow (when the input is greater than largest uint192).\n *\n * Counterpart to Solidity's `uint192` operator.\n *\n * Requirements:\n *\n * - input must fit into 192 bits\n *\n * _Available since v4.7._\n */\n function toUint192(uint256 value) internal pure returns (uint192) {\n require(value <= type(uint192).max, \"SafeCast: value doesn't fit in 192 bits\");\n return uint192(value);\n }\n\n /**\n * @dev Returns the downcasted uint184 from uint256, reverting on\n * overflow (when the input is greater than largest uint184).\n *\n * Counterpart to Solidity's `uint184` operator.\n *\n * Requirements:\n *\n * - input must fit into 184 bits\n *\n * _Available since v4.7._\n */\n function toUint184(uint256 value) internal pure returns (uint184) {\n require(value <= type(uint184).max, \"SafeCast: value doesn't fit in 184 bits\");\n return uint184(value);\n }\n\n /**\n * @dev Returns the downcasted uint176 from uint256, reverting on\n * overflow (when the input is greater than largest uint176).\n *\n * Counterpart to Solidity's `uint176` operator.\n *\n * Requirements:\n *\n * - input must fit into 176 bits\n *\n * _Available since v4.7._\n */\n function toUint176(uint256 value) internal pure returns (uint176) {\n require(value <= type(uint176).max, \"SafeCast: value doesn't fit in 176 bits\");\n return uint176(value);\n }\n\n /**\n * @dev Returns the downcasted uint168 from uint256, reverting on\n * overflow (when the input is greater than largest uint168).\n *\n * Counterpart to Solidity's `uint168` operator.\n *\n * Requirements:\n *\n * - input must fit into 168 bits\n *\n * _Available since v4.7._\n */\n function toUint168(uint256 value) internal pure returns (uint168) {\n require(value <= type(uint168).max, \"SafeCast: value doesn't fit in 168 bits\");\n return uint168(value);\n }\n\n /**\n * @dev Returns the downcasted uint160 from uint256, reverting on\n * overflow (when the input is greater than largest uint160).\n *\n * Counterpart to Solidity's `uint160` operator.\n *\n * Requirements:\n *\n * - input must fit into 160 bits\n *\n * _Available since v4.7._\n */\n function toUint160(uint256 value) internal pure returns (uint160) {\n require(value <= type(uint160).max, \"SafeCast: value doesn't fit in 160 bits\");\n return uint160(value);\n }\n\n /**\n * @dev Returns the downcasted uint152 from uint256, reverting on\n * overflow (when the input is greater than largest uint152).\n *\n * Counterpart to Solidity's `uint152` operator.\n *\n * Requirements:\n *\n * - input must fit into 152 bits\n *\n * _Available since v4.7._\n */\n function toUint152(uint256 value) internal pure returns (uint152) {\n require(value <= type(uint152).max, \"SafeCast: value doesn't fit in 152 bits\");\n return uint152(value);\n }\n\n /**\n * @dev Returns the downcasted uint144 from uint256, reverting on\n * overflow (when the input is greater than largest uint144).\n *\n * Counterpart to Solidity's `uint144` operator.\n *\n * Requirements:\n *\n * - input must fit into 144 bits\n *\n * _Available since v4.7._\n */\n function toUint144(uint256 value) internal pure returns (uint144) {\n require(value <= type(uint144).max, \"SafeCast: value doesn't fit in 144 bits\");\n return uint144(value);\n }\n\n /**\n * @dev Returns the downcasted uint136 from uint256, reverting on\n * overflow (when the input is greater than largest uint136).\n *\n * Counterpart to Solidity's `uint136` operator.\n *\n * Requirements:\n *\n * - input must fit into 136 bits\n *\n * _Available since v4.7._\n */\n function toUint136(uint256 value) internal pure returns (uint136) {\n require(value <= type(uint136).max, \"SafeCast: value doesn't fit in 136 bits\");\n return uint136(value);\n }\n\n /**\n * @dev Returns the downcasted uint128 from uint256, reverting on\n * overflow (when the input is greater than largest uint128).\n *\n * Counterpart to Solidity's `uint128` operator.\n *\n * Requirements:\n *\n * - input must fit into 128 bits\n *\n * _Available since v2.5._\n */\n function toUint128(uint256 value) internal pure returns (uint128) {\n require(value <= type(uint128).max, \"SafeCast: value doesn't fit in 128 bits\");\n return uint128(value);\n }\n\n /**\n * @dev Returns the downcasted uint120 from uint256, reverting on\n * overflow (when the input is greater than largest uint120).\n *\n * Counterpart to Solidity's `uint120` operator.\n *\n * Requirements:\n *\n * - input must fit into 120 bits\n *\n * _Available since v4.7._\n */\n function toUint120(uint256 value) internal pure returns (uint120) {\n require(value <= type(uint120).max, \"SafeCast: value doesn't fit in 120 bits\");\n return uint120(value);\n }\n\n /**\n * @dev Returns the downcasted uint112 from uint256, reverting on\n * overflow (when the input is greater than largest uint112).\n *\n * Counterpart to Solidity's `uint112` operator.\n *\n * Requirements:\n *\n * - input must fit into 112 bits\n *\n * _Available since v4.7._\n */\n function toUint112(uint256 value) internal pure returns (uint112) {\n require(value <= type(uint112).max, \"SafeCast: value doesn't fit in 112 bits\");\n return uint112(value);\n }\n\n /**\n * @dev Returns the downcasted uint104 from uint256, reverting on\n * overflow (when the input is greater than largest uint104).\n *\n * Counterpart to Solidity's `uint104` operator.\n *\n * Requirements:\n *\n * - input must fit into 104 bits\n *\n * _Available since v4.7._\n */\n function toUint104(uint256 value) internal pure returns (uint104) {\n require(value <= type(uint104).max, \"SafeCast: value doesn't fit in 104 bits\");\n return uint104(value);\n }\n\n /**\n * @dev Returns the downcasted uint96 from uint256, reverting on\n * overflow (when the input is greater than largest uint96).\n *\n * Counterpart to Solidity's `uint96` operator.\n *\n * Requirements:\n *\n * - input must fit into 96 bits\n *\n * _Available since v4.2._\n */\n function toUint96(uint256 value) internal pure returns (uint96) {\n require(value <= type(uint96).max, \"SafeCast: value doesn't fit in 96 bits\");\n return uint96(value);\n }\n\n /**\n * @dev Returns the downcasted uint88 from uint256, reverting on\n * overflow (when the input is greater than largest uint88).\n *\n * Counterpart to Solidity's `uint88` operator.\n *\n * Requirements:\n *\n * - input must fit into 88 bits\n *\n * _Available since v4.7._\n */\n function toUint88(uint256 value) internal pure returns (uint88) {\n require(value <= type(uint88).max, \"SafeCast: value doesn't fit in 88 bits\");\n return uint88(value);\n }\n\n /**\n * @dev Returns the downcasted uint80 from uint256, reverting on\n * overflow (when the input is greater than largest uint80).\n *\n * Counterpart to Solidity's `uint80` operator.\n *\n * Requirements:\n *\n * - input must fit into 80 bits\n *\n * _Available since v4.7._\n */\n function toUint80(uint256 value) internal pure returns (uint80) {\n require(value <= type(uint80).max, \"SafeCast: value doesn't fit in 80 bits\");\n return uint80(value);\n }\n\n /**\n * @dev Returns the downcasted uint72 from uint256, reverting on\n * overflow (when the input is greater than largest uint72).\n *\n * Counterpart to Solidity's `uint72` operator.\n *\n * Requirements:\n *\n * - input must fit into 72 bits\n *\n * _Available since v4.7._\n */\n function toUint72(uint256 value) internal pure returns (uint72) {\n require(value <= type(uint72).max, \"SafeCast: value doesn't fit in 72 bits\");\n return uint72(value);\n }\n\n /**\n * @dev Returns the downcasted uint64 from uint256, reverting on\n * overflow (when the input is greater than largest uint64).\n *\n * Counterpart to Solidity's `uint64` operator.\n *\n * Requirements:\n *\n * - input must fit into 64 bits\n *\n * _Available since v2.5._\n */\n function toUint64(uint256 value) internal pure returns (uint64) {\n require(value <= type(uint64).max, \"SafeCast: value doesn't fit in 64 bits\");\n return uint64(value);\n }\n\n /**\n * @dev Returns the downcasted uint56 from uint256, reverting on\n * overflow (when the input is greater than largest uint56).\n *\n * Counterpart to Solidity's `uint56` operator.\n *\n * Requirements:\n *\n * - input must fit into 56 bits\n *\n * _Available since v4.7._\n */\n function toUint56(uint256 value) internal pure returns (uint56) {\n require(value <= type(uint56).max, \"SafeCast: value doesn't fit in 56 bits\");\n return uint56(value);\n }\n\n /**\n * @dev Returns the downcasted uint48 from uint256, reverting on\n * overflow (when the input is greater than largest uint48).\n *\n * Counterpart to Solidity's `uint48` operator.\n *\n * Requirements:\n *\n * - input must fit into 48 bits\n *\n * _Available since v4.7._\n */\n function toUint48(uint256 value) internal pure returns (uint48) {\n require(value <= type(uint48).max, \"SafeCast: value doesn't fit in 48 bits\");\n return uint48(value);\n }\n\n /**\n * @dev Returns the downcasted uint40 from uint256, reverting on\n * overflow (when the input is greater than largest uint40).\n *\n * Counterpart to Solidity's `uint40` operator.\n *\n * Requirements:\n *\n * - input must fit into 40 bits\n *\n * _Available since v4.7._\n */\n function toUint40(uint256 value) internal pure returns (uint40) {\n require(value <= type(uint40).max, \"SafeCast: value doesn't fit in 40 bits\");\n return uint40(value);\n }\n\n /**\n * @dev Returns the downcasted uint32 from uint256, reverting on\n * overflow (when the input is greater than largest uint32).\n *\n * Counterpart to Solidity's `uint32` operator.\n *\n * Requirements:\n *\n * - input must fit into 32 bits\n *\n * _Available since v2.5._\n */\n function toUint32(uint256 value) internal pure returns (uint32) {\n require(value <= type(uint32).max, \"SafeCast: value doesn't fit in 32 bits\");\n return uint32(value);\n }\n\n /**\n * @dev Returns the downcasted uint24 from uint256, reverting on\n * overflow (when the input is greater than largest uint24).\n *\n * Counterpart to Solidity's `uint24` operator.\n *\n * Requirements:\n *\n * - input must fit into 24 bits\n *\n * _Available since v4.7._\n */\n function toUint24(uint256 value) internal pure returns (uint24) {\n require(value <= type(uint24).max, \"SafeCast: value doesn't fit in 24 bits\");\n return uint24(value);\n }\n\n /**\n * @dev Returns the downcasted uint16 from uint256, reverting on\n * overflow (when the input is greater than largest uint16).\n *\n * Counterpart to Solidity's `uint16` operator.\n *\n * Requirements:\n *\n * - input must fit into 16 bits\n *\n * _Available since v2.5._\n */\n function toUint16(uint256 value) internal pure returns (uint16) {\n require(value <= type(uint16).max, \"SafeCast: value doesn't fit in 16 bits\");\n return uint16(value);\n }\n\n /**\n * @dev Returns the downcasted uint8 from uint256, reverting on\n * overflow (when the input is greater than largest uint8).\n *\n * Counterpart to Solidity's `uint8` operator.\n *\n * Requirements:\n *\n * - input must fit into 8 bits\n *\n * _Available since v2.5._\n */\n function toUint8(uint256 value) internal pure returns (uint8) {\n require(value <= type(uint8).max, \"SafeCast: value doesn't fit in 8 bits\");\n return uint8(value);\n }\n\n /**\n * @dev Converts a signed int256 into an unsigned uint256.\n *\n * Requirements:\n *\n * - input must be greater than or equal to 0.\n *\n * _Available since v3.0._\n */\n function toUint256(int256 value) internal pure returns (uint256) {\n require(value >= 0, \"SafeCast: value must be positive\");\n return uint256(value);\n }\n\n /**\n * @dev Returns the downcasted int248 from int256, reverting on\n * overflow (when the input is less than smallest int248 or\n * greater than largest int248).\n *\n * Counterpart to Solidity's `int248` operator.\n *\n * Requirements:\n *\n * - input must fit into 248 bits\n *\n * _Available since v4.7._\n */\n function toInt248(int256 value) internal pure returns (int248 downcasted) {\n downcasted = int248(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 248 bits\");\n }\n\n /**\n * @dev Returns the downcasted int240 from int256, reverting on\n * overflow (when the input is less than smallest int240 or\n * greater than largest int240).\n *\n * Counterpart to Solidity's `int240` operator.\n *\n * Requirements:\n *\n * - input must fit into 240 bits\n *\n * _Available since v4.7._\n */\n function toInt240(int256 value) internal pure returns (int240 downcasted) {\n downcasted = int240(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 240 bits\");\n }\n\n /**\n * @dev Returns the downcasted int232 from int256, reverting on\n * overflow (when the input is less than smallest int232 or\n * greater than largest int232).\n *\n * Counterpart to Solidity's `int232` operator.\n *\n * Requirements:\n *\n * - input must fit into 232 bits\n *\n * _Available since v4.7._\n */\n function toInt232(int256 value) internal pure returns (int232 downcasted) {\n downcasted = int232(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 232 bits\");\n }\n\n /**\n * @dev Returns the downcasted int224 from int256, reverting on\n * overflow (when the input is less than smallest int224 or\n * greater than largest int224).\n *\n * Counterpart to Solidity's `int224` operator.\n *\n * Requirements:\n *\n * - input must fit into 224 bits\n *\n * _Available since v4.7._\n */\n function toInt224(int256 value) internal pure returns (int224 downcasted) {\n downcasted = int224(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 224 bits\");\n }\n\n /**\n * @dev Returns the downcasted int216 from int256, reverting on\n * overflow (when the input is less than smallest int216 or\n * greater than largest int216).\n *\n * Counterpart to Solidity's `int216` operator.\n *\n * Requirements:\n *\n * - input must fit into 216 bits\n *\n * _Available since v4.7._\n */\n function toInt216(int256 value) internal pure returns (int216 downcasted) {\n downcasted = int216(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 216 bits\");\n }\n\n /**\n * @dev Returns the downcasted int208 from int256, reverting on\n * overflow (when the input is less than smallest int208 or\n * greater than largest int208).\n *\n * Counterpart to Solidity's `int208` operator.\n *\n * Requirements:\n *\n * - input must fit into 208 bits\n *\n * _Available since v4.7._\n */\n function toInt208(int256 value) internal pure returns (int208 downcasted) {\n downcasted = int208(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 208 bits\");\n }\n\n /**\n * @dev Returns the downcasted int200 from int256, reverting on\n * overflow (when the input is less than smallest int200 or\n * greater than largest int200).\n *\n * Counterpart to Solidity's `int200` operator.\n *\n * Requirements:\n *\n * - input must fit into 200 bits\n *\n * _Available since v4.7._\n */\n function toInt200(int256 value) internal pure returns (int200 downcasted) {\n downcasted = int200(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 200 bits\");\n }\n\n /**\n * @dev Returns the downcasted int192 from int256, reverting on\n * overflow (when the input is less than smallest int192 or\n * greater than largest int192).\n *\n * Counterpart to Solidity's `int192` operator.\n *\n * Requirements:\n *\n * - input must fit into 192 bits\n *\n * _Available since v4.7._\n */\n function toInt192(int256 value) internal pure returns (int192 downcasted) {\n downcasted = int192(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 192 bits\");\n }\n\n /**\n * @dev Returns the downcasted int184 from int256, reverting on\n * overflow (when the input is less than smallest int184 or\n * greater than largest int184).\n *\n * Counterpart to Solidity's `int184` operator.\n *\n * Requirements:\n *\n * - input must fit into 184 bits\n *\n * _Available since v4.7._\n */\n function toInt184(int256 value) internal pure returns (int184 downcasted) {\n downcasted = int184(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 184 bits\");\n }\n\n /**\n * @dev Returns the downcasted int176 from int256, reverting on\n * overflow (when the input is less than smallest int176 or\n * greater than largest int176).\n *\n * Counterpart to Solidity's `int176` operator.\n *\n * Requirements:\n *\n * - input must fit into 176 bits\n *\n * _Available since v4.7._\n */\n function toInt176(int256 value) internal pure returns (int176 downcasted) {\n downcasted = int176(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 176 bits\");\n }\n\n /**\n * @dev Returns the downcasted int168 from int256, reverting on\n * overflow (when the input is less than smallest int168 or\n * greater than largest int168).\n *\n * Counterpart to Solidity's `int168` operator.\n *\n * Requirements:\n *\n * - input must fit into 168 bits\n *\n * _Available since v4.7._\n */\n function toInt168(int256 value) internal pure returns (int168 downcasted) {\n downcasted = int168(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 168 bits\");\n }\n\n /**\n * @dev Returns the downcasted int160 from int256, reverting on\n * overflow (when the input is less than smallest int160 or\n * greater than largest int160).\n *\n * Counterpart to Solidity's `int160` operator.\n *\n * Requirements:\n *\n * - input must fit into 160 bits\n *\n * _Available since v4.7._\n */\n function toInt160(int256 value) internal pure returns (int160 downcasted) {\n downcasted = int160(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 160 bits\");\n }\n\n /**\n * @dev Returns the downcasted int152 from int256, reverting on\n * overflow (when the input is less than smallest int152 or\n * greater than largest int152).\n *\n * Counterpart to Solidity's `int152` operator.\n *\n * Requirements:\n *\n * - input must fit into 152 bits\n *\n * _Available since v4.7._\n */\n function toInt152(int256 value) internal pure returns (int152 downcasted) {\n downcasted = int152(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 152 bits\");\n }\n\n /**\n * @dev Returns the downcasted int144 from int256, reverting on\n * overflow (when the input is less than smallest int144 or\n * greater than largest int144).\n *\n * Counterpart to Solidity's `int144` operator.\n *\n * Requirements:\n *\n * - input must fit into 144 bits\n *\n * _Available since v4.7._\n */\n function toInt144(int256 value) internal pure returns (int144 downcasted) {\n downcasted = int144(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 144 bits\");\n }\n\n /**\n * @dev Returns the downcasted int136 from int256, reverting on\n * overflow (when the input is less than smallest int136 or\n * greater than largest int136).\n *\n * Counterpart to Solidity's `int136` operator.\n *\n * Requirements:\n *\n * - input must fit into 136 bits\n *\n * _Available since v4.7._\n */\n function toInt136(int256 value) internal pure returns (int136 downcasted) {\n downcasted = int136(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 136 bits\");\n }\n\n /**\n * @dev Returns the downcasted int128 from int256, reverting on\n * overflow (when the input is less than smallest int128 or\n * greater than largest int128).\n *\n * Counterpart to Solidity's `int128` operator.\n *\n * Requirements:\n *\n * - input must fit into 128 bits\n *\n * _Available since v3.1._\n */\n function toInt128(int256 value) internal pure returns (int128 downcasted) {\n downcasted = int128(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 128 bits\");\n }\n\n /**\n * @dev Returns the downcasted int120 from int256, reverting on\n * overflow (when the input is less than smallest int120 or\n * greater than largest int120).\n *\n * Counterpart to Solidity's `int120` operator.\n *\n * Requirements:\n *\n * - input must fit into 120 bits\n *\n * _Available since v4.7._\n */\n function toInt120(int256 value) internal pure returns (int120 downcasted) {\n downcasted = int120(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 120 bits\");\n }\n\n /**\n * @dev Returns the downcasted int112 from int256, reverting on\n * overflow (when the input is less than smallest int112 or\n * greater than largest int112).\n *\n * Counterpart to Solidity's `int112` operator.\n *\n * Requirements:\n *\n * - input must fit into 112 bits\n *\n * _Available since v4.7._\n */\n function toInt112(int256 value) internal pure returns (int112 downcasted) {\n downcasted = int112(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 112 bits\");\n }\n\n /**\n * @dev Returns the downcasted int104 from int256, reverting on\n * overflow (when the input is less than smallest int104 or\n * greater than largest int104).\n *\n * Counterpart to Solidity's `int104` operator.\n *\n * Requirements:\n *\n * - input must fit into 104 bits\n *\n * _Available since v4.7._\n */\n function toInt104(int256 value) internal pure returns (int104 downcasted) {\n downcasted = int104(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 104 bits\");\n }\n\n /**\n * @dev Returns the downcasted int96 from int256, reverting on\n * overflow (when the input is less than smallest int96 or\n * greater than largest int96).\n *\n * Counterpart to Solidity's `int96` operator.\n *\n * Requirements:\n *\n * - input must fit into 96 bits\n *\n * _Available since v4.7._\n */\n function toInt96(int256 value) internal pure returns (int96 downcasted) {\n downcasted = int96(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 96 bits\");\n }\n\n /**\n * @dev Returns the downcasted int88 from int256, reverting on\n * overflow (when the input is less than smallest int88 or\n * greater than largest int88).\n *\n * Counterpart to Solidity's `int88` operator.\n *\n * Requirements:\n *\n * - input must fit into 88 bits\n *\n * _Available since v4.7._\n */\n function toInt88(int256 value) internal pure returns (int88 downcasted) {\n downcasted = int88(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 88 bits\");\n }\n\n /**\n * @dev Returns the downcasted int80 from int256, reverting on\n * overflow (when the input is less than smallest int80 or\n * greater than largest int80).\n *\n * Counterpart to Solidity's `int80` operator.\n *\n * Requirements:\n *\n * - input must fit into 80 bits\n *\n * _Available since v4.7._\n */\n function toInt80(int256 value) internal pure returns (int80 downcasted) {\n downcasted = int80(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 80 bits\");\n }\n\n /**\n * @dev Returns the downcasted int72 from int256, reverting on\n * overflow (when the input is less than smallest int72 or\n * greater than largest int72).\n *\n * Counterpart to Solidity's `int72` operator.\n *\n * Requirements:\n *\n * - input must fit into 72 bits\n *\n * _Available since v4.7._\n */\n function toInt72(int256 value) internal pure returns (int72 downcasted) {\n downcasted = int72(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 72 bits\");\n }\n\n /**\n * @dev Returns the downcasted int64 from int256, reverting on\n * overflow (when the input is less than smallest int64 or\n * greater than largest int64).\n *\n * Counterpart to Solidity's `int64` operator.\n *\n * Requirements:\n *\n * - input must fit into 64 bits\n *\n * _Available since v3.1._\n */\n function toInt64(int256 value) internal pure returns (int64 downcasted) {\n downcasted = int64(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 64 bits\");\n }\n\n /**\n * @dev Returns the downcasted int56 from int256, reverting on\n * overflow (when the input is less than smallest int56 or\n * greater than largest int56).\n *\n * Counterpart to Solidity's `int56` operator.\n *\n * Requirements:\n *\n * - input must fit into 56 bits\n *\n * _Available since v4.7._\n */\n function toInt56(int256 value) internal pure returns (int56 downcasted) {\n downcasted = int56(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 56 bits\");\n }\n\n /**\n * @dev Returns the downcasted int48 from int256, reverting on\n * overflow (when the input is less than smallest int48 or\n * greater than largest int48).\n *\n * Counterpart to Solidity's `int48` operator.\n *\n * Requirements:\n *\n * - input must fit into 48 bits\n *\n * _Available since v4.7._\n */\n function toInt48(int256 value) internal pure returns (int48 downcasted) {\n downcasted = int48(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 48 bits\");\n }\n\n /**\n * @dev Returns the downcasted int40 from int256, reverting on\n * overflow (when the input is less than smallest int40 or\n * greater than largest int40).\n *\n * Counterpart to Solidity's `int40` operator.\n *\n * Requirements:\n *\n * - input must fit into 40 bits\n *\n * _Available since v4.7._\n */\n function toInt40(int256 value) internal pure returns (int40 downcasted) {\n downcasted = int40(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 40 bits\");\n }\n\n /**\n * @dev Returns the downcasted int32 from int256, reverting on\n * overflow (when the input is less than smallest int32 or\n * greater than largest int32).\n *\n * Counterpart to Solidity's `int32` operator.\n *\n * Requirements:\n *\n * - input must fit into 32 bits\n *\n * _Available since v3.1._\n */\n function toInt32(int256 value) internal pure returns (int32 downcasted) {\n downcasted = int32(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 32 bits\");\n }\n\n /**\n * @dev Returns the downcasted int24 from int256, reverting on\n * overflow (when the input is less than smallest int24 or\n * greater than largest int24).\n *\n * Counterpart to Solidity's `int24` operator.\n *\n * Requirements:\n *\n * - input must fit into 24 bits\n *\n * _Available since v4.7._\n */\n function toInt24(int256 value) internal pure returns (int24 downcasted) {\n downcasted = int24(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 24 bits\");\n }\n\n /**\n * @dev Returns the downcasted int16 from int256, reverting on\n * overflow (when the input is less than smallest int16 or\n * greater than largest int16).\n *\n * Counterpart to Solidity's `int16` operator.\n *\n * Requirements:\n *\n * - input must fit into 16 bits\n *\n * _Available since v3.1._\n */\n function toInt16(int256 value) internal pure returns (int16 downcasted) {\n downcasted = int16(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 16 bits\");\n }\n\n /**\n * @dev Returns the downcasted int8 from int256, reverting on\n * overflow (when the input is less than smallest int8 or\n * greater than largest int8).\n *\n * Counterpart to Solidity's `int8` operator.\n *\n * Requirements:\n *\n * - input must fit into 8 bits\n *\n * _Available since v3.1._\n */\n function toInt8(int256 value) internal pure returns (int8 downcasted) {\n downcasted = int8(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 8 bits\");\n }\n\n /**\n * @dev Converts an unsigned uint256 into a signed int256.\n *\n * Requirements:\n *\n * - input must be less than or equal to maxInt256.\n *\n * _Available since v3.0._\n */\n function toInt256(uint256 value) internal pure returns (int256) {\n // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive\n require(value <= uint256(type(int256).max), \"SafeCast: value doesn't fit in an int256\");\n return int256(value);\n }\n}\n"},"lib/LayerZero-v2/protocol/contracts/messagelib/libs/ExecutorOptions.sol":{"content":"// SPDX-License-Identifier: LZBL-1.2\n\npragma solidity ^0.8.20;\n\nimport { CalldataBytesLib } from \"../../libs/CalldataBytesLib.sol\";\n\nlibrary ExecutorOptions {\n using CalldataBytesLib for bytes;\n\n uint8 internal constant WORKER_ID = 1;\n\n uint8 internal constant OPTION_TYPE_LZRECEIVE = 1;\n uint8 internal constant OPTION_TYPE_NATIVE_DROP = 2;\n uint8 internal constant OPTION_TYPE_LZCOMPOSE = 3;\n uint8 internal constant OPTION_TYPE_ORDERED_EXECUTION = 4;\n\n error Executor_InvalidLzReceiveOption();\n error Executor_InvalidNativeDropOption();\n error Executor_InvalidLzComposeOption();\n\n /// @dev decode the next executor option from the options starting from the specified cursor\n /// @param _options [executor_id][executor_option][executor_id][executor_option]...\n /// executor_option = [option_size][option_type][option]\n /// option_size = len(option_type) + len(option)\n /// executor_id: uint8, option_size: uint16, option_type: uint8, option: bytes\n /// @param _cursor the cursor to start decoding from\n /// @return optionType the type of the option\n /// @return option the option of the executor\n /// @return cursor the cursor to start decoding the next executor option\n function nextExecutorOption(\n bytes calldata _options,\n uint256 _cursor\n ) internal pure returns (uint8 optionType, bytes calldata option, uint256 cursor) {\n unchecked {\n // skip worker id\n cursor = _cursor + 1;\n\n // read option size\n uint16 size = _options.toU16(cursor);\n cursor += 2;\n\n // read option type\n optionType = _options.toU8(cursor);\n\n // startCursor and endCursor are used to slice the option from _options\n uint256 startCursor = cursor + 1; // skip option type\n uint256 endCursor = cursor + size;\n option = _options[startCursor:endCursor];\n cursor += size;\n }\n }\n\n function decodeLzReceiveOption(bytes calldata _option) internal pure returns (uint128 gas, uint128 value) {\n if (_option.length != 16 && _option.length != 32) revert Executor_InvalidLzReceiveOption();\n gas = _option.toU128(0);\n value = _option.length == 32 ? _option.toU128(16) : 0;\n }\n\n function decodeNativeDropOption(bytes calldata _option) internal pure returns (uint128 amount, bytes32 receiver) {\n if (_option.length != 48) revert Executor_InvalidNativeDropOption();\n amount = _option.toU128(0);\n receiver = _option.toB32(16);\n }\n\n function decodeLzComposeOption(\n bytes calldata _option\n ) internal pure returns (uint16 index, uint128 gas, uint128 value) {\n if (_option.length != 18 && _option.length != 34) revert Executor_InvalidLzComposeOption();\n index = _option.toU16(0);\n gas = _option.toU128(2);\n value = _option.length == 34 ? _option.toU128(18) : 0;\n }\n\n function encodeLzReceiveOption(uint128 _gas, uint128 _value) internal pure returns (bytes memory) {\n return _value == 0 ? abi.encodePacked(_gas) : abi.encodePacked(_gas, _value);\n }\n\n function encodeNativeDropOption(uint128 _amount, bytes32 _receiver) internal pure returns (bytes memory) {\n return abi.encodePacked(_amount, _receiver);\n }\n\n function encodeLzComposeOption(uint16 _index, uint128 _gas, uint128 _value) internal pure returns (bytes memory) {\n return _value == 0 ? abi.encodePacked(_index, _gas) : abi.encodePacked(_index, _gas, _value);\n }\n}\n"},"lib/LayerZero-v2/messagelib/contracts/uln/libs/DVNOptions.sol":{"content":"// SPDX-License-Identifier: LZBL-1.2\n\npragma solidity ^0.8.20;\n\nimport { BytesLib } from \"solidity-bytes-utils/contracts/BytesLib.sol\";\n\nimport { BitMap256 } from \"@layerzerolabs/lz-evm-protocol-v2/contracts/messagelib/libs/BitMaps.sol\";\nimport { CalldataBytesLib } from \"@layerzerolabs/lz-evm-protocol-v2/contracts/libs/CalldataBytesLib.sol\";\n\nlibrary DVNOptions {\n using CalldataBytesLib for bytes;\n using BytesLib for bytes;\n\n uint8 internal constant WORKER_ID = 2;\n uint8 internal constant OPTION_TYPE_PRECRIME = 1;\n\n error DVN_InvalidDVNIdx();\n error DVN_InvalidDVNOptions(uint256 cursor);\n\n /// @dev group dvn options by its idx\n /// @param _options [dvn_id][dvn_option][dvn_id][dvn_option]...\n /// dvn_option = [option_size][dvn_idx][option_type][option]\n /// option_size = len(dvn_idx) + len(option_type) + len(option)\n /// dvn_id: uint8, dvn_idx: uint8, option_size: uint16, option_type: uint8, option: bytes\n /// @return dvnOptions the grouped options, still share the same format of _options\n /// @return dvnIndices the dvn indices\n function groupDVNOptionsByIdx(\n bytes memory _options\n ) internal pure returns (bytes[] memory dvnOptions, uint8[] memory dvnIndices) {\n if (_options.length == 0) return (dvnOptions, dvnIndices);\n\n uint8 numDVNs = getNumDVNs(_options);\n\n // if there is only 1 dvn, we can just return the whole options\n if (numDVNs == 1) {\n dvnOptions = new bytes[](1);\n dvnOptions[0] = _options;\n\n dvnIndices = new uint8[](1);\n dvnIndices[0] = _options.toUint8(3); // dvn idx\n return (dvnOptions, dvnIndices);\n }\n\n // otherwise, we need to group the options by dvn_idx\n dvnIndices = new uint8[](numDVNs);\n dvnOptions = new bytes[](numDVNs);\n unchecked {\n uint256 cursor = 0;\n uint256 start = 0;\n uint8 lastDVNIdx = 255; // 255 is an invalid dvn_idx\n\n while (cursor < _options.length) {\n ++cursor; // skip worker_id\n\n // optionLength asserted in getNumDVNs (skip check)\n uint16 optionLength = _options.toUint16(cursor);\n cursor += 2;\n\n // dvnIdx asserted in getNumDVNs (skip check)\n uint8 dvnIdx = _options.toUint8(cursor);\n\n // dvnIdx must equal to the lastDVNIdx for the first option\n // so it is always skipped in the first option\n // this operation slices out options whenever the scan finds a different lastDVNIdx\n if (lastDVNIdx == 255) {\n lastDVNIdx = dvnIdx;\n } else if (dvnIdx != lastDVNIdx) {\n uint256 len = cursor - start - 3; // 3 is for worker_id and option_length\n bytes memory opt = _options.slice(start, len);\n _insertDVNOptions(dvnOptions, dvnIndices, lastDVNIdx, opt);\n\n // reset the start and lastDVNIdx\n start += len;\n lastDVNIdx = dvnIdx;\n }\n\n cursor += optionLength;\n }\n\n // skip check the cursor here because the cursor is asserted in getNumDVNs\n // if we have reached the end of the options, we need to process the last dvn\n uint256 size = cursor - start;\n bytes memory op = _options.slice(start, size);\n _insertDVNOptions(dvnOptions, dvnIndices, lastDVNIdx, op);\n\n // revert dvnIndices to start from 0\n for (uint8 i = 0; i < numDVNs; ++i) {\n --dvnIndices[i];\n }\n }\n }\n\n function _insertDVNOptions(\n bytes[] memory _dvnOptions,\n uint8[] memory _dvnIndices,\n uint8 _dvnIdx,\n bytes memory _newOptions\n ) internal pure {\n // dvnIdx starts from 0 but default value of dvnIndices is 0,\n // so we tell if the slot is empty by adding 1 to dvnIdx\n if (_dvnIdx == 255) revert DVN_InvalidDVNIdx();\n uint8 dvnIdxAdj = _dvnIdx + 1;\n\n for (uint256 j = 0; j < _dvnIndices.length; ++j) {\n uint8 index = _dvnIndices[j];\n if (dvnIdxAdj == index) {\n _dvnOptions[j] = abi.encodePacked(_dvnOptions[j], _newOptions);\n break;\n } else if (index == 0) {\n // empty slot, that means it is the first time we see this dvn\n _dvnIndices[j] = dvnIdxAdj;\n _dvnOptions[j] = _newOptions;\n break;\n }\n }\n }\n\n /// @dev get the number of unique dvns\n /// @param _options the format is the same as groupDVNOptionsByIdx\n function getNumDVNs(bytes memory _options) internal pure returns (uint8 numDVNs) {\n uint256 cursor = 0;\n BitMap256 bitmap;\n\n // find number of unique dvn_idx\n unchecked {\n while (cursor < _options.length) {\n ++cursor; // skip worker_id\n\n uint16 optionLength = _options.toUint16(cursor);\n cursor += 2;\n if (optionLength < 2) revert DVN_InvalidDVNOptions(cursor); // at least 1 byte for dvn_idx and 1 byte for option_type\n\n uint8 dvnIdx = _options.toUint8(cursor);\n\n // if dvnIdx is not set, increment numDVNs\n // max num of dvns is 255, 255 is an invalid dvn_idx\n // The order of the dvnIdx is not required to be sequential, as enforcing the order may weaken\n // the composability of the options. e.g. if we refrain from enforcing the order, an OApp that has\n // already enforced certain options can append additional options to the end of the enforced\n // ones without restrictions.\n if (dvnIdx == 255) revert DVN_InvalidDVNIdx();\n if (!bitmap.get(dvnIdx)) {\n ++numDVNs;\n bitmap = bitmap.set(dvnIdx);\n }\n\n cursor += optionLength;\n }\n }\n if (cursor != _options.length) revert DVN_InvalidDVNOptions(cursor);\n }\n\n /// @dev decode the next dvn option from _options starting from the specified cursor\n /// @param _options the format is the same as groupDVNOptionsByIdx\n /// @param _cursor the cursor to start decoding\n /// @return optionType the type of the option\n /// @return option the option\n /// @return cursor the cursor to start decoding the next option\n function nextDVNOption(\n bytes calldata _options,\n uint256 _cursor\n ) internal pure returns (uint8 optionType, bytes calldata option, uint256 cursor) {\n unchecked {\n // skip worker id\n cursor = _cursor + 1;\n\n // read option size\n uint16 size = _options.toU16(cursor);\n cursor += 2;\n\n // read option type\n optionType = _options.toU8(cursor + 1); // skip dvn_idx\n\n // startCursor and endCursor are used to slice the option from _options\n uint256 startCursor = cursor + 2; // skip option type and dvn_idx\n uint256 endCursor = cursor + size;\n option = _options[startCursor:endCursor];\n cursor += size;\n }\n }\n}\n"},"lib/openzeppelin-contracts-upgradeable/contracts/utils/ContextUpgradeable.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.4) (utils/Context.sol)\n\npragma solidity ^0.8.0;\nimport {Initializable} from \"../proxy/utils/Initializable.sol\";\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 ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\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 /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n"},"lib/openzeppelin-contracts-upgradeable/contracts/utils/AddressUpgradeable.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n *\n * Furthermore, `isContract` will also return true if the target contract within\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\n * which only has an effect at the end of a transaction.\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\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.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\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, it is bubbled up by this\n * function (like regular Solidity function calls).\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 * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\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 * _Available since v3.1._\n */\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\n *\n * _Available since v4.8._\n */\n function verifyCallResultFromTarget(\n address target,\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n if (success) {\n if (returndata.length == 0) {\n // only check isContract if the call was successful and the return data is empty\n // otherwise we already know that it was a contract\n require(isContract(target), \"Address: call to non-contract\");\n }\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n /**\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason or using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n function _revert(bytes memory returndata, string memory errorMessage) 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(errorMessage);\n }\n }\n}\n"},"lib/openzeppelin-contracts/contracts/token/ERC20/utils/SafeERC20.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\nimport \"../extensions/IERC20Permit.sol\";\nimport \"../../../utils/Address.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n using Address for address;\n\n /**\n * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\n * non-reverting calls are assumed to be successful.\n */\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n /**\n * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the\n * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.\n */\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n }\n\n /**\n * @dev Deprecated. This function has issues similar to the ones found in\n * {IERC20-approve}, and its usage is discouraged.\n *\n * Whenever possible, use {safeIncreaseAllowance} and\n * {safeDecreaseAllowance} instead.\n */\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\n // safeApprove should only be called when setting an initial allowance,\n // or when resetting it to zero. To increase and decrease it, use\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\n require(\n (value == 0) || (token.allowance(address(this), spender) == 0),\n \"SafeERC20: approve from non-zero to non-zero allowance\"\n );\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n }\n\n /**\n * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\n * non-reverting calls are assumed to be successful.\n */\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n uint256 oldAllowance = token.allowance(address(this), spender);\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));\n }\n\n /**\n * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\n * non-reverting calls are assumed to be successful.\n */\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n unchecked {\n uint256 oldAllowance = token.allowance(address(this), spender);\n require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));\n }\n }\n\n /**\n * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\n * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval\n * to be set to zero before setting it to a non-zero value, such as USDT.\n */\n function forceApprove(IERC20 token, address spender, uint256 value) internal {\n bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);\n\n if (!_callOptionalReturnBool(token, approvalCall)) {\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));\n _callOptionalReturn(token, approvalCall);\n }\n }\n\n /**\n * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.\n * Revert on invalid signature.\n */\n function safePermit(\n IERC20Permit token,\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal {\n uint256 nonceBefore = token.nonces(owner);\n token.permit(owner, spender, value, deadline, v, r, s);\n uint256 nonceAfter = token.nonces(owner);\n require(nonceAfter == nonceBefore + 1, \"SafeERC20: permit did not succeed\");\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n */\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that\n // the target address contains contract code and also asserts for success in the low-level call.\n\n bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n require(returndata.length == 0 || abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n *\n * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.\n */\n function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false\n // and not revert is the subcall reverts.\n\n (bool success, bytes memory returndata) = address(token).call(data);\n return\n success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token));\n }\n}\n"},"lib/LayerZero-v2/protocol/contracts/interfaces/IMessageLibManager.sol":{"content":"// SPDX-License-Identifier: MIT\n\npragma solidity >=0.8.0;\n\nstruct SetConfigParam {\n uint32 eid;\n uint32 configType;\n bytes config;\n}\n\ninterface IMessageLibManager {\n struct Timeout {\n address lib;\n uint256 expiry;\n }\n\n event LibraryRegistered(address newLib);\n event DefaultSendLibrarySet(uint32 eid, address newLib);\n event DefaultReceiveLibrarySet(uint32 eid, address newLib);\n event DefaultReceiveLibraryTimeoutSet(uint32 eid, address oldLib, uint256 expiry);\n event SendLibrarySet(address sender, uint32 eid, address newLib);\n event ReceiveLibrarySet(address receiver, uint32 eid, address newLib);\n event ReceiveLibraryTimeoutSet(address receiver, uint32 eid, address oldLib, uint256 timeout);\n\n function registerLibrary(address _lib) external;\n\n function isRegisteredLibrary(address _lib) external view returns (bool);\n\n function getRegisteredLibraries() external view returns (address[] memory);\n\n function setDefaultSendLibrary(uint32 _eid, address _newLib) external;\n\n function defaultSendLibrary(uint32 _eid) external view returns (address);\n\n function setDefaultReceiveLibrary(uint32 _eid, address _newLib, uint256 _timeout) external;\n\n function defaultReceiveLibrary(uint32 _eid) external view returns (address);\n\n function setDefaultReceiveLibraryTimeout(uint32 _eid, address _lib, uint256 _expiry) external;\n\n function defaultReceiveLibraryTimeout(uint32 _eid) external view returns (address lib, uint256 expiry);\n\n function isSupportedEid(uint32 _eid) external view returns (bool);\n\n function isValidReceiveLibrary(address _receiver, uint32 _eid, address _lib) external view returns (bool);\n\n /// ------------------- OApp interfaces -------------------\n function setSendLibrary(address _oapp, uint32 _eid, address _newLib) external;\n\n function getSendLibrary(address _sender, uint32 _eid) external view returns (address lib);\n\n function isDefaultSendLibrary(address _sender, uint32 _eid) external view returns (bool);\n\n function setReceiveLibrary(address _oapp, uint32 _eid, address _newLib, uint256 _gracePeriod) external;\n\n function getReceiveLibrary(address _receiver, uint32 _eid) external view returns (address lib, bool isDefault);\n\n function setReceiveLibraryTimeout(address _oapp, uint32 _eid, address _lib, uint256 _gracePeriod) external;\n\n function receiveLibraryTimeout(address _receiver, uint32 _eid) external view returns (address lib, uint256 expiry);\n\n function setConfig(address _oapp, address _lib, SetConfigParam[] calldata _params) external;\n\n function getConfig(\n address _oapp,\n address _lib,\n uint32 _eid,\n uint32 _configType\n ) external view returns (bytes memory config);\n}\n"},"lib/LayerZero-v2/protocol/contracts/interfaces/IMessagingComposer.sol":{"content":"// SPDX-License-Identifier: MIT\n\npragma solidity >=0.8.0;\n\ninterface IMessagingComposer {\n event ComposeSent(address from, address to, bytes32 guid, uint16 index, bytes message);\n event ComposeDelivered(address from, address to, bytes32 guid, uint16 index);\n event LzComposeAlert(\n address indexed from,\n address indexed to,\n address indexed executor,\n bytes32 guid,\n uint16 index,\n uint256 gas,\n uint256 value,\n bytes message,\n bytes extraData,\n bytes reason\n );\n\n function composeQueue(\n address _from,\n address _to,\n bytes32 _guid,\n uint16 _index\n ) external view returns (bytes32 messageHash);\n\n function sendCompose(address _to, bytes32 _guid, uint16 _index, bytes calldata _message) external;\n\n function lzCompose(\n address _from,\n address _to,\n bytes32 _guid,\n uint16 _index,\n bytes calldata _message,\n bytes calldata _extraData\n ) external payable;\n}\n"},"lib/LayerZero-v2/protocol/contracts/interfaces/IMessagingChannel.sol":{"content":"// SPDX-License-Identifier: MIT\n\npragma solidity >=0.8.0;\n\ninterface IMessagingChannel {\n event InboundNonceSkipped(uint32 srcEid, bytes32 sender, address receiver, uint64 nonce);\n event PacketNilified(uint32 srcEid, bytes32 sender, address receiver, uint64 nonce, bytes32 payloadHash);\n event PacketBurnt(uint32 srcEid, bytes32 sender, address receiver, uint64 nonce, bytes32 payloadHash);\n\n function eid() external view returns (uint32);\n\n // this is an emergency function if a message cannot be verified for some reasons\n // required to provide _nextNonce to avoid race condition\n function skip(address _oapp, uint32 _srcEid, bytes32 _sender, uint64 _nonce) external;\n\n function nilify(address _oapp, uint32 _srcEid, bytes32 _sender, uint64 _nonce, bytes32 _payloadHash) external;\n\n function burn(address _oapp, uint32 _srcEid, bytes32 _sender, uint64 _nonce, bytes32 _payloadHash) external;\n\n function nextGuid(address _sender, uint32 _dstEid, bytes32 _receiver) external view returns (bytes32);\n\n function inboundNonce(address _receiver, uint32 _srcEid, bytes32 _sender) external view returns (uint64);\n\n function outboundNonce(address _sender, uint32 _dstEid, bytes32 _receiver) external view returns (uint64);\n\n function inboundPayloadHash(\n address _receiver,\n uint32 _srcEid,\n bytes32 _sender,\n uint64 _nonce\n ) external view returns (bytes32);\n\n function lazyInboundNonce(address _receiver, uint32 _srcEid, bytes32 _sender) external view returns (uint64);\n}\n"},"lib/LayerZero-v2/protocol/contracts/interfaces/IMessagingContext.sol":{"content":"// SPDX-License-Identifier: MIT\n\npragma solidity >=0.8.0;\n\ninterface IMessagingContext {\n function isSendingMessage() external view returns (bool);\n\n function getSendContext() external view returns (uint32 dstEid, address sender);\n}\n"},"lib/LayerZero-v2/protocol/contracts/libs/CalldataBytesLib.sol":{"content":"// SPDX-License-Identifier: LZBL-1.2\n\npragma solidity ^0.8.20;\n\nlibrary CalldataBytesLib {\n function toU8(bytes calldata _bytes, uint256 _start) internal pure returns (uint8) {\n return uint8(_bytes[_start]);\n }\n\n function toU16(bytes calldata _bytes, uint256 _start) internal pure returns (uint16) {\n unchecked {\n uint256 end = _start + 2;\n return uint16(bytes2(_bytes[_start:end]));\n }\n }\n\n function toU32(bytes calldata _bytes, uint256 _start) internal pure returns (uint32) {\n unchecked {\n uint256 end = _start + 4;\n return uint32(bytes4(_bytes[_start:end]));\n }\n }\n\n function toU64(bytes calldata _bytes, uint256 _start) internal pure returns (uint64) {\n unchecked {\n uint256 end = _start + 8;\n return uint64(bytes8(_bytes[_start:end]));\n }\n }\n\n function toU128(bytes calldata _bytes, uint256 _start) internal pure returns (uint128) {\n unchecked {\n uint256 end = _start + 16;\n return uint128(bytes16(_bytes[_start:end]));\n }\n }\n\n function toU256(bytes calldata _bytes, uint256 _start) internal pure returns (uint256) {\n unchecked {\n uint256 end = _start + 32;\n return uint256(bytes32(_bytes[_start:end]));\n }\n }\n\n function toAddr(bytes calldata _bytes, uint256 _start) internal pure returns (address) {\n unchecked {\n uint256 end = _start + 20;\n return address(bytes20(_bytes[_start:end]));\n }\n }\n\n function toB32(bytes calldata _bytes, uint256 _start) internal pure returns (bytes32) {\n unchecked {\n uint256 end = _start + 32;\n return bytes32(_bytes[_start:end]);\n }\n }\n}\n"},"lib/LayerZero-v2/protocol/contracts/messagelib/libs/BitMaps.sol":{"content":"// SPDX-License-Identifier: MIT\n\n// modified from https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/structs/BitMaps.sol\npragma solidity ^0.8.20;\n\ntype BitMap256 is uint256;\n\nusing BitMaps for BitMap256 global;\n\nlibrary BitMaps {\n /**\n * @dev Returns whether the bit at `index` is set.\n */\n function get(BitMap256 bitmap, uint8 index) internal pure returns (bool) {\n uint256 mask = 1 << index;\n return BitMap256.unwrap(bitmap) & mask != 0;\n }\n\n /**\n * @dev Sets the bit at `index`.\n */\n function set(BitMap256 bitmap, uint8 index) internal pure returns (BitMap256) {\n uint256 mask = 1 << index;\n return BitMap256.wrap(BitMap256.unwrap(bitmap) | mask);\n }\n}\n"},"lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\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 amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` 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 amount) 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 `amount` as the allowance of `spender` over the 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 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` 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 amount) external returns (bool);\n}\n"},"lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Permit.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.4) (token/ERC20/extensions/IERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n *\n * ==== Security Considerations\n *\n * There are two important considerations concerning the use of `permit`. The first is that a valid permit signature\n * expresses an allowance, and it should not be assumed to convey additional meaning. In particular, it should not be\n * considered as an intention to spend the allowance in any specific way. The second is that because permits have\n * built-in replay protection and can be submitted by anyone, they can be frontrun. A protocol that uses permits should\n * take this into consideration and allow a `permit` call to fail. Combining these two aspects, a pattern that may be\n * generally recommended is:\n *\n * ```solidity\n * function doThingWithPermit(..., uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public {\n * try token.permit(msg.sender, address(this), value, deadline, v, r, s) {} catch {}\n * doThing(..., value);\n * }\n *\n * function doThing(..., uint256 value) public {\n * token.safeTransferFrom(msg.sender, address(this), value);\n * ...\n * }\n * ```\n *\n * Observe that: 1) `msg.sender` is used as the owner, leaving no ambiguity as to the signer intent, and 2) the use of\n * `try/catch` allows the permit to fail and makes the code tolerant to frontrunning. (See also\n * {SafeERC20-safeTransferFrom}).\n *\n * Additionally, note that smart contract wallets (such as Argent or Safe) are not able to produce permit signatures, so\n * contracts should have entry points that don't rely on permit.\n */\ninterface IERC20Permit {\n /**\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\n * given ``owner``'s signed approval.\n *\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\n * ordering also apply here.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `deadline` must be a timestamp in the future.\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\n * over the EIP712-formatted function arguments.\n * - the signature must use ``owner``'s current nonce (see {nonces}).\n *\n * For more information on the signature format, see the\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\n * section].\n *\n * CAUTION: See Security Considerations above.\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n\n /**\n * @dev Returns the current nonce for `owner`. This value must be\n * included whenever a signature is generated for {permit}.\n *\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\n * prevents a signature from being used multiple times.\n */\n function nonces(address owner) external view returns (uint256);\n\n /**\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n"},"lib/openzeppelin-contracts/contracts/utils/Address.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n *\n * Furthermore, `isContract` will also return true if the target contract within\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\n * which only has an effect at the end of a transaction.\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\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.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\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, it is bubbled up by this\n * function (like regular Solidity function calls).\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 * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\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 * _Available since v3.1._\n */\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\n *\n * _Available since v4.8._\n */\n function verifyCallResultFromTarget(\n address target,\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n if (success) {\n if (returndata.length == 0) {\n // only check isContract if the call was successful and the return data is empty\n // otherwise we already know that it was a contract\n require(isContract(target), \"Address: call to non-contract\");\n }\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n /**\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason or using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n function _revert(bytes memory returndata, string memory errorMessage) 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(errorMessage);\n }\n }\n}\n"}},"settings":{"remappings":["ds-test/=lib/forge-std/lib/ds-test/src/","forge-std/=lib/forge-std/src/","@layerzero-contracts/=lib/solidity-examples/contracts/","@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/","@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/","@layerzero-v2/=lib/LayerZero-v2/","@layerzerolabs/lz-evm-protocol-v2/=lib/LayerZero-v2/protocol/","@layerzerolabs/lz-evm-oapp-v2/=lib/LayerZero-v2/oapp/","@layerzerolabs/lz-evm-messagelib-v2/=lib/LayerZero-v2/messagelib/","@beacon-oracle/=lib/eigenlayer-beacon-oracle/","solidity-bytes-utils/=lib/solidity-bytes-utils/","LayerZero-v2/=lib/LayerZero-v2/","LayerZero/=lib/LayerZero/contracts/","eigenlayer-beacon-oracle/=lib/eigenlayer-beacon-oracle/contracts/","erc4626-tests/=lib/openzeppelin-contracts-upgradeable/lib/erc4626-tests/","openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/","openzeppelin-contracts/=lib/openzeppelin-contracts/","openzeppelin/=lib/openzeppelin-contracts-upgradeable/contracts/","solidity-examples/=lib/solidity-examples/contracts/"],"optimizer":{"enabled":true,"runs":200},"metadata":{"useLiteralContent":false,"bytecodeHash":"ipfs","appendCBOR":true},"outputSelection":{"*":{"*":["abi","evm.bytecode","evm.deployedBytecode","evm.methodIdentifiers","metadata"]}},"evmVersion":"paris","viaIR":false,"libraries":{}}} diff --git a/src/core/ExoCapsule.sol b/src/core/ExoCapsule.sol index 7e450604..2c9d06a1 100644 --- a/src/core/ExoCapsule.sol +++ b/src/core/ExoCapsule.sol @@ -182,10 +182,6 @@ contract ExoCapsule is ReentrancyGuardUpgradeable, ExoCapsuleStorage, IExoCapsul revert StaleValidatorContainer(validatorPubkey, proof.beaconBlockTimestamp); } - if (!_isActivatedAtEpoch(validatorContainer, proof.beaconBlockTimestamp)) { - revert InactiveValidatorContainer(validatorPubkey); - } - if (withdrawalCredentials != bytes32(capsuleWithdrawalCredentials())) { revert WithdrawalCredentialsNotMatch(); } From 6629b5507bfeb09623dc84456a9b8651ded8190b Mon Sep 17 00:00:00 2001 From: adu Date: Mon, 29 Jul 2024 15:41:47 +0800 Subject: [PATCH 2/4] refactor: remove isActivatedAtEpoch check for verifyDepositProof --- test/foundry/unit/ExoCapsule.t.sol | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/test/foundry/unit/ExoCapsule.t.sol b/test/foundry/unit/ExoCapsule.t.sol index 71884007..8edb206f 100644 --- a/test/foundry/unit/ExoCapsule.t.sol +++ b/test/foundry/unit/ExoCapsule.t.sol @@ -221,7 +221,7 @@ contract VerifyDepositProof is DepositSetup { capsule.verifyDepositProof(validatorContainer, validatorProof); } - function test_verifyDepositProof_revert_inactiveValidatorContainer() public { + function test_verifyDepositProof_success_inactiveValidatorContainer() public { uint256 activationTimestamp = BEACON_CHAIN_GENESIS_TIME + _getActivationEpoch(validatorContainer) * SECONDS_PER_EPOCH; @@ -236,10 +236,15 @@ contract VerifyDepositProof is DepositSetup { mockCurrentBlockTimestamp = mockProofTimestamp + SECONDS_PER_SLOT; vm.warp(mockCurrentBlockTimestamp); validatorProof.beaconBlockTimestamp = mockProofTimestamp; - vm.expectRevert( - abi.encodeWithSelector(ExoCapsule.InactiveValidatorContainer.selector, _getPubkey(validatorContainer)) - ); + capsule.verifyDepositProof(validatorContainer, validatorProof); + + ExoCapsuleStorage.Validator memory validator = + capsule.getRegisteredValidatorByPubkey(_getPubkey(validatorContainer)); + assertEq(uint8(validator.status), uint8(ExoCapsuleStorage.VALIDATOR_STATUS.REGISTERED)); + assertEq(validator.validatorIndex, validatorProof.validatorIndex); + assertEq(validator.mostRecentBalanceUpdateTimestamp, validatorProof.beaconBlockTimestamp); + assertEq(validator.restakedBalanceGwei, _getEffectiveBalance(validatorContainer)); } function test_verifyDepositProof_revert_mismatchWithdrawalCredentials() public { From c276af46f7c530bb2ebb692778fd0b1fad285735 Mon Sep 17 00:00:00 2001 From: adu Date: Mon, 29 Jul 2024 15:45:57 +0800 Subject: [PATCH 3/4] remove input.json --- input.json | 1 - 1 file changed, 1 deletion(-) delete mode 100644 input.json diff --git a/input.json b/input.json deleted file mode 100644 index 9feac0a5..00000000 --- a/input.json +++ /dev/null @@ -1 +0,0 @@ -{"language":"Solidity","sources":{"src/core/ExocoreGateway.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {IExocoreGateway} from \"../interfaces/IExocoreGateway.sol\";\n\nimport {ASSETS_CONTRACT, ASSETS_PRECOMPILE_ADDRESS} from \"../interfaces/precompiles/IAssets.sol\";\nimport {CLAIM_REWARD_CONTRACT, CLAIM_REWARD_PRECOMPILE_ADDRESS} from \"../interfaces/precompiles/IClaimReward.sol\";\nimport {DELEGATION_CONTRACT, DELEGATION_PRECOMPILE_ADDRESS} from \"../interfaces/precompiles/IDelegation.sol\";\n\nimport {\n MessagingFee,\n MessagingReceipt,\n OAppReceiverUpgradeable,\n OAppUpgradeable,\n Origin\n} from \"../lzApp/OAppUpgradeable.sol\";\nimport {ExocoreGatewayStorage} from \"../storage/ExocoreGatewayStorage.sol\";\n\nimport {Errors} from \"../libraries/Errors.sol\";\nimport {OAppCoreUpgradeable} from \"../lzApp/OAppCoreUpgradeable.sol\";\nimport {IOAppCore} from \"@layerzero-v2/oapp/contracts/oapp/interfaces/IOAppCore.sol\";\nimport {OptionsBuilder} from \"@layerzero-v2/oapp/contracts/oapp/libs/OptionsBuilder.sol\";\nimport {ILayerZeroReceiver} from \"@layerzero-v2/protocol/contracts/interfaces/ILayerZeroReceiver.sol\";\nimport {OwnableUpgradeable} from \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport {Initializable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport {PausableUpgradeable} from \"@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol\";\nimport {ReentrancyGuardUpgradeable} from \"@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol\";\n\n/// @title ExocoreGateway\n/// @author ExocoreNetwork\n/// @notice The gateway contract deployed on Exocore chain for client chain operations.\n/// @dev This contract address must be registered in the `x/assets` module for the precompile operations to go through.\ncontract ExocoreGateway is\n Initializable,\n PausableUpgradeable,\n OwnableUpgradeable,\n ReentrancyGuardUpgradeable,\n IExocoreGateway,\n ExocoreGatewayStorage,\n OAppUpgradeable\n{\n\n using OptionsBuilder for bytes;\n\n /// @dev Ensures that the function is called only from this contract via low-level call.\n modifier onlyCalledFromThis() {\n if (msg.sender != address(this)) {\n revert Errors.ExocoreGatewayOnlyCalledFromThis();\n }\n _;\n }\n\n /// @notice Creates the ExocoreGateway contract.\n /// @param endpoint_ The LayerZero endpoint address deployed on this chain\n constructor(address endpoint_) OAppUpgradeable(endpoint_) {\n _disableInitializers();\n }\n\n receive() external payable {}\n\n /// @notice Initializes the ExocoreGateway contract.\n /// @param owner_ The address of the contract owner.\n function initialize(address owner_) external initializer {\n if (owner_ == address(0)) {\n revert Errors.ZeroAddress();\n }\n\n _initializeWhitelistFunctionSelectors();\n _transferOwnership(owner_);\n __OAppCore_init_unchained(owner_);\n __Pausable_init_unchained();\n __ReentrancyGuard_init_unchained();\n }\n\n /// @dev Initializes the whitelist function selectors.\n function _initializeWhitelistFunctionSelectors() private {\n _whiteListFunctionSelectors[Action.REQUEST_DEPOSIT] = this.requestDeposit.selector;\n _whiteListFunctionSelectors[Action.REQUEST_DELEGATE_TO] = this.requestDelegateTo.selector;\n _whiteListFunctionSelectors[Action.REQUEST_UNDELEGATE_FROM] = this.requestUndelegateFrom.selector;\n _whiteListFunctionSelectors[Action.REQUEST_WITHDRAW_PRINCIPAL_FROM_EXOCORE] =\n this.requestWithdrawPrincipal.selector;\n _whiteListFunctionSelectors[Action.REQUEST_WITHDRAW_REWARD_FROM_EXOCORE] = this.requestWithdrawReward.selector;\n _whiteListFunctionSelectors[Action.REQUEST_DEPOSIT_THEN_DELEGATE_TO] =\n this.requestDepositThenDelegateTo.selector;\n }\n\n /// @notice Pauses the contract.\n function pause() external onlyOwner {\n _pause();\n }\n\n /// @notice Unpauses the contract.\n function unpause() external onlyOwner {\n _unpause();\n }\n\n /// @notice Marks the bootstrap on all chains.\n /// @dev This function obtains a list of client chain ids from the precompile, and then\n /// sends a `REQUEST_MARK_BOOTSTRAP` to all of them. In response, the Bootstrap contract\n /// on those chains should upgrade itself to the ClientChainGateway contract.\n /// This function should be the first to be called after the LZ infrastructure is ready.\n // TODO: call this function automatically, either within the initializer (which requires\n // setPeer) or be triggered by Golang after the contract is deployed.\n // For manual calls, this function should be called immediately after deployment and\n // then never needs to be called again.\n function markBootstrapOnAllChains() public whenNotPaused nonReentrant {\n (bool success, bytes memory result) =\n ASSETS_PRECOMPILE_ADDRESS.staticcall(abi.encodeWithSelector(ASSETS_CONTRACT.getClientChains.selector));\n if (!success) {\n revert Errors.ExocoreGatewayFailedToGetClientChainIds();\n }\n (bool ok, uint32[] memory clientChainIds) = abi.decode(result, (bool, uint32[]));\n if (!ok) {\n revert Errors.ExocoreGatewayFailedToDecodeClientChainIds();\n }\n for (uint256 i = 0; i < clientChainIds.length; i++) {\n uint32 clientChainId = clientChainIds[i];\n if (!chainToBootstrapped[clientChainId]) {\n _sendInterchainMsg(clientChainId, Action.REQUEST_MARK_BOOTSTRAP, \"\", true);\n // TODO: should this be marked only upon receiving a response?\n chainToBootstrapped[clientChainId] = true;\n }\n }\n }\n\n /// @inheritdoc IExocoreGateway\n function registerOrUpdateClientChain(\n uint32 clientChainId,\n bytes32 peer,\n uint8 addressLength,\n string calldata name,\n string calldata metaInfo,\n string calldata signatureType\n ) public onlyOwner whenNotPaused {\n if (\n clientChainId == uint32(0) || peer == bytes32(0) || addressLength == 0 || bytes(name).length == 0\n || bytes(metaInfo).length == 0\n ) {\n revert Errors.ZeroValue();\n }\n // signature type could be left as empty for current implementation\n _registerClientChain(clientChainId, addressLength, name, metaInfo, signatureType);\n super.setPeer(clientChainId, peer);\n\n if (!isRegisteredClientChain[clientChainId]) {\n isRegisteredClientChain[clientChainId] = true;\n emit ClientChainRegistered(clientChainId);\n } else {\n emit ClientChainUpdated(clientChainId);\n }\n }\n\n /// @notice Sets a peer on the destination chain for this contract.\n /// @dev This is the LayerZero peer.\n /// @param clientChainId The id of the client chain.\n /// @param clientChainGateway The address of the peer as bytes32.\n function setPeer(uint32 clientChainId, bytes32 clientChainGateway)\n public\n override(IOAppCore, OAppCoreUpgradeable)\n onlyOwner\n whenNotPaused\n {\n if (!isRegisteredClientChain[clientChainId]) {\n revert Errors.ExocoreGatewayNotRegisteredClientChainId();\n }\n\n super.setPeer(clientChainId, clientChainGateway);\n }\n\n /// @inheritdoc IExocoreGateway\n function addWhitelistTokens(\n uint32 clientChainId,\n bytes32[] calldata tokens,\n uint8[] calldata decimals,\n uint256[] calldata tvlLimits,\n string[] calldata names,\n string[] calldata metaData\n ) external payable onlyOwner whenNotPaused nonReentrant {\n _addOrUpdateWhitelistTokens(clientChainId, tokens, decimals, tvlLimits, names, metaData, true);\n }\n\n /// @inheritdoc IExocoreGateway\n function updateWhitelistedTokens(\n uint32 clientChainId,\n bytes32[] calldata tokens,\n uint8[] calldata decimals,\n uint256[] calldata tvlLimits,\n string[] calldata names,\n string[] calldata metaData\n ) external onlyOwner whenNotPaused {\n _addOrUpdateWhitelistTokens(clientChainId, tokens, decimals, tvlLimits, names, metaData, false);\n }\n\n /// @dev The internal version of addWhitelistTokens and updateWhitelistedTokens.\n /// @param clientChainId Source client chain id\n /// @param tokens List of token addresses\n /// @param decimals List of token decimals (like 18)\n /// @param tvlLimits List of TVL limits (like max supply)\n /// @param names List of token names\n /// @param metaData List of arbitrary meta data for each token\n /// @param add Whether to add or update the tokens\n /// @dev Validates that lengths are equal, <= 255, and that the chain is registered.\n // Though this function would call precompiled contract, all precompiled contracts belong to Exocore\n // and we could make sure its implementation does not have dangerous behavior like reentrancy.\n // slither-disable-next-line reentrancy-no-eth\n function _addOrUpdateWhitelistTokens(\n uint32 clientChainId,\n bytes32[] calldata tokens,\n uint8[] calldata decimals,\n uint256[] calldata tvlLimits,\n string[] calldata names,\n string[] calldata metaData,\n bool add\n ) internal {\n _validateWhitelistTokensInput(clientChainId, tokens, decimals, tvlLimits, names, metaData);\n\n for (uint256 i; i < tokens.length; i++) {\n require(tokens[i] != bytes32(0), \"ExocoreGateway: token cannot be zero address\");\n if (!add) {\n require(isWhitelistedToken[tokens[i]], \"ExocoreGateway: token has not been added to whitelist before\");\n }\n require(tvlLimits[i] > 0, \"ExocoreGateway: tvl limit should not be zero\");\n require(bytes(names[i]).length != 0, \"ExocoreGateway: name cannot be empty\");\n require(bytes(metaData[i]).length != 0, \"ExocoreGateway: meta data cannot be empty\");\n\n bool success = ASSETS_CONTRACT.registerToken(\n clientChainId, abi.encodePacked(tokens[i]), decimals[i], tvlLimits[i], names[i], metaData[i]\n );\n\n if (success) {\n if (add) {\n isWhitelistedToken[tokens[i]] = true;\n emit WhitelistTokenAdded(clientChainId, tokens[i]);\n } else {\n emit WhitelistTokenUpdated(clientChainId, tokens[i]);\n }\n } else {\n if (add) {\n revert AddWhitelistTokenFailed(tokens[i]);\n } else {\n revert UpdateWhitelistTokenFailed(tokens[i]);\n }\n }\n }\n if (add) {\n _sendInterchainMsg(\n clientChainId,\n Action.REQUEST_ADD_WHITELIST_TOKENS,\n abi.encodePacked(uint8(tokens.length), tokens),\n false\n );\n }\n }\n\n /// @dev Validates the input for whitelist tokens.\n /// @param clientChainId The client chain id, which must have been previously registered.\n /// @param tokens The list of token addresses, length must be <= 255.\n /// @param decimals The list of token decimals, length must be equal to that of @param tokens.\n /// @param tvlLimits The list of token TVL limits, length must be equal to that of @param tokens.\n /// @param names The list of token names, length must be equal to that of @param tokens.\n /// @param metaData The list of token meta data, length must be equal to that of @param tokens.\n function _validateWhitelistTokensInput(\n uint32 clientChainId,\n bytes32[] calldata tokens,\n uint8[] calldata decimals,\n uint256[] calldata tvlLimits,\n string[] calldata names,\n string[] calldata metaData\n ) internal view {\n if (!isRegisteredClientChain[clientChainId]) {\n revert ClientChainIDNotRegisteredBefore(clientChainId);\n }\n\n uint256 expectedLength = tokens.length;\n if (expectedLength > type(uint8).max) {\n revert WhitelistTokensListTooLong();\n }\n\n if (\n decimals.length != expectedLength || tvlLimits.length != expectedLength || names.length != expectedLength\n || metaData.length != expectedLength\n ) {\n revert InvalidWhitelistTokensInput();\n }\n }\n\n /// @dev The internal version of registerClientChain.\n /// @param clientChainId The client chain id.\n /// @param addressLength The length of the address type on the client chain.\n /// @param name The name of the client chain.\n /// @param metaInfo The arbitrary metadata for the client chain.\n /// @param signatureType The signature type supported by the client chain.\n function _registerClientChain(\n uint32 clientChainId,\n uint8 addressLength,\n string calldata name,\n string calldata metaInfo,\n string calldata signatureType\n ) internal {\n bool success = ASSETS_CONTRACT.registerClientChain(clientChainId, addressLength, name, metaInfo, signatureType);\n if (!success) {\n revert RegisterClientChainToExocoreFailed(clientChainId);\n }\n }\n\n /// @inheritdoc OAppReceiverUpgradeable\n function _lzReceive(Origin calldata _origin, bytes calldata payload)\n internal\n virtual\n override\n whenNotPaused\n nonReentrant\n {\n _verifyAndUpdateNonce(_origin.srcEid, _origin.sender, _origin.nonce);\n\n Action act = Action(uint8(payload[0]));\n bytes4 selector_ = _whiteListFunctionSelectors[act];\n if (selector_ == bytes4(0)) {\n revert UnsupportedRequest(act);\n }\n\n (bool success, bytes memory responseOrReason) =\n address(this).call(abi.encodePacked(selector_, abi.encode(_origin.srcEid, _origin.nonce, payload[1:])));\n if (!success) {\n revert RequestExecuteFailed(act, _origin.nonce, responseOrReason);\n }\n }\n\n /// @notice Responds to a deposit request from a client chain.\n /// @dev Can only be called from this contract via low-level call.\n /// @param srcChainId The source chain id.\n /// @param lzNonce The layer zero nonce.\n /// @param payload The request payload.\n function requestDeposit(uint32 srcChainId, uint64 lzNonce, bytes calldata payload) public onlyCalledFromThis {\n _validatePayloadLength(payload, DEPOSIT_REQUEST_LENGTH, Action.REQUEST_DEPOSIT);\n\n bytes memory token = payload[:32];\n bytes memory depositor = payload[32:64];\n uint256 amount = uint256(bytes32(payload[64:96]));\n\n (bool success, uint256 updatedBalance) = ASSETS_CONTRACT.depositTo(srcChainId, token, depositor, amount);\n if (!success) {\n revert DepositRequestShouldNotFail(srcChainId, lzNonce);\n }\n\n _sendInterchainMsg(srcChainId, Action.RESPOND, abi.encodePacked(lzNonce, success, updatedBalance), true);\n\n emit DepositResult(true, bytes32(token), bytes32(depositor), amount);\n }\n\n /// @notice Responds to a withdraw-principal request from a client chain.\n /// @dev Can only be called from this contract via low-level call.\n /// @param srcChainId The source chain id.\n /// @param lzNonce The layer zero nonce.\n /// @param payload The request payload.\n function requestWithdrawPrincipal(uint32 srcChainId, uint64 lzNonce, bytes calldata payload)\n public\n onlyCalledFromThis\n {\n _validatePayloadLength(\n payload, WITHDRAW_PRINCIPAL_REQUEST_LENGTH, Action.REQUEST_WITHDRAW_PRINCIPAL_FROM_EXOCORE\n );\n\n bytes memory token = payload[:32];\n bytes memory withdrawer = payload[32:64];\n uint256 amount = uint256(bytes32(payload[64:96]));\n\n bool result = false;\n try ASSETS_CONTRACT.withdrawPrincipal(srcChainId, token, withdrawer, amount) returns (\n bool success, uint256 updatedBalance\n ) {\n result = success;\n _sendInterchainMsg(srcChainId, Action.RESPOND, abi.encodePacked(lzNonce, success, updatedBalance), true);\n } catch {\n emit ExocorePrecompileError(ASSETS_PRECOMPILE_ADDRESS, lzNonce);\n\n _sendInterchainMsg(srcChainId, Action.RESPOND, abi.encodePacked(lzNonce, false, uint256(0)), true);\n }\n\n emit WithdrawPrincipalResult(result, bytes32(token), bytes32(withdrawer), amount);\n }\n\n /// @notice Responds to a withdraw-reward request from a client chain.\n /// @dev Can only be called from this contract via low-level call.\n /// @param srcChainId The source chain id.\n /// @param lzNonce The layer zero nonce.\n /// @param payload The request payload.\n function requestWithdrawReward(uint32 srcChainId, uint64 lzNonce, bytes calldata payload)\n public\n onlyCalledFromThis\n {\n _validatePayloadLength(payload, CLAIM_REWARD_REQUEST_LENGTH, Action.REQUEST_WITHDRAW_REWARD_FROM_EXOCORE);\n\n bytes memory token = payload[:32];\n bytes memory withdrawer = payload[32:64];\n uint256 amount = uint256(bytes32(payload[64:96]));\n\n bool result = false;\n try CLAIM_REWARD_CONTRACT.claimReward(srcChainId, token, withdrawer, amount) returns (\n bool success, uint256 updatedBalance\n ) {\n result = success;\n _sendInterchainMsg(srcChainId, Action.RESPOND, abi.encodePacked(lzNonce, success, updatedBalance), true);\n } catch {\n emit ExocorePrecompileError(CLAIM_REWARD_PRECOMPILE_ADDRESS, lzNonce);\n\n _sendInterchainMsg(srcChainId, Action.RESPOND, abi.encodePacked(lzNonce, false, uint256(0)), true);\n }\n\n emit WithdrawRewardResult(result, bytes32(token), bytes32(withdrawer), amount);\n }\n\n /// @notice Responds to a delegate request from a client chain.\n /// @dev Can only be called from this contract via low-level call.\n /// @param srcChainId The source chain id.\n /// @param lzNonce The layer zero nonce.\n /// @param payload The request payload.\n function requestDelegateTo(uint32 srcChainId, uint64 lzNonce, bytes calldata payload) public onlyCalledFromThis {\n _validatePayloadLength(payload, DELEGATE_REQUEST_LENGTH, Action.REQUEST_DELEGATE_TO);\n\n bytes memory token = payload[:32];\n bytes memory delegator = payload[32:64];\n bytes memory operator = payload[64:106];\n uint256 amount = uint256(bytes32(payload[106:138]));\n\n bool result = false;\n try DELEGATION_CONTRACT.delegateToThroughClientChain(srcChainId, lzNonce, token, delegator, operator, amount)\n returns (bool success) {\n result = success;\n _sendInterchainMsg(srcChainId, Action.RESPOND, abi.encodePacked(lzNonce, success), true);\n } catch {\n emit ExocorePrecompileError(DELEGATION_PRECOMPILE_ADDRESS, lzNonce);\n\n _sendInterchainMsg(srcChainId, Action.RESPOND, abi.encodePacked(lzNonce, false), true);\n }\n\n emit DelegateResult(result, bytes32(token), bytes32(delegator), string(operator), amount);\n }\n\n /// @notice Responds to an undelegate request from a client chain.\n /// @dev Can only be called from this contract via low-level call.\n /// @param srcChainId The source chain id.\n /// @param lzNonce The layer zero nonce.\n /// @param payload The request payload.\n function requestUndelegateFrom(uint32 srcChainId, uint64 lzNonce, bytes calldata payload)\n public\n onlyCalledFromThis\n {\n _validatePayloadLength(payload, UNDELEGATE_REQUEST_LENGTH, Action.REQUEST_UNDELEGATE_FROM);\n\n bytes memory token = payload[:32];\n bytes memory delegator = payload[32:64];\n bytes memory operator = payload[64:106];\n uint256 amount = uint256(bytes32(payload[106:138]));\n\n bool result = false;\n try DELEGATION_CONTRACT.undelegateFromThroughClientChain(\n srcChainId, lzNonce, token, delegator, operator, amount\n ) returns (bool success) {\n result = success;\n _sendInterchainMsg(srcChainId, Action.RESPOND, abi.encodePacked(lzNonce, success), true);\n } catch {\n emit ExocorePrecompileError(DELEGATION_PRECOMPILE_ADDRESS, lzNonce);\n\n _sendInterchainMsg(srcChainId, Action.RESPOND, abi.encodePacked(lzNonce, false), true);\n }\n\n emit UndelegateResult(result, bytes32(token), bytes32(delegator), string(operator), amount);\n }\n\n /// @notice Responds to a deposit-then-delegate request from a client chain.\n /// @dev Can only be called from this contract via low-level call.\n /// @param srcChainId The source chain id.\n /// @param lzNonce The layer zero nonce.\n /// @param payload The request payload.\n function requestDepositThenDelegateTo(uint32 srcChainId, uint64 lzNonce, bytes calldata payload)\n public\n onlyCalledFromThis\n {\n _validatePayloadLength(payload, DEPOSIT_THEN_DELEGATE_REQUEST_LENGTH, Action.REQUEST_DEPOSIT_THEN_DELEGATE_TO);\n\n bytes memory token = payload[:32];\n bytes memory depositor = payload[32:64];\n bytes memory operator = payload[64:106];\n uint256 amount = uint256(bytes32(payload[106:138]));\n\n // while some of the code from requestDeposit and requestDelegateTo is duplicated here,\n // it is done intentionally to work around Solidity's limitations with regards to\n // function calls, error handling and indexing the return data of memory type.\n // for example, you cannot index a bytes memory result from the requestDepositTo call,\n // if you were to modify it to return bytes and then process them here.\n\n bool result = false;\n (bool success, uint256 updatedBalance) = ASSETS_CONTRACT.depositTo(srcChainId, token, depositor, amount);\n if (!success) {\n revert DepositRequestShouldNotFail(srcChainId, lzNonce);\n }\n emit DepositResult(true, bytes32(token), bytes32(depositor), amount);\n\n try DELEGATION_CONTRACT.delegateToThroughClientChain(srcChainId, lzNonce, token, depositor, operator, amount)\n returns (bool delegateSuccess) {\n result = delegateSuccess;\n _sendInterchainMsg(\n srcChainId, Action.RESPOND, abi.encodePacked(lzNonce, delegateSuccess, updatedBalance), true\n );\n } catch {\n emit ExocorePrecompileError(DELEGATION_PRECOMPILE_ADDRESS, lzNonce);\n _sendInterchainMsg(srcChainId, Action.RESPOND, abi.encodePacked(lzNonce, false, updatedBalance), true);\n }\n emit DelegateResult(result, bytes32(token), bytes32(depositor), string(operator), amount);\n }\n\n /// @dev Validates the payload length, that it matches the expected length.\n /// @param payload The payload to validate.\n /// @param expectedLength The expected length of the payload.\n /// @param action The action that the payload is for.\n function _validatePayloadLength(bytes calldata payload, uint256 expectedLength, Action action) private pure {\n if (payload.length != expectedLength) {\n revert InvalidRequestLength(action, expectedLength, payload.length);\n }\n }\n\n /// @dev Sends an interchain message to the client chain.\n /// @param srcChainId The chain id of the source chain, from which a message was received, and to which a response\n /// is being sent.\n /// @param act The action to be performed.\n /// @param actionArgs The arguments for the action.\n /// @param payByApp If the source for the transaction funds is this contract.\n function _sendInterchainMsg(uint32 srcChainId, Action act, bytes memory actionArgs, bool payByApp)\n internal\n whenNotPaused\n {\n bytes memory payload = abi.encodePacked(act, actionArgs);\n bytes memory options = OptionsBuilder.newOptions().addExecutorLzReceiveOption(\n DESTINATION_GAS_LIMIT, DESTINATION_MSG_VALUE\n ).addExecutorOrderedExecutionOption();\n MessagingFee memory fee = _quote(srcChainId, payload, options, false);\n\n MessagingReceipt memory receipt =\n _lzSend(srcChainId, payload, options, MessagingFee(fee.nativeFee, 0), msg.sender, payByApp);\n emit MessageSent(act, receipt.guid, receipt.nonce, receipt.fee.nativeFee);\n }\n\n /// @inheritdoc IExocoreGateway\n function quote(uint32 srcChainid, bytes memory _message) public view returns (uint256 nativeFee) {\n bytes memory options = OptionsBuilder.newOptions().addExecutorLzReceiveOption(\n DESTINATION_GAS_LIMIT, DESTINATION_MSG_VALUE\n ).addExecutorOrderedExecutionOption();\n MessagingFee memory fee = _quote(srcChainid, _message, options, false);\n return fee.nativeFee;\n }\n\n /// @inheritdoc OAppReceiverUpgradeable\n function nextNonce(uint32 srcEid, bytes32 sender)\n public\n view\n virtual\n override(ILayerZeroReceiver, OAppReceiverUpgradeable)\n returns (uint64)\n {\n return inboundNonce[srcEid][sender] + 1;\n }\n\n}\n"},"src/interfaces/IExocoreGateway.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {IOAppCore} from \"@layerzero-v2/oapp/contracts/oapp/interfaces/IOAppCore.sol\";\nimport {IOAppReceiver} from \"@layerzero-v2/oapp/contracts/oapp/interfaces/IOAppReceiver.sol\";\n\n/// @title IExocoreGateway\n/// @author ExocoreNetwork\n/// @notice IExocoreGateway is the interface for the ExocoreGateway contract. It provides a set of functions for\n/// ExocoreGateway operations.\n/// @dev It is deployed on the Exocore end and is designed to interact with other chains,\n/// as well as precompiles on the Exocore chain in response to messages from other chains.\ninterface IExocoreGateway is IOAppReceiver, IOAppCore {\n\n /// @notice Calculates the native fee for sending a message with specific options.\n /// @param srcChainid The chain id of the source chain, from which a message was received,\n /// and to which a response is being sent.\n /// @param _message The message for which the fee is being calculated.\n /// @return nativeFee The calculated native fee for the given message.\n function quote(uint32 srcChainid, bytes memory _message) external view returns (uint256 nativeFee);\n\n /// @notice Registers the @param clientChainId and other meta data to Exocore native module or update the client\n /// chain's meta data, if a chain identified by @param clientChainId already exists. Sets trusted @param peer to\n /// enable cross-chain communication.\n /// @param clientChainId The endpoint ID for client chain.\n /// @param peer The trusted remote contract address to be associated with the corresponding endpoint or some\n /// authorized signer that would be trusted for sending messages from/to source chain to/from this contract.\n /// @param addressLength The bytes length of address type on that client chain.\n /// @param name The name of client chain.\n /// @param metaInfo The arbitrary metadata for client chain.\n /// @param signatureType The cryptographic signature type that client chain supports.\n /// @dev Only the owner/admin of the OApp can call this function.\n /// @dev Indicates that the peer is trusted to send LayerZero messages to this OApp.\n /// @dev Peer is a bytes32 to accommodate non-evm chains.\n function registerOrUpdateClientChain(\n uint32 clientChainId,\n bytes32 peer,\n uint8 addressLength,\n string calldata name,\n string calldata metaInfo,\n string calldata signatureType\n ) external;\n\n /// @notice Adds a list of whitelisted tokens to the client chain.\n /// @param clientChainId The LayerZero chain id of the client chain.\n /// @param tokens The list of token addresses to be whitelisted.\n /// @param decimals The list of token decimals, in the same order as the tokens list.\n /// @param tvlLimits The list of token TVL limits (typically max supply),in the same order as the tokens list.\n /// @param names The names of the tokens, in the same order as the tokens list.\n /// @param metaData The meta information of the tokens, in the same order as the tokens list.\n /// @dev The chain must be registered before adding tokens.\n function addWhitelistTokens(\n uint32 clientChainId,\n bytes32[] calldata tokens,\n uint8[] calldata decimals,\n uint256[] calldata tvlLimits,\n string[] calldata names,\n string[] calldata metaData\n ) external payable;\n\n /// @notice Updates a list of whitelisted tokens to the client chain.\n /// @param clientChainId The LayerZero chain id of the client chain.\n /// @param tokens The list of token addresses to be whitelisted.\n /// @param decimals The list of token decimals, in the same order as the tokens list.\n /// @param tvlLimits The list of token TVL limits (typically max supply),in the same order as the tokens list.\n /// @param names The names of the tokens, in the same order as the tokens list.\n /// @param metaData The meta information of the tokens, in the same order as the tokens list.\n /// @dev The chain must be registered before updating tokens, and the token as well.\n function updateWhitelistedTokens(\n uint32 clientChainId,\n bytes32[] calldata tokens,\n uint8[] calldata decimals,\n uint256[] calldata tvlLimits,\n string[] calldata names,\n string[] calldata metaData\n ) external;\n\n}\n"},"src/interfaces/precompiles/IAssets.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity >=0.8.17;\n\n/// @dev The Assets contract's address.\naddress constant ASSETS_PRECOMPILE_ADDRESS = 0x0000000000000000000000000000000000000804;\n\n/// @dev The Assets contract's instance.\nIAssets constant ASSETS_CONTRACT = IAssets(ASSETS_PRECOMPILE_ADDRESS);\n\n/// @author Exocore Team\n/// @title Assets Precompile Contract\n/// @dev The interface through which solidity contracts will interact with assets module\n/// @custom:address 0x0000000000000000000000000000000000000804\ninterface IAssets {\n\n /// TRANSACTIONS\n /// @dev deposit the client chain assets for the staker,\n /// that will change the state in deposit module\n /// Note that this address cannot be a module account.\n /// @param clientChainLzID The LzID of client chain\n /// @param assetsAddress The client chain asset address\n /// @param stakerAddress The staker address\n /// @param opAmount The amount to deposit\n function depositTo(uint32 clientChainLzID, bytes memory assetsAddress, bytes memory stakerAddress, uint256 opAmount)\n external\n returns (bool success, uint256 latestAssetState);\n\n /// TRANSACTIONS\n /// @dev withdraw To the staker, that will change the state in withdraw module\n /// Note that this address cannot be a module account.\n /// @param clientChainLzID The LzID of client chain\n /// @param assetsAddress The client chain asset Address\n /// @param withdrawAddress The withdraw address\n /// @param opAmount The withdraw amount\n function withdrawPrincipal(\n uint32 clientChainLzID,\n bytes memory assetsAddress,\n bytes memory withdrawAddress,\n uint256 opAmount\n ) external returns (bool success, uint256 latestAssetState);\n\n /// QUERIES\n /// @dev Returns the chain indices of the client chains.\n function getClientChains() external view returns (bool, uint32[] memory);\n\n /// TRANSACTIONS\n /// @dev register some client chain to allow token registration from that chain, staking\n /// from that chain, and other operations from that chain.\n /// @param clientChainID is the layerZero chainID if it is supported.\n // It might be allocated by Exocore when the client chain isn't supported\n // by layerZero\n function registerClientChain(\n uint32 clientChainID,\n uint8 addressLength,\n string calldata name,\n string calldata metaInfo,\n string calldata signatureType\n ) external returns (bool success);\n\n /// TRANSACTIONS\n /// @dev register unwhitelisted token address to exocore assets module\n /// @param clientChainID is the layerZero chainID if it is supported.\n // It might be allocated by Exocore when the client chain isn't supported\n // by layerZero\n /// @param token The token address that would be registered to exocore\n function registerToken(\n uint32 clientChainID,\n bytes calldata token,\n uint8 decimals,\n uint256 tvlLimit,\n string calldata name,\n string calldata metaData\n ) external returns (bool success);\n\n}\n"},"src/interfaces/precompiles/IClaimReward.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity >=0.8.17;\n\n/// TODO: we might remove this precompile contract and merge it into assets precompile\n/// if we decide to handle reward withdrawal request by assets precompile\n\n/// @dev The claimReward contract's address.\naddress constant CLAIM_REWARD_PRECOMPILE_ADDRESS = 0x0000000000000000000000000000000000000806;\n\n/// @dev The claimReward contract's instance.\nIClaimReward constant CLAIM_REWARD_CONTRACT = IClaimReward(CLAIM_REWARD_PRECOMPILE_ADDRESS);\n\n/// @author Exocore Team\n/// @title ClaimReward Precompile Contract\n/// @dev The interface through which solidity contracts will interact with ClaimReward\n/// @custom:address 0x0000000000000000000000000000000000000806\ninterface IClaimReward {\n\n /// TRANSACTIONS\n /// @dev ClaimReward To the staker, that will change the state in reward module\n /// Note that this address cannot be a module account.\n /// @param clientChainLzId The lzId of client chain\n /// @param assetsAddress The client chain asset Address\n /// @param withdrawRewardAddress The claim reward address\n /// @param opAmount The reward amount\n function claimReward(\n uint32 clientChainLzId,\n bytes memory assetsAddress,\n bytes memory withdrawRewardAddress,\n uint256 opAmount\n ) external returns (bool success, uint256 latestAssetState);\n\n}\n"},"src/interfaces/precompiles/IDelegation.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity >=0.8.17;\n\n/// @dev The delegation contract's address.\naddress constant DELEGATION_PRECOMPILE_ADDRESS = 0x0000000000000000000000000000000000000805;\n\n/// @dev The delegation contract's instance.\nIDelegation constant DELEGATION_CONTRACT = IDelegation(DELEGATION_PRECOMPILE_ADDRESS);\n\n/// @author Exocore Team\n/// @title delegation Precompile Contract\n/// @dev The interface through which solidity contracts will interact with delegation\n/// @custom:address 0x0000000000000000000000000000000000000805\ninterface IDelegation {\n\n /// TRANSACTIONS\n /// @dev delegate the client chain assets to the operator through client chain, that will change the states in\n /// delegation and assets module.\n /// Note that this address cannot be a module account.\n /// @param clientChainLzId The lzId of client chain\n /// @param lzNonce The cross chain tx layerZero nonce\n /// @param assetsAddress The client chain asset Address\n /// @param stakerAddress The staker address\n /// @param operatorAddr The operator address that wants to be delegated to\n /// @param opAmount The delegation amount\n function delegateToThroughClientChain(\n uint32 clientChainLzId,\n uint64 lzNonce,\n bytes memory assetsAddress,\n bytes memory stakerAddress,\n bytes memory operatorAddr,\n uint256 opAmount\n ) external returns (bool success);\n\n /// TRANSACTIONS\n /// @dev undelegate the client chain assets from the operator through client chain, that will change the states in\n /// delegation and assets module\n /// Note that this address cannot be a module account.\n /// @param clientChainLzId The lzId of client chain\n /// @param lzNonce The cross chain tx layerZero nonce\n /// @param assetsAddress The client chain asset Address\n /// @param stakerAddress The staker address\n /// @param operatorAddr The operator address that wants to unDelegate from\n /// @param opAmount The Undelegation amount\n function undelegateFromThroughClientChain(\n uint32 clientChainLzId,\n uint64 lzNonce,\n bytes memory assetsAddress,\n bytes memory stakerAddress,\n bytes memory operatorAddr,\n uint256 opAmount\n ) external returns (bool success);\n\n}\n"},"src/lzApp/OAppUpgradeable.sol":{"content":"// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.20;\n\n// @dev Import the 'MessagingFee' and 'MessagingReceipt' so it's exposed to OApp implementers\n// solhint-disable-next-line no-unused-import\nimport {MessagingFee, MessagingReceipt, OAppSenderUpgradeable} from \"./OAppSenderUpgradeable.sol\";\n// @dev Import the 'Origin' so it's exposed to OApp implementers\n// solhint-disable-next-line no-unused-import\n\nimport {OAppCoreUpgradeable} from \"./OAppCoreUpgradeable.sol\";\nimport {OAppReceiverUpgradeable, Origin} from \"./OAppReceiverUpgradeable.sol\";\n\n/**\n * @title OApp\n * @dev Abstract contract serving as the base for OApp implementation, combining OAppSender and OAppReceiver\n * functionality.\n */\nabstract contract OAppUpgradeable is OAppSenderUpgradeable, OAppReceiverUpgradeable {\n\n /**\n * @dev Constructor to initialize the OApp with the provided endpoint.\n * @param _endpoint The address of the LOCAL LayerZero endpoint.\n */\n constructor(address _endpoint) OAppCoreUpgradeable(_endpoint) {}\n\n /**\n * @dev Initialize delegate\n * @param _delegate The delegate capable of making OApp configurations inside of the endpoint.\n */\n function __OApp_init(address _delegate) internal onlyInitializing {\n __OAppCore_init(_delegate);\n }\n\n function __OApp_init_unchained(address _delegate) internal onlyInitializing {\n __OAppCore_init_unchained(_delegate);\n }\n\n /**\n * @notice Retrieves the OApp version information.\n * @return senderVersion The version of the OAppSender.sol implementation.\n * @return receiverVersion The version of the OAppReceiver.sol implementation.\n */\n function oAppVersion()\n public\n pure\n virtual\n override(OAppSenderUpgradeable, OAppReceiverUpgradeable)\n returns (uint64 senderVersion, uint64 receiverVersion)\n {\n return (SENDER_VERSION, RECEIVER_VERSION);\n }\n\n}\n"},"src/storage/ExocoreGatewayStorage.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {GatewayStorage} from \"./GatewayStorage.sol\";\n\n/// @title ExocoreGatewayStorage\n/// @notice Storage used by the ExocoreGateway contract.\n/// @author ExocoreNetwork\ncontract ExocoreGatewayStorage is GatewayStorage {\n\n /// @dev The length of a deposit request, in bytes.\n // bytes32 token + bytes32 depositor + uint256 amount\n uint256 internal constant DEPOSIT_REQUEST_LENGTH = 96;\n\n /// @dev The length of a delegate request, in bytes.\n // bytes32 token + bytes32 delegator + bytes(42) operator + uint256 amount\n uint256 internal constant DELEGATE_REQUEST_LENGTH = 138;\n\n /// @dev The length of an undelegate request, in bytes.\n // bytes32 token + bytes32 delegator + bytes(42) operator + uint256 amount\n uint256 internal constant UNDELEGATE_REQUEST_LENGTH = 138;\n\n /// @dev The length of a withdraw principal request, in bytes.\n // bytes32 token + bytes32 withdrawer + uint256 amount\n uint256 internal constant WITHDRAW_PRINCIPAL_REQUEST_LENGTH = 96;\n\n /// @dev The length of a claim reward request, in bytes.\n // bytes32 token + bytes32 withdrawer + uint256 amount\n uint256 internal constant CLAIM_REWARD_REQUEST_LENGTH = 96;\n\n /// @dev The length of a deposit-then-delegate request, in bytes.\n // bytes32 token + bytes32 delegator + bytes(42) operator + uint256 amount\n uint256 internal constant DEPOSIT_THEN_DELEGATE_REQUEST_LENGTH = DELEGATE_REQUEST_LENGTH;\n\n // constants used for layerzero messaging\n /// @dev The gas limit for all the destination chains.\n uint128 internal constant DESTINATION_GAS_LIMIT = 500_000;\n\n /// @dev The msg.value for all the destination chains.\n uint128 internal constant DESTINATION_MSG_VALUE = 0;\n\n /// @notice A mapping from client chain IDs to whether the chain has been bootstrapped.\n /// @dev Used to ensure no repeated bootstrap requests are sent.\n mapping(uint32 clienChainId => bool) public chainToBootstrapped;\n\n /// @notice A mapping from client chain IDs to whether the chain has been registered.\n /// @dev Used to ensure that only registered client chains can interact with the gateway.\n mapping(uint32 clienChainId => bool registered) public isRegisteredClientChain;\n\n /// @notice A mapping from token address to whether the token is whitelisted.\n /// @dev Used to ensure no duplicate tokens are added to the whitelist.\n mapping(bytes32 token => bool whitelisted) public isWhitelistedToken;\n\n /// @notice Emitted when a precompile call fails.\n /// @param precompile Address of the precompile contract.\n /// @param nonce The LayerZero nonce\n event ExocorePrecompileError(address indexed precompile, uint64 nonce);\n\n /// @notice Emitted upon the registration of a new client chain.\n /// @param clientChainId The LayerZero chain ID of the client chain.\n event ClientChainRegistered(uint32 clientChainId);\n\n /// @notice Emitted upon the update of a client chain.\n /// @param clientChainId The LayerZero chain ID of the client chain.\n event ClientChainUpdated(uint32 clientChainId);\n\n /// @notice Emitted when a token is added to the whitelist.\n /// @param clientChainId The LayerZero chain ID of the client chain.\n /// @param token The address of the token.\n event WhitelistTokenAdded(uint32 clientChainId, bytes32 token);\n\n /// @notice Emitted when a token is updated in the whitelist.\n /// @param clientChainId The LayerZero chain ID of the client chain.\n /// @param token The address of the token.\n event WhitelistTokenUpdated(uint32 clientChainId, bytes32 token);\n\n /* --------- asset operations results and staking operations results -------- */\n /// @notice Emitted when reward is withdrawn.\n /// @param success Whether the withdrawal was successful.\n /// @param token The address of the token.\n /// @param withdrawer The address of the withdrawer.\n /// @param amount The amount of the token withdrawn.\n event WithdrawRewardResult(bool indexed success, bytes32 indexed token, bytes32 indexed withdrawer, uint256 amount);\n\n /// @notice Emitted when a deposit happens.\n /// @param success Whether the deposit was successful.\n /// @param token The address of the token.\n /// @param depositor The address of the depositor.\n /// @param amount The amount of the token deposited.\n event DepositResult(bool indexed success, bytes32 indexed token, bytes32 indexed depositor, uint256 amount);\n\n /// @notice Emitted when principal is withdrawn.\n /// @param success Whether the withdrawal was successful.\n /// @param token The address of the token.\n /// @param withdrawer The address of the withdrawer.\n /// @param amount The amount of the token withdrawn.\n event WithdrawPrincipalResult(\n bool indexed success, bytes32 indexed token, bytes32 indexed withdrawer, uint256 amount\n );\n\n /// @notice Emitted upon delegation.\n /// @param success Whether the delegation was successful.\n /// @param token The address of the token.\n /// @param delegator The address of the delegator.\n /// @param operator The Exo account address of the operator.\n /// @param amount The amount of the token delegated.\n event DelegateResult(\n bool indexed success, bytes32 indexed token, bytes32 indexed delegator, string operator, uint256 amount\n );\n\n /// @notice Emitted upon undelegation\n /// @param success Whether the undelegation was successful.\n /// @param token The address of the token.\n /// @param undelegator The address of the undelegator.\n /// @param operator The Exo account address of the operator.\n /// @param amount The amount of the token undelegated.\n event UndelegateResult(\n bool indexed success, bytes32 indexed token, bytes32 indexed undelegator, string operator, uint256 amount\n );\n\n /// @notice Thrown when the execution of a request fails\n /// @param act The action that failed.\n /// @param nonce The LayerZero nonce.\n /// @param reason The reason for the failure.\n error RequestExecuteFailed(Action act, uint64 nonce, bytes reason);\n\n /// @notice Thrown when the execution of a precompile call fails.\n /// @param selector_ The function selector of the precompile call.\n /// @param reason The reason for the failure.\n error PrecompileCallFailed(bytes4 selector_, bytes reason);\n\n /// @notice Thrown when the request length is invalid.\n /// @param act The action that failed.\n /// @param expectedLength The expected length of the request.\n /// @param actualLength The actual length of the request.\n error InvalidRequestLength(Action act, uint256 expectedLength, uint256 actualLength);\n\n /// @notice Thrown when a deposit request fails.\n /// @param srcChainId The source chain ID.\n /// @param lzNonce The LayerZero nonce.\n /// @dev This is considered a critical error.\n error DepositRequestShouldNotFail(uint32 srcChainId, uint64 lzNonce);\n\n /// @notice Thrown when a client chain registration fails\n /// @param clientChainId The LayerZero chain ID of the client chain.\n error RegisterClientChainToExocoreFailed(uint32 clientChainId);\n\n /// @notice Thrown when a whitelist token addition fails\n /// @param token The address of the token.\n error AddWhitelistTokenFailed(bytes32 token);\n\n /// @notice Thrown when a whitelist token update fails\n /// @param token The address of the token.\n error UpdateWhitelistTokenFailed(bytes32 token);\n\n /// @notice Thrown when the whitelist tokens input is invalid.\n error InvalidWhitelistTokensInput();\n\n /// @notice Thrown when the client chain ID is not registered.\n /// @param clientChainId The LayerZero chain ID of the client chain.\n error ClientChainIDNotRegisteredBefore(uint32 clientChainId);\n\n /// @notice Thrown when the whitelist tokens list is too long.\n error WhitelistTokensListTooLong();\n\n /// @dev Storage gap to allow for future upgrades.\n uint256[40] private __gap;\n\n}\n"},"src/libraries/Errors.sol":{"content":"pragma solidity ^0.8.19;\n\n/// @dev @title Errors library\n/// @dev @notice A library for all errors that can be thrown in the Exocore contracts\n/// @dev All errors in Exocore follow the following syntax: 'error ContractNameErrorName(arg1, arg2, ...)', where\n/// @dev 'ContractName' is the name of the contract\n/// @dev that the error originates from and 'ErrorName' is the name of the error. The arguments are optional and are\n/// used to\n/// @dev provide additional context to the error\n/// @dev 'Global' errors are those that are thrown from various contracts throughout the protocol and do not have a\n/// @dev 'ContractName' prefix\n\nlibrary Errors {\n\n /////////////////////\n // Global Errors //\n /////////////////////\n\n /// @dev Thrown when the passed-in address is the zero address, i.e. address(0)\n error ZeroAddress();\n\n /// @dev Thrown when passed-in amount is zero\n error ZeroAmount();\n\n /// @dev Thrown wehn the passed-in value is zero\n /// @dev This is used when the value in question is not an amount\n error ZeroValue();\n\n /// @dev Index out of array bounds\n error IndexOutOfBounds();\n\n ////////////////////////\n // Bootstrap Errors //\n ////////////////////////\n\n /// @dev Bootstrap: spawn time should be in the future\n error BootstrapSpawnTimeAlreadyPast();\n\n /// @dev Bootstrap: spawn time should be greater than offset duration\n error BootstrapSpawnTimeLessThanDuration();\n\n /// @dev Bootstrap: lock time should be in the future\n error BootstrapLockTimeAlreadyPast();\n\n /// @dev Bootstrap: operation not allowed after lock time\n error BootstrapBeforeLocked();\n\n /// @dev Bootstrap: token should be not whitelisted before\n /// @param token The address of the token already whitelisted\n error BootstrapAlreadyWhitelisted(address token);\n\n /// @dev Bootstrap: Ethereum address already linked to a validator\n /// @param validator The Ethereum address of the validator\n error BootstrapValidatorAlreadyHasAddress(address validator);\n\n /// @dev Bootstrap: Validator with this Exocore address is already registered\n error BootstrapValidatorAlreadyRegistered();\n\n /// @dev Bootstrap: Consensus public key already in use\n /// @param publicKey The public key that is already in use\n error BootstrapConsensusPubkeyAlreadyUsed(bytes32 publicKey);\n\n /// @dev Bootstrap: Validator name already in use\n error BootstrapValidatorNameAlreadyUsed();\n\n /// @dev Bootstrap: Invalid commission\n error BootstrapInvalidCommission();\n\n /// @dev Bootstrap: validator does not exist\n error BootstrapValidatorNotExist();\n\n /// @dev Bootstrap: Commission already edited once\n error BootstrapComissionAlreadyEdited();\n\n /// @dev Bootstrap: Rate exceeds max rate\n error BootstrapRateExceedsMaxRate();\n\n /// @dev Bootstrap: Rate change exceeds max change rate\n error BootstrapRateChangeExceedsMaxChangeRate();\n\n /// @dev Bootstrap: insufficient deposited balance\n error BootstrapInsufficientDepositedBalance();\n\n /// @dev Bootstrap: insufficient withdrawable balance\n error BootstrapInsufficientWithdrawableBalance();\n\n /// @dev Bootstrap: insufficient delegated balance\n error BootstrapInsufficientDelegatedBalance();\n\n /// @dev Bootstrap: no ether required for delegation/undelegation\n error BootstrapNoEtherForDelegation();\n\n /// @dev Bootstrap: not yet in the bootstrap time\n error BootstrapNotSpawnTime();\n\n /// @dev Bootstrap: not yet bootstrapped\n error BootstrapAlreadyBootstrapped();\n\n /// @dev Bootstrap: client chain initialization data is malformed\n error BootstrapClientChainDataMalformed();\n\n //////////////////////////////////\n // BootstrapLzReceiver Errors //\n //////////////////////////////////\n\n /// @dev BootstrapLzReceiver: could only be called from this contract itself with low level call\n error BootstrapLzReceiverOnlyCalledFromThis();\n\n /// @dev BootstrapLzReceiver: invalid action\n error BootstrapLzReceiverInvalidAction();\n\n /////////////////////////////////\n // ClientChainGateway Errors //\n /////////////////////////////////\n\n /// @dev ClientChainGateway: tokens length should not execeed 255\n error ClientChainGatewayAddWhitelistTooManyTokens();\n\n /// @dev ClientChainGateway: token should not be whitelisted before\n error ClientChainGatewayAlreadyWhitelisted();\n\n //////////////////////////////////////\n // ClientGatewayLzReceiver Errors //\n //////////////////////////////////////\n\n /// @dev ClientChainLzReceiver: could only be called from this contract itself with low level call\n error ClientGatewayLzReceiverOnlyCalledFromThis();\n\n ///////////////////////////////\n // CustomProxyAdmin Errors //\n ///////////////////////////////\n\n /// @dev CustomProxyAdmin: sender must be bootstrapper\n error CustomProxyAdminOnlyCalledFromBootstrapper();\n\n /// @dev CustomProxyAdmin: sender must be the proxy itself\n error CustomProxyAdminOnlyCalledFromProxy();\n\n /////////////////////////\n // ExoCapsule Errors //\n /////////////////////////\n\n /// @dev ExoCapsule: withdrawal amount is larger than staker's withdrawable balance\n error ExoCapsuleWithdrawalAmountExceeds();\n\n /// @dev ExoCapsule: withdrawNonBeaconChainETHBalance: amountToWithdraw is greater than nonBeaconChainETHBalance\n error ExoCapsuleNonBeaconChainWithdrawalAmountExceeds();\n\n /// @dev ExoCapsule: timestamp should be greater than beacon chain genesis timestamp\n error ExoCapsuleTimestampBeforeGenesis();\n\n /////////////////////////////\n // ExocoreGateway Errors //\n /////////////////////////////\n\n /// @dev ExocoreGateway: can only be called from this contract itself with a low-level call\n error ExocoreGatewayOnlyCalledFromThis();\n\n /// @dev ExocoreGateway: failed to get client chain ids\n error ExocoreGatewayFailedToGetClientChainIds();\n\n /// @dev ExocoreGateway: failed to decode client chain ids\n error ExocoreGatewayFailedToDecodeClientChainIds();\n\n /// @dev ExocoreGateway: client chain should be registered before setting peer to change peer address\n error ExocoreGatewayNotRegisteredClientChainId();\n\n ////////////////////////////////////////\n // NativeRestakingController Errors //\n ////////////////////////////////////////\n\n /// @dev NativeRestakingController: native restaking is not enabled\n error NativeRestakingControllerNotWhitelisted();\n\n /// @dev NativeRestakingController: stake value must be exactly 32 ether\n error NativeRestakingControllerInvalidStakeValue();\n\n /// @dev NativeRestakingController: message sender has already created the capsule\n error NativeRestakingControllerCapsuleAlreadyCreated();\n\n ////////////////////\n // Vault Errors //\n ////////////////////\n\n /// @dev Vault: caller is not the gateway\n error VaultCallerIsNotGateway();\n\n /// @dev Vault: withdrawal amount is larger than depositor's withdrawable balance\n error VaultWithdrawalAmountExceeds();\n\n /// @dev Vault: total principal unlock amount is larger than the total deposited amount\n error VaultPrincipalExceedsTotalDeposit();\n\n /// @dev Vault: total principal unlock amount is larger than the total deposited amount\n error VaultTotalUnlockPrincipalExceedsDeposit();\n\n}\n"},"src/lzApp/OAppCoreUpgradeable.sol":{"content":"// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.20;\n\nimport {ILayerZeroEndpointV2, IOAppCore} from \"@layerzero-v2/oapp/contracts/oapp/interfaces/IOAppCore.sol\";\nimport {OwnableUpgradeable} from \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\n\n/**\n * @title OAppCoreUpgradeable\n * @dev Abstract contract implementing the IOAppCore interface with basic OApp configurations.\n */\nabstract contract OAppCoreUpgradeable is IOAppCore, OwnableUpgradeable {\n\n // The LayerZero endpoint associated with the given OApp\n ILayerZeroEndpointV2 public immutable endpoint;\n\n // Mapping to store peers associated with corresponding endpoints\n mapping(uint32 eid => bytes32 peer) public peers;\n\n /**\n * @dev Constructor to initialize the OAppCore with the provided endpoint and delegate.\n * @param _endpoint The address of the LOCAL Layer Zero endpoint.\n */\n constructor(address _endpoint) {\n require(_endpoint != address(0), \"layerzero endpoint should not be empty\");\n endpoint = ILayerZeroEndpointV2(_endpoint);\n\n _disableInitializers();\n }\n\n /**\n * @dev The delegate typically should be set as the owner of the contract.\n * @param _delegate The delegate capable of making OApp configurations inside of the endpoint.\n */\n function __OAppCore_init(address _delegate) internal onlyInitializing {\n if (_delegate == address(0)) {\n revert InvalidDelegate();\n }\n endpoint.setDelegate(_delegate);\n _transferOwnership(_delegate);\n }\n\n /**\n * @dev The delegate typically should be set as the owner of the contract.\n * @param _delegate The delegate capable of making OApp configurations inside of the endpoint.\n */\n function __OAppCore_init_unchained(address _delegate) internal onlyInitializing {\n if (_delegate == address(0)) {\n revert InvalidDelegate();\n }\n endpoint.setDelegate(_delegate);\n }\n\n /**\n * @notice Sets the peer address (OApp instance) for a corresponding endpoint.\n * @param _eid The endpoint ID.\n * @param _peer The address of the peer to be associated with the corresponding endpoint.\n *\n * @dev Only the owner/admin of the OApp can call this function.\n * @dev Indicates that the peer is trusted to send LayerZero messages to this OApp.\n * @dev Set this to bytes32(0) to remove the peer address.\n * @dev Peer is a bytes32 to accommodate non-evm chains.\n */\n function setPeer(uint32 _eid, bytes32 _peer) public virtual onlyOwner {\n peers[_eid] = _peer;\n emit PeerSet(_eid, _peer);\n }\n\n /**\n * @notice Internal function to get the peer address associated with a specific endpoint; reverts if NOT set.\n * ie. the peer is set to bytes32(0).\n * @param _eid The endpoint ID.\n * @return peer The address of the peer associated with the specified endpoint.\n */\n function _getPeerOrRevert(uint32 _eid) internal view virtual returns (bytes32) {\n bytes32 peer = peers[_eid];\n if (peer == bytes32(0)) {\n revert NoPeer(_eid);\n }\n return peer;\n }\n\n /**\n * @notice Sets the delegate address for the OApp.\n * @param _delegate The address of the delegate to be set.\n *\n * @dev Only the owner/admin of the OApp can call this function.\n * @dev Provides the ability for a delegate to set configs, on behalf of the OApp, directly on the Endpoint\n * contract.\n */\n function setDelegate(address _delegate) public onlyOwner {\n endpoint.setDelegate(_delegate);\n }\n\n}\n"},"lib/LayerZero-v2/oapp/contracts/oapp/interfaces/IOAppCore.sol":{"content":"// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.20;\n\nimport { ILayerZeroEndpointV2 } from \"@layerzerolabs/lz-evm-protocol-v2/contracts/interfaces/ILayerZeroEndpointV2.sol\";\n\n/**\n * @title IOAppCore\n */\ninterface IOAppCore {\n // Custom error messages\n error OnlyPeer(uint32 eid, bytes32 sender);\n error NoPeer(uint32 eid);\n error InvalidEndpointCall();\n error InvalidDelegate();\n\n // Event emitted when a peer (OApp) is set for a corresponding endpoint\n event PeerSet(uint32 eid, bytes32 peer);\n\n /**\n * @notice Retrieves the OApp version information.\n * @return senderVersion The version of the OAppSender.sol contract.\n * @return receiverVersion The version of the OAppReceiver.sol contract.\n */\n function oAppVersion() external view returns (uint64 senderVersion, uint64 receiverVersion);\n\n /**\n * @notice Retrieves the LayerZero endpoint associated with the OApp.\n * @return iEndpoint The LayerZero endpoint as an interface.\n */\n function endpoint() external view returns (ILayerZeroEndpointV2 iEndpoint);\n\n /**\n * @notice Retrieves the peer (OApp) associated with a corresponding endpoint.\n * @param _eid The endpoint ID.\n * @return peer The peer address (OApp instance) associated with the corresponding endpoint.\n */\n function peers(uint32 _eid) external view returns (bytes32 peer);\n\n /**\n * @notice Sets the peer address (OApp instance) for a corresponding endpoint.\n * @param _eid The endpoint ID.\n * @param _peer The address of the peer to be associated with the corresponding endpoint.\n */\n function setPeer(uint32 _eid, bytes32 _peer) external;\n\n /**\n * @notice Sets the delegate address for the OApp Core.\n * @param _delegate The address of the delegate to be set.\n */\n function setDelegate(address _delegate) external;\n}\n"},"lib/LayerZero-v2/oapp/contracts/oapp/libs/OptionsBuilder.sol":{"content":"// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.20;\n\nimport { BytesLib } from \"solidity-bytes-utils/contracts/BytesLib.sol\";\nimport { SafeCast } from \"@openzeppelin/contracts/utils/math/SafeCast.sol\";\n\nimport { ExecutorOptions } from \"@layerzerolabs/lz-evm-protocol-v2/contracts/messagelib/libs/ExecutorOptions.sol\";\nimport { DVNOptions } from \"@layerzerolabs/lz-evm-messagelib-v2/contracts/uln/libs/DVNOptions.sol\";\n\n/**\n * @title OptionsBuilder\n * @dev Library for building and encoding various message options.\n */\nlibrary OptionsBuilder {\n using SafeCast for uint256;\n using BytesLib for bytes;\n\n // Constants for options types\n uint16 internal constant TYPE_1 = 1; // legacy options type 1\n uint16 internal constant TYPE_2 = 2; // legacy options type 2\n uint16 internal constant TYPE_3 = 3;\n\n // Custom error message\n error InvalidSize(uint256 max, uint256 actual);\n error InvalidOptionType(uint16 optionType);\n\n // Modifier to ensure only options of type 3 are used\n modifier onlyType3(bytes memory _options) {\n if (_options.toUint16(0) != TYPE_3) revert InvalidOptionType(_options.toUint16(0));\n _;\n }\n\n /**\n * @dev Creates a new options container with type 3.\n * @return options The newly created options container.\n */\n function newOptions() internal pure returns (bytes memory) {\n return abi.encodePacked(TYPE_3);\n }\n\n /**\n * @dev Adds an executor LZ receive option to the existing options.\n * @param _options The existing options container.\n * @param _gas The gasLimit used on the lzReceive() function in the OApp.\n * @param _value The msg.value passed to the lzReceive() function in the OApp.\n * @return options The updated options container.\n *\n * @dev When multiples of this option are added, they are summed by the executor\n * eg. if (_gas: 200k, and _value: 1 ether) AND (_gas: 100k, _value: 0.5 ether) are sent in an option to the LayerZeroEndpoint,\n * that becomes (300k, 1.5 ether) when the message is executed on the remote lzReceive() function.\n */\n function addExecutorLzReceiveOption(\n bytes memory _options,\n uint128 _gas,\n uint128 _value\n ) internal pure onlyType3(_options) returns (bytes memory) {\n bytes memory option = ExecutorOptions.encodeLzReceiveOption(_gas, _value);\n return addExecutorOption(_options, ExecutorOptions.OPTION_TYPE_LZRECEIVE, option);\n }\n\n /**\n * @dev Adds an executor native drop option to the existing options.\n * @param _options The existing options container.\n * @param _amount The amount for the native value that is airdropped to the 'receiver'.\n * @param _receiver The receiver address for the native drop option.\n * @return options The updated options container.\n *\n * @dev When multiples of this option are added, they are summed by the executor on the remote chain.\n */\n function addExecutorNativeDropOption(\n bytes memory _options,\n uint128 _amount,\n bytes32 _receiver\n ) internal pure onlyType3(_options) returns (bytes memory) {\n bytes memory option = ExecutorOptions.encodeNativeDropOption(_amount, _receiver);\n return addExecutorOption(_options, ExecutorOptions.OPTION_TYPE_NATIVE_DROP, option);\n }\n\n /**\n * @dev Adds an executor LZ compose option to the existing options.\n * @param _options The existing options container.\n * @param _index The index for the lzCompose() function call.\n * @param _gas The gasLimit for the lzCompose() function call.\n * @param _value The msg.value for the lzCompose() function call.\n * @return options The updated options container.\n *\n * @dev When multiples of this option are added, they are summed PER index by the executor on the remote chain.\n * @dev If the OApp sends N lzCompose calls on the remote, you must provide N incremented indexes starting with 0.\n * ie. When your remote OApp composes (N = 3) messages, you must set this option for index 0,1,2\n */\n function addExecutorLzComposeOption(\n bytes memory _options,\n uint16 _index,\n uint128 _gas,\n uint128 _value\n ) internal pure onlyType3(_options) returns (bytes memory) {\n bytes memory option = ExecutorOptions.encodeLzComposeOption(_index, _gas, _value);\n return addExecutorOption(_options, ExecutorOptions.OPTION_TYPE_LZCOMPOSE, option);\n }\n\n /**\n * @dev Adds an executor ordered execution option to the existing options.\n * @param _options The existing options container.\n * @return options The updated options container.\n */\n function addExecutorOrderedExecutionOption(\n bytes memory _options\n ) internal pure onlyType3(_options) returns (bytes memory) {\n return addExecutorOption(_options, ExecutorOptions.OPTION_TYPE_ORDERED_EXECUTION, bytes(\"\"));\n }\n\n /**\n * @dev Adds a DVN pre-crime option to the existing options.\n * @param _options The existing options container.\n * @param _dvnIdx The DVN index for the pre-crime option.\n * @return options The updated options container.\n */\n function addDVNPreCrimeOption(\n bytes memory _options,\n uint8 _dvnIdx\n ) internal pure onlyType3(_options) returns (bytes memory) {\n return addDVNOption(_options, _dvnIdx, DVNOptions.OPTION_TYPE_PRECRIME, bytes(\"\"));\n }\n\n /**\n * @dev Adds an executor option to the existing options.\n * @param _options The existing options container.\n * @param _optionType The type of the executor option.\n * @param _option The encoded data for the executor option.\n * @return options The updated options container.\n */\n function addExecutorOption(\n bytes memory _options,\n uint8 _optionType,\n bytes memory _option\n ) internal pure onlyType3(_options) returns (bytes memory) {\n return\n abi.encodePacked(\n _options,\n ExecutorOptions.WORKER_ID,\n _option.length.toUint16() + 1, // +1 for optionType\n _optionType,\n _option\n );\n }\n\n /**\n * @dev Adds a DVN option to the existing options.\n * @param _options The existing options container.\n * @param _dvnIdx The DVN index for the DVN option.\n * @param _optionType The type of the DVN option.\n * @param _option The encoded data for the DVN option.\n * @return options The updated options container.\n */\n function addDVNOption(\n bytes memory _options,\n uint8 _dvnIdx,\n uint8 _optionType,\n bytes memory _option\n ) internal pure onlyType3(_options) returns (bytes memory) {\n return\n abi.encodePacked(\n _options,\n DVNOptions.WORKER_ID,\n _option.length.toUint16() + 2, // +2 for optionType and dvnIdx\n _dvnIdx,\n _optionType,\n _option\n );\n }\n\n /**\n * @dev Encodes legacy options of type 1.\n * @param _executionGas The gasLimit value passed to lzReceive().\n * @return legacyOptions The encoded legacy options.\n */\n function encodeLegacyOptionsType1(uint256 _executionGas) internal pure returns (bytes memory) {\n if (_executionGas > type(uint128).max) revert InvalidSize(type(uint128).max, _executionGas);\n return abi.encodePacked(TYPE_1, _executionGas);\n }\n\n /**\n * @dev Encodes legacy options of type 2.\n * @param _executionGas The gasLimit value passed to lzReceive().\n * @param _nativeForDst The amount of native air dropped to the receiver.\n * @param _receiver The _nativeForDst receiver address.\n * @return legacyOptions The encoded legacy options of type 2.\n */\n function encodeLegacyOptionsType2(\n uint256 _executionGas,\n uint256 _nativeForDst,\n bytes memory _receiver // @dev Use bytes instead of bytes32 in legacy type 2 for _receiver.\n ) internal pure returns (bytes memory) {\n if (_executionGas > type(uint128).max) revert InvalidSize(type(uint128).max, _executionGas);\n if (_nativeForDst > type(uint128).max) revert InvalidSize(type(uint128).max, _nativeForDst);\n if (_receiver.length > 32) revert InvalidSize(32, _receiver.length);\n return abi.encodePacked(TYPE_2, _executionGas, _nativeForDst, _receiver);\n }\n}\n"},"lib/LayerZero-v2/protocol/contracts/interfaces/ILayerZeroReceiver.sol":{"content":"// SPDX-License-Identifier: MIT\n\npragma solidity >=0.8.0;\n\nimport { Origin } from \"./ILayerZeroEndpointV2.sol\";\n\ninterface ILayerZeroReceiver {\n function allowInitializePath(Origin calldata _origin) external view returns (bool);\n\n function nextNonce(uint32 _eid, bytes32 _sender) external view returns (uint64);\n\n function lzReceive(\n Origin calldata _origin,\n bytes32 _guid,\n bytes calldata _message,\n address _executor,\n bytes calldata _extraData\n ) external payable;\n}\n"},"lib/openzeppelin-contracts-upgradeable/contracts/access/OwnableUpgradeable.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/ContextUpgradeable.sol\";\nimport {Initializable} from \"../proxy/utils/Initializable.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 * By default, the owner account will be the one that deploys the contract. This\n * can 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 OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\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 require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\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 require(newOwner != address(0), \"Ownable: new owner is the zero address\");\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 /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n"},"lib/openzeppelin-contracts-upgradeable/contracts/proxy/utils/Initializable.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../../utils/AddressUpgradeable.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```solidity\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n *\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts.\n *\n * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a\n * constructor.\n *\n * Emits an {Initialized} event.\n */\n modifier initializer() {\n bool isTopLevelCall = !_initializing;\n require(\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\n \"Initializable: contract is already initialized\"\n );\n _initialized = 1;\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * A reinitializer may be used after the original initialization step. This is essential to configure modules that\n * are added through upgrades and that require initialization.\n *\n * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`\n * cannot be nested. If one is invoked in the context of another, execution will revert.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n *\n * WARNING: setting the version to 255 will prevent any future reinitialization.\n *\n * Emits an {Initialized} event.\n */\n modifier reinitializer(uint8 version) {\n require(!_initializing && _initialized < version, \"Initializable: contract is already initialized\");\n _initialized = version;\n _initializing = true;\n _;\n _initializing = false;\n emit Initialized(version);\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n *\n * Emits an {Initialized} event the first time it is successfully executed.\n */\n function _disableInitializers() internal virtual {\n require(!_initializing, \"Initializable: contract is initializing\");\n if (_initialized != type(uint8).max) {\n _initialized = type(uint8).max;\n emit Initialized(type(uint8).max);\n }\n }\n\n /**\n * @dev Returns the highest version that has been initialized. See {reinitializer}.\n */\n function _getInitializedVersion() internal view returns (uint8) {\n return _initialized;\n }\n\n /**\n * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.\n */\n function _isInitializing() internal view returns (bool) {\n return _initializing;\n }\n}\n"},"lib/openzeppelin-contracts-upgradeable/contracts/security/PausableUpgradeable.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (security/Pausable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/ContextUpgradeable.sol\";\nimport {Initializable} from \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module which allows children to implement an emergency stop\n * mechanism that can be triggered by an authorized account.\n *\n * This module is used through inheritance. It will make available the\n * modifiers `whenNotPaused` and `whenPaused`, which can be applied to\n * the functions of your contract. Note that they will not be pausable by\n * simply including this module, only once the modifiers are put in place.\n */\nabstract contract PausableUpgradeable is Initializable, ContextUpgradeable {\n /**\n * @dev Emitted when the pause is triggered by `account`.\n */\n event Paused(address account);\n\n /**\n * @dev Emitted when the pause is lifted by `account`.\n */\n event Unpaused(address account);\n\n bool private _paused;\n\n /**\n * @dev Initializes the contract in unpaused state.\n */\n function __Pausable_init() internal onlyInitializing {\n __Pausable_init_unchained();\n }\n\n function __Pausable_init_unchained() internal onlyInitializing {\n _paused = false;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is not paused.\n *\n * Requirements:\n *\n * - The contract must not be paused.\n */\n modifier whenNotPaused() {\n _requireNotPaused();\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is paused.\n *\n * Requirements:\n *\n * - The contract must be paused.\n */\n modifier whenPaused() {\n _requirePaused();\n _;\n }\n\n /**\n * @dev Returns true if the contract is paused, and false otherwise.\n */\n function paused() public view virtual returns (bool) {\n return _paused;\n }\n\n /**\n * @dev Throws if the contract is paused.\n */\n function _requireNotPaused() internal view virtual {\n require(!paused(), \"Pausable: paused\");\n }\n\n /**\n * @dev Throws if the contract is not paused.\n */\n function _requirePaused() internal view virtual {\n require(paused(), \"Pausable: not paused\");\n }\n\n /**\n * @dev Triggers stopped state.\n *\n * Requirements:\n *\n * - The contract must not be paused.\n */\n function _pause() internal virtual whenNotPaused {\n _paused = true;\n emit Paused(_msgSender());\n }\n\n /**\n * @dev Returns to normal state.\n *\n * Requirements:\n *\n * - The contract must be paused.\n */\n function _unpause() internal virtual whenPaused {\n _paused = false;\n emit Unpaused(_msgSender());\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n"},"lib/openzeppelin-contracts-upgradeable/contracts/security/ReentrancyGuardUpgradeable.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (security/ReentrancyGuard.sol)\n\npragma solidity ^0.8.0;\nimport {Initializable} from \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module that helps prevent reentrant calls to a function.\n *\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\n * available, which can be applied to functions to make sure there are no nested\n * (reentrant) calls to them.\n *\n * Note that because there is a single `nonReentrant` guard, functions marked as\n * `nonReentrant` may not call one another. This can be worked around by making\n * those functions `private`, and then adding `external` `nonReentrant` entry\n * points to them.\n *\n * TIP: If you would like to learn more about reentrancy and alternative ways\n * to protect against it, check out our blog post\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\n */\nabstract contract ReentrancyGuardUpgradeable is Initializable {\n // Booleans are more expensive than uint256 or any type that takes up a full\n // word because each write operation emits an extra SLOAD to first read the\n // slot's contents, replace the bits taken up by the boolean, and then write\n // back. This is the compiler's defense against contract upgrades and\n // pointer aliasing, and it cannot be disabled.\n\n // The values being non-zero value makes deployment a bit more expensive,\n // but in exchange the refund on every call to nonReentrant will be lower in\n // amount. Since refunds are capped to a percentage of the total\n // transaction's gas, it is best to keep them low in cases like this one, to\n // increase the likelihood of the full refund coming into effect.\n uint256 private constant _NOT_ENTERED = 1;\n uint256 private constant _ENTERED = 2;\n\n uint256 private _status;\n\n function __ReentrancyGuard_init() internal onlyInitializing {\n __ReentrancyGuard_init_unchained();\n }\n\n function __ReentrancyGuard_init_unchained() internal onlyInitializing {\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n * Calling a `nonReentrant` function from another `nonReentrant`\n * function is not supported. It is possible to prevent this from happening\n * by making the `nonReentrant` function external, and making it call a\n * `private` function that does the actual work.\n */\n modifier nonReentrant() {\n _nonReentrantBefore();\n _;\n _nonReentrantAfter();\n }\n\n function _nonReentrantBefore() private {\n // On the first call to nonReentrant, _status will be _NOT_ENTERED\n require(_status != _ENTERED, \"ReentrancyGuard: reentrant call\");\n\n // Any calls to nonReentrant after this point will fail\n _status = _ENTERED;\n }\n\n function _nonReentrantAfter() private {\n // By storing the original value once again, a refund is triggered (see\n // https://eips.ethereum.org/EIPS/eip-2200)\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Returns true if the reentrancy guard is currently set to \"entered\", which indicates there is a\n * `nonReentrant` function in the call stack.\n */\n function _reentrancyGuardEntered() internal view returns (bool) {\n return _status == _ENTERED;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n"},"lib/LayerZero-v2/oapp/contracts/oapp/interfaces/IOAppReceiver.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.20;\n\nimport { ILayerZeroReceiver, Origin } from \"@layerzerolabs/lz-evm-protocol-v2/contracts/interfaces/ILayerZeroReceiver.sol\";\n\ninterface IOAppReceiver is ILayerZeroReceiver {\n /**\n * @notice Retrieves the address responsible for 'sending' composeMsg's to the Endpoint.\n * @return sender The address responsible for 'sending' composeMsg's to the Endpoint.\n *\n * @dev Applications can optionally choose to implement a separate composeMsg sender that is NOT the bridging layer.\n * @dev The default sender IS the OApp implementer.\n */\n function composeMsgSender() external view returns (address sender);\n}\n"},"src/lzApp/OAppSenderUpgradeable.sol":{"content":"// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.20;\n\nimport {OAppCoreUpgradeable} from \"./OAppCoreUpgradeable.sol\";\nimport {\n MessagingFee,\n MessagingParams,\n MessagingReceipt\n} from \"@layerzero-v2/protocol/contracts/interfaces/ILayerZeroEndpointV2.sol\";\nimport {IERC20, SafeERC20} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\n/**\n * @title OAppSenderUpgradeable\n * @dev Abstract contract implementing the OAppSender functionality for sending messages to a LayerZero endpoint.\n */\nabstract contract OAppSenderUpgradeable is OAppCoreUpgradeable {\n\n using SafeERC20 for IERC20;\n\n // Custom error messages\n error NotExactNativeFee(uint256 msgValue);\n error LzTokenUnavailable();\n\n // @dev The version of the OAppSender implementation.\n // @dev Version is bumped when changes are made to this contract.\n uint64 internal constant SENDER_VERSION = 1;\n\n /**\n * @notice Retrieves the OApp version information.\n * @return senderVersion The version of the OAppSender.sol contract.\n * @return receiverVersion The version of the OAppReceiver.sol contract.\n *\n * @dev Providing 0 as the default for OAppReceiver version. Indicates that the OAppReceiver is not implemented.\n * ie. this is a SEND only OApp.\n * @dev If the OApp uses both OAppSender and OAppReceiver, then this needs to be override returning the correct\n * versions\n */\n function oAppVersion() public view virtual returns (uint64 senderVersion, uint64 receiverVersion) {\n return (SENDER_VERSION, 0);\n }\n\n /**\n * @dev Internal function to interact with the LayerZero EndpointV2.quote() for fee calculation.\n * @param _dstEid The destination endpoint ID.\n * @param _message The message payload.\n * @param _options Additional options for the message.\n * @param _payInLzToken Flag indicating whether to pay the fee in LZ tokens.\n * @return fee The calculated MessagingFee for the message.\n * - nativeFee: The native fee for the message.\n * - lzTokenFee: The LZ token fee for the message.\n */\n function _quote(uint32 _dstEid, bytes memory _message, bytes memory _options, bool _payInLzToken)\n internal\n view\n virtual\n returns (MessagingFee memory fee)\n {\n return endpoint.quote(\n MessagingParams(_dstEid, _getPeerOrRevert(_dstEid), _message, _options, _payInLzToken), address(this)\n );\n }\n\n /**\n * @dev Internal function to interact with the LayerZero EndpointV2.send() for sending a message.\n * @param _dstEid The destination endpoint ID.\n * @param _message The message payload.\n * @param _options Additional options for the message.\n * @param _fee The calculated LayerZero fee for the message.\n * - nativeFee: The native fee.\n * - lzTokenFee: The lzToken fee.\n * @param _refundAddress The address to receive any excess fee values sent to the endpoint.\n * @param byApp Whether the native fee is paid by the app itself or by the app caller,\n * if byApp is true, app caller does not need to specify msg.value to pay for the native fee.\n * @return receipt The receipt for the sent message.\n * - guid: The unique identifier for the sent message.\n * - nonce: The nonce of the sent message.\n * - fee: The LayerZero fee incurred for the message.\n */\n function _lzSend(\n uint32 _dstEid,\n bytes memory _message,\n bytes memory _options,\n MessagingFee memory _fee,\n address _refundAddress,\n bool byApp\n ) internal virtual returns (MessagingReceipt memory receipt) {\n // @dev Push corresponding fees to the endpoint, any excess is sent back to the _refundAddress from the\n // endpoint.\n uint256 messageValue = _payNative(_fee.nativeFee, byApp);\n if (_fee.lzTokenFee > 0) {\n _payLzToken(_fee.lzTokenFee);\n }\n\n return endpoint.send{value: messageValue}(\n // solhint-disable-next-line check-send-result\n MessagingParams(_dstEid, _getPeerOrRevert(_dstEid), _message, _options, _fee.lzTokenFee > 0),\n _refundAddress\n );\n }\n\n /**\n * @dev Internal function to pay the native fee associated with the message.\n * @param _nativeFee The native fee to be paid.\n * @param byApp Whether the native fee is paid by the app itself or by the app caller,\n * if byApp is true, do not check that the msg.value is equal to nativeFee.\n * @return nativeFee The amount of native currency paid.\n *\n * @dev If the OApp needs to initiate MULTIPLE LayerZero messages in a single transaction,\n * this will need to be overridden because msg.value would contain multiple lzFees.\n * @dev Should be overridden in the event the LayerZero endpoint requires a different native currency.\n * @dev Some EVMs use an ERC20 as a method for paying transactions/gasFees.\n * @dev The endpoint is EITHER/OR, ie. it will NOT support both types of native payment at a time.\n */\n function _payNative(uint256 _nativeFee, bool byApp) internal virtual returns (uint256 nativeFee) {\n if (!byApp && msg.value != _nativeFee) {\n revert NotExactNativeFee(msg.value);\n }\n return _nativeFee;\n }\n\n /**\n * @dev Internal function to pay the LZ token fee associated with the message.\n * @param _lzTokenFee The LZ token fee to be paid.\n *\n * @dev If the caller is trying to pay in the specified lzToken, then the lzTokenFee is passed to the endpoint.\n * @dev Any excess sent, is passed back to the specified _refundAddress in the _lzSend().\n */\n function _payLzToken(uint256 _lzTokenFee) internal virtual {\n // @dev Cannot cache the token because it is not immutable in the endpoint.\n address lzToken = endpoint.lzToken();\n if (lzToken == address(0)) {\n revert LzTokenUnavailable();\n }\n\n // Pay LZ token fee by sending tokens to the endpoint.\n IERC20(lzToken).safeTransferFrom(msg.sender, address(endpoint), _lzTokenFee);\n }\n\n}\n"},"src/lzApp/OAppReceiverUpgradeable.sol":{"content":"// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.20;\n\nimport {OAppCoreUpgradeable} from \"./OAppCoreUpgradeable.sol\";\nimport {IOAppReceiver, Origin} from \"@layerzero-v2/oapp/contracts/oapp/interfaces/IOAppReceiver.sol\";\n\n/**\n * @title OAppReceiverUpgradeable\n * @dev Abstract contract implementing the ILayerZeroReceiver interface and extending OAppCore for OApp receivers.\n */\nabstract contract OAppReceiverUpgradeable is IOAppReceiver, OAppCoreUpgradeable {\n\n // Custom error message for when the caller is not the registered endpoint/\n error OnlyEndpoint(address addr);\n\n // @dev The version of the OAppReceiver implementation.\n // @dev Version is bumped when changes are made to this contract.\n uint64 internal constant RECEIVER_VERSION = 1;\n\n /**\n * @notice Retrieves the OApp version information.\n * @return senderVersion The version of the OAppSender.sol contract.\n * @return receiverVersion The version of the OAppReceiver.sol contract.\n *\n * @dev Providing 0 as the default for OAppSender version. Indicates that the OAppSender is not implemented.\n * ie. this is a RECEIVE only OApp.\n * @dev If the OApp uses both OAppSender and OAppReceiver, then this needs to be override returning the correct\n * versions.\n */\n function oAppVersion() public view virtual returns (uint64 senderVersion, uint64 receiverVersion) {\n return (0, RECEIVER_VERSION);\n }\n\n /**\n * @notice Retrieves the address responsible for 'sending' composeMsg's to the Endpoint.\n * @return sender The address responsible for 'sending' composeMsg's to the Endpoint.\n *\n * @dev Applications can optionally choose to implement a separate composeMsg sender that is NOT the bridging layer.\n * @dev The default sender IS the OApp implementer.\n */\n function composeMsgSender() public view virtual returns (address sender) {\n return address(this);\n }\n\n /**\n * @notice Checks if the path initialization is allowed based on the provided origin.\n * @param origin The origin information containing the source endpoint and sender address.\n * @return Whether the path has been initialized.\n *\n * @dev This indicates to the endpoint that the OApp has enabled msgs for this particular path to be received.\n * @dev This defaults to assuming if a peer has been set, its initialized.\n * Can be overridden by the OApp if there is other logic to determine this.\n */\n function allowInitializePath(Origin calldata origin) public view virtual returns (bool) {\n return peers[origin.srcEid] == origin.sender;\n }\n\n /**\n * @notice Retrieves the next nonce for a given source endpoint and sender address.\n * @dev _srcEid The source endpoint ID.\n * @dev _sender The sender address.\n * @return nonce The next nonce.\n *\n * @dev The path nonce starts from 1. If 0 is returned it means that there is NO nonce ordered enforcement.\n * @dev Is required by the off-chain executor to determine the OApp expects msg execution is ordered.\n * @dev This is also enforced by the OApp.\n * @dev By default this is NOT enabled. ie. nextNonce is hardcoded to return 0.\n */\n function nextNonce(uint32, /*_srcEid*/ bytes32 /*_sender*/ ) public view virtual returns (uint64 nonce) {\n return 0;\n }\n\n /**\n * @dev Entry point for receiving messages or packets from the endpoint.\n * @param _origin The origin information containing the source endpoint and sender address.\n * - srcEid: The source chain endpoint ID.\n * - sender: The sender address on the src chain.\n * - nonce: The nonce of the message.\n * @param _guid The unique identifier for the received LayerZero message.\n * @param _message The payload of the received message.\n * @param _executor The address of the executor for the received message.\n * @param _extraData Additional arbitrary data provided by the corresponding executor.\n *\n * @dev Entry point for receiving msg/packet from the LayerZero endpoint.\n */\n function lzReceive(\n Origin calldata _origin,\n bytes32 _guid,\n bytes calldata _message,\n address _executor,\n bytes calldata _extraData\n ) public payable virtual {\n // Ensures that only the endpoint can attempt to lzReceive() messages to this OApp.\n if (address(endpoint) != msg.sender) {\n revert OnlyEndpoint(msg.sender);\n }\n\n // Ensure that the sender matches the expected peer for the source endpoint.\n if (_getPeerOrRevert(_origin.srcEid) != _origin.sender) {\n revert OnlyPeer(_origin.srcEid, _origin.sender);\n }\n\n // Call the internal OApp implementation of lzReceive.\n _lzReceive(_origin, _message);\n }\n\n /**\n * @dev Internal function to implement lzReceive logic without needing to copy the basic parameter validation.\n */\n function _lzReceive(Origin calldata _origin, bytes calldata _message) internal virtual;\n\n}\n"},"src/storage/GatewayStorage.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\n/// @title GatewayStorage\n/// @notice Storage used by both ends of the gateway contract.\n/// @dev This contract is used as the base storage and is inherited by the storage for Bootstrap and ExocoreGateway.\ncontract GatewayStorage {\n\n /// @notice Enum representing various actions that can be performed.\n enum Action {\n REQUEST_DEPOSIT,\n REQUEST_WITHDRAW_PRINCIPAL_FROM_EXOCORE,\n REQUEST_WITHDRAW_REWARD_FROM_EXOCORE,\n REQUEST_DELEGATE_TO,\n REQUEST_UNDELEGATE_FROM,\n REQUEST_DEPOSIT_THEN_DELEGATE_TO,\n REQUEST_MARK_BOOTSTRAP,\n REQUEST_ADD_WHITELIST_TOKENS,\n RESPOND\n }\n\n /// @dev Mapping of actions to their corresponding function selectors.\n mapping(Action => bytes4) internal _whiteListFunctionSelectors;\n\n /// @dev Mapping to track inbound nonces for each chain and sender.\n mapping(uint32 eid => mapping(bytes32 sender => uint64 nonce)) public inboundNonce;\n\n /// @dev Storage gap to allow for future upgrades.\n uint256[40] private __gap;\n\n /// @notice Emitted when a message is sent through the gateway.\n /// @param act The action being performed.\n /// @param packetId The unique identifier for the packet.\n /// @param nonce The nonce associated with the message.\n /// @param nativeFee The native fee paid for the message.\n event MessageSent(Action indexed act, bytes32 packetId, uint64 nonce, uint256 nativeFee);\n\n /// @notice Error thrown when an unsupported request is made.\n /// @param act The unsupported action.\n error UnsupportedRequest(Action act);\n\n /// @notice Error thrown when a message is received from an unexpected source chain.\n /// @param unexpectedSrcEndpointId The unexpected source chain ID.\n error UnexpectedSourceChain(uint32 unexpectedSrcEndpointId);\n\n /// @notice Error thrown when the inbound nonce is not as expected.\n /// @param expectedNonce The expected nonce.\n /// @param actualNonce The actual nonce received.\n error UnexpectedInboundNonce(uint64 expectedNonce, uint64 actualNonce);\n\n /// @notice Verifies and updates the inbound nonce for a given source chain and address.\n /// @dev This function reverts if the nonce is not as expected.\n /// @param srcChainId The ID of the source chain.\n /// @param srcAddress The address of the sender on the source chain.\n /// @param nonce The nonce to be verified and updated.\n function _verifyAndUpdateNonce(uint32 srcChainId, bytes32 srcAddress, uint64 nonce) internal {\n uint64 expectedNonce = inboundNonce[srcChainId][srcAddress] + 1;\n if (nonce != expectedNonce) {\n revert UnexpectedInboundNonce(expectedNonce, nonce);\n }\n inboundNonce[srcChainId][srcAddress] = nonce;\n }\n\n}\n"},"lib/LayerZero-v2/protocol/contracts/interfaces/ILayerZeroEndpointV2.sol":{"content":"// SPDX-License-Identifier: MIT\n\npragma solidity >=0.8.0;\n\nimport { IMessageLibManager } from \"./IMessageLibManager.sol\";\nimport { IMessagingComposer } from \"./IMessagingComposer.sol\";\nimport { IMessagingChannel } from \"./IMessagingChannel.sol\";\nimport { IMessagingContext } from \"./IMessagingContext.sol\";\n\nstruct MessagingParams {\n uint32 dstEid;\n bytes32 receiver;\n bytes message;\n bytes options;\n bool payInLzToken;\n}\n\nstruct MessagingReceipt {\n bytes32 guid;\n uint64 nonce;\n MessagingFee fee;\n}\n\nstruct MessagingFee {\n uint256 nativeFee;\n uint256 lzTokenFee;\n}\n\nstruct Origin {\n uint32 srcEid;\n bytes32 sender;\n uint64 nonce;\n}\n\ninterface ILayerZeroEndpointV2 is IMessageLibManager, IMessagingComposer, IMessagingChannel, IMessagingContext {\n event PacketSent(bytes encodedPayload, bytes options, address sendLibrary);\n\n event PacketVerified(Origin origin, address receiver, bytes32 payloadHash);\n\n event PacketDelivered(Origin origin, address receiver);\n\n event LzReceiveAlert(\n address indexed receiver,\n address indexed executor,\n Origin origin,\n bytes32 guid,\n uint256 gas,\n uint256 value,\n bytes message,\n bytes extraData,\n bytes reason\n );\n\n event LzTokenSet(address token);\n\n event DelegateSet(address sender, address delegate);\n\n function quote(MessagingParams calldata _params, address _sender) external view returns (MessagingFee memory);\n\n function send(\n MessagingParams calldata _params,\n address _refundAddress\n ) external payable returns (MessagingReceipt memory);\n\n function verify(Origin calldata _origin, address _receiver, bytes32 _payloadHash) external;\n\n function verifiable(Origin calldata _origin, address _receiver) external view returns (bool);\n\n function initializable(Origin calldata _origin, address _receiver) external view returns (bool);\n\n function lzReceive(\n Origin calldata _origin,\n address _receiver,\n bytes32 _guid,\n bytes calldata _message,\n bytes calldata _extraData\n ) external payable;\n\n // oapp can burn messages partially by calling this function with its own business logic if messages are verified in order\n function clear(address _oapp, Origin calldata _origin, bytes32 _guid, bytes calldata _message) external;\n\n function setLzToken(address _lzToken) external;\n\n function lzToken() external view returns (address);\n\n function nativeToken() external view returns (address);\n\n function setDelegate(address _delegate) external;\n}\n"},"lib/solidity-bytes-utils/contracts/BytesLib.sol":{"content":"// SPDX-License-Identifier: Unlicense\n/*\n * @title Solidity Bytes Arrays Utils\n * @author Gonçalo Sá \n *\n * @dev Bytes tightly packed arrays utility library for ethereum contracts written in Solidity.\n * The library lets you concatenate, slice and type cast bytes arrays both in memory and storage.\n */\npragma solidity >=0.8.0 <0.9.0;\n\n\nlibrary BytesLib {\n function concat(\n bytes memory _preBytes,\n bytes memory _postBytes\n )\n internal\n pure\n returns (bytes memory)\n {\n bytes memory tempBytes;\n\n assembly {\n // Get a location of some free memory and store it in tempBytes as\n // Solidity does for memory variables.\n tempBytes := mload(0x40)\n\n // Store the length of the first bytes array at the beginning of\n // the memory for tempBytes.\n let length := mload(_preBytes)\n mstore(tempBytes, length)\n\n // Maintain a memory counter for the current write location in the\n // temp bytes array by adding the 32 bytes for the array length to\n // the starting location.\n let mc := add(tempBytes, 0x20)\n // Stop copying when the memory counter reaches the length of the\n // first bytes array.\n let end := add(mc, length)\n\n for {\n // Initialize a copy counter to the start of the _preBytes data,\n // 32 bytes into its memory.\n let cc := add(_preBytes, 0x20)\n } lt(mc, end) {\n // Increase both counters by 32 bytes each iteration.\n mc := add(mc, 0x20)\n cc := add(cc, 0x20)\n } {\n // Write the _preBytes data into the tempBytes memory 32 bytes\n // at a time.\n mstore(mc, mload(cc))\n }\n\n // Add the length of _postBytes to the current length of tempBytes\n // and store it as the new length in the first 32 bytes of the\n // tempBytes memory.\n length := mload(_postBytes)\n mstore(tempBytes, add(length, mload(tempBytes)))\n\n // Move the memory counter back from a multiple of 0x20 to the\n // actual end of the _preBytes data.\n mc := end\n // Stop copying when the memory counter reaches the new combined\n // length of the arrays.\n end := add(mc, length)\n\n for {\n let cc := add(_postBytes, 0x20)\n } lt(mc, end) {\n mc := add(mc, 0x20)\n cc := add(cc, 0x20)\n } {\n mstore(mc, mload(cc))\n }\n\n // Update the free-memory pointer by padding our last write location\n // to 32 bytes: add 31 bytes to the end of tempBytes to move to the\n // next 32 byte block, then round down to the nearest multiple of\n // 32. If the sum of the length of the two arrays is zero then add\n // one before rounding down to leave a blank 32 bytes (the length block with 0).\n mstore(0x40, and(\n add(add(end, iszero(add(length, mload(_preBytes)))), 31),\n not(31) // Round down to the nearest 32 bytes.\n ))\n }\n\n return tempBytes;\n }\n\n function concatStorage(bytes storage _preBytes, bytes memory _postBytes) internal {\n assembly {\n // Read the first 32 bytes of _preBytes storage, which is the length\n // of the array. (We don't need to use the offset into the slot\n // because arrays use the entire slot.)\n let fslot := sload(_preBytes.slot)\n // Arrays of 31 bytes or less have an even value in their slot,\n // while longer arrays have an odd value. The actual length is\n // the slot divided by two for odd values, and the lowest order\n // byte divided by two for even values.\n // If the slot is even, bitwise and the slot with 255 and divide by\n // two to get the length. If the slot is odd, bitwise and the slot\n // with -1 and divide by two.\n let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2)\n let mlength := mload(_postBytes)\n let newlength := add(slength, mlength)\n // slength can contain both the length and contents of the array\n // if length < 32 bytes so let's prepare for that\n // v. http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage\n switch add(lt(slength, 32), lt(newlength, 32))\n case 2 {\n // Since the new array still fits in the slot, we just need to\n // update the contents of the slot.\n // uint256(bytes_storage) = uint256(bytes_storage) + uint256(bytes_memory) + new_length\n sstore(\n _preBytes.slot,\n // all the modifications to the slot are inside this\n // next block\n add(\n // we can just add to the slot contents because the\n // bytes we want to change are the LSBs\n fslot,\n add(\n mul(\n div(\n // load the bytes from memory\n mload(add(_postBytes, 0x20)),\n // zero all bytes to the right\n exp(0x100, sub(32, mlength))\n ),\n // and now shift left the number of bytes to\n // leave space for the length in the slot\n exp(0x100, sub(32, newlength))\n ),\n // increase length by the double of the memory\n // bytes length\n mul(mlength, 2)\n )\n )\n )\n }\n case 1 {\n // The stored value fits in the slot, but the combined value\n // will exceed it.\n // get the keccak hash to get the contents of the array\n mstore(0x0, _preBytes.slot)\n let sc := add(keccak256(0x0, 0x20), div(slength, 32))\n\n // save new length\n sstore(_preBytes.slot, add(mul(newlength, 2), 1))\n\n // The contents of the _postBytes array start 32 bytes into\n // the structure. Our first read should obtain the `submod`\n // bytes that can fit into the unused space in the last word\n // of the stored array. To get this, we read 32 bytes starting\n // from `submod`, so the data we read overlaps with the array\n // contents by `submod` bytes. Masking the lowest-order\n // `submod` bytes allows us to add that value directly to the\n // stored value.\n\n let submod := sub(32, slength)\n let mc := add(_postBytes, submod)\n let end := add(_postBytes, mlength)\n let mask := sub(exp(0x100, submod), 1)\n\n sstore(\n sc,\n add(\n and(\n fslot,\n 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00\n ),\n and(mload(mc), mask)\n )\n )\n\n for {\n mc := add(mc, 0x20)\n sc := add(sc, 1)\n } lt(mc, end) {\n sc := add(sc, 1)\n mc := add(mc, 0x20)\n } {\n sstore(sc, mload(mc))\n }\n\n mask := exp(0x100, sub(mc, end))\n\n sstore(sc, mul(div(mload(mc), mask), mask))\n }\n default {\n // get the keccak hash to get the contents of the array\n mstore(0x0, _preBytes.slot)\n // Start copying to the last used word of the stored array.\n let sc := add(keccak256(0x0, 0x20), div(slength, 32))\n\n // save new length\n sstore(_preBytes.slot, add(mul(newlength, 2), 1))\n\n // Copy over the first `submod` bytes of the new data as in\n // case 1 above.\n let slengthmod := mod(slength, 32)\n let mlengthmod := mod(mlength, 32)\n let submod := sub(32, slengthmod)\n let mc := add(_postBytes, submod)\n let end := add(_postBytes, mlength)\n let mask := sub(exp(0x100, submod), 1)\n\n sstore(sc, add(sload(sc), and(mload(mc), mask)))\n\n for {\n sc := add(sc, 1)\n mc := add(mc, 0x20)\n } lt(mc, end) {\n sc := add(sc, 1)\n mc := add(mc, 0x20)\n } {\n sstore(sc, mload(mc))\n }\n\n mask := exp(0x100, sub(mc, end))\n\n sstore(sc, mul(div(mload(mc), mask), mask))\n }\n }\n }\n\n function slice(\n bytes memory _bytes,\n uint256 _start,\n uint256 _length\n )\n internal\n pure\n returns (bytes memory)\n {\n require(_length + 31 >= _length, \"slice_overflow\");\n require(_bytes.length >= _start + _length, \"slice_outOfBounds\");\n\n bytes memory tempBytes;\n\n assembly {\n switch iszero(_length)\n case 0 {\n // Get a location of some free memory and store it in tempBytes as\n // Solidity does for memory variables.\n tempBytes := mload(0x40)\n\n // The first word of the slice result is potentially a partial\n // word read from the original array. To read it, we calculate\n // the length of that partial word and start copying that many\n // bytes into the array. The first word we copy will start with\n // data we don't care about, but the last `lengthmod` bytes will\n // land at the beginning of the contents of the new array. When\n // we're done copying, we overwrite the full first word with\n // the actual length of the slice.\n let lengthmod := and(_length, 31)\n\n // The multiplication in the next line is necessary\n // because when slicing multiples of 32 bytes (lengthmod == 0)\n // the following copy loop was copying the origin's length\n // and then ending prematurely not copying everything it should.\n let mc := add(add(tempBytes, lengthmod), mul(0x20, iszero(lengthmod)))\n let end := add(mc, _length)\n\n for {\n // The multiplication in the next line has the same exact purpose\n // as the one above.\n let cc := add(add(add(_bytes, lengthmod), mul(0x20, iszero(lengthmod))), _start)\n } lt(mc, end) {\n mc := add(mc, 0x20)\n cc := add(cc, 0x20)\n } {\n mstore(mc, mload(cc))\n }\n\n mstore(tempBytes, _length)\n\n //update free-memory pointer\n //allocating the array padded to 32 bytes like the compiler does now\n mstore(0x40, and(add(mc, 31), not(31)))\n }\n //if we want a zero-length slice let's just return a zero-length array\n default {\n tempBytes := mload(0x40)\n //zero out the 32 bytes slice we are about to return\n //we need to do it because Solidity does not garbage collect\n mstore(tempBytes, 0)\n\n mstore(0x40, add(tempBytes, 0x20))\n }\n }\n\n return tempBytes;\n }\n\n function toAddress(bytes memory _bytes, uint256 _start) internal pure returns (address) {\n require(_bytes.length >= _start + 20, \"toAddress_outOfBounds\");\n address tempAddress;\n\n assembly {\n tempAddress := div(mload(add(add(_bytes, 0x20), _start)), 0x1000000000000000000000000)\n }\n\n return tempAddress;\n }\n\n function toUint8(bytes memory _bytes, uint256 _start) internal pure returns (uint8) {\n require(_bytes.length >= _start + 1 , \"toUint8_outOfBounds\");\n uint8 tempUint;\n\n assembly {\n tempUint := mload(add(add(_bytes, 0x1), _start))\n }\n\n return tempUint;\n }\n\n function toUint16(bytes memory _bytes, uint256 _start) internal pure returns (uint16) {\n require(_bytes.length >= _start + 2, \"toUint16_outOfBounds\");\n uint16 tempUint;\n\n assembly {\n tempUint := mload(add(add(_bytes, 0x2), _start))\n }\n\n return tempUint;\n }\n\n function toUint32(bytes memory _bytes, uint256 _start) internal pure returns (uint32) {\n require(_bytes.length >= _start + 4, \"toUint32_outOfBounds\");\n uint32 tempUint;\n\n assembly {\n tempUint := mload(add(add(_bytes, 0x4), _start))\n }\n\n return tempUint;\n }\n\n function toUint64(bytes memory _bytes, uint256 _start) internal pure returns (uint64) {\n require(_bytes.length >= _start + 8, \"toUint64_outOfBounds\");\n uint64 tempUint;\n\n assembly {\n tempUint := mload(add(add(_bytes, 0x8), _start))\n }\n\n return tempUint;\n }\n\n function toUint96(bytes memory _bytes, uint256 _start) internal pure returns (uint96) {\n require(_bytes.length >= _start + 12, \"toUint96_outOfBounds\");\n uint96 tempUint;\n\n assembly {\n tempUint := mload(add(add(_bytes, 0xc), _start))\n }\n\n return tempUint;\n }\n\n function toUint128(bytes memory _bytes, uint256 _start) internal pure returns (uint128) {\n require(_bytes.length >= _start + 16, \"toUint128_outOfBounds\");\n uint128 tempUint;\n\n assembly {\n tempUint := mload(add(add(_bytes, 0x10), _start))\n }\n\n return tempUint;\n }\n\n function toUint256(bytes memory _bytes, uint256 _start) internal pure returns (uint256) {\n require(_bytes.length >= _start + 32, \"toUint256_outOfBounds\");\n uint256 tempUint;\n\n assembly {\n tempUint := mload(add(add(_bytes, 0x20), _start))\n }\n\n return tempUint;\n }\n\n function toBytes32(bytes memory _bytes, uint256 _start) internal pure returns (bytes32) {\n require(_bytes.length >= _start + 32, \"toBytes32_outOfBounds\");\n bytes32 tempBytes32;\n\n assembly {\n tempBytes32 := mload(add(add(_bytes, 0x20), _start))\n }\n\n return tempBytes32;\n }\n\n function equal(bytes memory _preBytes, bytes memory _postBytes) internal pure returns (bool) {\n bool success = true;\n\n assembly {\n let length := mload(_preBytes)\n\n // if lengths don't match the arrays are not equal\n switch eq(length, mload(_postBytes))\n case 1 {\n // cb is a circuit breaker in the for loop since there's\n // no said feature for inline assembly loops\n // cb = 1 - don't breaker\n // cb = 0 - break\n let cb := 1\n\n let mc := add(_preBytes, 0x20)\n let end := add(mc, length)\n\n for {\n let cc := add(_postBytes, 0x20)\n // the next line is the loop condition:\n // while(uint256(mc < end) + cb == 2)\n } eq(add(lt(mc, end), cb), 2) {\n mc := add(mc, 0x20)\n cc := add(cc, 0x20)\n } {\n // if any of these checks fails then arrays are not equal\n if iszero(eq(mload(mc), mload(cc))) {\n // unsuccess:\n success := 0\n cb := 0\n }\n }\n }\n default {\n // unsuccess:\n success := 0\n }\n }\n\n return success;\n }\n\n function equal_nonAligned(bytes memory _preBytes, bytes memory _postBytes) internal pure returns (bool) {\n bool success = true;\n\n assembly {\n let length := mload(_preBytes)\n\n // if lengths don't match the arrays are not equal\n switch eq(length, mload(_postBytes))\n case 1 {\n // cb is a circuit breaker in the for loop since there's\n // no said feature for inline assembly loops\n // cb = 1 - don't breaker\n // cb = 0 - break\n let cb := 1\n\n let endMinusWord := add(_preBytes, length)\n let mc := add(_preBytes, 0x20)\n let cc := add(_postBytes, 0x20)\n\n for {\n // the next line is the loop condition:\n // while(uint256(mc < endWord) + cb == 2)\n } eq(add(lt(mc, endMinusWord), cb), 2) {\n mc := add(mc, 0x20)\n cc := add(cc, 0x20)\n } {\n // if any of these checks fails then arrays are not equal\n if iszero(eq(mload(mc), mload(cc))) {\n // unsuccess:\n success := 0\n cb := 0\n }\n }\n\n // Only if still successful\n // For <1 word tail bytes\n if gt(success, 0) {\n // Get the remainder of length/32\n // length % 32 = AND(length, 32 - 1)\n let numTailBytes := and(length, 0x1f)\n let mcRem := mload(mc)\n let ccRem := mload(cc)\n for {\n let i := 0\n // the next line is the loop condition:\n // while(uint256(i < numTailBytes) + cb == 2)\n } eq(add(lt(i, numTailBytes), cb), 2) {\n i := add(i, 1)\n } {\n if iszero(eq(byte(i, mcRem), byte(i, ccRem))) {\n // unsuccess:\n success := 0\n cb := 0\n }\n }\n }\n }\n default {\n // unsuccess:\n success := 0\n }\n }\n\n return success;\n }\n\n function equalStorage(\n bytes storage _preBytes,\n bytes memory _postBytes\n )\n internal\n view\n returns (bool)\n {\n bool success = true;\n\n assembly {\n // we know _preBytes_offset is 0\n let fslot := sload(_preBytes.slot)\n // Decode the length of the stored array like in concatStorage().\n let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2)\n let mlength := mload(_postBytes)\n\n // if lengths don't match the arrays are not equal\n switch eq(slength, mlength)\n case 1 {\n // slength can contain both the length and contents of the array\n // if length < 32 bytes so let's prepare for that\n // v. http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage\n if iszero(iszero(slength)) {\n switch lt(slength, 32)\n case 1 {\n // blank the last byte which is the length\n fslot := mul(div(fslot, 0x100), 0x100)\n\n if iszero(eq(fslot, mload(add(_postBytes, 0x20)))) {\n // unsuccess:\n success := 0\n }\n }\n default {\n // cb is a circuit breaker in the for loop since there's\n // no said feature for inline assembly loops\n // cb = 1 - don't breaker\n // cb = 0 - break\n let cb := 1\n\n // get the keccak hash to get the contents of the array\n mstore(0x0, _preBytes.slot)\n let sc := keccak256(0x0, 0x20)\n\n let mc := add(_postBytes, 0x20)\n let end := add(mc, mlength)\n\n // the next line is the loop condition:\n // while(uint256(mc < end) + cb == 2)\n for {} eq(add(lt(mc, end), cb), 2) {\n sc := add(sc, 1)\n mc := add(mc, 0x20)\n } {\n if iszero(eq(sload(sc), mload(mc))) {\n // unsuccess:\n success := 0\n cb := 0\n }\n }\n }\n }\n }\n default {\n // unsuccess:\n success := 0\n }\n }\n\n return success;\n }\n}\n"},"lib/openzeppelin-contracts/contracts/utils/math/SafeCast.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SafeCast.sol)\n// This file was procedurally generated from scripts/generate/templates/SafeCast.js.\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\n * checks.\n *\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\n * easily result in undesired exploitation or bugs, since developers usually\n * assume that overflows raise errors. `SafeCast` restores this intuition by\n * reverting the transaction when such an operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n *\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\n * all math on `uint256` and `int256` and then downcasting.\n */\nlibrary SafeCast {\n /**\n * @dev Returns the downcasted uint248 from uint256, reverting on\n * overflow (when the input is greater than largest uint248).\n *\n * Counterpart to Solidity's `uint248` operator.\n *\n * Requirements:\n *\n * - input must fit into 248 bits\n *\n * _Available since v4.7._\n */\n function toUint248(uint256 value) internal pure returns (uint248) {\n require(value <= type(uint248).max, \"SafeCast: value doesn't fit in 248 bits\");\n return uint248(value);\n }\n\n /**\n * @dev Returns the downcasted uint240 from uint256, reverting on\n * overflow (when the input is greater than largest uint240).\n *\n * Counterpart to Solidity's `uint240` operator.\n *\n * Requirements:\n *\n * - input must fit into 240 bits\n *\n * _Available since v4.7._\n */\n function toUint240(uint256 value) internal pure returns (uint240) {\n require(value <= type(uint240).max, \"SafeCast: value doesn't fit in 240 bits\");\n return uint240(value);\n }\n\n /**\n * @dev Returns the downcasted uint232 from uint256, reverting on\n * overflow (when the input is greater than largest uint232).\n *\n * Counterpart to Solidity's `uint232` operator.\n *\n * Requirements:\n *\n * - input must fit into 232 bits\n *\n * _Available since v4.7._\n */\n function toUint232(uint256 value) internal pure returns (uint232) {\n require(value <= type(uint232).max, \"SafeCast: value doesn't fit in 232 bits\");\n return uint232(value);\n }\n\n /**\n * @dev Returns the downcasted uint224 from uint256, reverting on\n * overflow (when the input is greater than largest uint224).\n *\n * Counterpart to Solidity's `uint224` operator.\n *\n * Requirements:\n *\n * - input must fit into 224 bits\n *\n * _Available since v4.2._\n */\n function toUint224(uint256 value) internal pure returns (uint224) {\n require(value <= type(uint224).max, \"SafeCast: value doesn't fit in 224 bits\");\n return uint224(value);\n }\n\n /**\n * @dev Returns the downcasted uint216 from uint256, reverting on\n * overflow (when the input is greater than largest uint216).\n *\n * Counterpart to Solidity's `uint216` operator.\n *\n * Requirements:\n *\n * - input must fit into 216 bits\n *\n * _Available since v4.7._\n */\n function toUint216(uint256 value) internal pure returns (uint216) {\n require(value <= type(uint216).max, \"SafeCast: value doesn't fit in 216 bits\");\n return uint216(value);\n }\n\n /**\n * @dev Returns the downcasted uint208 from uint256, reverting on\n * overflow (when the input is greater than largest uint208).\n *\n * Counterpart to Solidity's `uint208` operator.\n *\n * Requirements:\n *\n * - input must fit into 208 bits\n *\n * _Available since v4.7._\n */\n function toUint208(uint256 value) internal pure returns (uint208) {\n require(value <= type(uint208).max, \"SafeCast: value doesn't fit in 208 bits\");\n return uint208(value);\n }\n\n /**\n * @dev Returns the downcasted uint200 from uint256, reverting on\n * overflow (when the input is greater than largest uint200).\n *\n * Counterpart to Solidity's `uint200` operator.\n *\n * Requirements:\n *\n * - input must fit into 200 bits\n *\n * _Available since v4.7._\n */\n function toUint200(uint256 value) internal pure returns (uint200) {\n require(value <= type(uint200).max, \"SafeCast: value doesn't fit in 200 bits\");\n return uint200(value);\n }\n\n /**\n * @dev Returns the downcasted uint192 from uint256, reverting on\n * overflow (when the input is greater than largest uint192).\n *\n * Counterpart to Solidity's `uint192` operator.\n *\n * Requirements:\n *\n * - input must fit into 192 bits\n *\n * _Available since v4.7._\n */\n function toUint192(uint256 value) internal pure returns (uint192) {\n require(value <= type(uint192).max, \"SafeCast: value doesn't fit in 192 bits\");\n return uint192(value);\n }\n\n /**\n * @dev Returns the downcasted uint184 from uint256, reverting on\n * overflow (when the input is greater than largest uint184).\n *\n * Counterpart to Solidity's `uint184` operator.\n *\n * Requirements:\n *\n * - input must fit into 184 bits\n *\n * _Available since v4.7._\n */\n function toUint184(uint256 value) internal pure returns (uint184) {\n require(value <= type(uint184).max, \"SafeCast: value doesn't fit in 184 bits\");\n return uint184(value);\n }\n\n /**\n * @dev Returns the downcasted uint176 from uint256, reverting on\n * overflow (when the input is greater than largest uint176).\n *\n * Counterpart to Solidity's `uint176` operator.\n *\n * Requirements:\n *\n * - input must fit into 176 bits\n *\n * _Available since v4.7._\n */\n function toUint176(uint256 value) internal pure returns (uint176) {\n require(value <= type(uint176).max, \"SafeCast: value doesn't fit in 176 bits\");\n return uint176(value);\n }\n\n /**\n * @dev Returns the downcasted uint168 from uint256, reverting on\n * overflow (when the input is greater than largest uint168).\n *\n * Counterpart to Solidity's `uint168` operator.\n *\n * Requirements:\n *\n * - input must fit into 168 bits\n *\n * _Available since v4.7._\n */\n function toUint168(uint256 value) internal pure returns (uint168) {\n require(value <= type(uint168).max, \"SafeCast: value doesn't fit in 168 bits\");\n return uint168(value);\n }\n\n /**\n * @dev Returns the downcasted uint160 from uint256, reverting on\n * overflow (when the input is greater than largest uint160).\n *\n * Counterpart to Solidity's `uint160` operator.\n *\n * Requirements:\n *\n * - input must fit into 160 bits\n *\n * _Available since v4.7._\n */\n function toUint160(uint256 value) internal pure returns (uint160) {\n require(value <= type(uint160).max, \"SafeCast: value doesn't fit in 160 bits\");\n return uint160(value);\n }\n\n /**\n * @dev Returns the downcasted uint152 from uint256, reverting on\n * overflow (when the input is greater than largest uint152).\n *\n * Counterpart to Solidity's `uint152` operator.\n *\n * Requirements:\n *\n * - input must fit into 152 bits\n *\n * _Available since v4.7._\n */\n function toUint152(uint256 value) internal pure returns (uint152) {\n require(value <= type(uint152).max, \"SafeCast: value doesn't fit in 152 bits\");\n return uint152(value);\n }\n\n /**\n * @dev Returns the downcasted uint144 from uint256, reverting on\n * overflow (when the input is greater than largest uint144).\n *\n * Counterpart to Solidity's `uint144` operator.\n *\n * Requirements:\n *\n * - input must fit into 144 bits\n *\n * _Available since v4.7._\n */\n function toUint144(uint256 value) internal pure returns (uint144) {\n require(value <= type(uint144).max, \"SafeCast: value doesn't fit in 144 bits\");\n return uint144(value);\n }\n\n /**\n * @dev Returns the downcasted uint136 from uint256, reverting on\n * overflow (when the input is greater than largest uint136).\n *\n * Counterpart to Solidity's `uint136` operator.\n *\n * Requirements:\n *\n * - input must fit into 136 bits\n *\n * _Available since v4.7._\n */\n function toUint136(uint256 value) internal pure returns (uint136) {\n require(value <= type(uint136).max, \"SafeCast: value doesn't fit in 136 bits\");\n return uint136(value);\n }\n\n /**\n * @dev Returns the downcasted uint128 from uint256, reverting on\n * overflow (when the input is greater than largest uint128).\n *\n * Counterpart to Solidity's `uint128` operator.\n *\n * Requirements:\n *\n * - input must fit into 128 bits\n *\n * _Available since v2.5._\n */\n function toUint128(uint256 value) internal pure returns (uint128) {\n require(value <= type(uint128).max, \"SafeCast: value doesn't fit in 128 bits\");\n return uint128(value);\n }\n\n /**\n * @dev Returns the downcasted uint120 from uint256, reverting on\n * overflow (when the input is greater than largest uint120).\n *\n * Counterpart to Solidity's `uint120` operator.\n *\n * Requirements:\n *\n * - input must fit into 120 bits\n *\n * _Available since v4.7._\n */\n function toUint120(uint256 value) internal pure returns (uint120) {\n require(value <= type(uint120).max, \"SafeCast: value doesn't fit in 120 bits\");\n return uint120(value);\n }\n\n /**\n * @dev Returns the downcasted uint112 from uint256, reverting on\n * overflow (when the input is greater than largest uint112).\n *\n * Counterpart to Solidity's `uint112` operator.\n *\n * Requirements:\n *\n * - input must fit into 112 bits\n *\n * _Available since v4.7._\n */\n function toUint112(uint256 value) internal pure returns (uint112) {\n require(value <= type(uint112).max, \"SafeCast: value doesn't fit in 112 bits\");\n return uint112(value);\n }\n\n /**\n * @dev Returns the downcasted uint104 from uint256, reverting on\n * overflow (when the input is greater than largest uint104).\n *\n * Counterpart to Solidity's `uint104` operator.\n *\n * Requirements:\n *\n * - input must fit into 104 bits\n *\n * _Available since v4.7._\n */\n function toUint104(uint256 value) internal pure returns (uint104) {\n require(value <= type(uint104).max, \"SafeCast: value doesn't fit in 104 bits\");\n return uint104(value);\n }\n\n /**\n * @dev Returns the downcasted uint96 from uint256, reverting on\n * overflow (when the input is greater than largest uint96).\n *\n * Counterpart to Solidity's `uint96` operator.\n *\n * Requirements:\n *\n * - input must fit into 96 bits\n *\n * _Available since v4.2._\n */\n function toUint96(uint256 value) internal pure returns (uint96) {\n require(value <= type(uint96).max, \"SafeCast: value doesn't fit in 96 bits\");\n return uint96(value);\n }\n\n /**\n * @dev Returns the downcasted uint88 from uint256, reverting on\n * overflow (when the input is greater than largest uint88).\n *\n * Counterpart to Solidity's `uint88` operator.\n *\n * Requirements:\n *\n * - input must fit into 88 bits\n *\n * _Available since v4.7._\n */\n function toUint88(uint256 value) internal pure returns (uint88) {\n require(value <= type(uint88).max, \"SafeCast: value doesn't fit in 88 bits\");\n return uint88(value);\n }\n\n /**\n * @dev Returns the downcasted uint80 from uint256, reverting on\n * overflow (when the input is greater than largest uint80).\n *\n * Counterpart to Solidity's `uint80` operator.\n *\n * Requirements:\n *\n * - input must fit into 80 bits\n *\n * _Available since v4.7._\n */\n function toUint80(uint256 value) internal pure returns (uint80) {\n require(value <= type(uint80).max, \"SafeCast: value doesn't fit in 80 bits\");\n return uint80(value);\n }\n\n /**\n * @dev Returns the downcasted uint72 from uint256, reverting on\n * overflow (when the input is greater than largest uint72).\n *\n * Counterpart to Solidity's `uint72` operator.\n *\n * Requirements:\n *\n * - input must fit into 72 bits\n *\n * _Available since v4.7._\n */\n function toUint72(uint256 value) internal pure returns (uint72) {\n require(value <= type(uint72).max, \"SafeCast: value doesn't fit in 72 bits\");\n return uint72(value);\n }\n\n /**\n * @dev Returns the downcasted uint64 from uint256, reverting on\n * overflow (when the input is greater than largest uint64).\n *\n * Counterpart to Solidity's `uint64` operator.\n *\n * Requirements:\n *\n * - input must fit into 64 bits\n *\n * _Available since v2.5._\n */\n function toUint64(uint256 value) internal pure returns (uint64) {\n require(value <= type(uint64).max, \"SafeCast: value doesn't fit in 64 bits\");\n return uint64(value);\n }\n\n /**\n * @dev Returns the downcasted uint56 from uint256, reverting on\n * overflow (when the input is greater than largest uint56).\n *\n * Counterpart to Solidity's `uint56` operator.\n *\n * Requirements:\n *\n * - input must fit into 56 bits\n *\n * _Available since v4.7._\n */\n function toUint56(uint256 value) internal pure returns (uint56) {\n require(value <= type(uint56).max, \"SafeCast: value doesn't fit in 56 bits\");\n return uint56(value);\n }\n\n /**\n * @dev Returns the downcasted uint48 from uint256, reverting on\n * overflow (when the input is greater than largest uint48).\n *\n * Counterpart to Solidity's `uint48` operator.\n *\n * Requirements:\n *\n * - input must fit into 48 bits\n *\n * _Available since v4.7._\n */\n function toUint48(uint256 value) internal pure returns (uint48) {\n require(value <= type(uint48).max, \"SafeCast: value doesn't fit in 48 bits\");\n return uint48(value);\n }\n\n /**\n * @dev Returns the downcasted uint40 from uint256, reverting on\n * overflow (when the input is greater than largest uint40).\n *\n * Counterpart to Solidity's `uint40` operator.\n *\n * Requirements:\n *\n * - input must fit into 40 bits\n *\n * _Available since v4.7._\n */\n function toUint40(uint256 value) internal pure returns (uint40) {\n require(value <= type(uint40).max, \"SafeCast: value doesn't fit in 40 bits\");\n return uint40(value);\n }\n\n /**\n * @dev Returns the downcasted uint32 from uint256, reverting on\n * overflow (when the input is greater than largest uint32).\n *\n * Counterpart to Solidity's `uint32` operator.\n *\n * Requirements:\n *\n * - input must fit into 32 bits\n *\n * _Available since v2.5._\n */\n function toUint32(uint256 value) internal pure returns (uint32) {\n require(value <= type(uint32).max, \"SafeCast: value doesn't fit in 32 bits\");\n return uint32(value);\n }\n\n /**\n * @dev Returns the downcasted uint24 from uint256, reverting on\n * overflow (when the input is greater than largest uint24).\n *\n * Counterpart to Solidity's `uint24` operator.\n *\n * Requirements:\n *\n * - input must fit into 24 bits\n *\n * _Available since v4.7._\n */\n function toUint24(uint256 value) internal pure returns (uint24) {\n require(value <= type(uint24).max, \"SafeCast: value doesn't fit in 24 bits\");\n return uint24(value);\n }\n\n /**\n * @dev Returns the downcasted uint16 from uint256, reverting on\n * overflow (when the input is greater than largest uint16).\n *\n * Counterpart to Solidity's `uint16` operator.\n *\n * Requirements:\n *\n * - input must fit into 16 bits\n *\n * _Available since v2.5._\n */\n function toUint16(uint256 value) internal pure returns (uint16) {\n require(value <= type(uint16).max, \"SafeCast: value doesn't fit in 16 bits\");\n return uint16(value);\n }\n\n /**\n * @dev Returns the downcasted uint8 from uint256, reverting on\n * overflow (when the input is greater than largest uint8).\n *\n * Counterpart to Solidity's `uint8` operator.\n *\n * Requirements:\n *\n * - input must fit into 8 bits\n *\n * _Available since v2.5._\n */\n function toUint8(uint256 value) internal pure returns (uint8) {\n require(value <= type(uint8).max, \"SafeCast: value doesn't fit in 8 bits\");\n return uint8(value);\n }\n\n /**\n * @dev Converts a signed int256 into an unsigned uint256.\n *\n * Requirements:\n *\n * - input must be greater than or equal to 0.\n *\n * _Available since v3.0._\n */\n function toUint256(int256 value) internal pure returns (uint256) {\n require(value >= 0, \"SafeCast: value must be positive\");\n return uint256(value);\n }\n\n /**\n * @dev Returns the downcasted int248 from int256, reverting on\n * overflow (when the input is less than smallest int248 or\n * greater than largest int248).\n *\n * Counterpart to Solidity's `int248` operator.\n *\n * Requirements:\n *\n * - input must fit into 248 bits\n *\n * _Available since v4.7._\n */\n function toInt248(int256 value) internal pure returns (int248 downcasted) {\n downcasted = int248(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 248 bits\");\n }\n\n /**\n * @dev Returns the downcasted int240 from int256, reverting on\n * overflow (when the input is less than smallest int240 or\n * greater than largest int240).\n *\n * Counterpart to Solidity's `int240` operator.\n *\n * Requirements:\n *\n * - input must fit into 240 bits\n *\n * _Available since v4.7._\n */\n function toInt240(int256 value) internal pure returns (int240 downcasted) {\n downcasted = int240(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 240 bits\");\n }\n\n /**\n * @dev Returns the downcasted int232 from int256, reverting on\n * overflow (when the input is less than smallest int232 or\n * greater than largest int232).\n *\n * Counterpart to Solidity's `int232` operator.\n *\n * Requirements:\n *\n * - input must fit into 232 bits\n *\n * _Available since v4.7._\n */\n function toInt232(int256 value) internal pure returns (int232 downcasted) {\n downcasted = int232(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 232 bits\");\n }\n\n /**\n * @dev Returns the downcasted int224 from int256, reverting on\n * overflow (when the input is less than smallest int224 or\n * greater than largest int224).\n *\n * Counterpart to Solidity's `int224` operator.\n *\n * Requirements:\n *\n * - input must fit into 224 bits\n *\n * _Available since v4.7._\n */\n function toInt224(int256 value) internal pure returns (int224 downcasted) {\n downcasted = int224(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 224 bits\");\n }\n\n /**\n * @dev Returns the downcasted int216 from int256, reverting on\n * overflow (when the input is less than smallest int216 or\n * greater than largest int216).\n *\n * Counterpart to Solidity's `int216` operator.\n *\n * Requirements:\n *\n * - input must fit into 216 bits\n *\n * _Available since v4.7._\n */\n function toInt216(int256 value) internal pure returns (int216 downcasted) {\n downcasted = int216(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 216 bits\");\n }\n\n /**\n * @dev Returns the downcasted int208 from int256, reverting on\n * overflow (when the input is less than smallest int208 or\n * greater than largest int208).\n *\n * Counterpart to Solidity's `int208` operator.\n *\n * Requirements:\n *\n * - input must fit into 208 bits\n *\n * _Available since v4.7._\n */\n function toInt208(int256 value) internal pure returns (int208 downcasted) {\n downcasted = int208(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 208 bits\");\n }\n\n /**\n * @dev Returns the downcasted int200 from int256, reverting on\n * overflow (when the input is less than smallest int200 or\n * greater than largest int200).\n *\n * Counterpart to Solidity's `int200` operator.\n *\n * Requirements:\n *\n * - input must fit into 200 bits\n *\n * _Available since v4.7._\n */\n function toInt200(int256 value) internal pure returns (int200 downcasted) {\n downcasted = int200(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 200 bits\");\n }\n\n /**\n * @dev Returns the downcasted int192 from int256, reverting on\n * overflow (when the input is less than smallest int192 or\n * greater than largest int192).\n *\n * Counterpart to Solidity's `int192` operator.\n *\n * Requirements:\n *\n * - input must fit into 192 bits\n *\n * _Available since v4.7._\n */\n function toInt192(int256 value) internal pure returns (int192 downcasted) {\n downcasted = int192(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 192 bits\");\n }\n\n /**\n * @dev Returns the downcasted int184 from int256, reverting on\n * overflow (when the input is less than smallest int184 or\n * greater than largest int184).\n *\n * Counterpart to Solidity's `int184` operator.\n *\n * Requirements:\n *\n * - input must fit into 184 bits\n *\n * _Available since v4.7._\n */\n function toInt184(int256 value) internal pure returns (int184 downcasted) {\n downcasted = int184(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 184 bits\");\n }\n\n /**\n * @dev Returns the downcasted int176 from int256, reverting on\n * overflow (when the input is less than smallest int176 or\n * greater than largest int176).\n *\n * Counterpart to Solidity's `int176` operator.\n *\n * Requirements:\n *\n * - input must fit into 176 bits\n *\n * _Available since v4.7._\n */\n function toInt176(int256 value) internal pure returns (int176 downcasted) {\n downcasted = int176(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 176 bits\");\n }\n\n /**\n * @dev Returns the downcasted int168 from int256, reverting on\n * overflow (when the input is less than smallest int168 or\n * greater than largest int168).\n *\n * Counterpart to Solidity's `int168` operator.\n *\n * Requirements:\n *\n * - input must fit into 168 bits\n *\n * _Available since v4.7._\n */\n function toInt168(int256 value) internal pure returns (int168 downcasted) {\n downcasted = int168(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 168 bits\");\n }\n\n /**\n * @dev Returns the downcasted int160 from int256, reverting on\n * overflow (when the input is less than smallest int160 or\n * greater than largest int160).\n *\n * Counterpart to Solidity's `int160` operator.\n *\n * Requirements:\n *\n * - input must fit into 160 bits\n *\n * _Available since v4.7._\n */\n function toInt160(int256 value) internal pure returns (int160 downcasted) {\n downcasted = int160(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 160 bits\");\n }\n\n /**\n * @dev Returns the downcasted int152 from int256, reverting on\n * overflow (when the input is less than smallest int152 or\n * greater than largest int152).\n *\n * Counterpart to Solidity's `int152` operator.\n *\n * Requirements:\n *\n * - input must fit into 152 bits\n *\n * _Available since v4.7._\n */\n function toInt152(int256 value) internal pure returns (int152 downcasted) {\n downcasted = int152(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 152 bits\");\n }\n\n /**\n * @dev Returns the downcasted int144 from int256, reverting on\n * overflow (when the input is less than smallest int144 or\n * greater than largest int144).\n *\n * Counterpart to Solidity's `int144` operator.\n *\n * Requirements:\n *\n * - input must fit into 144 bits\n *\n * _Available since v4.7._\n */\n function toInt144(int256 value) internal pure returns (int144 downcasted) {\n downcasted = int144(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 144 bits\");\n }\n\n /**\n * @dev Returns the downcasted int136 from int256, reverting on\n * overflow (when the input is less than smallest int136 or\n * greater than largest int136).\n *\n * Counterpart to Solidity's `int136` operator.\n *\n * Requirements:\n *\n * - input must fit into 136 bits\n *\n * _Available since v4.7._\n */\n function toInt136(int256 value) internal pure returns (int136 downcasted) {\n downcasted = int136(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 136 bits\");\n }\n\n /**\n * @dev Returns the downcasted int128 from int256, reverting on\n * overflow (when the input is less than smallest int128 or\n * greater than largest int128).\n *\n * Counterpart to Solidity's `int128` operator.\n *\n * Requirements:\n *\n * - input must fit into 128 bits\n *\n * _Available since v3.1._\n */\n function toInt128(int256 value) internal pure returns (int128 downcasted) {\n downcasted = int128(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 128 bits\");\n }\n\n /**\n * @dev Returns the downcasted int120 from int256, reverting on\n * overflow (when the input is less than smallest int120 or\n * greater than largest int120).\n *\n * Counterpart to Solidity's `int120` operator.\n *\n * Requirements:\n *\n * - input must fit into 120 bits\n *\n * _Available since v4.7._\n */\n function toInt120(int256 value) internal pure returns (int120 downcasted) {\n downcasted = int120(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 120 bits\");\n }\n\n /**\n * @dev Returns the downcasted int112 from int256, reverting on\n * overflow (when the input is less than smallest int112 or\n * greater than largest int112).\n *\n * Counterpart to Solidity's `int112` operator.\n *\n * Requirements:\n *\n * - input must fit into 112 bits\n *\n * _Available since v4.7._\n */\n function toInt112(int256 value) internal pure returns (int112 downcasted) {\n downcasted = int112(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 112 bits\");\n }\n\n /**\n * @dev Returns the downcasted int104 from int256, reverting on\n * overflow (when the input is less than smallest int104 or\n * greater than largest int104).\n *\n * Counterpart to Solidity's `int104` operator.\n *\n * Requirements:\n *\n * - input must fit into 104 bits\n *\n * _Available since v4.7._\n */\n function toInt104(int256 value) internal pure returns (int104 downcasted) {\n downcasted = int104(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 104 bits\");\n }\n\n /**\n * @dev Returns the downcasted int96 from int256, reverting on\n * overflow (when the input is less than smallest int96 or\n * greater than largest int96).\n *\n * Counterpart to Solidity's `int96` operator.\n *\n * Requirements:\n *\n * - input must fit into 96 bits\n *\n * _Available since v4.7._\n */\n function toInt96(int256 value) internal pure returns (int96 downcasted) {\n downcasted = int96(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 96 bits\");\n }\n\n /**\n * @dev Returns the downcasted int88 from int256, reverting on\n * overflow (when the input is less than smallest int88 or\n * greater than largest int88).\n *\n * Counterpart to Solidity's `int88` operator.\n *\n * Requirements:\n *\n * - input must fit into 88 bits\n *\n * _Available since v4.7._\n */\n function toInt88(int256 value) internal pure returns (int88 downcasted) {\n downcasted = int88(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 88 bits\");\n }\n\n /**\n * @dev Returns the downcasted int80 from int256, reverting on\n * overflow (when the input is less than smallest int80 or\n * greater than largest int80).\n *\n * Counterpart to Solidity's `int80` operator.\n *\n * Requirements:\n *\n * - input must fit into 80 bits\n *\n * _Available since v4.7._\n */\n function toInt80(int256 value) internal pure returns (int80 downcasted) {\n downcasted = int80(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 80 bits\");\n }\n\n /**\n * @dev Returns the downcasted int72 from int256, reverting on\n * overflow (when the input is less than smallest int72 or\n * greater than largest int72).\n *\n * Counterpart to Solidity's `int72` operator.\n *\n * Requirements:\n *\n * - input must fit into 72 bits\n *\n * _Available since v4.7._\n */\n function toInt72(int256 value) internal pure returns (int72 downcasted) {\n downcasted = int72(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 72 bits\");\n }\n\n /**\n * @dev Returns the downcasted int64 from int256, reverting on\n * overflow (when the input is less than smallest int64 or\n * greater than largest int64).\n *\n * Counterpart to Solidity's `int64` operator.\n *\n * Requirements:\n *\n * - input must fit into 64 bits\n *\n * _Available since v3.1._\n */\n function toInt64(int256 value) internal pure returns (int64 downcasted) {\n downcasted = int64(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 64 bits\");\n }\n\n /**\n * @dev Returns the downcasted int56 from int256, reverting on\n * overflow (when the input is less than smallest int56 or\n * greater than largest int56).\n *\n * Counterpart to Solidity's `int56` operator.\n *\n * Requirements:\n *\n * - input must fit into 56 bits\n *\n * _Available since v4.7._\n */\n function toInt56(int256 value) internal pure returns (int56 downcasted) {\n downcasted = int56(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 56 bits\");\n }\n\n /**\n * @dev Returns the downcasted int48 from int256, reverting on\n * overflow (when the input is less than smallest int48 or\n * greater than largest int48).\n *\n * Counterpart to Solidity's `int48` operator.\n *\n * Requirements:\n *\n * - input must fit into 48 bits\n *\n * _Available since v4.7._\n */\n function toInt48(int256 value) internal pure returns (int48 downcasted) {\n downcasted = int48(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 48 bits\");\n }\n\n /**\n * @dev Returns the downcasted int40 from int256, reverting on\n * overflow (when the input is less than smallest int40 or\n * greater than largest int40).\n *\n * Counterpart to Solidity's `int40` operator.\n *\n * Requirements:\n *\n * - input must fit into 40 bits\n *\n * _Available since v4.7._\n */\n function toInt40(int256 value) internal pure returns (int40 downcasted) {\n downcasted = int40(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 40 bits\");\n }\n\n /**\n * @dev Returns the downcasted int32 from int256, reverting on\n * overflow (when the input is less than smallest int32 or\n * greater than largest int32).\n *\n * Counterpart to Solidity's `int32` operator.\n *\n * Requirements:\n *\n * - input must fit into 32 bits\n *\n * _Available since v3.1._\n */\n function toInt32(int256 value) internal pure returns (int32 downcasted) {\n downcasted = int32(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 32 bits\");\n }\n\n /**\n * @dev Returns the downcasted int24 from int256, reverting on\n * overflow (when the input is less than smallest int24 or\n * greater than largest int24).\n *\n * Counterpart to Solidity's `int24` operator.\n *\n * Requirements:\n *\n * - input must fit into 24 bits\n *\n * _Available since v4.7._\n */\n function toInt24(int256 value) internal pure returns (int24 downcasted) {\n downcasted = int24(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 24 bits\");\n }\n\n /**\n * @dev Returns the downcasted int16 from int256, reverting on\n * overflow (when the input is less than smallest int16 or\n * greater than largest int16).\n *\n * Counterpart to Solidity's `int16` operator.\n *\n * Requirements:\n *\n * - input must fit into 16 bits\n *\n * _Available since v3.1._\n */\n function toInt16(int256 value) internal pure returns (int16 downcasted) {\n downcasted = int16(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 16 bits\");\n }\n\n /**\n * @dev Returns the downcasted int8 from int256, reverting on\n * overflow (when the input is less than smallest int8 or\n * greater than largest int8).\n *\n * Counterpart to Solidity's `int8` operator.\n *\n * Requirements:\n *\n * - input must fit into 8 bits\n *\n * _Available since v3.1._\n */\n function toInt8(int256 value) internal pure returns (int8 downcasted) {\n downcasted = int8(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 8 bits\");\n }\n\n /**\n * @dev Converts an unsigned uint256 into a signed int256.\n *\n * Requirements:\n *\n * - input must be less than or equal to maxInt256.\n *\n * _Available since v3.0._\n */\n function toInt256(uint256 value) internal pure returns (int256) {\n // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive\n require(value <= uint256(type(int256).max), \"SafeCast: value doesn't fit in an int256\");\n return int256(value);\n }\n}\n"},"lib/LayerZero-v2/protocol/contracts/messagelib/libs/ExecutorOptions.sol":{"content":"// SPDX-License-Identifier: LZBL-1.2\n\npragma solidity ^0.8.20;\n\nimport { CalldataBytesLib } from \"../../libs/CalldataBytesLib.sol\";\n\nlibrary ExecutorOptions {\n using CalldataBytesLib for bytes;\n\n uint8 internal constant WORKER_ID = 1;\n\n uint8 internal constant OPTION_TYPE_LZRECEIVE = 1;\n uint8 internal constant OPTION_TYPE_NATIVE_DROP = 2;\n uint8 internal constant OPTION_TYPE_LZCOMPOSE = 3;\n uint8 internal constant OPTION_TYPE_ORDERED_EXECUTION = 4;\n\n error Executor_InvalidLzReceiveOption();\n error Executor_InvalidNativeDropOption();\n error Executor_InvalidLzComposeOption();\n\n /// @dev decode the next executor option from the options starting from the specified cursor\n /// @param _options [executor_id][executor_option][executor_id][executor_option]...\n /// executor_option = [option_size][option_type][option]\n /// option_size = len(option_type) + len(option)\n /// executor_id: uint8, option_size: uint16, option_type: uint8, option: bytes\n /// @param _cursor the cursor to start decoding from\n /// @return optionType the type of the option\n /// @return option the option of the executor\n /// @return cursor the cursor to start decoding the next executor option\n function nextExecutorOption(\n bytes calldata _options,\n uint256 _cursor\n ) internal pure returns (uint8 optionType, bytes calldata option, uint256 cursor) {\n unchecked {\n // skip worker id\n cursor = _cursor + 1;\n\n // read option size\n uint16 size = _options.toU16(cursor);\n cursor += 2;\n\n // read option type\n optionType = _options.toU8(cursor);\n\n // startCursor and endCursor are used to slice the option from _options\n uint256 startCursor = cursor + 1; // skip option type\n uint256 endCursor = cursor + size;\n option = _options[startCursor:endCursor];\n cursor += size;\n }\n }\n\n function decodeLzReceiveOption(bytes calldata _option) internal pure returns (uint128 gas, uint128 value) {\n if (_option.length != 16 && _option.length != 32) revert Executor_InvalidLzReceiveOption();\n gas = _option.toU128(0);\n value = _option.length == 32 ? _option.toU128(16) : 0;\n }\n\n function decodeNativeDropOption(bytes calldata _option) internal pure returns (uint128 amount, bytes32 receiver) {\n if (_option.length != 48) revert Executor_InvalidNativeDropOption();\n amount = _option.toU128(0);\n receiver = _option.toB32(16);\n }\n\n function decodeLzComposeOption(\n bytes calldata _option\n ) internal pure returns (uint16 index, uint128 gas, uint128 value) {\n if (_option.length != 18 && _option.length != 34) revert Executor_InvalidLzComposeOption();\n index = _option.toU16(0);\n gas = _option.toU128(2);\n value = _option.length == 34 ? _option.toU128(18) : 0;\n }\n\n function encodeLzReceiveOption(uint128 _gas, uint128 _value) internal pure returns (bytes memory) {\n return _value == 0 ? abi.encodePacked(_gas) : abi.encodePacked(_gas, _value);\n }\n\n function encodeNativeDropOption(uint128 _amount, bytes32 _receiver) internal pure returns (bytes memory) {\n return abi.encodePacked(_amount, _receiver);\n }\n\n function encodeLzComposeOption(uint16 _index, uint128 _gas, uint128 _value) internal pure returns (bytes memory) {\n return _value == 0 ? abi.encodePacked(_index, _gas) : abi.encodePacked(_index, _gas, _value);\n }\n}\n"},"lib/LayerZero-v2/messagelib/contracts/uln/libs/DVNOptions.sol":{"content":"// SPDX-License-Identifier: LZBL-1.2\n\npragma solidity ^0.8.20;\n\nimport { BytesLib } from \"solidity-bytes-utils/contracts/BytesLib.sol\";\n\nimport { BitMap256 } from \"@layerzerolabs/lz-evm-protocol-v2/contracts/messagelib/libs/BitMaps.sol\";\nimport { CalldataBytesLib } from \"@layerzerolabs/lz-evm-protocol-v2/contracts/libs/CalldataBytesLib.sol\";\n\nlibrary DVNOptions {\n using CalldataBytesLib for bytes;\n using BytesLib for bytes;\n\n uint8 internal constant WORKER_ID = 2;\n uint8 internal constant OPTION_TYPE_PRECRIME = 1;\n\n error DVN_InvalidDVNIdx();\n error DVN_InvalidDVNOptions(uint256 cursor);\n\n /// @dev group dvn options by its idx\n /// @param _options [dvn_id][dvn_option][dvn_id][dvn_option]...\n /// dvn_option = [option_size][dvn_idx][option_type][option]\n /// option_size = len(dvn_idx) + len(option_type) + len(option)\n /// dvn_id: uint8, dvn_idx: uint8, option_size: uint16, option_type: uint8, option: bytes\n /// @return dvnOptions the grouped options, still share the same format of _options\n /// @return dvnIndices the dvn indices\n function groupDVNOptionsByIdx(\n bytes memory _options\n ) internal pure returns (bytes[] memory dvnOptions, uint8[] memory dvnIndices) {\n if (_options.length == 0) return (dvnOptions, dvnIndices);\n\n uint8 numDVNs = getNumDVNs(_options);\n\n // if there is only 1 dvn, we can just return the whole options\n if (numDVNs == 1) {\n dvnOptions = new bytes[](1);\n dvnOptions[0] = _options;\n\n dvnIndices = new uint8[](1);\n dvnIndices[0] = _options.toUint8(3); // dvn idx\n return (dvnOptions, dvnIndices);\n }\n\n // otherwise, we need to group the options by dvn_idx\n dvnIndices = new uint8[](numDVNs);\n dvnOptions = new bytes[](numDVNs);\n unchecked {\n uint256 cursor = 0;\n uint256 start = 0;\n uint8 lastDVNIdx = 255; // 255 is an invalid dvn_idx\n\n while (cursor < _options.length) {\n ++cursor; // skip worker_id\n\n // optionLength asserted in getNumDVNs (skip check)\n uint16 optionLength = _options.toUint16(cursor);\n cursor += 2;\n\n // dvnIdx asserted in getNumDVNs (skip check)\n uint8 dvnIdx = _options.toUint8(cursor);\n\n // dvnIdx must equal to the lastDVNIdx for the first option\n // so it is always skipped in the first option\n // this operation slices out options whenever the scan finds a different lastDVNIdx\n if (lastDVNIdx == 255) {\n lastDVNIdx = dvnIdx;\n } else if (dvnIdx != lastDVNIdx) {\n uint256 len = cursor - start - 3; // 3 is for worker_id and option_length\n bytes memory opt = _options.slice(start, len);\n _insertDVNOptions(dvnOptions, dvnIndices, lastDVNIdx, opt);\n\n // reset the start and lastDVNIdx\n start += len;\n lastDVNIdx = dvnIdx;\n }\n\n cursor += optionLength;\n }\n\n // skip check the cursor here because the cursor is asserted in getNumDVNs\n // if we have reached the end of the options, we need to process the last dvn\n uint256 size = cursor - start;\n bytes memory op = _options.slice(start, size);\n _insertDVNOptions(dvnOptions, dvnIndices, lastDVNIdx, op);\n\n // revert dvnIndices to start from 0\n for (uint8 i = 0; i < numDVNs; ++i) {\n --dvnIndices[i];\n }\n }\n }\n\n function _insertDVNOptions(\n bytes[] memory _dvnOptions,\n uint8[] memory _dvnIndices,\n uint8 _dvnIdx,\n bytes memory _newOptions\n ) internal pure {\n // dvnIdx starts from 0 but default value of dvnIndices is 0,\n // so we tell if the slot is empty by adding 1 to dvnIdx\n if (_dvnIdx == 255) revert DVN_InvalidDVNIdx();\n uint8 dvnIdxAdj = _dvnIdx + 1;\n\n for (uint256 j = 0; j < _dvnIndices.length; ++j) {\n uint8 index = _dvnIndices[j];\n if (dvnIdxAdj == index) {\n _dvnOptions[j] = abi.encodePacked(_dvnOptions[j], _newOptions);\n break;\n } else if (index == 0) {\n // empty slot, that means it is the first time we see this dvn\n _dvnIndices[j] = dvnIdxAdj;\n _dvnOptions[j] = _newOptions;\n break;\n }\n }\n }\n\n /// @dev get the number of unique dvns\n /// @param _options the format is the same as groupDVNOptionsByIdx\n function getNumDVNs(bytes memory _options) internal pure returns (uint8 numDVNs) {\n uint256 cursor = 0;\n BitMap256 bitmap;\n\n // find number of unique dvn_idx\n unchecked {\n while (cursor < _options.length) {\n ++cursor; // skip worker_id\n\n uint16 optionLength = _options.toUint16(cursor);\n cursor += 2;\n if (optionLength < 2) revert DVN_InvalidDVNOptions(cursor); // at least 1 byte for dvn_idx and 1 byte for option_type\n\n uint8 dvnIdx = _options.toUint8(cursor);\n\n // if dvnIdx is not set, increment numDVNs\n // max num of dvns is 255, 255 is an invalid dvn_idx\n // The order of the dvnIdx is not required to be sequential, as enforcing the order may weaken\n // the composability of the options. e.g. if we refrain from enforcing the order, an OApp that has\n // already enforced certain options can append additional options to the end of the enforced\n // ones without restrictions.\n if (dvnIdx == 255) revert DVN_InvalidDVNIdx();\n if (!bitmap.get(dvnIdx)) {\n ++numDVNs;\n bitmap = bitmap.set(dvnIdx);\n }\n\n cursor += optionLength;\n }\n }\n if (cursor != _options.length) revert DVN_InvalidDVNOptions(cursor);\n }\n\n /// @dev decode the next dvn option from _options starting from the specified cursor\n /// @param _options the format is the same as groupDVNOptionsByIdx\n /// @param _cursor the cursor to start decoding\n /// @return optionType the type of the option\n /// @return option the option\n /// @return cursor the cursor to start decoding the next option\n function nextDVNOption(\n bytes calldata _options,\n uint256 _cursor\n ) internal pure returns (uint8 optionType, bytes calldata option, uint256 cursor) {\n unchecked {\n // skip worker id\n cursor = _cursor + 1;\n\n // read option size\n uint16 size = _options.toU16(cursor);\n cursor += 2;\n\n // read option type\n optionType = _options.toU8(cursor + 1); // skip dvn_idx\n\n // startCursor and endCursor are used to slice the option from _options\n uint256 startCursor = cursor + 2; // skip option type and dvn_idx\n uint256 endCursor = cursor + size;\n option = _options[startCursor:endCursor];\n cursor += size;\n }\n }\n}\n"},"lib/openzeppelin-contracts-upgradeable/contracts/utils/ContextUpgradeable.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.4) (utils/Context.sol)\n\npragma solidity ^0.8.0;\nimport {Initializable} from \"../proxy/utils/Initializable.sol\";\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 ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\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 /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n"},"lib/openzeppelin-contracts-upgradeable/contracts/utils/AddressUpgradeable.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n *\n * Furthermore, `isContract` will also return true if the target contract within\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\n * which only has an effect at the end of a transaction.\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\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.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\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, it is bubbled up by this\n * function (like regular Solidity function calls).\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 * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\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 * _Available since v3.1._\n */\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\n *\n * _Available since v4.8._\n */\n function verifyCallResultFromTarget(\n address target,\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n if (success) {\n if (returndata.length == 0) {\n // only check isContract if the call was successful and the return data is empty\n // otherwise we already know that it was a contract\n require(isContract(target), \"Address: call to non-contract\");\n }\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n /**\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason or using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n function _revert(bytes memory returndata, string memory errorMessage) 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(errorMessage);\n }\n }\n}\n"},"lib/openzeppelin-contracts/contracts/token/ERC20/utils/SafeERC20.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\nimport \"../extensions/IERC20Permit.sol\";\nimport \"../../../utils/Address.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n using Address for address;\n\n /**\n * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\n * non-reverting calls are assumed to be successful.\n */\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n /**\n * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the\n * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.\n */\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n }\n\n /**\n * @dev Deprecated. This function has issues similar to the ones found in\n * {IERC20-approve}, and its usage is discouraged.\n *\n * Whenever possible, use {safeIncreaseAllowance} and\n * {safeDecreaseAllowance} instead.\n */\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\n // safeApprove should only be called when setting an initial allowance,\n // or when resetting it to zero. To increase and decrease it, use\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\n require(\n (value == 0) || (token.allowance(address(this), spender) == 0),\n \"SafeERC20: approve from non-zero to non-zero allowance\"\n );\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n }\n\n /**\n * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\n * non-reverting calls are assumed to be successful.\n */\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n uint256 oldAllowance = token.allowance(address(this), spender);\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));\n }\n\n /**\n * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\n * non-reverting calls are assumed to be successful.\n */\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n unchecked {\n uint256 oldAllowance = token.allowance(address(this), spender);\n require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));\n }\n }\n\n /**\n * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\n * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval\n * to be set to zero before setting it to a non-zero value, such as USDT.\n */\n function forceApprove(IERC20 token, address spender, uint256 value) internal {\n bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);\n\n if (!_callOptionalReturnBool(token, approvalCall)) {\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));\n _callOptionalReturn(token, approvalCall);\n }\n }\n\n /**\n * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.\n * Revert on invalid signature.\n */\n function safePermit(\n IERC20Permit token,\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal {\n uint256 nonceBefore = token.nonces(owner);\n token.permit(owner, spender, value, deadline, v, r, s);\n uint256 nonceAfter = token.nonces(owner);\n require(nonceAfter == nonceBefore + 1, \"SafeERC20: permit did not succeed\");\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n */\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that\n // the target address contains contract code and also asserts for success in the low-level call.\n\n bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n require(returndata.length == 0 || abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n *\n * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.\n */\n function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false\n // and not revert is the subcall reverts.\n\n (bool success, bytes memory returndata) = address(token).call(data);\n return\n success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token));\n }\n}\n"},"lib/LayerZero-v2/protocol/contracts/interfaces/IMessageLibManager.sol":{"content":"// SPDX-License-Identifier: MIT\n\npragma solidity >=0.8.0;\n\nstruct SetConfigParam {\n uint32 eid;\n uint32 configType;\n bytes config;\n}\n\ninterface IMessageLibManager {\n struct Timeout {\n address lib;\n uint256 expiry;\n }\n\n event LibraryRegistered(address newLib);\n event DefaultSendLibrarySet(uint32 eid, address newLib);\n event DefaultReceiveLibrarySet(uint32 eid, address newLib);\n event DefaultReceiveLibraryTimeoutSet(uint32 eid, address oldLib, uint256 expiry);\n event SendLibrarySet(address sender, uint32 eid, address newLib);\n event ReceiveLibrarySet(address receiver, uint32 eid, address newLib);\n event ReceiveLibraryTimeoutSet(address receiver, uint32 eid, address oldLib, uint256 timeout);\n\n function registerLibrary(address _lib) external;\n\n function isRegisteredLibrary(address _lib) external view returns (bool);\n\n function getRegisteredLibraries() external view returns (address[] memory);\n\n function setDefaultSendLibrary(uint32 _eid, address _newLib) external;\n\n function defaultSendLibrary(uint32 _eid) external view returns (address);\n\n function setDefaultReceiveLibrary(uint32 _eid, address _newLib, uint256 _timeout) external;\n\n function defaultReceiveLibrary(uint32 _eid) external view returns (address);\n\n function setDefaultReceiveLibraryTimeout(uint32 _eid, address _lib, uint256 _expiry) external;\n\n function defaultReceiveLibraryTimeout(uint32 _eid) external view returns (address lib, uint256 expiry);\n\n function isSupportedEid(uint32 _eid) external view returns (bool);\n\n function isValidReceiveLibrary(address _receiver, uint32 _eid, address _lib) external view returns (bool);\n\n /// ------------------- OApp interfaces -------------------\n function setSendLibrary(address _oapp, uint32 _eid, address _newLib) external;\n\n function getSendLibrary(address _sender, uint32 _eid) external view returns (address lib);\n\n function isDefaultSendLibrary(address _sender, uint32 _eid) external view returns (bool);\n\n function setReceiveLibrary(address _oapp, uint32 _eid, address _newLib, uint256 _gracePeriod) external;\n\n function getReceiveLibrary(address _receiver, uint32 _eid) external view returns (address lib, bool isDefault);\n\n function setReceiveLibraryTimeout(address _oapp, uint32 _eid, address _lib, uint256 _gracePeriod) external;\n\n function receiveLibraryTimeout(address _receiver, uint32 _eid) external view returns (address lib, uint256 expiry);\n\n function setConfig(address _oapp, address _lib, SetConfigParam[] calldata _params) external;\n\n function getConfig(\n address _oapp,\n address _lib,\n uint32 _eid,\n uint32 _configType\n ) external view returns (bytes memory config);\n}\n"},"lib/LayerZero-v2/protocol/contracts/interfaces/IMessagingComposer.sol":{"content":"// SPDX-License-Identifier: MIT\n\npragma solidity >=0.8.0;\n\ninterface IMessagingComposer {\n event ComposeSent(address from, address to, bytes32 guid, uint16 index, bytes message);\n event ComposeDelivered(address from, address to, bytes32 guid, uint16 index);\n event LzComposeAlert(\n address indexed from,\n address indexed to,\n address indexed executor,\n bytes32 guid,\n uint16 index,\n uint256 gas,\n uint256 value,\n bytes message,\n bytes extraData,\n bytes reason\n );\n\n function composeQueue(\n address _from,\n address _to,\n bytes32 _guid,\n uint16 _index\n ) external view returns (bytes32 messageHash);\n\n function sendCompose(address _to, bytes32 _guid, uint16 _index, bytes calldata _message) external;\n\n function lzCompose(\n address _from,\n address _to,\n bytes32 _guid,\n uint16 _index,\n bytes calldata _message,\n bytes calldata _extraData\n ) external payable;\n}\n"},"lib/LayerZero-v2/protocol/contracts/interfaces/IMessagingChannel.sol":{"content":"// SPDX-License-Identifier: MIT\n\npragma solidity >=0.8.0;\n\ninterface IMessagingChannel {\n event InboundNonceSkipped(uint32 srcEid, bytes32 sender, address receiver, uint64 nonce);\n event PacketNilified(uint32 srcEid, bytes32 sender, address receiver, uint64 nonce, bytes32 payloadHash);\n event PacketBurnt(uint32 srcEid, bytes32 sender, address receiver, uint64 nonce, bytes32 payloadHash);\n\n function eid() external view returns (uint32);\n\n // this is an emergency function if a message cannot be verified for some reasons\n // required to provide _nextNonce to avoid race condition\n function skip(address _oapp, uint32 _srcEid, bytes32 _sender, uint64 _nonce) external;\n\n function nilify(address _oapp, uint32 _srcEid, bytes32 _sender, uint64 _nonce, bytes32 _payloadHash) external;\n\n function burn(address _oapp, uint32 _srcEid, bytes32 _sender, uint64 _nonce, bytes32 _payloadHash) external;\n\n function nextGuid(address _sender, uint32 _dstEid, bytes32 _receiver) external view returns (bytes32);\n\n function inboundNonce(address _receiver, uint32 _srcEid, bytes32 _sender) external view returns (uint64);\n\n function outboundNonce(address _sender, uint32 _dstEid, bytes32 _receiver) external view returns (uint64);\n\n function inboundPayloadHash(\n address _receiver,\n uint32 _srcEid,\n bytes32 _sender,\n uint64 _nonce\n ) external view returns (bytes32);\n\n function lazyInboundNonce(address _receiver, uint32 _srcEid, bytes32 _sender) external view returns (uint64);\n}\n"},"lib/LayerZero-v2/protocol/contracts/interfaces/IMessagingContext.sol":{"content":"// SPDX-License-Identifier: MIT\n\npragma solidity >=0.8.0;\n\ninterface IMessagingContext {\n function isSendingMessage() external view returns (bool);\n\n function getSendContext() external view returns (uint32 dstEid, address sender);\n}\n"},"lib/LayerZero-v2/protocol/contracts/libs/CalldataBytesLib.sol":{"content":"// SPDX-License-Identifier: LZBL-1.2\n\npragma solidity ^0.8.20;\n\nlibrary CalldataBytesLib {\n function toU8(bytes calldata _bytes, uint256 _start) internal pure returns (uint8) {\n return uint8(_bytes[_start]);\n }\n\n function toU16(bytes calldata _bytes, uint256 _start) internal pure returns (uint16) {\n unchecked {\n uint256 end = _start + 2;\n return uint16(bytes2(_bytes[_start:end]));\n }\n }\n\n function toU32(bytes calldata _bytes, uint256 _start) internal pure returns (uint32) {\n unchecked {\n uint256 end = _start + 4;\n return uint32(bytes4(_bytes[_start:end]));\n }\n }\n\n function toU64(bytes calldata _bytes, uint256 _start) internal pure returns (uint64) {\n unchecked {\n uint256 end = _start + 8;\n return uint64(bytes8(_bytes[_start:end]));\n }\n }\n\n function toU128(bytes calldata _bytes, uint256 _start) internal pure returns (uint128) {\n unchecked {\n uint256 end = _start + 16;\n return uint128(bytes16(_bytes[_start:end]));\n }\n }\n\n function toU256(bytes calldata _bytes, uint256 _start) internal pure returns (uint256) {\n unchecked {\n uint256 end = _start + 32;\n return uint256(bytes32(_bytes[_start:end]));\n }\n }\n\n function toAddr(bytes calldata _bytes, uint256 _start) internal pure returns (address) {\n unchecked {\n uint256 end = _start + 20;\n return address(bytes20(_bytes[_start:end]));\n }\n }\n\n function toB32(bytes calldata _bytes, uint256 _start) internal pure returns (bytes32) {\n unchecked {\n uint256 end = _start + 32;\n return bytes32(_bytes[_start:end]);\n }\n }\n}\n"},"lib/LayerZero-v2/protocol/contracts/messagelib/libs/BitMaps.sol":{"content":"// SPDX-License-Identifier: MIT\n\n// modified from https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/structs/BitMaps.sol\npragma solidity ^0.8.20;\n\ntype BitMap256 is uint256;\n\nusing BitMaps for BitMap256 global;\n\nlibrary BitMaps {\n /**\n * @dev Returns whether the bit at `index` is set.\n */\n function get(BitMap256 bitmap, uint8 index) internal pure returns (bool) {\n uint256 mask = 1 << index;\n return BitMap256.unwrap(bitmap) & mask != 0;\n }\n\n /**\n * @dev Sets the bit at `index`.\n */\n function set(BitMap256 bitmap, uint8 index) internal pure returns (BitMap256) {\n uint256 mask = 1 << index;\n return BitMap256.wrap(BitMap256.unwrap(bitmap) | mask);\n }\n}\n"},"lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\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 amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` 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 amount) 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 `amount` as the allowance of `spender` over the 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 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` 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 amount) external returns (bool);\n}\n"},"lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Permit.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.4) (token/ERC20/extensions/IERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n *\n * ==== Security Considerations\n *\n * There are two important considerations concerning the use of `permit`. The first is that a valid permit signature\n * expresses an allowance, and it should not be assumed to convey additional meaning. In particular, it should not be\n * considered as an intention to spend the allowance in any specific way. The second is that because permits have\n * built-in replay protection and can be submitted by anyone, they can be frontrun. A protocol that uses permits should\n * take this into consideration and allow a `permit` call to fail. Combining these two aspects, a pattern that may be\n * generally recommended is:\n *\n * ```solidity\n * function doThingWithPermit(..., uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public {\n * try token.permit(msg.sender, address(this), value, deadline, v, r, s) {} catch {}\n * doThing(..., value);\n * }\n *\n * function doThing(..., uint256 value) public {\n * token.safeTransferFrom(msg.sender, address(this), value);\n * ...\n * }\n * ```\n *\n * Observe that: 1) `msg.sender` is used as the owner, leaving no ambiguity as to the signer intent, and 2) the use of\n * `try/catch` allows the permit to fail and makes the code tolerant to frontrunning. (See also\n * {SafeERC20-safeTransferFrom}).\n *\n * Additionally, note that smart contract wallets (such as Argent or Safe) are not able to produce permit signatures, so\n * contracts should have entry points that don't rely on permit.\n */\ninterface IERC20Permit {\n /**\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\n * given ``owner``'s signed approval.\n *\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\n * ordering also apply here.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `deadline` must be a timestamp in the future.\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\n * over the EIP712-formatted function arguments.\n * - the signature must use ``owner``'s current nonce (see {nonces}).\n *\n * For more information on the signature format, see the\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\n * section].\n *\n * CAUTION: See Security Considerations above.\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n\n /**\n * @dev Returns the current nonce for `owner`. This value must be\n * included whenever a signature is generated for {permit}.\n *\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\n * prevents a signature from being used multiple times.\n */\n function nonces(address owner) external view returns (uint256);\n\n /**\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n"},"lib/openzeppelin-contracts/contracts/utils/Address.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n *\n * Furthermore, `isContract` will also return true if the target contract within\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\n * which only has an effect at the end of a transaction.\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\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.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\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, it is bubbled up by this\n * function (like regular Solidity function calls).\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 * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\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 * _Available since v3.1._\n */\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\n *\n * _Available since v4.8._\n */\n function verifyCallResultFromTarget(\n address target,\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n if (success) {\n if (returndata.length == 0) {\n // only check isContract if the call was successful and the return data is empty\n // otherwise we already know that it was a contract\n require(isContract(target), \"Address: call to non-contract\");\n }\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n /**\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason or using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n function _revert(bytes memory returndata, string memory errorMessage) 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(errorMessage);\n }\n }\n}\n"}},"settings":{"remappings":["ds-test/=lib/forge-std/lib/ds-test/src/","forge-std/=lib/forge-std/src/","@layerzero-contracts/=lib/solidity-examples/contracts/","@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/","@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/","@layerzero-v2/=lib/LayerZero-v2/","@layerzerolabs/lz-evm-protocol-v2/=lib/LayerZero-v2/protocol/","@layerzerolabs/lz-evm-oapp-v2/=lib/LayerZero-v2/oapp/","@layerzerolabs/lz-evm-messagelib-v2/=lib/LayerZero-v2/messagelib/","@beacon-oracle/=lib/eigenlayer-beacon-oracle/","solidity-bytes-utils/=lib/solidity-bytes-utils/","LayerZero-v2/=lib/LayerZero-v2/","LayerZero/=lib/LayerZero/contracts/","eigenlayer-beacon-oracle/=lib/eigenlayer-beacon-oracle/contracts/","erc4626-tests/=lib/openzeppelin-contracts-upgradeable/lib/erc4626-tests/","openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/","openzeppelin-contracts/=lib/openzeppelin-contracts/","openzeppelin/=lib/openzeppelin-contracts-upgradeable/contracts/","solidity-examples/=lib/solidity-examples/contracts/"],"optimizer":{"enabled":true,"runs":200},"metadata":{"useLiteralContent":false,"bytecodeHash":"ipfs","appendCBOR":true},"outputSelection":{"*":{"*":["abi","evm.bytecode","evm.deployedBytecode","evm.methodIdentifiers","metadata"]}},"evmVersion":"paris","viaIR":false,"libraries":{}}} From ad21b9ea4335942cae71c9d2eec62e066710c8cf Mon Sep 17 00:00:00 2001 From: adu Date: Mon, 29 Jul 2024 15:55:05 +0800 Subject: [PATCH 4/4] remove _isActivatedAtEpoch --- src/core/ExoCapsule.sol | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/src/core/ExoCapsule.sol b/src/core/ExoCapsule.sol index 2c9d06a1..c7255fbc 100644 --- a/src/core/ExoCapsule.sol +++ b/src/core/ExoCapsule.sol @@ -396,20 +396,6 @@ contract ExoCapsule is ReentrancyGuardUpgradeable, ExoCapsuleStorage, IExoCapsul } } - /// @dev Checks if the validator is activated at the given epoch. - /// @param validatorContainer The validator container. - /// @param atTimestamp The timestamp at which the activation is checked. - function _isActivatedAtEpoch(bytes32[] calldata validatorContainer, uint256 atTimestamp) - internal - pure - returns (bool) - { - uint64 atEpoch = _timestampToEpoch(atTimestamp); - uint64 activationEpoch = validatorContainer.getActivationEpoch(); - - return atEpoch >= activationEpoch; - } - /// @dev Checks if the proof is stale (too old). /// @param validator The validator to check. /// @param proofTimestamp The timestamp of the proof.