{"file_path":"src/machine/Machine.sol","creation_status":"success","source_code":"// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.28;\n\nimport {EnumerableMap} from \"@openzeppelin/contracts/utils/structs/EnumerableMap.sol\";\nimport {EnumerableSet} from \"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\";\nimport {IERC20Metadata} from \"@openzeppelin/contracts/interfaces/IERC20Metadata.sol\";\nimport {Math} from \"@openzeppelin/contracts/utils/math/Math.sol\";\nimport {ReentrancyGuard} from \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\nimport {SafeERC20} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\nimport {IBridgeAdapter} from \"../interfaces/IBridgeAdapter.sol\";\nimport {IBridgeController} from \"../interfaces/IBridgeController.sol\";\nimport {ICaliber} from \"../interfaces/ICaliber.sol\";\nimport {ICreReceiver} from \"../interfaces/ICreReceiver.sol\";\nimport {IHubCoreRegistry} from \"../interfaces/IHubCoreRegistry.sol\";\nimport {IMachine} from \"../interfaces/IMachine.sol\";\nimport {IMachineEndpoint} from \"../interfaces/IMachineEndpoint.sol\";\nimport {IMachineShare} from \"../interfaces/IMachineShare.sol\";\nimport {IOracleRegistry} from \"../interfaces/IOracleRegistry.sol\";\nimport {IOwnable2Step} from \"../interfaces/IOwnable2Step.sol\";\nimport {BridgeController} from \"../bridge/controller/BridgeController.sol\";\nimport {Errors} from \"../libraries/Errors.sol\";\nimport {DecimalsUtils} from \"../libraries/DecimalsUtils.sol\";\nimport {MachineUtils} from \"../libraries/MachineUtils.sol\";\nimport {MakinaContext} from \"../utils/MakinaContext.sol\";\nimport {MakinaGovernable} from \"../utils/MakinaGovernable.sol\";\nimport {SpokeSnapshotConsumer} from \"../utils/SpokeSnapshotConsumer.sol\";\n\ncontract Machine is MakinaGovernable, BridgeController, SpokeSnapshotConsumer, ReentrancyGuard, IMachine {\n    using Math for uint256;\n    using SafeERC20 for IERC20Metadata;\n    using EnumerableSet for EnumerableSet.AddressSet;\n    using EnumerableMap for EnumerableMap.AddressToUintMap;\n\n    /// @custom:storage-location erc7201:makina.storage.Machine\n    struct MachineStorage {\n        address _shareToken;\n        address _accountingToken;\n        address _depositor;\n        address _redeemer;\n        address _feeManager;\n        uint256 _caliberStaleThreshold;\n        uint256 _lastTotalAum;\n        uint256 _lastGlobalAccountingTime;\n        uint256 _lastMintedFeesTime;\n        uint256 _lastMintedFeesSharePrice;\n        uint256 _maxFixedFeeAccrualRate;\n        uint256 _maxPerfFeeAccrualRate;\n        uint256 _feeMintCooldown;\n        uint256 _shareTokenDecimalsOffset;\n        uint256 _shareLimit;\n        uint256 _hubChainId;\n        address _hubCaliber;\n        uint256[] _spokeChainIds;\n        mapping(uint256 chainId => SpokeCaliberData data) _spokeCalibersData;\n        EnumerableSet.AddressSet _idleTokens;\n        uint256 _maxSharePriceChangeRate;\n    }\n\n    // keccak256(abi.encode(uint256(keccak256(\"makina.storage.Machine\")) - 1)) & ~bytes32(uint256(0xff))\n    bytes32 private constant MachineStorageLocation =\n        0x55fe2a17e400bcd0e2125123a7fc955478e727b29a4c522f4f2bd95d961bd900;\n\n    function _getMachineStorage() private pure returns (MachineStorage storage $) {\n        assembly {\n            $.slot := MachineStorageLocation\n        }\n    }\n\n    constructor(address _registry, address _creForwarder)\n        MakinaContext(_registry)\n        SpokeSnapshotConsumer(_creForwarder)\n    {\n        _disableInitializers();\n    }\n\n    /// @inheritdoc IMachine\n    function initialize(\n        MachineInitParams calldata mParams,\n        MakinaGovernableInitParams calldata mgParams,\n        SpokeSnapshotConsumerInitParams calldata sscParams,\n        address _preDepositVault,\n        address _shareToken,\n        address _accountingToken,\n        address _hubCaliber\n    ) external override initializer {\n        MachineStorage storage $ = _getMachineStorage();\n\n        $._hubChainId = block.chainid;\n        $._hubCaliber = _hubCaliber;\n\n        address oracleRegistry = IHubCoreRegistry(registry).oracleRegistry();\n        if (!IOracleRegistry(oracleRegistry).isFeedRouteRegistered(_accountingToken)) {\n            revert Errors.PriceFeedRouteNotRegistered(_accountingToken);\n        }\n\n        uint256 atDecimals = IERC20Metadata(_accountingToken).decimals();\n\n        $._shareToken = _shareToken;\n        $._accountingToken = _accountingToken;\n        $._idleTokens.add(_accountingToken);\n        $._shareTokenDecimalsOffset = DecimalsUtils.SHARE_TOKEN_DECIMALS - atDecimals;\n\n        if (_preDepositVault != address(0)) {\n            MachineUtils.migrateFromPreDeposit($, _preDepositVault, oracleRegistry);\n            uint256 currentShareSupply = IERC20Metadata($._shareToken).totalSupply();\n            $._lastMintedFeesSharePrice =\n                MachineUtils.getSharePrice($._lastTotalAum, currentShareSupply, $._shareTokenDecimalsOffset);\n        } else {\n            $._lastMintedFeesSharePrice = 10 ** atDecimals;\n        }\n\n        IOwnable2Step(_shareToken).acceptOwnership();\n\n        $._lastGlobalAccountingTime = block.timestamp;\n        $._lastMintedFeesTime = block.timestamp;\n        $._depositor = mParams.initialDepositor;\n        $._redeemer = mParams.initialRedeemer;\n        $._feeManager = mParams.initialFeeManager;\n        $._caliberStaleThreshold = mParams.initialCaliberStaleThreshold;\n        $._maxFixedFeeAccrualRate = mParams.initialMaxFixedFeeAccrualRate;\n        $._maxPerfFeeAccrualRate = mParams.initialMaxPerfFeeAccrualRate;\n        $._feeMintCooldown = mParams.initialFeeMintCooldown;\n        $._shareLimit = mParams.initialShareLimit;\n        $._maxSharePriceChangeRate = mParams.initialMaxSharePriceChangeRate;\n        __MakinaGovernable_init(mgParams);\n        __SpokeSnapshotConsumer_init(sscParams);\n    }\n\n    /// @inheritdoc IMachine\n    function depositor() external view override returns (address) {\n        return _getMachineStorage()._depositor;\n    }\n\n    /// @inheritdoc IMachine\n    function redeemer() external view override returns (address) {\n        return _getMachineStorage()._redeemer;\n    }\n\n    /// @inheritdoc IMachine\n    function shareToken() external view override returns (address) {\n        return _getMachineStorage()._shareToken;\n    }\n\n    /// @inheritdoc IMachine\n    function accountingToken() external view override returns (address) {\n        return _getMachineStorage()._accountingToken;\n    }\n\n    /// @inheritdoc IMachine\n    function hubCaliber() external view override returns (address) {\n        return _getMachineStorage()._hubCaliber;\n    }\n\n    /// @inheritdoc IMachine\n    function feeManager() external view override returns (address) {\n        return _getMachineStorage()._feeManager;\n    }\n\n    /// @inheritdoc IMachine\n    function caliberStaleThreshold() external view override returns (uint256) {\n        return _getMachineStorage()._caliberStaleThreshold;\n    }\n\n    /// @inheritdoc IMachine\n    function maxFixedFeeAccrualRate() external view override returns (uint256) {\n        return _getMachineStorage()._maxFixedFeeAccrualRate;\n    }\n\n    /// @inheritdoc IMachine\n    function maxPerfFeeAccrualRate() external view override returns (uint256) {\n        return _getMachineStorage()._maxPerfFeeAccrualRate;\n    }\n\n    /// @inheritdoc IMachine\n    function feeMintCooldown() external view override returns (uint256) {\n        return _getMachineStorage()._feeMintCooldown;\n    }\n\n    /// @inheritdoc IMachine\n    function shareLimit() external view override returns (uint256) {\n        return _getMachineStorage()._shareLimit;\n    }\n\n    /// @inheritdoc IMachine\n    function maxSharePriceChangeRate() external view override returns (uint256) {\n        return _getMachineStorage()._maxSharePriceChangeRate;\n    }\n\n    /// @inheritdoc IMachine\n    function maxMint() public view override returns (uint256) {\n        MachineStorage storage $ = _getMachineStorage();\n        if ($._shareLimit == type(uint256).max) {\n            return type(uint256).max;\n        }\n        uint256 totalSupply = IERC20Metadata($._shareToken).totalSupply();\n        return totalSupply < $._shareLimit ? $._shareLimit - totalSupply : 0;\n    }\n\n    /// @inheritdoc IMachine\n    function maxWithdraw() public view override returns (uint256) {\n        MachineStorage storage $ = _getMachineStorage();\n        return IERC20Metadata($._accountingToken).balanceOf(address(this));\n    }\n\n    /// @inheritdoc IMachine\n    function lastTotalAum() external view override returns (uint256) {\n        return _getMachineStorage()._lastTotalAum;\n    }\n\n    /// @inheritdoc IMachine\n    function lastGlobalAccountingTime() external view override returns (uint256) {\n        return _getMachineStorage()._lastGlobalAccountingTime;\n    }\n\n    /// @inheritdoc IMachine\n    function getSpokeCalibersLength() external view override returns (uint256) {\n        return _getMachineStorage()._spokeChainIds.length;\n    }\n\n    /// @inheritdoc IMachine\n    function getSpokeChainId(uint256 idx) external view override returns (uint256) {\n        return _getMachineStorage()._spokeChainIds[idx];\n    }\n\n    /// @inheritdoc IMachine\n    function getSpokeCaliberNetAum(uint256 chainId) external view override returns (uint256, uint256) {\n        SpokeCaliberData storage scData = _getMachineStorage()._spokeCalibersData[chainId];\n        if (scData.mailbox == address(0)) {\n            revert Errors.InvalidChainId();\n        }\n        return (scData.netAum, scData.timestamp);\n    }\n\n    /// @inheritdoc IMachine\n    function getSpokeCaliberMailbox(uint256 chainId) external view override returns (address) {\n        SpokeCaliberData storage scData = _getMachineStorage()._spokeCalibersData[chainId];\n        if (scData.mailbox == address(0)) {\n            revert Errors.InvalidChainId();\n        }\n        return scData.mailbox;\n    }\n\n    /// @inheritdoc IMachine\n    function isSpokeCaliberEnabled(uint256 chainId) external view override returns (bool) {\n        SpokeCaliberData storage scData = _getMachineStorage()._spokeCalibersData[chainId];\n        if (scData.mailbox == address(0)) {\n            revert Errors.InvalidChainId();\n        }\n        return !scData.disabled;\n    }\n\n    /// @inheritdoc IMachine\n    function getSpokeBridgeAdapter(uint256 chainId, uint16 bridgeId) external view override returns (address) {\n        SpokeCaliberData storage scData = _getMachineStorage()._spokeCalibersData[chainId];\n        if (scData.mailbox == address(0)) {\n            revert Errors.InvalidChainId();\n        }\n        address adapter = scData.bridgeAdapters[bridgeId];\n        if (adapter == address(0)) {\n            revert Errors.SpokeBridgeAdapterNotSet();\n        }\n        return adapter;\n    }\n\n    /// @inheritdoc IMachine\n    function isIdleToken(address token) external view override returns (bool) {\n        return _getMachineStorage()._idleTokens.contains(token);\n    }\n\n    /// @inheritdoc IMachine\n    function getIdleTokensLength() external view override returns (uint256) {\n        return _getMachineStorage()._idleTokens.length();\n    }\n\n    /// @inheritdoc IMachine\n    function getIdleToken(uint256 idx) external view override returns (address) {\n        return _getMachineStorage()._idleTokens.at(idx);\n    }\n\n    /// @inheritdoc IMachine\n    function convertToShares(uint256 assets) public view override returns (uint256) {\n        MachineStorage storage $ = _getMachineStorage();\n        return assets.mulDiv(\n            IERC20Metadata($._shareToken).totalSupply() + 10 ** $._shareTokenDecimalsOffset, $._lastTotalAum + 1\n        );\n    }\n\n    /// @inheritdoc IMachine\n    function convertToAssets(uint256 shares) public view override returns (uint256) {\n        MachineStorage storage $ = _getMachineStorage();\n        return shares.mulDiv(\n            $._lastTotalAum + 1, IERC20Metadata($._shareToken).totalSupply() + 10 ** $._shareTokenDecimalsOffset\n        );\n    }\n\n    /// @inheritdoc IMachineEndpoint\n    function manageTransfer(address token, uint256 amount, bytes calldata data) external override nonReentrant {\n        MachineStorage storage $ = _getMachineStorage();\n\n        if (_isBridgeAdapter(msg.sender)) {\n            (uint256 chainId, uint256 inputAmount, bool refund) = abi.decode(data, (uint256, uint256, bool));\n\n            SpokeCaliberData storage caliberData = $._spokeCalibersData[chainId];\n\n            if (caliberData.mailbox == address(0)) {\n                revert Errors.InvalidChainId();\n            }\n\n            if (refund) {\n                uint256 mOut = caliberData.machineBridgesOut.get(token);\n                uint256 newMOut = mOut - inputAmount;\n                (, uint256 cIn) = caliberData.caliberBridgesIn.tryGet(token);\n                if (cIn > newMOut) {\n                    revert Errors.BridgeStateMismatch();\n                }\n                caliberData.machineBridgesOut.set(token, newMOut);\n            } else {\n                (, uint256 mIn) = caliberData.machineBridgesIn.tryGet(token);\n                uint256 newMIn = mIn + inputAmount;\n                (, uint256 cOut) = caliberData.caliberBridgesOut.tryGet(token);\n                if (newMIn > cOut) {\n                    revert Errors.BridgeStateMismatch();\n                }\n                caliberData.machineBridgesIn.set(token, newMIn);\n            }\n        } else if (msg.sender != $._hubCaliber) {\n            revert Errors.UnauthorizedCaller();\n        }\n\n        IERC20Metadata(token).safeTransferFrom(msg.sender, address(this), amount);\n        _notifyIdleToken(token);\n    }\n\n    /// @inheritdoc IMachine\n    function transferToHubCaliber(address token, uint256 amount) external override notRecoveryMode onlyMechanic {\n        MachineStorage storage $ = _getMachineStorage();\n\n        IERC20Metadata(token).forceApprove($._hubCaliber, amount);\n        ICaliber($._hubCaliber).notifyIncomingTransfer(token, amount);\n\n        emit TransferToCaliber($._hubChainId, token, amount);\n\n        if (IERC20Metadata(token).balanceOf(address(this)) == 0 && token != $._accountingToken) {\n            $._idleTokens.remove(token);\n        }\n    }\n\n    /// @inheritdoc IMachine\n    function transferToSpokeCaliber(\n        uint16 bridgeId,\n        uint256 chainId,\n        address token,\n        uint256 amount,\n        uint256 minOutputAmount\n    ) external override nonReentrant notRecoveryMode onlyMechanic {\n        MachineStorage storage $ = _getMachineStorage();\n        SpokeCaliberData storage caliberData = $._spokeCalibersData[chainId];\n\n        if (caliberData.mailbox == address(0)) {\n            revert Errors.InvalidChainId();\n        }\n\n        if (caliberData.disabled) {\n            revert Errors.SpokeCaliberNotEnabled();\n        }\n\n        address recipient = caliberData.bridgeAdapters[bridgeId];\n        if (recipient == address(0)) {\n            revert Errors.SpokeBridgeAdapterNotSet();\n        }\n\n        (bool exists, uint256 mOut) = caliberData.machineBridgesOut.tryGet(token);\n        (, uint256 cIn) = caliberData.caliberBridgesIn.tryGet(token);\n        if (mOut > cIn) {\n            revert Errors.PendingBridgeTransfer();\n        } else if (mOut < cIn) {\n            revert Errors.BridgeStateMismatch();\n        }\n        caliberData.machineBridgesOut.set(token, exists ? mOut + amount : amount);\n\n        _scheduleOutBridgeTransfer(bridgeId, chainId, recipient, token, amount, minOutputAmount);\n\n        emit TransferToCaliber(chainId, token, amount);\n\n        if (IERC20Metadata(token).balanceOf(address(this)) == 0 && token != $._accountingToken) {\n            $._idleTokens.remove(token);\n        }\n    }\n\n    /// @inheritdoc IBridgeController\n    function sendOutBridgeTransfer(uint16 bridgeId, uint256 transferId, bytes calldata data)\n        external\n        override\n        notRecoveryMode\n        onlyMechanic\n    {\n        _sendOutBridgeTransfer(bridgeId, transferId, data);\n    }\n\n    /// @inheritdoc IBridgeController\n    function authorizeInBridgeTransfer(uint16 bridgeId, bytes32 messageHash) external override onlyOperator {\n        _authorizeInBridgeTransfer(bridgeId, messageHash);\n    }\n\n    /// @inheritdoc IBridgeController\n    function claimInBridgeTransfer(uint16 bridgeId, uint256 transferId) external override onlyOperator {\n        _claimInBridgeTransfer(bridgeId, transferId);\n    }\n\n    /// @inheritdoc IBridgeController\n    function cancelOutBridgeTransfer(uint16 bridgeId, uint256 transferId) external override onlyOperator {\n        _cancelOutBridgeTransfer(bridgeId, transferId);\n    }\n\n    /// @inheritdoc IMachine\n    function updateTotalAum() external override nonReentrant onlyAccountingAuthorized returns (uint256) {\n        MachineStorage storage $ = _getMachineStorage();\n\n        uint256 _lastTotalAum = MachineUtils.updateTotalAum(\n            $, IHubCoreRegistry(registry).oracleRegistry(), msg.sender != securityCouncil()\n        );\n        emit TotalAumUpdated(_lastTotalAum);\n\n        uint256 _mintedFees = MachineUtils.manageFees($);\n        if (_mintedFees != 0) {\n            emit FeesMinted(_mintedFees);\n        }\n\n        return _lastTotalAum;\n    }\n\n    /// @inheritdoc IMachine\n    function deposit(uint256 assets, address receiver, uint256 minShares, bytes32 referralKey)\n        external\n        override\n        nonReentrant\n        notRecoveryMode\n        returns (uint256)\n    {\n        MachineStorage storage $ = _getMachineStorage();\n\n        if (msg.sender != $._depositor) {\n            revert Errors.UnauthorizedCaller();\n        }\n\n        uint256 shares = convertToShares(assets);\n        uint256 _maxMint = maxMint();\n        if (shares > _maxMint) {\n            revert Errors.ExceededMaxMint(shares, _maxMint);\n        }\n        if (shares < minShares) {\n            revert Errors.SlippageProtection();\n        }\n\n        IERC20Metadata($._accountingToken).safeTransferFrom(msg.sender, address(this), assets);\n        IMachineShare($._shareToken).mint(receiver, shares);\n        $._lastTotalAum += assets;\n        emit Deposit(msg.sender, receiver, assets, shares, referralKey);\n\n        return shares;\n    }\n\n    /// @inheritdoc IMachine\n    function redeem(uint256 shares, address receiver, uint256 minAssets)\n        external\n        override\n        nonReentrant\n        notRecoveryMode\n        returns (uint256)\n    {\n        MachineStorage storage $ = _getMachineStorage();\n\n        if (msg.sender != $._redeemer) {\n            revert Errors.UnauthorizedCaller();\n        }\n\n        uint256 assets = convertToAssets(shares);\n\n        uint256 _maxWithdraw = maxWithdraw();\n        if (assets > _maxWithdraw) {\n            revert Errors.ExceededMaxWithdraw(assets, _maxWithdraw);\n        }\n        if (assets < minAssets) {\n            revert Errors.SlippageProtection();\n        }\n\n        IERC20Metadata($._accountingToken).safeTransfer(receiver, assets);\n        IMachineShare($._shareToken).burn(msg.sender, shares);\n        $._lastTotalAum -= assets;\n        emit Redeem(msg.sender, receiver, assets, shares);\n\n        return assets;\n    }\n\n    /// @inheritdoc ICreReceiver\n    function onReport(bytes calldata metadata, bytes calldata report) external override nonReentrant {\n        address sender = msg.sender;\n        if (sender == creForwarder) {\n            _validateMetadata(metadata);\n        } else if (sender != securityCouncil()) {\n            revert Errors.UnauthorizedCaller();\n        }\n\n        MachineUtils.reportSpokeAccountingSnapshots(\n            _getMachineStorage(), IHubCoreRegistry(registry).tokenRegistry(), report\n        );\n    }\n\n    /// @inheritdoc IMachine\n    function setSpokeCaliber(\n        uint256 chainId,\n        address spokeCaliberMailbox,\n        uint16[] calldata bridges,\n        address[] calldata adapters\n    ) external override nonReentrant restricted {\n        MachineStorage storage $ = _getMachineStorage();\n\n        if (chainId == 0) {\n            revert Errors.ZeroChainId();\n        }\n        if (chainId == $._hubChainId) {\n            revert Errors.ProtectedChainId();\n        }\n\n        SpokeCaliberData storage caliberData = $._spokeCalibersData[chainId];\n\n        if (caliberData.mailbox != address(0)) {\n            revert Errors.SpokeCaliberAlreadySet();\n        }\n\n        if (spokeCaliberMailbox == address(0)) {\n            revert Errors.ZeroSpokeCaliberMailboxAddress();\n        }\n\n        $._spokeChainIds.push(chainId);\n        caliberData.mailbox = spokeCaliberMailbox;\n\n        emit SpokeCaliberMailboxSet(chainId, spokeCaliberMailbox);\n\n        uint256 len = bridges.length;\n        if (len != adapters.length) {\n            revert Errors.MismatchedLengths();\n        }\n        for (uint256 i; i < len; ++i) {\n            _setSpokeBridgeAdapter(chainId, bridges[i], adapters[i]);\n        }\n    }\n\n    /// @inheritdoc IMachine\n    function disableSpokeCaliber(uint256 chainId) external override nonReentrant restricted {\n        MachineStorage storage $ = _getMachineStorage();\n        SpokeCaliberData storage caliberData = $._spokeCalibersData[chainId];\n\n        if (caliberData.mailbox == address(0)) {\n            revert Errors.InvalidChainId();\n        }\n\n        if (caliberData.disabled) {\n            revert Errors.AlreadyDisabled();\n        }\n\n        if (caliberData.netAum != 0) {\n            revert Errors.CaliberNotEmpty();\n        }\n\n        MachineUtils.checkBridgeTransfersSettled(caliberData);\n\n        caliberData.disabled = true;\n\n        emit SpokeCaliberDisabled(chainId);\n    }\n\n    /// @inheritdoc IMachine\n    function enableSpokeCaliber(uint256 chainId) external override nonReentrant restricted {\n        MachineStorage storage $ = _getMachineStorage();\n        SpokeCaliberData storage caliberData = $._spokeCalibersData[chainId];\n\n        if (caliberData.mailbox == address(0)) {\n            revert Errors.InvalidChainId();\n        }\n\n        if (!caliberData.disabled) {\n            revert Errors.AlreadyEnabled();\n        }\n\n        caliberData.disabled = false;\n\n        emit SpokeCaliberEnabled(chainId);\n    }\n\n    /// @inheritdoc IMachine\n    function setSpokeBridgeAdapter(uint256 chainId, uint16 bridgeId, address adapter)\n        external\n        override\n        nonReentrant\n        restricted\n    {\n        SpokeCaliberData storage caliberData = _getMachineStorage()._spokeCalibersData[chainId];\n\n        if (caliberData.mailbox == address(0)) {\n            revert Errors.InvalidChainId();\n        }\n        _setSpokeBridgeAdapter(chainId, bridgeId, adapter);\n    }\n\n    /// @inheritdoc IMachine\n    function setDepositor(address newDepositor) external override restricted {\n        MachineStorage storage $ = _getMachineStorage();\n        emit DepositorChanged($._depositor, newDepositor);\n        $._depositor = newDepositor;\n    }\n\n    /// @inheritdoc IMachine\n    function setRedeemer(address newRedeemer) external override restricted {\n        MachineStorage storage $ = _getMachineStorage();\n        emit RedeemerChanged($._redeemer, newRedeemer);\n        $._redeemer = newRedeemer;\n    }\n\n    /// @inheritdoc IMachine\n    function setFeeManager(address newFeeManager) external override restricted {\n        MachineStorage storage $ = _getMachineStorage();\n        emit FeeManagerChanged($._feeManager, newFeeManager);\n        $._feeManager = newFeeManager;\n    }\n\n    /// @inheritdoc IMachine\n    function setCaliberStaleThreshold(uint256 newCaliberStaleThreshold) external override onlyRiskManagerTimelock {\n        MachineStorage storage $ = _getMachineStorage();\n        emit CaliberStaleThresholdChanged($._caliberStaleThreshold, newCaliberStaleThreshold);\n        $._caliberStaleThreshold = newCaliberStaleThreshold;\n    }\n\n    /// @inheritdoc IMachine\n    function setMaxFixedFeeAccrualRate(uint256 newMaxAccrualRate) external override onlyRiskManagerTimelock {\n        MachineStorage storage $ = _getMachineStorage();\n        emit MaxFixedFeeAccrualRateChanged($._maxFixedFeeAccrualRate, newMaxAccrualRate);\n        $._maxFixedFeeAccrualRate = newMaxAccrualRate;\n    }\n\n    /// @inheritdoc IMachine\n    function setMaxPerfFeeAccrualRate(uint256 newMaxAccrualRate) external override onlyRiskManagerTimelock {\n        MachineStorage storage $ = _getMachineStorage();\n        emit MaxPerfFeeAccrualRateChanged($._maxPerfFeeAccrualRate, newMaxAccrualRate);\n        $._maxPerfFeeAccrualRate = newMaxAccrualRate;\n    }\n\n    /// @inheritdoc IMachine\n    function setFeeMintCooldown(uint256 newFeeMintCooldown) external override onlyRiskManagerTimelock {\n        MachineStorage storage $ = _getMachineStorage();\n        emit FeeMintCooldownChanged($._feeMintCooldown, newFeeMintCooldown);\n        $._feeMintCooldown = newFeeMintCooldown;\n    }\n\n    /// @inheritdoc IMachine\n    function setShareLimit(uint256 newShareLimit) external override onlyRiskManager {\n        MachineStorage storage $ = _getMachineStorage();\n        emit ShareLimitChanged($._shareLimit, newShareLimit);\n        $._shareLimit = newShareLimit;\n    }\n\n    /// @inheritdoc IMachine\n    function setMaxSharePriceChangeRate(uint256 newMaxSharePriceChangeRate) external override onlyRiskManagerTimelock {\n        MachineStorage storage $ = _getMachineStorage();\n        emit MaxSharePriceChangeRateChanged($._maxSharePriceChangeRate, newMaxSharePriceChangeRate);\n        $._maxSharePriceChangeRate = newMaxSharePriceChangeRate;\n    }\n\n    /// @inheritdoc IBridgeController\n    function disableOutTransfer(uint16 bridgeId) external override onlyRiskManagerTimelock {\n        _disableOutTransfer(bridgeId);\n    }\n\n    /// @inheritdoc IBridgeController\n    function enableOutTransfer(uint16 bridgeId) external override onlyRiskManagerTimelock {\n        _enableOutTransfer(bridgeId);\n    }\n\n    /// @inheritdoc IBridgeController\n    function setMaxBridgeLossBps(uint16 bridgeId, uint256 maxBridgeLossBps) external override onlyRiskManagerTimelock {\n        _setMaxBridgeLossBps(bridgeId, maxBridgeLossBps);\n    }\n\n    /// @inheritdoc IBridgeController\n    function resetBridgingState(address token) external override nonReentrant onlySecurityCouncil {\n        MachineStorage storage $ = _getMachineStorage();\n        uint256 len = $._spokeChainIds.length;\n        for (uint256 i; i < len; ++i) {\n            SpokeCaliberData storage caliberData = $._spokeCalibersData[$._spokeChainIds[i]];\n\n            caliberData.caliberBridgesIn.remove(token);\n            caliberData.caliberBridgesOut.remove(token);\n            caliberData.machineBridgesIn.remove(token);\n            caliberData.machineBridgesOut.remove(token);\n        }\n\n        BridgeControllerStorage storage $bc = _getBridgeControllerStorage();\n        len = $bc._supportedBridges.length;\n        for (uint256 i; i < len; ++i) {\n            address bridgeAdapter = $bc._bridgeAdapters[$bc._supportedBridges[i]];\n            IBridgeAdapter(bridgeAdapter).withdrawPendingFunds(token);\n        }\n\n        _notifyIdleToken(token);\n\n        emit BridgingStateReset(token);\n    }\n\n    /// @dev Sets the spoke bridge adapter for a given chain ID and bridge ID.\n    function _setSpokeBridgeAdapter(uint256 chainId, uint16 bridgeId, address adapter) internal {\n        SpokeCaliberData storage caliberData = _getMachineStorage()._spokeCalibersData[chainId];\n\n        if (caliberData.bridgeAdapters[bridgeId] != address(0)) {\n            revert Errors.SpokeBridgeAdapterAlreadySet();\n        }\n        if (adapter == address(0)) {\n            revert Errors.ZeroBridgeAdapterAddress();\n        }\n        caliberData.bridgeAdapters[bridgeId] = adapter;\n\n        emit SpokeBridgeAdapterSet(chainId, uint256(bridgeId), adapter);\n    }\n\n    /// @dev Checks token balance, and registers token if needed.\n    function _notifyIdleToken(address token) internal {\n        if (IERC20Metadata(token).balanceOf(address(this)) > 0) {\n            bool newlyAdded = _getMachineStorage()._idleTokens.add(token);\n            if (\n                newlyAdded && !IOracleRegistry(IHubCoreRegistry(registry).oracleRegistry()).isFeedRouteRegistered(token)\n            ) {\n                revert Errors.PriceFeedRouteNotRegistered(token);\n            }\n        }\n    }\n}\n","deployed_bytecode":"0x608060405234801561000f575f5ffd5b50600436106104bb575f3560e01c80637f26728811610279578063b921af6211610156578063da68cf8b116100ca578063f77f39761161008f578063f77f397614610a16578063fb42148714610a29578063fb95138e14610a3c578063fe5e5b3114610a4f578063fe9e89f114610a62578063fff40e0414610a75575f5ffd5b8063da68cf8b146109c2578063db016810146109ca578063dd2d104a146109dd578063ed08a2dd146109f0578063f2c098b714610a03575f5ffd5b8063c7c4ff461161011b578063c7c4ff461461097c578063c926c98b14610984578063cc1472d31461098c578063d0fb020314610994578063d114542b1461099c578063d8780161146109af575f5ffd5b8063b921af621461091f578063bf7e214f14610946578063c349e4321461094e578063c549beec14610961578063c6e6f59214610969575f5ffd5b806395179bc6116101ed578063a8020377116101b2578063a8020377146108c3578063a81762e3146108d6578063ac7a1b5b146108e9578063b3b3d5ce146108f1578063b7131c58146108f9578063b7e3c1b31461090c575f5ffd5b806395179bc61461086f578063971c5dee146108825780639a31e968146108955780639b4fa611146108a85780639d16d644146108b0575f5ffd5b806386e807f81161023e57806386e807f8146107fa57806387831bfd1461080d5780638ad30499146108205780638fb3603714610828578063904587df1461084957806392905bf71461085c575f5ffd5b80637f26728814610791578063805f2132146107a457806381c4ac2a146107b75780638601b34e146107df57806386dabf77146107f2575f5ffd5b806340fa9503116103a75780635d92632f1161031b57806374c59381116102e057806374c59381146107215780637501f741146107295780637564e42e14610731578063764eb869146107445780637a9e5e4b146107575780637b1039991461076a575f5ffd5b80635d92632f146106cd57806362ca8460146106e057806362d83f7d146106f357806364d9e88a146107065780636c9fa59e14610719575f5ffd5b80634ccc3df11161036c5780634ccc3df1146106715780634d2fba1f146106845780634ebd0b9414610697578063511436d41461069f578063570ca735146106b25780635a480c3c146106ba575f5ffd5b806340fa95031461061d578063472d35b914610630578063478426631461064357806348c04ed41461064b5780634b68fabb1461065e575f5ffd5b80631856ef9f1161043e57806327eb6c0f1161040357806327eb6c0f146105d75780632909ee27146105df5780632ba29d38146105f25780633307ce84146105fa57806334a411881461060d5780633be75aa314610615575f5ffd5b80631856ef9f146105765780631c1083e2146105895780631ce192d01461059c5780632310cce6146105b157806327ce952a146105c4575f5ffd5b80630e0c9129116104845780630e0c912914610538578063104285071461054b5780631046cb24146105535780631182570e1461056657806315bef4c11461056e575f5ffd5b8062e17b45146104bf57806301ffc9a7146104e557806302dc6d031461050857806307a00b1f1461051d57806307a2d13a14610525575b5f5ffd5b6104d26104cd366004614f03565b610a88565b6040519081526020015b60405180910390f35b6104f86104f3366004614f1a565b610ab5565b60405190151581526020016104dc565b61051b610516366004614f03565b610aeb565b005b6104f8610b60565b6104d2610533366004614f03565b610b7c565b61051b610546366004614f76565b610c30565b6104d2610ca2565b61051b610561366004614fb3565b610cbb565b6104d2610e91565b6104d2610ea3565b6104d2610584366004614fdd565b610eb5565b61051b610597366004614ff6565b610f18565b6105a4610f8c565b6040516104dc9190615011565b61051b6105bf366004614ff6565b610fa7565b61051b6105d236600461503b565b610fbc565b6105a46115a9565b6105a46105ed366004614f03565b6115c4565b6105a46115da565b61051b610608366004614ff6565b6115e3565b6105a4611657565b6104d2611672565b6104f861062b366004614f03565b611684565b61051b61063e366004614ff6565b61169e565b6105a4611712565b61051b61065936600461513e565b61172d565b61051b61066c366004614ff6565b61179e565b61051b61067f366004614ff6565b61180c565b6104f8610692366004614ff6565b611880565b6104d26118e1565b61051b6106ad366004614f03565b611b30565b6105a4611b42565b6105a46106c8366004615193565b611b87565b6104f86106db366004614ff6565b611c11565b61051b6106ee366004614ff6565b611ca0565b61051b610701366004614f03565b611d14565b61051b6107143660046151bd565b611d89565b6105a4611dd0565b6104d2611de8565b6104d2611dfa565b61051b61073f366004614f03565b611eae565b61051b610752366004614fdd565b611f23565b61051b610765366004614ff6565b611f60565b6105a47f0000000000000000000000000faeeceab0bcb63be2fe984ea8c77778989d53ea81565b61051b61079f366004614ff6565b611fd0565b61051b6107b23660046151d7565b6121bb565b6107ca6107c5366004614f03565b612334565b604080519283526020830191909152016104dc565b6104f86107ed366004614ff6565b61238f565b6104d26123a5565b6104d2610808366004615229565b6123b7565b6104f861081b366004614fdd565b612574565b6104d261259c565b6108306125ae565b6040516001600160e01b031990911681526020016104dc565b61051b610857366004614f03565b6125e3565b61051b61086a366004615270565b6125f5565b61051b61087d36600461528b565b6126aa565b6105a4610890366004614fdd565b612847565b61051b6108a3366004614f03565b612891565b6104d2612906565b61051b6108be3660046152a9565b612918565b6105a46108d1366004614f03565b612b01565b61051b6108e43660046152e5565b612b57565b6104d2612df9565b6104d2612e75565b61051b6109073660046151bd565b612e87565b61051b61091a366004614fdd565b612eca565b6105a47f0000000000000000000000000b93082d9b3c7c97facd250082899bacf3af388581565b6105a4612f07565b6104f861095c366004614f03565b612f1c565b6105a4612f70565b6104d2610977366004614f03565b612f79565b6105a461301e565b6104f8613027565b6104d2613043565b6105a4613055565b61051b6109aa366004614f03565b613070565b6104d26109bd366004615331565b6130e5565b6105a461329f565b61051b6109d83660046151bd565b6132a8565b61051b6109eb3660046151bd565b6132eb565b61051b6109fe366004614f03565b613329565b61051b610a11366004614ff6565b6133e3565b61051b610a24366004615270565b613457565b61051b610a37366004615395565b6134d5565b6104f8610a4a366004614fdd565b613690565b61051b610a5d366004614f03565b6136c5565b61051b610a70366004614ff6565b613804565b61051b610a83366004614f03565b613816565b5f610a9161388b565b6011018281548110610aa557610aa561541e565b905f5260205f2001549050919050565b5f6001600160e01b0319821663402f909960e11b1480610ae557506301ffc9a760e01b6001600160e01b03198316145b92915050565b610af36138af565b600301546001600160a01b03163314610b1f57604051635c427cd960e01b815260040160405180910390fd5b5f610b2861388b565b600a81015460405191925083917f0e03f7b96ab4a7bfa6f4031ad2b5b26d00ab8842798bedd8d127fd93203a4f03905f90a3600a0155565b5f610b696138af565b60030154600160a01b900460ff16919050565b5f5f610b8661388b565b9050610c2981600601546001610b9c9190615446565b600d830154610bac90600a61553c565b8354604080516318160ddd60e01b815290516001600160a01b03909216916318160ddd916004808201926020929091908290030181865afa158015610bf3573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610c179190615547565b610c219190615446565b8591906138d3565b9392505050565b610c38613983565b610c44335b5f3661399f565b5f610c4d61388b565b5f8581526012919091016020526040902080549091506001600160a01b0316610c8957604051633d23e4d160e11b815260040160405180910390fd5b610c94848484613a8c565b50610c9d613b6e565b505050565b5f610cb6610cae61388b565b601301613b83565b905090565b610cc36138af565b60030154600160a01b900460ff1615610cef57604051633dffcec760e11b815260040160405180910390fd5b610cf76138af565b546001600160a01b03163314610d2057604051635c427cd960e01b815260040160405180910390fd5b5f610d2961388b565b6010810154909150610d48906001600160a01b03858116911684613b8c565b601081015460405163421ddd4f60e11b81526001600160a01b039091169063843bba9e90610d7c908690869060040161555e565b5f604051808303815f87803b158015610d93575f5ffd5b505af1158015610da5573d5f5f3e3d5ffd5b50505050826001600160a01b031681600f01547fb89c5d3291e293d70a6d4a836c1b4f7f5c3e96cd11eead5bce2c4b259722ea8584604051610de991815260200190565b60405180910390a36040516370a0823160e01b81526001600160a01b038416906370a0823190610e1d903090600401615011565b602060405180830381865afa158015610e38573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610e5c9190615547565b158015610e79575060018101546001600160a01b03848116911614155b15610c9d57610e8b6013820184613bf4565b50505050565b5f610e9a61388b565b60070154905090565b5f610eac61388b565b600b0154905090565b5f5f610ebf613c08565b61ffff84165f9081526001820160205260409020549091506001600160a01b0316610efd57604051630b91e58760e41b815260040160405180910390fd5b61ffff9092165f908152600290920160205250604090205490565b610f2133610c3d565b5f610f2a6138af565b60018101546040519192506001600160a01b03808516929116907f47b4da9ab18bde67f1748d49bcbdde4ad81292aecedd7f0ba3585f5f7d8f110c905f90a360010180546001600160a01b0319166001600160a01b0392909216919091179055565b5f610f956138af565b600301546001600160a01b0316919050565b610fb033610c3d565b610fb981613c2c565b50565b5f610fc5613cf2565b805490915060ff600160401b82041615906001600160401b03165f81158015610feb5750825b90505f826001600160401b031660011480156110065750303b155b905081158015611014575080155b156110325760405163f92ee8a960e01b815260040160405180910390fd5b845467ffffffffffffffff19166001178555831561105c57845460ff60401b1916600160401b1785555b5f61106561388b565b90504681600f018190555086816010015f6101000a8154816001600160a01b0302191690836001600160a01b031602179055505f7f0000000000000000000000000faeeceab0bcb63be2fe984ea8c77778989d53ea6001600160a01b0316634bb93ab16040518163ffffffff1660e01b8152600401602060405180830381865afa1580156110f5573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111199190615577565b60405163094b14a760e21b81529091506001600160a01b0382169063252c529c90611148908c90600401615011565b602060405180830381865afa158015611163573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111879190615592565b6111af578860405163ebb3197d60e01b81526004016111a69190615011565b60405180910390fd5b5f896001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156111ec573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061121091906155ad565b83546001600160a01b03808e166001600160a01b0319928316178655600186018054918e169190921617905560ff16905061124e601384018b613d1a565b5061125a8160126155cd565b600d8401556001600160a01b038c16156113ea57604051637221254f60e01b8152600481018490526001600160a01b03808e16602483015283166044820152739913685acda266d44a32ec1d9262435a0f891ea390637221254f906064015f6040518083038186803b1580156112ce575f5ffd5b505af41580156112e0573d5f5f3e3d5ffd5b50508454604080516318160ddd60e01b815290515f94506001600160a01b0390921692506318160ddd9160048083019260209291908290030181865afa15801561132c573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906113509190615547565b6006850154600d8601546040516001622b2d2b60e01b031981526004810192909252602482018390526044820152909150739913685acda266d44a32ec1d9262435a0f891ea39063ffd4d2d590606401602060405180830381865af41580156113bb573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906113df9190615547565b6009850155506113fb565b6113f581600a61553c565b60098401555b8a6001600160a01b03166379ba50976040518163ffffffff1660e01b81526004015f604051808303815f87803b158015611433575f5ffd5b505af1158015611445573d5f5f3e3d5ffd5b505050504283600701819055504283600801819055508e5f01602081019061146d9190614ff6565b836002015f6101000a8154816001600160a01b0302191690836001600160a01b031602179055508e60200160208101906114a79190614ff6565b836003015f6101000a8154816001600160a01b0302191690836001600160a01b031602179055508e60400160208101906114e19190614ff6565b6004840180546001600160a01b0319166001600160a01b039290921691909117905560608f0135600584015560808f0135600a84015560a08f0135600b84015560c08f0135600c84015560e08f0135600e8401556101008f013560158401556115498e613d2e565b6115528d613ea0565b505050831561159b57845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b505050505050505050505050565b5f6115b26138af565b600101546001600160a01b0316919050565b5f610ae5826115d161388b565b60130190613ef2565b5f610f9561388b565b6115ec33610c3d565b5f6115f561388b565b60038101546040519192506001600160a01b03808516929116907fcd1fff739849339e94f95ee5c7fc6b3610b5f8feb959037c03f9f317eb1b1911905f90a360030180546001600160a01b0319166001600160a01b0392909216919091179055565b5f61166061388b565b601001546001600160a01b0316919050565b5f61167b61388b565b600e0154905090565b5f610ae5825f5160206157d05f395f51905f525b90613efd565b6116a733610c3d565b5f6116b061388b565b60048101546040519192506001600160a01b03808516929116907facbd074db1a997c1632eb3d55a4c9813e0883267f14740568d0535dc23077ce4905f90a360040180546001600160a01b0319166001600160a01b0392909216919091179055565b5f61171b6138af565b600201546001600160a01b0316919050565b6117356138af565b60030154600160a01b900460ff161561176157604051633dffcec760e11b815260040160405180910390fd5b6117696138af565b546001600160a01b0316331461179257604051635c427cd960e01b815260040160405180910390fd5b610e8b84848484613f14565b6117a733610c3d565b5f6117b06138af565b80546040519192506001600160a01b03808516929116907fd9266cd7f40f2b8e1a597180acd92a051a1a91f97ff78127f3a318f85727beff905f90a380546001600160a01b0319166001600160a01b0392909216919091179055565b61181533610c3d565b5f61181e6138af565b60038101546040519192506001600160a01b03808516929116907f5c156e2486854ba582ce30e5428a1cce1a4de221f180f8472445b83c7136a34b905f90a360030180546001600160a01b0319166001600160a01b0392909216919091179055565b5f5f61188a6138af565b80549091506001600160a01b03848116911614806118b7575060018101546001600160a01b038481169116145b80610c2957506001600160a01b0383165f90815260048201602052604090205460ff169392505050565b5f6118ea613983565b6118f333611c11565b61191057604051635c427cd960e01b815260040160405180910390fd5b5f61191961388b565b90505f739913685acda266d44a32ec1d9262435a0f891ea363bc336959837f0000000000000000000000000faeeceab0bcb63be2fe984ea8c77778989d53ea6001600160a01b0316634bb93ab16040518163ffffffff1660e01b8152600401602060405180830381865afa158015611993573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906119b79190615577565b6119bf6115a9565b60405160e085901b6001600160e01b031916815260048101939093526001600160a01b039182166024840152163314156044820152606401602060405180830381865af4158015611a12573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611a369190615547565b90507f22510cc1266408a3b15fed6f8895391925f85578a5d5a557966133dc0614b43d81604051611a6991815260200190565b60405180910390a16040516381b0f91360e01b8152600481018390525f90739913685acda266d44a32ec1d9262435a0f891ea3906381b0f91390602401602060405180830381865af4158015611ac1573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611ae59190615547565b90508015611b21576040518181527fef45ded67a593d4122c09b7572f8af65d972a83769c560cbf443d82c9054a05d9060200160405180910390a15b50915050611b2d613b6e565b90565b611b3933610c3d565b610fb981613fc3565b5f5f611b4c6138af565b6003810154909150600160a01b900460ff16611b725780546001600160a01b0316611b81565b60018101546001600160a01b03165b91505090565b5f5f611b9161388b565b5f8581526012919091016020526040902080549091506001600160a01b0316611bcd57604051633d23e4d160e11b815260040160405180910390fd5b61ffff83165f9081526001820160205260409020546001600160a01b031680611c0957604051635f8b0aab60e01b815260040160405180910390fd5b949350505050565b5f5f611c1b6138af565b6003810154909150600160a01b900460ff16158015611c8057506003810154600160a81b900460ff161580611c5c575080546001600160a01b038481169116145b80611c8057506001600160a01b0383165f90815260048201602052604090205460ff165b80610c29575060018101546001600160a01b038481169116149392505050565b611ca933610c3d565b5f611cb26138af565b60028101546040519192506001600160a01b03808516929116907f0ff73514c2ecd6855fbfd168fd7555ac8e74037d368f1458f568cd0db706fe30905f90a360020180546001600160a01b0319166001600160a01b0392909216919091179055565b611d1c6138af565b600301546001600160a01b03163314611d4857604051635c427cd960e01b815260040160405180910390fd5b5f611d5161388b565b600b81015460405191925083917faec7bc124bf42fd28983fed34c19fc24cd2f208810f7a49bfc47b420d0dd1fb5905f90a3600b0155565b611d91611b42565b6001600160a01b0316336001600160a01b031614611dc257604051635c427cd960e01b815260040160405180910390fd5b611dcc8282614024565b5050565b5f611dd961388b565b546001600160a01b0316919050565b5f611df161388b565b60060154905090565b5f5f611e0461388b565b90505f1981600e015403611e1a575f1991505090565b8054604080516318160ddd60e01b815290515f926001600160a01b0316916318160ddd9160048083019260209291908290030181865afa158015611e60573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611e849190615547565b905081600e01548110611e97575f611ea7565b8082600e0154611ea791906155cd565b9250505090565b611eb66138af565b600301546001600160a01b03163314611ee257604051635c427cd960e01b815260040160405180910390fd5b5f611eeb61388b565b600c81015460405191925083917fc88eb0fbdebf4d858eb97fa1aa1fa76c132ccb2ece37c136583bf0d890529b24905f90a3600c0155565b611f2b6138af565b600301546001600160a01b03163314611f5757604051635c427cd960e01b815260040160405180910390fd5b610fb98161408c565b33611f69612f07565b6001600160a01b0316816001600160a01b031614611f9b578060405162d1953b60e31b81526004016111a69190615011565b816001600160a01b03163b5f03611fc757816040516361798f2f60e11b81526004016111a69190615011565b611dcc8261414d565b611fd8613983565b611fe06138af565b600101546001600160a01b0316331461200c57604051635c427cd960e01b815260040160405180910390fd5b5f61201561388b565b60118101549091505f5b818110156120a4575f836012015f8560110184815481106120425761204261541e565b905f5260205f20015481526020019081526020015f20905061207085826006016141a490919063ffffffff16565b5061207e60098201866141a4565b5061208c600c8201866141a4565b5061209a600f8201866141a4565b505060010161201f565b505f6120ae613c08565b8054925090505f5b82811015612173575f826001015f845f0184815481106120d8576120d861541e565b5f9182526020808320601083040154600f9092166002026101000a90910461ffff1683528201929092526040908101909120549051633df4e34160e11b81526001600160a01b0390911691508190637be9c6829061213a908990600401615011565b5f604051808303815f87803b158015612151575f5ffd5b505af1158015612163573d5f5f3e3d5ffd5b50505050508060010190506120b6565b5061217d846141b8565b6040516001600160a01b038516907f5c2bda6e4510afb949f70a9e2b6c6f6fdfc29cc77bf5b4c3913f1b806dd22edb905f90a2505050610fb9613b6e565b6121c3613983565b336001600160a01b037f0000000000000000000000000b93082d9b3c7c97facd250082899bacf3af3885168103612203576121fe8585614357565b61223c565b61220b6115a9565b6001600160a01b0316816001600160a01b03161461223c57604051635c427cd960e01b815260040160405180910390fd5b739913685acda266d44a32ec1d9262435a0f891ea36325663f2961225e61388b565b7f0000000000000000000000000faeeceab0bcb63be2fe984ea8c77778989d53ea6001600160a01b0316639d23c4c76040518163ffffffff1660e01b8152600401602060405180830381865afa1580156122ba573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906122de9190615577565b86866040518563ffffffff1660e01b81526004016122ff9493929190615608565b5f6040518083038186803b158015612315575f5ffd5b505af4158015612327573d5f5f3e3d5ffd5b5050505050610e8b613b6e565b5f5f5f61233f61388b565b5f8581526012919091016020526040902080549091506001600160a01b031661237b57604051633d23e4d160e11b815260040160405180910390fd5b806003015481600201549250925050915091565b5f610ae58261239c61388b565b601301906143ae565b5f6123ae61388b565b60110154919050565b5f6123c0613983565b6123c86138af565b60030154600160a01b900460ff16156123f457604051633dffcec760e11b815260040160405180910390fd5b5f6123fd61388b565b60028101549091506001600160a01b0316331461242d57604051635c427cd960e01b815260040160405180910390fd5b5f61243787612f79565b90505f612442611dfa565b90508082111561246f57604051634a768b1360e01b815260048101839052602481018290526044016111a6565b85821015612490576040516305f50c7d60e21b815260040160405180910390fd5b60018301546124aa906001600160a01b031633308b6143cf565b82546040516340c10f1960e01b81526001600160a01b03909116906340c10f19906124db908a90869060040161555e565b5f604051808303815f87803b1580156124f2575f5ffd5b505af1158015612504573d5f5f3e3d5ffd5b5050505087836006015f82825461251b9190615446565b9091555050604080518981526020810184905286916001600160a01b038a169133917f6e610d335252f97251efcf0ddbb78a6c6d2ae0e5c0e4b123bc0e6de074628a64910160405180910390a450915050611c09613b6e565b5f61257d613c08565b61ffff9092165f90815260039290920160205250604090205460ff1690565b5f6125a561388b565b60150154905090565b5f5160206157b05f395f51905f5280545f9190600160a01b900460ff166125d5575f611b81565b638fb3603760e01b91505090565b6125ec33610c3d565b610fb9816143fc565b6125fd6138af565b600101546001600160a01b0316331461262957604051635c427cd960e01b815260040160405180910390fd5b5f6126326138af565b600381015490915060ff600160a01b90910416151582151514611dcc57600381018054831515600160a01b0260ff60a01b199091161790556040517fb8db430d57a0e0c8a3c76dcd89a53a978c46ad23c7dccc6915212384711949ef9061269e90841515815260200190565b60405180910390a15050565b6126b2613983565b5f6126bb61388b565b90506126c63361445d565b156127f3575f80806126da8587018761563c565b5f838152601288016020526040902080549396509194509250906001600160a01b031661271a57604051633d23e4d160e11b815260040160405180910390fd5b8115612786575f61272e600f83018b61448a565b90505f61273b85836155cd565b90505f61274b600685018d61449e565b9150508181111561276f57604051633eb172e760e01b815260040160405180910390fd5b61277d600f85018d846144c4565b505050506127ea565b5f612794600c83018b61449e565b91505f90506127a38583615446565b90505f6127b3600985018d61449e565b915050808211156127d757604051633eb172e760e01b815260040160405180910390fd5b6127e5600c85018d846144c4565b505050505b50505050612820565b60108101546001600160a01b0316331461282057604051635c427cd960e01b815260040160405180910390fd5b6128356001600160a01b0386163330876143cf565b61283e856141b8565b50610e8b613b6e565b5f5f612851613c08565b61ffff84165f90815260019190910160205260409020546001600160a01b0316905080610ae557604051630b91e58760e41b815260040160405180910390fd5b6128996138af565b600301546001600160a01b031633146128c557604051635c427cd960e01b815260040160405180910390fd5b5f6128ce61388b565b601581015460405191925083917f5f4eb30a629ace63c93aff5ffa6f95d4e7372a5952badf2b715872f48609a1ab905f90a360150155565b5f61290f61388b565b60050154905090565b7f0000000000000000000000000faeeceab0bcb63be2fe984ea8c77778989d53ea6001600160a01b0316633d8df6676040518163ffffffff1660e01b8152600401602060405180830381865afa158015612974573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906129989190615577565b6001600160a01b0316336001600160a01b0316146129c957604051631966391b60e11b815260040160405180910390fd5b5f6129d2613c08565b61ffff85165f9081526001820160205260409020549091506001600160a01b031615612a115760405163cb01460760e01b815260040160405180910390fd5b6001600160a01b038316612a3857604051630c2495b960e11b815260040160405180910390fd5b61ffff8085165f81815260018085016020908152604080842080546001600160a01b038b166001600160a01b03199091168117909155600280890184528286208a9055600389018452828620805460ff19908116871790915582875260048a0185528387208054909116861790558854948501895588865292852060108504018054600f9095169093026101000a80870297021990931695909517905592517f9455b805174f4eafd22526b0232e96c50ec74ba9be4a0b2f45228add478543e69190a350505050565b5f5f612b0b61388b565b5f8481526012919091016020526040902080549091506001600160a01b0316612b4757604051633d23e4d160e11b815260040160405180910390fd5b546001600160a01b031692915050565b612b5f613983565b612b676138af565b60030154600160a01b900460ff1615612b9357604051633dffcec760e11b815260040160405180910390fd5b612b9b6138af565b546001600160a01b03163314612bc457604051635c427cd960e01b815260040160405180910390fd5b5f612bcd61388b565b5f86815260128201602052604090208054919250906001600160a01b0316612c0857604051633d23e4d160e11b815260040160405180910390fd5b601281015460ff1615612c2e57604051634307631760e11b815260040160405180910390fd5b61ffff87165f9081526001820160205260409020546001600160a01b031680612c6a57604051635f8b0aab60e01b815260040160405180910390fd5b5f80612c79600f85018961449e565b90925090505f612c8c600686018a61449e565b91505080821115612cb05760405163b61b9df760e01b815260040160405180910390fd5b80821015612cd157604051633eb172e760e01b815260040160405180910390fd5b612cf58984612ce05789612cea565b612cea8a85615446565b600f880191906144c4565b50612d048b8b868c8c8c6144d9565b886001600160a01b03168a7fb89c5d3291e293d70a6d4a836c1b4f7f5c3e96cd11eead5bce2c4b259722ea858a604051612d4091815260200190565b60405180910390a36040516370a0823160e01b81526001600160a01b038a16906370a0823190612d74903090600401615011565b602060405180830381865afa158015612d8f573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612db39190615547565b158015612dd0575060018601546001600160a01b038a8116911614155b15612de457612de2601387018a613bf4565b505b505050505050612df2613b6e565b5050505050565b5f5f612e0361388b565b60018101546040516370a0823160e01b81529192506001600160a01b0316906370a0823190612e36903090600401615011565b602060405180830381865afa158015612e51573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611b819190615547565b5f612e7e61388b565b600a0154905090565b612e8f611b42565b6001600160a01b0316336001600160a01b031614612ec057604051635c427cd960e01b815260040160405180910390fd5b611dcc8282614721565b612ed26138af565b600301546001600160a01b03163314612efe57604051635c427cd960e01b815260040160405180910390fd5b610fb98161475b565b5f805f5160206157b05f395f51905f52612b47565b5f5f612f2661388b565b5f8481526012919091016020526040902080549091506001600160a01b0316612f6257604051633d23e4d160e11b815260040160405180910390fd5b6012015460ff161592915050565b5f611dd96138af565b5f5f612f8361388b565b9050610c2981600d0154600a612f99919061553c565b8254604080516318160ddd60e01b815290516001600160a01b03909216916318160ddd916004808201926020929091908290030181865afa158015612fe0573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906130049190615547565b61300e9190615446565b6006830154610c21906001615446565b5f61171b61388b565b5f6130306138af565b60030154600160a81b900460ff16919050565b5f61304c61388b565b600c0154905090565b5f61305e61388b565b600401546001600160a01b0316919050565b6130786138af565b600201546001600160a01b031633146130a457604051635c427cd960e01b815260040160405180910390fd5b5f6130ad61388b565b600e81015460405191925083917f4f683a6f2905f2dfe5f0674962dc46bbda476371cbebc13ca42fe41e271c1b77905f90a3600e0155565b5f6130ee613983565b6130f66138af565b60030154600160a01b900460ff161561312257604051633dffcec760e11b815260040160405180910390fd5b5f61312b61388b565b60038101549091506001600160a01b0316331461315b57604051635c427cd960e01b815260040160405180910390fd5b5f61316586610b7c565b90505f613170612df9565b90508082111561319d5760405163264f877960e21b815260048101839052602481018290526044016111a6565b848210156131be576040516305f50c7d60e21b815260040160405180910390fd5b60018301546131d7906001600160a01b03168784614821565b8254604051632770a7eb60e21b81526001600160a01b0390911690639dc29fac906132089033908b9060040161555e565b5f604051808303815f87803b15801561321f575f5ffd5b505af1158015613231573d5f5f3e3d5ffd5b5050505081836006015f82825461324891906155cd565b909155505060408051838152602081018990526001600160a01b0388169133917f3f693fff038bb8a046aa76d9516190ac7444f7d69cf952c4cbdc086fdef2d6fc910160405180910390a350915050610c29613b6e565b5f6115b261388b565b6132b0611b42565b6001600160a01b0316336001600160a01b0316146132e157604051635c427cd960e01b815260040160405180910390fd5b611dcc828261482e565b6132f36138af565b600301546001600160a01b0316331461331f57604051635c427cd960e01b815260040160405180910390fd5b611dcc8282614868565b613331613983565b61333a33610c3d565b5f61334361388b565b5f83815260128201602052604090208054919250906001600160a01b031661337e57604051633d23e4d160e11b815260040160405180910390fd5b601281015460ff166133a357604051637952fbad60e11b815260040160405180910390fd5b60128101805460ff1916905560405183907fc4010b78fc4ede3c7bef523885761352419c2d251a00586c26f64d8d5e8315e9905f90a25050610fb9613b6e565b6133ec33610c3d565b5f6133f561388b565b60028101546040519192506001600160a01b03808516929116907f166d94140c1558bd891548eab89b904b8f87dc2e6877f4d8719849084d4fb4a3905f90a360020180546001600160a01b0319166001600160a01b0392909216919091179055565b61346033610c3d565b5f6134696138af565b600381015490915060ff600160a81b90910416151582151514611dcc57600381018054831515600160a81b0260ff60a81b199091161790556040517fd5b18724af9617cf1a7d350960b8c5e5b49a15dee0b85dffd817c8c50ff0a2a09061269e90841515815260200190565b6134dd613983565b6134e633610c3d565b5f6134ef61388b565b9050865f0361351157604051633212217560e21b815260040160405180910390fd5b80600f01548703613535576040516328151e8560e11b815260040160405180910390fd5b5f878152601282016020526040902080546001600160a01b03161561356d576040516328c1ba0160e01b815260040160405180910390fd5b6001600160a01b03871661359457604051631c2e8b0b60e11b815260040160405180910390fd5b6011820180546001810182555f918252602082200189905581546001600160a01b0319166001600160a01b038916908117835560405190918a917fca7785eb0ed792032b5c3582a99c476c34573693a5d096718fc4cf90570d54a99190a384838114613613576040516373f8993760e11b815260040160405180910390fd5b5f5b8181101561367c576136748a8989848181106136335761363361541e565b90506020020160208101906136489190614fdd565b88888581811061365a5761365a61541e565b905060200201602081019061366f9190614ff6565b613a8c565b600101613615565b50505050613688613b6e565b505050505050565b5f8061369a613c08565b61ffff939093165f90815260019093016020526040909220546001600160a01b031690911415919050565b6136cd613983565b6136d633610c3d565b5f6136df61388b565b5f83815260128201602052604090208054919250906001600160a01b031661371a57604051633d23e4d160e11b815260040160405180910390fd5b601281015460ff161561373f57604051625ecddb60e01b815260040160405180910390fd5b60038101541561376257604051636e933b5f60e11b815260040160405180910390fd5b60405163b25c0e1360e01b815260048101829052739913685acda266d44a32ec1d9262435a0f891ea39063b25c0e13906024015f6040518083038186803b1580156137ab575f5ffd5b505af41580156137bd573d5f5f3e3d5ffd5b50505060128201805460ff191660011790555060405183907ffbc0f7bdf76a0b3a03666f4796ab5d9754e975143fb8d037bae04daee68a4ae5905f90a25050610fb9613b6e565b61380d33610c3d565b610fb981614908565b61381e6138af565b600301546001600160a01b0316331461384a57604051635c427cd960e01b815260040160405180910390fd5b5f61385361388b565b600581015460405191925083917faeded51a1c475e849903f8cc85752a94e859a66faee995552e8ba8c69c86ccb2905f90a360050155565b7f55fe2a17e400bcd0e2125123a7fc955478e727b29a4c522f4f2bd95d961bd90090565b7f7e702089668346e906996be6de3dfc0cb2b0c125fc09b3c0391871825913e00090565b5f5f5f6138e086866149e1565b91509150815f03613904578381816138fa576138fa615667565b0492505050610c29565b81841161391b5761391b60038515026011186149fd565b5f848688095f868103871696879004966002600389028118808a02820302808a02820302808a02820302808a02820302808a02820302808a02909103029181900381900460010185841190960395909502919093039390930492909217029150509392505050565b61398b614a0e565b60025f5160206157f05f395f51905f525b55565b5f5160206157b05f395f51905f525f806139d76139ba612f07565b87306139c960045f8a8c61567b565b6139d2916156a2565b614a47565b91509150816136885763ffffffff811615613a7257825460ff60a01b1916600160a01b178355613a05612f07565b6001600160a01b03166394c7d7ee8787876040518463ffffffff1660e01b8152600401613a34939291906156d8565b5f604051808303815f87803b158015613a4b575f5ffd5b505af1158015613a5d573d5f5f3e3d5ffd5b5050845460ff60a01b19168555506136889050565b8560405162d1953b60e31b81526004016111a69190615011565b5f613a9561388b565b5f8581526012919091016020908152604080832061ffff8716845260018101909252909120549091506001600160a01b031615613ae5576040516331fec61f60e21b815260040160405180910390fd5b6001600160a01b038216613b0c57604051630c2495b960e11b815260040160405180910390fd5b61ffff83165f81815260018301602052604080822080546001600160a01b0319166001600160a01b038716908117909155905190929187917fe9fa606ff1542a4b25860722c547a2062732708a184ff8a5d797780fe7df03b29190a450505050565b60015f5160206157f05f395f51905f5261399c565b5f610ae5825490565b613b988383835f614ad9565b610c9d57613ba983835f6001614ad9565b613bc85782604051635274afe760e01b81526004016111a69190615011565b613bd58383836001614ad9565b610c9d5782604051635274afe760e01b81526004016111a69190615011565b5f610c29836001600160a01b038416614b3b565b7f7363d524082cdf545f1ac33985598b84d2470b8b4fbcc6cb47698cc1b2a0350090565b5f613c356138af565b80549091506001600160a01b0383811691161480613c62575060018101546001600160a01b038381169116145b80613c8657506001600160a01b0382165f90815260048201602052604090205460ff165b15613ca457604051630f9ef27d60e01b815260040160405180910390fd5b6001600160a01b0382165f818152600483016020526040808220805460ff19166001179055517f2a72788b2f28a2581746a26fe1b56e7d130aca3165f769fada57d119a5958e509190a25050565b5f807ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00610ae5565b5f610c29836001600160a01b038416614c25565b613d36614c71565b5f613d3f6138af565b9050613d4e6020830183614ff6565b81546001600160a01b0319166001600160a01b0391909116178155613d796040830160208401614ff6565b6001820180546001600160a01b0319166001600160a01b0392909216919091179055613dab6060830160408401614ff6565b6002820180546001600160a01b0319166001600160a01b0392909216919091179055613ddd6080830160608401614ff6565b6003820180546001600160a01b0319166001600160a01b0392909216919091179055613e0f60c0830160a08401615270565b600382018054911515600160a81b0260ff60a81b199092169190911790555f5b613e3c60c08401846156fc565b9050811015613e8757613e7f613e5560c08501856156fc565b83818110613e6557613e6561541e565b9050602002016020810190613e7a9190614ff6565b613c2c565b600101613e2f565b50611dcc613e9b60a0840160808501614ff6565b614c96565b613ea8614c71565b5f613eb382806156fc565b905090505f5b81811015610c9d57613eea613ece84806156fc565b83818110613ede57613ede61541e565b905060200201356143fc565b600101613eb9565b5f610c298383614ca7565b5f8181526001830160205260408120541515610c29565b5f613f1e85612847565b9050613f28613c08565b61ffff86165f908152600391909101602052604090205460ff16613f5f5760405163592c386560e01b815260040160405180910390fd5b6040516363ac907760e11b81526001600160a01b0382169063c75920ee90613f8f90879087908790600401615741565b5f604051808303815f87803b158015613fa6575f5ffd5b505af1158015613fb8573d5f5f3e3d5ffd5b505050505050505050565b613fda5f5160206157d05f395f51905f5282614ccd565b613ff757604051633d16c06160e21b815260040160405180910390fd5b60405181907fab3aa5ac034f828a77403db224191d1335e3d05091dbe3b2895756926ca45dbd905f90a250565b5f61402e83612847565b604051633a644cbf60e21b8152600481018490529091506001600160a01b0382169063e99132fc906024015b5f604051808303815f87803b158015614071575f5ffd5b505af1158015614083573d5f5f3e3d5ffd5b50505050505050565b5f614095613c08565b61ffff83165f9081526001820160205260409020549091506001600160a01b03166140d357604051630b91e58760e41b815260040160405180910390fd5b61ffff82165f90815260038201602052604090205460ff1661410757604051625ecddb60e01b815260040160405180910390fd5b61ffff82165f818152600383016020526040808220805460ff19169055517f88f476150f96d992b0624a303d4c68f8e075cd2a6a9d50747bfae2bfe625ef869190a25050565b5f5160206157b05f395f51905f5280546001600160a01b0319166001600160a01b0383161781556040517f2f658b440c35314f52658ea8a740e05b284cdc84dc9ae01e891f21b8933e7cad9061269e908490615011565b5f610c29836001600160a01b038416614cd8565b6040516370a0823160e01b81525f906001600160a01b038316906370a08231906141e6903090600401615011565b602060405180830381865afa158015614201573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906142259190615547565b1115610fb9575f6142418261423861388b565b60130190613d1a565b905080801561433757507f0000000000000000000000000faeeceab0bcb63be2fe984ea8c77778989d53ea6001600160a01b0316634bb93ab16040518163ffffffff1660e01b8152600401602060405180830381865afa1580156142a7573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906142cb9190615577565b6001600160a01b031663252c529c836040518263ffffffff1660e01b81526004016142f69190615011565b602060405180830381865afa158015614311573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906143359190615592565b155b15611dcc578160405163ebb3197d60e01b81526004016111a69190615011565b6040811461437857604051633a94310160e11b815260040160405180910390fd5b8135614391815f5160206157d05f395f51905f52611698565b610c9d57604051637d9ed8bb60e11b815260040160405180910390fd5b6001600160a01b0381165f9081526001830160205260408120541515610c29565b6143dd848484846001614cf4565b610e8b5783604051635274afe760e01b81526004016111a69190615011565b6144135f5160206157d05f395f51905f5282614d61565b6144305760405163e809b47160e01b815260040160405180910390fd5b60405181907f167f2ef0916cc07b225b41c99e634c73ac9dde50d336f05baebe24bc01dda63d905f90a250565b5f614466613c08565b6001600160a01b039092165f90815260049290920160205250604090205460ff1690565b5f610c29836001600160a01b038416614d6c565b5f8080806144b5866001600160a01b038716614db2565b909450925050505b9250929050565b5f611c09846001600160a01b03851684614dea565b5f6144e2613c08565b90505f6144ee88612847565b61ffff89165f90815260038401602052604090205490915060ff166145265760405163592c386560e01b815260040160405180910390fd5b61ffff88165f9081526002830160205260409020546145579061454b906127106155cd565b85906127106001614e06565b831015614577576040516313b1ca1360e01b815260040160405180910390fd5b83831115614598576040516398b35c0560e01b815260040160405180910390fd5b5f7f0000000000000000000000000faeeceab0bcb63be2fe984ea8c77778989d53ea6001600160a01b0316639d23c4c76040518163ffffffff1660e01b8152600401602060405180830381865afa1580156145f5573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906146199190615577565b6001600160a01b031663bbda76c8878a6040518363ffffffff1660e01b815260040161464692919061555e565b602060405180830381865afa158015614661573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906146859190615577565b905061469b6001600160a01b0387168387613b8c565b604051636cb3c0a160e01b8152600481018990526001600160a01b038881166024830152878116604483015260648201879052828116608483015260a48201869052831690636cb3c0a19060c4015f604051808303815f87803b158015614700575f5ffd5b505af1158015614712573d5f5f3e3d5ffd5b50505050505050505050505050565b5f61472b83612847565b60405163187834b560e11b8152600481018490529091506001600160a01b038216906330f0696a9060240161405a565b5f614764613c08565b61ffff83165f9081526001820160205260409020549091506001600160a01b03166147a257604051630b91e58760e41b815260040160405180910390fd5b61ffff82165f90815260038201602052604090205460ff16156147d857604051637952fbad60e11b815260040160405180910390fd5b61ffff82165f818152600383016020526040808220805460ff19166001179055517f8f86eba05a8d990e7035fac950b23b9eb70753c1028eb12ab28cf2814f4fe5859190a25050565b613bd58383836001614e51565b5f61483883612847565b60405163a3e2e39760e01b8152600481018490529091506001600160a01b0382169063a3e2e3979060240161405a565b5f614871613c08565b61ffff84165f9081526001820160205260409020549091506001600160a01b03166148af57604051630b91e58760e41b815260040160405180910390fd5b61ffff83165f818152600283016020526040808220549051859391927f80c3109759bf54a6031c8d1cf1aecb8bcf6542e65164ca6124ab1abdd87a314e91a461ffff9092165f9081526002909201602052604090912055565b5f6149116138af565b80549091506001600160a01b038381169116148061493e575060018101546001600160a01b038381169116145b1561495c576040516354b30c7f60e01b815260040160405180910390fd5b6001600160a01b0382165f90815260048201602052604090205460ff16614996576040516366790fe360e01b815260040160405180910390fd5b6001600160a01b0382165f818152600483016020526040808220805460ff19169055517fba2de54206fe2a237e72a332fa329a7caa151f9c73be4ad84e3af845f969e63e9190a25050565b5f805f1983850993909202808410938190039390930393915050565b634e487b715f52806020526024601cfd5b614a275f60025f5160206157f05f395f51905f52614e9b565b15614a4557604051633ee5aeb560e01b815260040160405180910390fd5b565b6040516001600160a01b038085166024830152831660448201526001600160e01b0319821660648201525f908190819060840160408051601f19818403018152918152602080830180516001600160e01b031663b700961360e01b1781525f808052918290528351939450919290918a5afa15614acf575f516020805191945081901c150291505b5094509492505050565b60405163095ea7b360e01b5f8181526001600160a01b038616600452602485905291602083604481808b5af1925060015f51148316614b2f578383151615614b23573d5f823e3d81fd5b5f873b113d1516831692505b60405250949350505050565b5f8181526001830160205260408120548015614c15575f614b5d6001836155cd565b85549091505f90614b70906001906155cd565b9050808214614bcf575f865f018281548110614b8e57614b8e61541e565b905f5260205f200154905080875f018481548110614bae57614bae61541e565b5f918252602080832090910192909255918252600188019052604090208390555b8554869080614be057614be061575a565b600190038181905f5260205f20015f90559055856001015f8681526020019081526020015f205f905560019350505050610ae5565b5f915050610ae5565b5092915050565b5f818152600183016020526040812054614c6a57508154600181810184555f848152602080822090930184905584548482528286019093526040902091909155610ae5565b505f610ae5565b614c79614ea2565b614a4557604051631afcd79f60e31b815260040160405180910390fd5b614c9e614c71565b610fb981614ebb565b5f825f018281548110614cbc57614cbc61541e565b905f5260205f200154905092915050565b5f610c298383614b3b565b5f8181526002830160205260408120819055610c298383614ccd565b6040516323b872dd60e01b5f8181526001600160a01b038781166004528616602452604485905291602083606481808c5af1925060015f51148316614d50578383151615614d44573d5f823e3d81fd5b5f883b113d1516831692505b604052505f60605295945050505050565b5f610c298383614c25565b5f81815260028301602052604081205480158015614d915750614d8f8484614ecc565b155b15610c295760405163015ab34360e11b8152600481018490526024016111a6565b5f818152600283016020526040812054819080614ddf57614dd38585614ecc565b92505f91506144bd9050565b6001925090506144bd565b5f8281526002840160205260408120829055611c098484614d61565b5f614e33614e1383614ed7565b8015614e2e57505f8480614e2957614e29615667565b868809115b151590565b614e3e8686866138d3565b614e489190615446565b95945050505050565b60405163a9059cbb60e01b5f8181526001600160a01b038616600452602485905291602083604481808b5af1925060015f51148316614b2f578383151615614b23573d5f823e3d81fd5b5414919050565b5f614eab613cf2565b54600160401b900460ff16919050565b614ec3614c71565b610fb98161414d565b5f610c298383613efd565b5f6002826003811115614eec57614eec61576e565b614ef69190615782565b60ff166001149050919050565b5f60208284031215614f13575f5ffd5b5035919050565b5f60208284031215614f2a575f5ffd5b81356001600160e01b031981168114610c29575f5ffd5b803561ffff81168114614f52575f5ffd5b919050565b6001600160a01b0381168114610fb9575f5ffd5b8035614f5281614f57565b5f5f5f60608486031215614f88575f5ffd5b83359250614f9860208501614f41565b91506040840135614fa881614f57565b809150509250925092565b5f5f60408385031215614fc4575f5ffd5b8235614fcf81614f57565b946020939093013593505050565b5f60208284031215614fed575f5ffd5b610c2982614f41565b5f60208284031215615006575f5ffd5b8135610c2981614f57565b6001600160a01b0391909116815260200190565b5f60208284031215615035575f5ffd5b50919050565b5f5f5f5f5f5f5f8789036101e0811215615053575f5ffd5b610120811215615061575f5ffd5b508796506101208801356001600160401b0381111561507e575f5ffd5b880160e0818b03121561508f575f5ffd5b95506101408801356001600160401b038111156150aa575f5ffd5b6150b68a828b01615025565b9550506150c66101608901614f6b565b93506150d56101808901614f6b565b92506150e46101a08901614f6b565b91506150f36101c08901614f6b565b905092959891949750929550565b5f5f83601f840112615111575f5ffd5b5081356001600160401b03811115615127575f5ffd5b6020830191508360208285010111156144bd575f5ffd5b5f5f5f5f60608587031215615151575f5ffd5b61515a85614f41565b93506020850135925060408501356001600160401b0381111561517b575f5ffd5b61518787828801615101565b95989497509550505050565b5f5f604083850312156151a4575f5ffd5b823591506151b460208401614f41565b90509250929050565b5f5f604083850312156151ce575f5ffd5b614fcf83614f41565b5f5f5f5f604085870312156151ea575f5ffd5b84356001600160401b038111156151ff575f5ffd5b61520b87828801615101565b90955093505060208501356001600160401b0381111561517b575f5ffd5b5f5f5f5f6080858703121561523c575f5ffd5b84359350602085013561524e81614f57565b93969395505050506040820135916060013590565b8015158114610fb9575f5ffd5b5f60208284031215615280575f5ffd5b8135610c2981615263565b5f5f5f5f6060858703121561529e575f5ffd5b843561515a81614f57565b5f5f5f606084860312156152bb575f5ffd5b6152c484614f41565b925060208401356152d481614f57565b929592945050506040919091013590565b5f5f5f5f5f60a086880312156152f9575f5ffd5b61530286614f41565b945060208601359350604086013561531981614f57565b94979396509394606081013594506080013592915050565b5f5f5f60608486031215615343575f5ffd5b8335925060208401356152d481614f57565b5f5f83601f840112615365575f5ffd5b5081356001600160401b0381111561537b575f5ffd5b6020830191508360208260051b85010111156144bd575f5ffd5b5f5f5f5f5f5f608087890312156153aa575f5ffd5b8635955060208701356153bc81614f57565b945060408701356001600160401b038111156153d6575f5ffd5b6153e289828a01615355565b90955093505060608701356001600160401b03811115615400575f5ffd5b61540c89828a01615355565b979a9699509497509295939492505050565b634e487b7160e01b5f52603260045260245ffd5b634e487b7160e01b5f52601160045260245ffd5b80820180821115610ae557610ae5615432565b6001815b60018411156154945780850481111561547857615478615432565b600184161561548657908102905b60019390931c92800261545d565b935093915050565b5f826154aa57506001610ae5565b816154b657505f610ae5565b81600181146154cc57600281146154d6576154f2565b6001915050610ae5565b60ff8411156154e7576154e7615432565b50506001821b610ae5565b5060208310610133831016604e8410600b8410161715615515575081810a610ae5565b6155215f198484615459565b805f190482111561553457615534615432565b029392505050565b5f610c29838361549c565b5f60208284031215615557575f5ffd5b5051919050565b6001600160a01b03929092168252602082015260400190565b5f60208284031215615587575f5ffd5b8151610c2981614f57565b5f602082840312156155a2575f5ffd5b8151610c2981615263565b5f602082840312156155bd575f5ffd5b815160ff81168114610c29575f5ffd5b81810381811115610ae557610ae5615432565b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b8481526001600160a01b03841660208201526060604082018190525f9061563290830184866155e0565b9695505050505050565b5f5f5f6060848603121561564e575f5ffd5b83359250602084013591506040840135614fa881615263565b634e487b7160e01b5f52601260045260245ffd5b5f5f85851115615689575f5ffd5b83861115615695575f5ffd5b5050820193919092039150565b80356001600160e01b03198116906004841015614c1e576001600160e01b031960049490940360031b84901b1690921692915050565b6001600160a01b03841681526040602082018190525f90614e4890830184866155e0565b5f5f8335601e19843603018112615711575f5ffd5b8301803591506001600160401b0382111561572a575f5ffd5b6020019150600581901b36038213156144bd575f5ffd5b838152604060208201525f614e486040830184866155e0565b634e487b7160e01b5f52603160045260245ffd5b634e487b7160e01b5f52602160045260245ffd5b5f60ff8316806157a057634e487b7160e01b5f52601260045260245ffd5b8060ff8416069150509291505056fef3177357ab46d8af007ab3fdb9af81da189e1068fefdc0073dca88a2cab40a00b63b6c1855ef12c3ce1467dc59d74e167a3a4f63f2ecef0203e34e2727af13009b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f00a2646970667358221220b245446cb93a09d7fd212357aa3c69531a64bfff69dd07f170c93d13540faae064736f6c634300081c0033","optimization_enabled":true,"verified_twin_address_hash":null,"is_verified":true,"compiler_settings":{"evmVersion":"cancun","libraries":{"src/machine/Machine.sol":{"MachineUtils":"0x9913685acda266d44a32ec1d9262435a0f891ea3"}},"metadata":{"appendCBOR":true,"bytecodeHash":"ipfs","useLiteralContent":false},"optimizer":{"enabled":true,"runs":150},"outputSelection":{"*":{"":["*"],"*":["*"]}},"remappings":["@openzeppelin/contracts/=lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/","@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/","@enso-weiroll/=lib/enso-weiroll/contracts/","@layerzerolabs/oft-evm/=lib/devtools/packages/oft-evm/","@layerzerolabs/oapp-evm/=lib/devtools/packages/oapp-evm/","@layerzerolabs/test-evm/=lib/devtools/packages/test-devtools-evm-foundry/","@layerzerolabs/lz-evm-protocol-v2/=lib/LayerZero-v2/packages/layerzero-v2/evm/protocol/","@layerzerolabs/lz-evm-oapp-v2/=lib/LayerZero-v2/packages/layerzero-v2/evm/oapp/","@layerzerolabs/lz-evm-messagelib-v2/=lib/LayerZero-v2/packages/layerzero-v2/evm/messagelib/","LayerZero-v2/=lib/LayerZero-v2/","devtools/=lib/devtools/packages/toolbox-foundry/src/","ds-test/=lib/LayerZero-v2/lib/forge-std/lib/ds-test/src/","enso-weiroll/=lib/enso-weiroll/contracts/","erc4626-tests/=lib/openzeppelin-contracts-upgradeable/lib/erc4626-tests/","forge-std/=lib/forge-std/src/","halmos-cheatcodes/=lib/openzeppelin-contracts-upgradeable/lib/halmos-cheatcodes/src/","openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/","openzeppelin-contracts/=lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/"],"viaIR":false},"optimization_runs":150,"sourcify_repo_url":null,"decoded_constructor_args":[["0x0FAEeCEab0BCb63bE2Fe984Ea8c77778989d53eA",{"internalType":"address","name":"_registry","type":"address"}],["0x0b93082D9b3C7C97fAcd250082899BAcf3af3885",{"internalType":"address","name":"_creForwarder","type":"address"}]],"compiler_version":"v0.8.28+commit.7893614a","is_verified_via_verifier_alliance":false,"verified_at":"2026-08-16T20:19:08.890485Z","implementations":[],"proxy_type":null,"external_libraries":[{"name":"src/libraries/MachineUtils.sol:MachineUtils","address_hash":"0x9913685AcdA266D44A32eC1d9262435A0F891EA3"},{"name":"src/machine/Machine.sol:MachineUtils","address_hash":"0x9913685AcdA266D44A32eC1d9262435A0F891EA3"}],"creation_bytecode":"0x60c060405234801561000f575f5ffd5b50604051615a18380380615a1883398101604081905261002e91610150565b6001600160a01b03821660805280610044610083565b6001600160a01b031660a05260017f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f005561007c610083565b5050610181565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00805468010000000000000000900460ff16156100d35760405163f92ee8a960e01b815260040160405180910390fd5b80546001600160401b03908116146101325780546001600160401b0319166001600160401b0390811782556040519081527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50565b80516001600160a01b038116811461014b575f5ffd5b919050565b5f5f60408385031215610161575f5ffd5b61016a83610135565b915061017860208401610135565b90509250929050565b60805160a0516158456101d35f395f818161092401526121ce01525f818161076f0152818161109b01528181611939015281816122600152818161291a0152818161424d015261459b01526158455ff3fe608060405234801561000f575f5ffd5b50600436106104bb575f3560e01c80637f26728811610279578063b921af6211610156578063da68cf8b116100ca578063f77f39761161008f578063f77f397614610a16578063fb42148714610a29578063fb95138e14610a3c578063fe5e5b3114610a4f578063fe9e89f114610a62578063fff40e0414610a75575f5ffd5b8063da68cf8b146109c2578063db016810146109ca578063dd2d104a146109dd578063ed08a2dd146109f0578063f2c098b714610a03575f5ffd5b8063c7c4ff461161011b578063c7c4ff461461097c578063c926c98b14610984578063cc1472d31461098c578063d0fb020314610994578063d114542b1461099c578063d8780161146109af575f5ffd5b8063b921af621461091f578063bf7e214f14610946578063c349e4321461094e578063c549beec14610961578063c6e6f59214610969575f5ffd5b806395179bc6116101ed578063a8020377116101b2578063a8020377146108c3578063a81762e3146108d6578063ac7a1b5b146108e9578063b3b3d5ce146108f1578063b7131c58146108f9578063b7e3c1b31461090c575f5ffd5b806395179bc61461086f578063971c5dee146108825780639a31e968146108955780639b4fa611146108a85780639d16d644146108b0575f5ffd5b806386e807f81161023e57806386e807f8146107fa57806387831bfd1461080d5780638ad30499146108205780638fb3603714610828578063904587df1461084957806392905bf71461085c575f5ffd5b80637f26728814610791578063805f2132146107a457806381c4ac2a146107b75780638601b34e146107df57806386dabf77146107f2575f5ffd5b806340fa9503116103a75780635d92632f1161031b57806374c59381116102e057806374c59381146107215780637501f741146107295780637564e42e14610731578063764eb869146107445780637a9e5e4b146107575780637b1039991461076a575f5ffd5b80635d92632f146106cd57806362ca8460146106e057806362d83f7d146106f357806364d9e88a146107065780636c9fa59e14610719575f5ffd5b80634ccc3df11161036c5780634ccc3df1146106715780634d2fba1f146106845780634ebd0b9414610697578063511436d41461069f578063570ca735146106b25780635a480c3c146106ba575f5ffd5b806340fa95031461061d578063472d35b914610630578063478426631461064357806348c04ed41461064b5780634b68fabb1461065e575f5ffd5b80631856ef9f1161043e57806327eb6c0f1161040357806327eb6c0f146105d75780632909ee27146105df5780632ba29d38146105f25780633307ce84146105fa57806334a411881461060d5780633be75aa314610615575f5ffd5b80631856ef9f146105765780631c1083e2146105895780631ce192d01461059c5780632310cce6146105b157806327ce952a146105c4575f5ffd5b80630e0c9129116104845780630e0c912914610538578063104285071461054b5780631046cb24146105535780631182570e1461056657806315bef4c11461056e575f5ffd5b8062e17b45146104bf57806301ffc9a7146104e557806302dc6d031461050857806307a00b1f1461051d57806307a2d13a14610525575b5f5ffd5b6104d26104cd366004614f03565b610a88565b6040519081526020015b60405180910390f35b6104f86104f3366004614f1a565b610ab5565b60405190151581526020016104dc565b61051b610516366004614f03565b610aeb565b005b6104f8610b60565b6104d2610533366004614f03565b610b7c565b61051b610546366004614f76565b610c30565b6104d2610ca2565b61051b610561366004614fb3565b610cbb565b6104d2610e91565b6104d2610ea3565b6104d2610584366004614fdd565b610eb5565b61051b610597366004614ff6565b610f18565b6105a4610f8c565b6040516104dc9190615011565b61051b6105bf366004614ff6565b610fa7565b61051b6105d236600461503b565b610fbc565b6105a46115a9565b6105a46105ed366004614f03565b6115c4565b6105a46115da565b61051b610608366004614ff6565b6115e3565b6105a4611657565b6104d2611672565b6104f861062b366004614f03565b611684565b61051b61063e366004614ff6565b61169e565b6105a4611712565b61051b61065936600461513e565b61172d565b61051b61066c366004614ff6565b61179e565b61051b61067f366004614ff6565b61180c565b6104f8610692366004614ff6565b611880565b6104d26118e1565b61051b6106ad366004614f03565b611b30565b6105a4611b42565b6105a46106c8366004615193565b611b87565b6104f86106db366004614ff6565b611c11565b61051b6106ee366004614ff6565b611ca0565b61051b610701366004614f03565b611d14565b61051b6107143660046151bd565b611d89565b6105a4611dd0565b6104d2611de8565b6104d2611dfa565b61051b61073f366004614f03565b611eae565b61051b610752366004614fdd565b611f23565b61051b610765366004614ff6565b611f60565b6105a47f000000000000000000000000000000000000000000000000000000000000000081565b61051b61079f366004614ff6565b611fd0565b61051b6107b23660046151d7565b6121bb565b6107ca6107c5366004614f03565b612334565b604080519283526020830191909152016104dc565b6104f86107ed366004614ff6565b61238f565b6104d26123a5565b6104d2610808366004615229565b6123b7565b6104f861081b366004614fdd565b612574565b6104d261259c565b6108306125ae565b6040516001600160e01b031990911681526020016104dc565b61051b610857366004614f03565b6125e3565b61051b61086a366004615270565b6125f5565b61051b61087d36600461528b565b6126aa565b6105a4610890366004614fdd565b612847565b61051b6108a3366004614f03565b612891565b6104d2612906565b61051b6108be3660046152a9565b612918565b6105a46108d1366004614f03565b612b01565b61051b6108e43660046152e5565b612b57565b6104d2612df9565b6104d2612e75565b61051b6109073660046151bd565b612e87565b61051b61091a366004614fdd565b612eca565b6105a47f000000000000000000000000000000000000000000000000000000000000000081565b6105a4612f07565b6104f861095c366004614f03565b612f1c565b6105a4612f70565b6104d2610977366004614f03565b612f79565b6105a461301e565b6104f8613027565b6104d2613043565b6105a4613055565b61051b6109aa366004614f03565b613070565b6104d26109bd366004615331565b6130e5565b6105a461329f565b61051b6109d83660046151bd565b6132a8565b61051b6109eb3660046151bd565b6132eb565b61051b6109fe366004614f03565b613329565b61051b610a11366004614ff6565b6133e3565b61051b610a24366004615270565b613457565b61051b610a37366004615395565b6134d5565b6104f8610a4a366004614fdd565b613690565b61051b610a5d366004614f03565b6136c5565b61051b610a70366004614ff6565b613804565b61051b610a83366004614f03565b613816565b5f610a9161388b565b6011018281548110610aa557610aa561541e565b905f5260205f2001549050919050565b5f6001600160e01b0319821663402f909960e11b1480610ae557506301ffc9a760e01b6001600160e01b03198316145b92915050565b610af36138af565b600301546001600160a01b03163314610b1f57604051635c427cd960e01b815260040160405180910390fd5b5f610b2861388b565b600a81015460405191925083917f0e03f7b96ab4a7bfa6f4031ad2b5b26d00ab8842798bedd8d127fd93203a4f03905f90a3600a0155565b5f610b696138af565b60030154600160a01b900460ff16919050565b5f5f610b8661388b565b9050610c2981600601546001610b9c9190615446565b600d830154610bac90600a61553c565b8354604080516318160ddd60e01b815290516001600160a01b03909216916318160ddd916004808201926020929091908290030181865afa158015610bf3573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610c179190615547565b610c219190615446565b8591906138d3565b9392505050565b610c38613983565b610c44335b5f3661399f565b5f610c4d61388b565b5f8581526012919091016020526040902080549091506001600160a01b0316610c8957604051633d23e4d160e11b815260040160405180910390fd5b610c94848484613a8c565b50610c9d613b6e565b505050565b5f610cb6610cae61388b565b601301613b83565b905090565b610cc36138af565b60030154600160a01b900460ff1615610cef57604051633dffcec760e11b815260040160405180910390fd5b610cf76138af565b546001600160a01b03163314610d2057604051635c427cd960e01b815260040160405180910390fd5b5f610d2961388b565b6010810154909150610d48906001600160a01b03858116911684613b8c565b601081015460405163421ddd4f60e11b81526001600160a01b039091169063843bba9e90610d7c908690869060040161555e565b5f604051808303815f87803b158015610d93575f5ffd5b505af1158015610da5573d5f5f3e3d5ffd5b50505050826001600160a01b031681600f01547fb89c5d3291e293d70a6d4a836c1b4f7f5c3e96cd11eead5bce2c4b259722ea8584604051610de991815260200190565b60405180910390a36040516370a0823160e01b81526001600160a01b038416906370a0823190610e1d903090600401615011565b602060405180830381865afa158015610e38573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610e5c9190615547565b158015610e79575060018101546001600160a01b03848116911614155b15610c9d57610e8b6013820184613bf4565b50505050565b5f610e9a61388b565b60070154905090565b5f610eac61388b565b600b0154905090565b5f5f610ebf613c08565b61ffff84165f9081526001820160205260409020549091506001600160a01b0316610efd57604051630b91e58760e41b815260040160405180910390fd5b61ffff9092165f908152600290920160205250604090205490565b610f2133610c3d565b5f610f2a6138af565b60018101546040519192506001600160a01b03808516929116907f47b4da9ab18bde67f1748d49bcbdde4ad81292aecedd7f0ba3585f5f7d8f110c905f90a360010180546001600160a01b0319166001600160a01b0392909216919091179055565b5f610f956138af565b600301546001600160a01b0316919050565b610fb033610c3d565b610fb981613c2c565b50565b5f610fc5613cf2565b805490915060ff600160401b82041615906001600160401b03165f81158015610feb5750825b90505f826001600160401b031660011480156110065750303b155b905081158015611014575080155b156110325760405163f92ee8a960e01b815260040160405180910390fd5b845467ffffffffffffffff19166001178555831561105c57845460ff60401b1916600160401b1785555b5f61106561388b565b90504681600f018190555086816010015f6101000a8154816001600160a01b0302191690836001600160a01b031602179055505f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316634bb93ab16040518163ffffffff1660e01b8152600401602060405180830381865afa1580156110f5573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111199190615577565b60405163094b14a760e21b81529091506001600160a01b0382169063252c529c90611148908c90600401615011565b602060405180830381865afa158015611163573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111879190615592565b6111af578860405163ebb3197d60e01b81526004016111a69190615011565b60405180910390fd5b5f896001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156111ec573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061121091906155ad565b83546001600160a01b03808e166001600160a01b0319928316178655600186018054918e169190921617905560ff16905061124e601384018b613d1a565b5061125a8160126155cd565b600d8401556001600160a01b038c16156113ea57604051637221254f60e01b8152600481018490526001600160a01b03808e16602483015283166044820152739913685acda266d44a32ec1d9262435a0f891ea390637221254f906064015f6040518083038186803b1580156112ce575f5ffd5b505af41580156112e0573d5f5f3e3d5ffd5b50508454604080516318160ddd60e01b815290515f94506001600160a01b0390921692506318160ddd9160048083019260209291908290030181865afa15801561132c573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906113509190615547565b6006850154600d8601546040516001622b2d2b60e01b031981526004810192909252602482018390526044820152909150739913685acda266d44a32ec1d9262435a0f891ea39063ffd4d2d590606401602060405180830381865af41580156113bb573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906113df9190615547565b6009850155506113fb565b6113f581600a61553c565b60098401555b8a6001600160a01b03166379ba50976040518163ffffffff1660e01b81526004015f604051808303815f87803b158015611433575f5ffd5b505af1158015611445573d5f5f3e3d5ffd5b505050504283600701819055504283600801819055508e5f01602081019061146d9190614ff6565b836002015f6101000a8154816001600160a01b0302191690836001600160a01b031602179055508e60200160208101906114a79190614ff6565b836003015f6101000a8154816001600160a01b0302191690836001600160a01b031602179055508e60400160208101906114e19190614ff6565b6004840180546001600160a01b0319166001600160a01b039290921691909117905560608f0135600584015560808f0135600a84015560a08f0135600b84015560c08f0135600c84015560e08f0135600e8401556101008f013560158401556115498e613d2e565b6115528d613ea0565b505050831561159b57845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b505050505050505050505050565b5f6115b26138af565b600101546001600160a01b0316919050565b5f610ae5826115d161388b565b60130190613ef2565b5f610f9561388b565b6115ec33610c3d565b5f6115f561388b565b60038101546040519192506001600160a01b03808516929116907fcd1fff739849339e94f95ee5c7fc6b3610b5f8feb959037c03f9f317eb1b1911905f90a360030180546001600160a01b0319166001600160a01b0392909216919091179055565b5f61166061388b565b601001546001600160a01b0316919050565b5f61167b61388b565b600e0154905090565b5f610ae5825f5160206157d05f395f51905f525b90613efd565b6116a733610c3d565b5f6116b061388b565b60048101546040519192506001600160a01b03808516929116907facbd074db1a997c1632eb3d55a4c9813e0883267f14740568d0535dc23077ce4905f90a360040180546001600160a01b0319166001600160a01b0392909216919091179055565b5f61171b6138af565b600201546001600160a01b0316919050565b6117356138af565b60030154600160a01b900460ff161561176157604051633dffcec760e11b815260040160405180910390fd5b6117696138af565b546001600160a01b0316331461179257604051635c427cd960e01b815260040160405180910390fd5b610e8b84848484613f14565b6117a733610c3d565b5f6117b06138af565b80546040519192506001600160a01b03808516929116907fd9266cd7f40f2b8e1a597180acd92a051a1a91f97ff78127f3a318f85727beff905f90a380546001600160a01b0319166001600160a01b0392909216919091179055565b61181533610c3d565b5f61181e6138af565b60038101546040519192506001600160a01b03808516929116907f5c156e2486854ba582ce30e5428a1cce1a4de221f180f8472445b83c7136a34b905f90a360030180546001600160a01b0319166001600160a01b0392909216919091179055565b5f5f61188a6138af565b80549091506001600160a01b03848116911614806118b7575060018101546001600160a01b038481169116145b80610c2957506001600160a01b0383165f90815260048201602052604090205460ff169392505050565b5f6118ea613983565b6118f333611c11565b61191057604051635c427cd960e01b815260040160405180910390fd5b5f61191961388b565b90505f739913685acda266d44a32ec1d9262435a0f891ea363bc336959837f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316634bb93ab16040518163ffffffff1660e01b8152600401602060405180830381865afa158015611993573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906119b79190615577565b6119bf6115a9565b60405160e085901b6001600160e01b031916815260048101939093526001600160a01b039182166024840152163314156044820152606401602060405180830381865af4158015611a12573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611a369190615547565b90507f22510cc1266408a3b15fed6f8895391925f85578a5d5a557966133dc0614b43d81604051611a6991815260200190565b60405180910390a16040516381b0f91360e01b8152600481018390525f90739913685acda266d44a32ec1d9262435a0f891ea3906381b0f91390602401602060405180830381865af4158015611ac1573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611ae59190615547565b90508015611b21576040518181527fef45ded67a593d4122c09b7572f8af65d972a83769c560cbf443d82c9054a05d9060200160405180910390a15b50915050611b2d613b6e565b90565b611b3933610c3d565b610fb981613fc3565b5f5f611b4c6138af565b6003810154909150600160a01b900460ff16611b725780546001600160a01b0316611b81565b60018101546001600160a01b03165b91505090565b5f5f611b9161388b565b5f8581526012919091016020526040902080549091506001600160a01b0316611bcd57604051633d23e4d160e11b815260040160405180910390fd5b61ffff83165f9081526001820160205260409020546001600160a01b031680611c0957604051635f8b0aab60e01b815260040160405180910390fd5b949350505050565b5f5f611c1b6138af565b6003810154909150600160a01b900460ff16158015611c8057506003810154600160a81b900460ff161580611c5c575080546001600160a01b038481169116145b80611c8057506001600160a01b0383165f90815260048201602052604090205460ff165b80610c29575060018101546001600160a01b038481169116149392505050565b611ca933610c3d565b5f611cb26138af565b60028101546040519192506001600160a01b03808516929116907f0ff73514c2ecd6855fbfd168fd7555ac8e74037d368f1458f568cd0db706fe30905f90a360020180546001600160a01b0319166001600160a01b0392909216919091179055565b611d1c6138af565b600301546001600160a01b03163314611d4857604051635c427cd960e01b815260040160405180910390fd5b5f611d5161388b565b600b81015460405191925083917faec7bc124bf42fd28983fed34c19fc24cd2f208810f7a49bfc47b420d0dd1fb5905f90a3600b0155565b611d91611b42565b6001600160a01b0316336001600160a01b031614611dc257604051635c427cd960e01b815260040160405180910390fd5b611dcc8282614024565b5050565b5f611dd961388b565b546001600160a01b0316919050565b5f611df161388b565b60060154905090565b5f5f611e0461388b565b90505f1981600e015403611e1a575f1991505090565b8054604080516318160ddd60e01b815290515f926001600160a01b0316916318160ddd9160048083019260209291908290030181865afa158015611e60573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611e849190615547565b905081600e01548110611e97575f611ea7565b8082600e0154611ea791906155cd565b9250505090565b611eb66138af565b600301546001600160a01b03163314611ee257604051635c427cd960e01b815260040160405180910390fd5b5f611eeb61388b565b600c81015460405191925083917fc88eb0fbdebf4d858eb97fa1aa1fa76c132ccb2ece37c136583bf0d890529b24905f90a3600c0155565b611f2b6138af565b600301546001600160a01b03163314611f5757604051635c427cd960e01b815260040160405180910390fd5b610fb98161408c565b33611f69612f07565b6001600160a01b0316816001600160a01b031614611f9b578060405162d1953b60e31b81526004016111a69190615011565b816001600160a01b03163b5f03611fc757816040516361798f2f60e11b81526004016111a69190615011565b611dcc8261414d565b611fd8613983565b611fe06138af565b600101546001600160a01b0316331461200c57604051635c427cd960e01b815260040160405180910390fd5b5f61201561388b565b60118101549091505f5b818110156120a4575f836012015f8560110184815481106120425761204261541e565b905f5260205f20015481526020019081526020015f20905061207085826006016141a490919063ffffffff16565b5061207e60098201866141a4565b5061208c600c8201866141a4565b5061209a600f8201866141a4565b505060010161201f565b505f6120ae613c08565b8054925090505f5b82811015612173575f826001015f845f0184815481106120d8576120d861541e565b5f9182526020808320601083040154600f9092166002026101000a90910461ffff1683528201929092526040908101909120549051633df4e34160e11b81526001600160a01b0390911691508190637be9c6829061213a908990600401615011565b5f604051808303815f87803b158015612151575f5ffd5b505af1158015612163573d5f5f3e3d5ffd5b50505050508060010190506120b6565b5061217d846141b8565b6040516001600160a01b038516907f5c2bda6e4510afb949f70a9e2b6c6f6fdfc29cc77bf5b4c3913f1b806dd22edb905f90a2505050610fb9613b6e565b6121c3613983565b336001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000168103612203576121fe8585614357565b61223c565b61220b6115a9565b6001600160a01b0316816001600160a01b03161461223c57604051635c427cd960e01b815260040160405180910390fd5b739913685acda266d44a32ec1d9262435a0f891ea36325663f2961225e61388b565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316639d23c4c76040518163ffffffff1660e01b8152600401602060405180830381865afa1580156122ba573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906122de9190615577565b86866040518563ffffffff1660e01b81526004016122ff9493929190615608565b5f6040518083038186803b158015612315575f5ffd5b505af4158015612327573d5f5f3e3d5ffd5b5050505050610e8b613b6e565b5f5f5f61233f61388b565b5f8581526012919091016020526040902080549091506001600160a01b031661237b57604051633d23e4d160e11b815260040160405180910390fd5b806003015481600201549250925050915091565b5f610ae58261239c61388b565b601301906143ae565b5f6123ae61388b565b60110154919050565b5f6123c0613983565b6123c86138af565b60030154600160a01b900460ff16156123f457604051633dffcec760e11b815260040160405180910390fd5b5f6123fd61388b565b60028101549091506001600160a01b0316331461242d57604051635c427cd960e01b815260040160405180910390fd5b5f61243787612f79565b90505f612442611dfa565b90508082111561246f57604051634a768b1360e01b815260048101839052602481018290526044016111a6565b85821015612490576040516305f50c7d60e21b815260040160405180910390fd5b60018301546124aa906001600160a01b031633308b6143cf565b82546040516340c10f1960e01b81526001600160a01b03909116906340c10f19906124db908a90869060040161555e565b5f604051808303815f87803b1580156124f2575f5ffd5b505af1158015612504573d5f5f3e3d5ffd5b5050505087836006015f82825461251b9190615446565b9091555050604080518981526020810184905286916001600160a01b038a169133917f6e610d335252f97251efcf0ddbb78a6c6d2ae0e5c0e4b123bc0e6de074628a64910160405180910390a450915050611c09613b6e565b5f61257d613c08565b61ffff9092165f90815260039290920160205250604090205460ff1690565b5f6125a561388b565b60150154905090565b5f5160206157b05f395f51905f5280545f9190600160a01b900460ff166125d5575f611b81565b638fb3603760e01b91505090565b6125ec33610c3d565b610fb9816143fc565b6125fd6138af565b600101546001600160a01b0316331461262957604051635c427cd960e01b815260040160405180910390fd5b5f6126326138af565b600381015490915060ff600160a01b90910416151582151514611dcc57600381018054831515600160a01b0260ff60a01b199091161790556040517fb8db430d57a0e0c8a3c76dcd89a53a978c46ad23c7dccc6915212384711949ef9061269e90841515815260200190565b60405180910390a15050565b6126b2613983565b5f6126bb61388b565b90506126c63361445d565b156127f3575f80806126da8587018761563c565b5f838152601288016020526040902080549396509194509250906001600160a01b031661271a57604051633d23e4d160e11b815260040160405180910390fd5b8115612786575f61272e600f83018b61448a565b90505f61273b85836155cd565b90505f61274b600685018d61449e565b9150508181111561276f57604051633eb172e760e01b815260040160405180910390fd5b61277d600f85018d846144c4565b505050506127ea565b5f612794600c83018b61449e565b91505f90506127a38583615446565b90505f6127b3600985018d61449e565b915050808211156127d757604051633eb172e760e01b815260040160405180910390fd5b6127e5600c85018d846144c4565b505050505b50505050612820565b60108101546001600160a01b0316331461282057604051635c427cd960e01b815260040160405180910390fd5b6128356001600160a01b0386163330876143cf565b61283e856141b8565b50610e8b613b6e565b5f5f612851613c08565b61ffff84165f90815260019190910160205260409020546001600160a01b0316905080610ae557604051630b91e58760e41b815260040160405180910390fd5b6128996138af565b600301546001600160a01b031633146128c557604051635c427cd960e01b815260040160405180910390fd5b5f6128ce61388b565b601581015460405191925083917f5f4eb30a629ace63c93aff5ffa6f95d4e7372a5952badf2b715872f48609a1ab905f90a360150155565b5f61290f61388b565b60050154905090565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316633d8df6676040518163ffffffff1660e01b8152600401602060405180830381865afa158015612974573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906129989190615577565b6001600160a01b0316336001600160a01b0316146129c957604051631966391b60e11b815260040160405180910390fd5b5f6129d2613c08565b61ffff85165f9081526001820160205260409020549091506001600160a01b031615612a115760405163cb01460760e01b815260040160405180910390fd5b6001600160a01b038316612a3857604051630c2495b960e11b815260040160405180910390fd5b61ffff8085165f81815260018085016020908152604080842080546001600160a01b038b166001600160a01b03199091168117909155600280890184528286208a9055600389018452828620805460ff19908116871790915582875260048a0185528387208054909116861790558854948501895588865292852060108504018054600f9095169093026101000a80870297021990931695909517905592517f9455b805174f4eafd22526b0232e96c50ec74ba9be4a0b2f45228add478543e69190a350505050565b5f5f612b0b61388b565b5f8481526012919091016020526040902080549091506001600160a01b0316612b4757604051633d23e4d160e11b815260040160405180910390fd5b546001600160a01b031692915050565b612b5f613983565b612b676138af565b60030154600160a01b900460ff1615612b9357604051633dffcec760e11b815260040160405180910390fd5b612b9b6138af565b546001600160a01b03163314612bc457604051635c427cd960e01b815260040160405180910390fd5b5f612bcd61388b565b5f86815260128201602052604090208054919250906001600160a01b0316612c0857604051633d23e4d160e11b815260040160405180910390fd5b601281015460ff1615612c2e57604051634307631760e11b815260040160405180910390fd5b61ffff87165f9081526001820160205260409020546001600160a01b031680612c6a57604051635f8b0aab60e01b815260040160405180910390fd5b5f80612c79600f85018961449e565b90925090505f612c8c600686018a61449e565b91505080821115612cb05760405163b61b9df760e01b815260040160405180910390fd5b80821015612cd157604051633eb172e760e01b815260040160405180910390fd5b612cf58984612ce05789612cea565b612cea8a85615446565b600f880191906144c4565b50612d048b8b868c8c8c6144d9565b886001600160a01b03168a7fb89c5d3291e293d70a6d4a836c1b4f7f5c3e96cd11eead5bce2c4b259722ea858a604051612d4091815260200190565b60405180910390a36040516370a0823160e01b81526001600160a01b038a16906370a0823190612d74903090600401615011565b602060405180830381865afa158015612d8f573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612db39190615547565b158015612dd0575060018601546001600160a01b038a8116911614155b15612de457612de2601387018a613bf4565b505b505050505050612df2613b6e565b5050505050565b5f5f612e0361388b565b60018101546040516370a0823160e01b81529192506001600160a01b0316906370a0823190612e36903090600401615011565b602060405180830381865afa158015612e51573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611b819190615547565b5f612e7e61388b565b600a0154905090565b612e8f611b42565b6001600160a01b0316336001600160a01b031614612ec057604051635c427cd960e01b815260040160405180910390fd5b611dcc8282614721565b612ed26138af565b600301546001600160a01b03163314612efe57604051635c427cd960e01b815260040160405180910390fd5b610fb98161475b565b5f805f5160206157b05f395f51905f52612b47565b5f5f612f2661388b565b5f8481526012919091016020526040902080549091506001600160a01b0316612f6257604051633d23e4d160e11b815260040160405180910390fd5b6012015460ff161592915050565b5f611dd96138af565b5f5f612f8361388b565b9050610c2981600d0154600a612f99919061553c565b8254604080516318160ddd60e01b815290516001600160a01b03909216916318160ddd916004808201926020929091908290030181865afa158015612fe0573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906130049190615547565b61300e9190615446565b6006830154610c21906001615446565b5f61171b61388b565b5f6130306138af565b60030154600160a81b900460ff16919050565b5f61304c61388b565b600c0154905090565b5f61305e61388b565b600401546001600160a01b0316919050565b6130786138af565b600201546001600160a01b031633146130a457604051635c427cd960e01b815260040160405180910390fd5b5f6130ad61388b565b600e81015460405191925083917f4f683a6f2905f2dfe5f0674962dc46bbda476371cbebc13ca42fe41e271c1b77905f90a3600e0155565b5f6130ee613983565b6130f66138af565b60030154600160a01b900460ff161561312257604051633dffcec760e11b815260040160405180910390fd5b5f61312b61388b565b60038101549091506001600160a01b0316331461315b57604051635c427cd960e01b815260040160405180910390fd5b5f61316586610b7c565b90505f613170612df9565b90508082111561319d5760405163264f877960e21b815260048101839052602481018290526044016111a6565b848210156131be576040516305f50c7d60e21b815260040160405180910390fd5b60018301546131d7906001600160a01b03168784614821565b8254604051632770a7eb60e21b81526001600160a01b0390911690639dc29fac906132089033908b9060040161555e565b5f604051808303815f87803b15801561321f575f5ffd5b505af1158015613231573d5f5f3e3d5ffd5b5050505081836006015f82825461324891906155cd565b909155505060408051838152602081018990526001600160a01b0388169133917f3f693fff038bb8a046aa76d9516190ac7444f7d69cf952c4cbdc086fdef2d6fc910160405180910390a350915050610c29613b6e565b5f6115b261388b565b6132b0611b42565b6001600160a01b0316336001600160a01b0316146132e157604051635c427cd960e01b815260040160405180910390fd5b611dcc828261482e565b6132f36138af565b600301546001600160a01b0316331461331f57604051635c427cd960e01b815260040160405180910390fd5b611dcc8282614868565b613331613983565b61333a33610c3d565b5f61334361388b565b5f83815260128201602052604090208054919250906001600160a01b031661337e57604051633d23e4d160e11b815260040160405180910390fd5b601281015460ff166133a357604051637952fbad60e11b815260040160405180910390fd5b60128101805460ff1916905560405183907fc4010b78fc4ede3c7bef523885761352419c2d251a00586c26f64d8d5e8315e9905f90a25050610fb9613b6e565b6133ec33610c3d565b5f6133f561388b565b60028101546040519192506001600160a01b03808516929116907f166d94140c1558bd891548eab89b904b8f87dc2e6877f4d8719849084d4fb4a3905f90a360020180546001600160a01b0319166001600160a01b0392909216919091179055565b61346033610c3d565b5f6134696138af565b600381015490915060ff600160a81b90910416151582151514611dcc57600381018054831515600160a81b0260ff60a81b199091161790556040517fd5b18724af9617cf1a7d350960b8c5e5b49a15dee0b85dffd817c8c50ff0a2a09061269e90841515815260200190565b6134dd613983565b6134e633610c3d565b5f6134ef61388b565b9050865f0361351157604051633212217560e21b815260040160405180910390fd5b80600f01548703613535576040516328151e8560e11b815260040160405180910390fd5b5f878152601282016020526040902080546001600160a01b03161561356d576040516328c1ba0160e01b815260040160405180910390fd5b6001600160a01b03871661359457604051631c2e8b0b60e11b815260040160405180910390fd5b6011820180546001810182555f918252602082200189905581546001600160a01b0319166001600160a01b038916908117835560405190918a917fca7785eb0ed792032b5c3582a99c476c34573693a5d096718fc4cf90570d54a99190a384838114613613576040516373f8993760e11b815260040160405180910390fd5b5f5b8181101561367c576136748a8989848181106136335761363361541e565b90506020020160208101906136489190614fdd565b88888581811061365a5761365a61541e565b905060200201602081019061366f9190614ff6565b613a8c565b600101613615565b50505050613688613b6e565b505050505050565b5f8061369a613c08565b61ffff939093165f90815260019093016020526040909220546001600160a01b031690911415919050565b6136cd613983565b6136d633610c3d565b5f6136df61388b565b5f83815260128201602052604090208054919250906001600160a01b031661371a57604051633d23e4d160e11b815260040160405180910390fd5b601281015460ff161561373f57604051625ecddb60e01b815260040160405180910390fd5b60038101541561376257604051636e933b5f60e11b815260040160405180910390fd5b60405163b25c0e1360e01b815260048101829052739913685acda266d44a32ec1d9262435a0f891ea39063b25c0e13906024015f6040518083038186803b1580156137ab575f5ffd5b505af41580156137bd573d5f5f3e3d5ffd5b50505060128201805460ff191660011790555060405183907ffbc0f7bdf76a0b3a03666f4796ab5d9754e975143fb8d037bae04daee68a4ae5905f90a25050610fb9613b6e565b61380d33610c3d565b610fb981614908565b61381e6138af565b600301546001600160a01b0316331461384a57604051635c427cd960e01b815260040160405180910390fd5b5f61385361388b565b600581015460405191925083917faeded51a1c475e849903f8cc85752a94e859a66faee995552e8ba8c69c86ccb2905f90a360050155565b7f55fe2a17e400bcd0e2125123a7fc955478e727b29a4c522f4f2bd95d961bd90090565b7f7e702089668346e906996be6de3dfc0cb2b0c125fc09b3c0391871825913e00090565b5f5f5f6138e086866149e1565b91509150815f03613904578381816138fa576138fa615667565b0492505050610c29565b81841161391b5761391b60038515026011186149fd565b5f848688095f868103871696879004966002600389028118808a02820302808a02820302808a02820302808a02820302808a02820302808a02909103029181900381900460010185841190960395909502919093039390930492909217029150509392505050565b61398b614a0e565b60025f5160206157f05f395f51905f525b55565b5f5160206157b05f395f51905f525f806139d76139ba612f07565b87306139c960045f8a8c61567b565b6139d2916156a2565b614a47565b91509150816136885763ffffffff811615613a7257825460ff60a01b1916600160a01b178355613a05612f07565b6001600160a01b03166394c7d7ee8787876040518463ffffffff1660e01b8152600401613a34939291906156d8565b5f604051808303815f87803b158015613a4b575f5ffd5b505af1158015613a5d573d5f5f3e3d5ffd5b5050845460ff60a01b19168555506136889050565b8560405162d1953b60e31b81526004016111a69190615011565b5f613a9561388b565b5f8581526012919091016020908152604080832061ffff8716845260018101909252909120549091506001600160a01b031615613ae5576040516331fec61f60e21b815260040160405180910390fd5b6001600160a01b038216613b0c57604051630c2495b960e11b815260040160405180910390fd5b61ffff83165f81815260018301602052604080822080546001600160a01b0319166001600160a01b038716908117909155905190929187917fe9fa606ff1542a4b25860722c547a2062732708a184ff8a5d797780fe7df03b29190a450505050565b60015f5160206157f05f395f51905f5261399c565b5f610ae5825490565b613b988383835f614ad9565b610c9d57613ba983835f6001614ad9565b613bc85782604051635274afe760e01b81526004016111a69190615011565b613bd58383836001614ad9565b610c9d5782604051635274afe760e01b81526004016111a69190615011565b5f610c29836001600160a01b038416614b3b565b7f7363d524082cdf545f1ac33985598b84d2470b8b4fbcc6cb47698cc1b2a0350090565b5f613c356138af565b80549091506001600160a01b0383811691161480613c62575060018101546001600160a01b038381169116145b80613c8657506001600160a01b0382165f90815260048201602052604090205460ff165b15613ca457604051630f9ef27d60e01b815260040160405180910390fd5b6001600160a01b0382165f818152600483016020526040808220805460ff19166001179055517f2a72788b2f28a2581746a26fe1b56e7d130aca3165f769fada57d119a5958e509190a25050565b5f807ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00610ae5565b5f610c29836001600160a01b038416614c25565b613d36614c71565b5f613d3f6138af565b9050613d4e6020830183614ff6565b81546001600160a01b0319166001600160a01b0391909116178155613d796040830160208401614ff6565b6001820180546001600160a01b0319166001600160a01b0392909216919091179055613dab6060830160408401614ff6565b6002820180546001600160a01b0319166001600160a01b0392909216919091179055613ddd6080830160608401614ff6565b6003820180546001600160a01b0319166001600160a01b0392909216919091179055613e0f60c0830160a08401615270565b600382018054911515600160a81b0260ff60a81b199092169190911790555f5b613e3c60c08401846156fc565b9050811015613e8757613e7f613e5560c08501856156fc565b83818110613e6557613e6561541e565b9050602002016020810190613e7a9190614ff6565b613c2c565b600101613e2f565b50611dcc613e9b60a0840160808501614ff6565b614c96565b613ea8614c71565b5f613eb382806156fc565b905090505f5b81811015610c9d57613eea613ece84806156fc565b83818110613ede57613ede61541e565b905060200201356143fc565b600101613eb9565b5f610c298383614ca7565b5f8181526001830160205260408120541515610c29565b5f613f1e85612847565b9050613f28613c08565b61ffff86165f908152600391909101602052604090205460ff16613f5f5760405163592c386560e01b815260040160405180910390fd5b6040516363ac907760e11b81526001600160a01b0382169063c75920ee90613f8f90879087908790600401615741565b5f604051808303815f87803b158015613fa6575f5ffd5b505af1158015613fb8573d5f5f3e3d5ffd5b505050505050505050565b613fda5f5160206157d05f395f51905f5282614ccd565b613ff757604051633d16c06160e21b815260040160405180910390fd5b60405181907fab3aa5ac034f828a77403db224191d1335e3d05091dbe3b2895756926ca45dbd905f90a250565b5f61402e83612847565b604051633a644cbf60e21b8152600481018490529091506001600160a01b0382169063e99132fc906024015b5f604051808303815f87803b158015614071575f5ffd5b505af1158015614083573d5f5f3e3d5ffd5b50505050505050565b5f614095613c08565b61ffff83165f9081526001820160205260409020549091506001600160a01b03166140d357604051630b91e58760e41b815260040160405180910390fd5b61ffff82165f90815260038201602052604090205460ff1661410757604051625ecddb60e01b815260040160405180910390fd5b61ffff82165f818152600383016020526040808220805460ff19169055517f88f476150f96d992b0624a303d4c68f8e075cd2a6a9d50747bfae2bfe625ef869190a25050565b5f5160206157b05f395f51905f5280546001600160a01b0319166001600160a01b0383161781556040517f2f658b440c35314f52658ea8a740e05b284cdc84dc9ae01e891f21b8933e7cad9061269e908490615011565b5f610c29836001600160a01b038416614cd8565b6040516370a0823160e01b81525f906001600160a01b038316906370a08231906141e6903090600401615011565b602060405180830381865afa158015614201573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906142259190615547565b1115610fb9575f6142418261423861388b565b60130190613d1a565b905080801561433757507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316634bb93ab16040518163ffffffff1660e01b8152600401602060405180830381865afa1580156142a7573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906142cb9190615577565b6001600160a01b031663252c529c836040518263ffffffff1660e01b81526004016142f69190615011565b602060405180830381865afa158015614311573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906143359190615592565b155b15611dcc578160405163ebb3197d60e01b81526004016111a69190615011565b6040811461437857604051633a94310160e11b815260040160405180910390fd5b8135614391815f5160206157d05f395f51905f52611698565b610c9d57604051637d9ed8bb60e11b815260040160405180910390fd5b6001600160a01b0381165f9081526001830160205260408120541515610c29565b6143dd848484846001614cf4565b610e8b5783604051635274afe760e01b81526004016111a69190615011565b6144135f5160206157d05f395f51905f5282614d61565b6144305760405163e809b47160e01b815260040160405180910390fd5b60405181907f167f2ef0916cc07b225b41c99e634c73ac9dde50d336f05baebe24bc01dda63d905f90a250565b5f614466613c08565b6001600160a01b039092165f90815260049290920160205250604090205460ff1690565b5f610c29836001600160a01b038416614d6c565b5f8080806144b5866001600160a01b038716614db2565b909450925050505b9250929050565b5f611c09846001600160a01b03851684614dea565b5f6144e2613c08565b90505f6144ee88612847565b61ffff89165f90815260038401602052604090205490915060ff166145265760405163592c386560e01b815260040160405180910390fd5b61ffff88165f9081526002830160205260409020546145579061454b906127106155cd565b85906127106001614e06565b831015614577576040516313b1ca1360e01b815260040160405180910390fd5b83831115614598576040516398b35c0560e01b815260040160405180910390fd5b5f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316639d23c4c76040518163ffffffff1660e01b8152600401602060405180830381865afa1580156145f5573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906146199190615577565b6001600160a01b031663bbda76c8878a6040518363ffffffff1660e01b815260040161464692919061555e565b602060405180830381865afa158015614661573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906146859190615577565b905061469b6001600160a01b0387168387613b8c565b604051636cb3c0a160e01b8152600481018990526001600160a01b038881166024830152878116604483015260648201879052828116608483015260a48201869052831690636cb3c0a19060c4015f604051808303815f87803b158015614700575f5ffd5b505af1158015614712573d5f5f3e3d5ffd5b50505050505050505050505050565b5f61472b83612847565b60405163187834b560e11b8152600481018490529091506001600160a01b038216906330f0696a9060240161405a565b5f614764613c08565b61ffff83165f9081526001820160205260409020549091506001600160a01b03166147a257604051630b91e58760e41b815260040160405180910390fd5b61ffff82165f90815260038201602052604090205460ff16156147d857604051637952fbad60e11b815260040160405180910390fd5b61ffff82165f818152600383016020526040808220805460ff19166001179055517f8f86eba05a8d990e7035fac950b23b9eb70753c1028eb12ab28cf2814f4fe5859190a25050565b613bd58383836001614e51565b5f61483883612847565b60405163a3e2e39760e01b8152600481018490529091506001600160a01b0382169063a3e2e3979060240161405a565b5f614871613c08565b61ffff84165f9081526001820160205260409020549091506001600160a01b03166148af57604051630b91e58760e41b815260040160405180910390fd5b61ffff83165f818152600283016020526040808220549051859391927f80c3109759bf54a6031c8d1cf1aecb8bcf6542e65164ca6124ab1abdd87a314e91a461ffff9092165f9081526002909201602052604090912055565b5f6149116138af565b80549091506001600160a01b038381169116148061493e575060018101546001600160a01b038381169116145b1561495c576040516354b30c7f60e01b815260040160405180910390fd5b6001600160a01b0382165f90815260048201602052604090205460ff16614996576040516366790fe360e01b815260040160405180910390fd5b6001600160a01b0382165f818152600483016020526040808220805460ff19169055517fba2de54206fe2a237e72a332fa329a7caa151f9c73be4ad84e3af845f969e63e9190a25050565b5f805f1983850993909202808410938190039390930393915050565b634e487b715f52806020526024601cfd5b614a275f60025f5160206157f05f395f51905f52614e9b565b15614a4557604051633ee5aeb560e01b815260040160405180910390fd5b565b6040516001600160a01b038085166024830152831660448201526001600160e01b0319821660648201525f908190819060840160408051601f19818403018152918152602080830180516001600160e01b031663b700961360e01b1781525f808052918290528351939450919290918a5afa15614acf575f516020805191945081901c150291505b5094509492505050565b60405163095ea7b360e01b5f8181526001600160a01b038616600452602485905291602083604481808b5af1925060015f51148316614b2f578383151615614b23573d5f823e3d81fd5b5f873b113d1516831692505b60405250949350505050565b5f8181526001830160205260408120548015614c15575f614b5d6001836155cd565b85549091505f90614b70906001906155cd565b9050808214614bcf575f865f018281548110614b8e57614b8e61541e565b905f5260205f200154905080875f018481548110614bae57614bae61541e565b5f918252602080832090910192909255918252600188019052604090208390555b8554869080614be057614be061575a565b600190038181905f5260205f20015f90559055856001015f8681526020019081526020015f205f905560019350505050610ae5565b5f915050610ae5565b5092915050565b5f818152600183016020526040812054614c6a57508154600181810184555f848152602080822090930184905584548482528286019093526040902091909155610ae5565b505f610ae5565b614c79614ea2565b614a4557604051631afcd79f60e31b815260040160405180910390fd5b614c9e614c71565b610fb981614ebb565b5f825f018281548110614cbc57614cbc61541e565b905f5260205f200154905092915050565b5f610c298383614b3b565b5f8181526002830160205260408120819055610c298383614ccd565b6040516323b872dd60e01b5f8181526001600160a01b038781166004528616602452604485905291602083606481808c5af1925060015f51148316614d50578383151615614d44573d5f823e3d81fd5b5f883b113d1516831692505b604052505f60605295945050505050565b5f610c298383614c25565b5f81815260028301602052604081205480158015614d915750614d8f8484614ecc565b155b15610c295760405163015ab34360e11b8152600481018490526024016111a6565b5f818152600283016020526040812054819080614ddf57614dd38585614ecc565b92505f91506144bd9050565b6001925090506144bd565b5f8281526002840160205260408120829055611c098484614d61565b5f614e33614e1383614ed7565b8015614e2e57505f8480614e2957614e29615667565b868809115b151590565b614e3e8686866138d3565b614e489190615446565b95945050505050565b60405163a9059cbb60e01b5f8181526001600160a01b038616600452602485905291602083604481808b5af1925060015f51148316614b2f578383151615614b23573d5f823e3d81fd5b5414919050565b5f614eab613cf2565b54600160401b900460ff16919050565b614ec3614c71565b610fb98161414d565b5f610c298383613efd565b5f6002826003811115614eec57614eec61576e565b614ef69190615782565b60ff166001149050919050565b5f60208284031215614f13575f5ffd5b5035919050565b5f60208284031215614f2a575f5ffd5b81356001600160e01b031981168114610c29575f5ffd5b803561ffff81168114614f52575f5ffd5b919050565b6001600160a01b0381168114610fb9575f5ffd5b8035614f5281614f57565b5f5f5f60608486031215614f88575f5ffd5b83359250614f9860208501614f41565b91506040840135614fa881614f57565b809150509250925092565b5f5f60408385031215614fc4575f5ffd5b8235614fcf81614f57565b946020939093013593505050565b5f60208284031215614fed575f5ffd5b610c2982614f41565b5f60208284031215615006575f5ffd5b8135610c2981614f57565b6001600160a01b0391909116815260200190565b5f60208284031215615035575f5ffd5b50919050565b5f5f5f5f5f5f5f8789036101e0811215615053575f5ffd5b610120811215615061575f5ffd5b508796506101208801356001600160401b0381111561507e575f5ffd5b880160e0818b03121561508f575f5ffd5b95506101408801356001600160401b038111156150aa575f5ffd5b6150b68a828b01615025565b9550506150c66101608901614f6b565b93506150d56101808901614f6b565b92506150e46101a08901614f6b565b91506150f36101c08901614f6b565b905092959891949750929550565b5f5f83601f840112615111575f5ffd5b5081356001600160401b03811115615127575f5ffd5b6020830191508360208285010111156144bd575f5ffd5b5f5f5f5f60608587031215615151575f5ffd5b61515a85614f41565b93506020850135925060408501356001600160401b0381111561517b575f5ffd5b61518787828801615101565b95989497509550505050565b5f5f604083850312156151a4575f5ffd5b823591506151b460208401614f41565b90509250929050565b5f5f604083850312156151ce575f5ffd5b614fcf83614f41565b5f5f5f5f604085870312156151ea575f5ffd5b84356001600160401b038111156151ff575f5ffd5b61520b87828801615101565b90955093505060208501356001600160401b0381111561517b575f5ffd5b5f5f5f5f6080858703121561523c575f5ffd5b84359350602085013561524e81614f57565b93969395505050506040820135916060013590565b8015158114610fb9575f5ffd5b5f60208284031215615280575f5ffd5b8135610c2981615263565b5f5f5f5f6060858703121561529e575f5ffd5b843561515a81614f57565b5f5f5f606084860312156152bb575f5ffd5b6152c484614f41565b925060208401356152d481614f57565b929592945050506040919091013590565b5f5f5f5f5f60a086880312156152f9575f5ffd5b61530286614f41565b945060208601359350604086013561531981614f57565b94979396509394606081013594506080013592915050565b5f5f5f60608486031215615343575f5ffd5b8335925060208401356152d481614f57565b5f5f83601f840112615365575f5ffd5b5081356001600160401b0381111561537b575f5ffd5b6020830191508360208260051b85010111156144bd575f5ffd5b5f5f5f5f5f5f608087890312156153aa575f5ffd5b8635955060208701356153bc81614f57565b945060408701356001600160401b038111156153d6575f5ffd5b6153e289828a01615355565b90955093505060608701356001600160401b03811115615400575f5ffd5b61540c89828a01615355565b979a9699509497509295939492505050565b634e487b7160e01b5f52603260045260245ffd5b634e487b7160e01b5f52601160045260245ffd5b80820180821115610ae557610ae5615432565b6001815b60018411156154945780850481111561547857615478615432565b600184161561548657908102905b60019390931c92800261545d565b935093915050565b5f826154aa57506001610ae5565b816154b657505f610ae5565b81600181146154cc57600281146154d6576154f2565b6001915050610ae5565b60ff8411156154e7576154e7615432565b50506001821b610ae5565b5060208310610133831016604e8410600b8410161715615515575081810a610ae5565b6155215f198484615459565b805f190482111561553457615534615432565b029392505050565b5f610c29838361549c565b5f60208284031215615557575f5ffd5b5051919050565b6001600160a01b03929092168252602082015260400190565b5f60208284031215615587575f5ffd5b8151610c2981614f57565b5f602082840312156155a2575f5ffd5b8151610c2981615263565b5f602082840312156155bd575f5ffd5b815160ff81168114610c29575f5ffd5b81810381811115610ae557610ae5615432565b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b8481526001600160a01b03841660208201526060604082018190525f9061563290830184866155e0565b9695505050505050565b5f5f5f6060848603121561564e575f5ffd5b83359250602084013591506040840135614fa881615263565b634e487b7160e01b5f52601260045260245ffd5b5f5f85851115615689575f5ffd5b83861115615695575f5ffd5b5050820193919092039150565b80356001600160e01b03198116906004841015614c1e576001600160e01b031960049490940360031b84901b1690921692915050565b6001600160a01b03841681526040602082018190525f90614e4890830184866155e0565b5f5f8335601e19843603018112615711575f5ffd5b8301803591506001600160401b0382111561572a575f5ffd5b6020019150600581901b36038213156144bd575f5ffd5b838152604060208201525f614e486040830184866155e0565b634e487b7160e01b5f52603160045260245ffd5b634e487b7160e01b5f52602160045260245ffd5b5f60ff8316806157a057634e487b7160e01b5f52601260045260245ffd5b8060ff8416069150509291505056fef3177357ab46d8af007ab3fdb9af81da189e1068fefdc0073dca88a2cab40a00b63b6c1855ef12c3ce1467dc59d74e167a3a4f63f2ecef0203e34e2727af13009b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f00a2646970667358221220b245446cb93a09d7fd212357aa3c69531a64bfff69dd07f170c93d13540faae064736f6c634300081c00330000000000000000000000000faeeceab0bcb63be2fe984ea8c77778989d53ea0000000000000000000000000b93082d9b3c7c97facd250082899bacf3af3885","name":"Machine","is_blueprint":false,"license_type":"none","is_fully_verified":false,"is_verified_via_eth_bytecode_db":false,"language":"solidity","evm_version":"cancun","can_be_visualized_via_sol2uml":true,"is_verified_via_sourcify":false,"additional_sources":[{"file_path":"lib/openzeppelin-contracts-upgradeable/contracts/access/manager/AccessManagedUpgradeable.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.4.0) (access/manager/AccessManaged.sol)\n\npragma solidity ^0.8.20;\n\nimport {AuthorityUtils} from \"@openzeppelin/contracts/access/manager/AuthorityUtils.sol\";\nimport {IAccessManager} from \"@openzeppelin/contracts/access/manager/IAccessManager.sol\";\nimport {IAccessManaged} from \"@openzeppelin/contracts/access/manager/IAccessManaged.sol\";\nimport {ContextUpgradeable} from \"../../utils/ContextUpgradeable.sol\";\nimport {Initializable} from \"@openzeppelin/contracts/proxy/utils/Initializable.sol\";\n\n/**\n * @dev This contract module makes available a {restricted} modifier. Functions decorated with this modifier will be\n * permissioned according to an \"authority\": a contract like {AccessManager} that follows the {IAuthority} interface,\n * implementing a policy that allows certain callers to access certain functions.\n *\n * IMPORTANT: The `restricted` modifier should never be used on `internal` functions, judiciously used in `public`\n * functions, and ideally only used in `external` functions. See {restricted}.\n */\nabstract contract AccessManagedUpgradeable is Initializable, ContextUpgradeable, IAccessManaged {\n    /// @custom:storage-location erc7201:openzeppelin.storage.AccessManaged\n    struct AccessManagedStorage {\n        address _authority;\n\n        bool _consumingSchedule;\n    }\n\n    // keccak256(abi.encode(uint256(keccak256(\"openzeppelin.storage.AccessManaged\")) - 1)) & ~bytes32(uint256(0xff))\n    bytes32 private constant AccessManagedStorageLocation = 0xf3177357ab46d8af007ab3fdb9af81da189e1068fefdc0073dca88a2cab40a00;\n\n    function _getAccessManagedStorage() private pure returns (AccessManagedStorage storage $) {\n        assembly {\n            $.slot := AccessManagedStorageLocation\n        }\n    }\n\n    /**\n     * @dev Initializes the contract connected to an initial authority.\n     */\n    function __AccessManaged_init(address initialAuthority) internal onlyInitializing {\n        __AccessManaged_init_unchained(initialAuthority);\n    }\n\n    function __AccessManaged_init_unchained(address initialAuthority) internal onlyInitializing {\n        _setAuthority(initialAuthority);\n    }\n\n    /**\n     * @dev Restricts access to a function as defined by the connected Authority for this contract and the\n     * caller and selector of the function that entered the contract.\n     *\n     * [IMPORTANT]\n     * ====\n     * In general, this modifier should only be used on `external` functions. It is okay to use it on `public`\n     * functions that are used as external entry points and are not called internally. Unless you know what you're\n     * doing, it should never be used on `internal` functions. Failure to follow these rules can have critical security\n     * implications! This is because the permissions are determined by the function that entered the contract, i.e. the\n     * function at the bottom of the call stack, and not the function where the modifier is visible in the source code.\n     * ====\n     *\n     * [WARNING]\n     * ====\n     * Avoid adding this modifier to the https://docs.soliditylang.org/en/v0.8.20/contracts.html#receive-ether-function[`receive()`]\n     * function or the https://docs.soliditylang.org/en/v0.8.20/contracts.html#fallback-function[`fallback()`]. These\n     * functions are the only execution paths where a function selector cannot be unambiguously determined from the calldata\n     * since the selector defaults to `0x00000000` in the `receive()` function and similarly in the `fallback()` function\n     * if no calldata is provided. (See {_checkCanCall}).\n     *\n     * The `receive()` function will always panic whereas the `fallback()` may panic depending on the calldata length.\n     * ====\n     */\n    modifier restricted() {\n        _checkCanCall(_msgSender(), _msgData());\n        _;\n    }\n\n    /// @inheritdoc IAccessManaged\n    function authority() public view virtual returns (address) {\n        AccessManagedStorage storage $ = _getAccessManagedStorage();\n        return $._authority;\n    }\n\n    /// @inheritdoc IAccessManaged\n    function setAuthority(address newAuthority) public virtual {\n        address caller = _msgSender();\n        if (caller != authority()) {\n            revert AccessManagedUnauthorized(caller);\n        }\n        if (newAuthority.code.length == 0) {\n            revert AccessManagedInvalidAuthority(newAuthority);\n        }\n        _setAuthority(newAuthority);\n    }\n\n    /// @inheritdoc IAccessManaged\n    function isConsumingScheduledOp() public view returns (bytes4) {\n        AccessManagedStorage storage $ = _getAccessManagedStorage();\n        return $._consumingSchedule ? this.isConsumingScheduledOp.selector : bytes4(0);\n    }\n\n    /**\n     * @dev Transfers control to a new authority. Internal function with no access restriction. Allows bypassing the\n     * permissions set by the current authority.\n     */\n    function _setAuthority(address newAuthority) internal virtual {\n        AccessManagedStorage storage $ = _getAccessManagedStorage();\n        $._authority = newAuthority;\n        emit AuthorityUpdated(newAuthority);\n    }\n\n    /**\n     * @dev Reverts if the caller is not allowed to call the function identified by a selector. Panics if the calldata\n     * is less than 4 bytes long.\n     */\n    function _checkCanCall(address caller, bytes calldata data) internal virtual {\n        AccessManagedStorage storage $ = _getAccessManagedStorage();\n        (bool immediate, uint32 delay) = AuthorityUtils.canCallWithDelay(\n            authority(),\n            caller,\n            address(this),\n            bytes4(data[0:4])\n        );\n        if (!immediate) {\n            if (delay > 0) {\n                $._consumingSchedule = true;\n                IAccessManager(authority()).consumeScheduledOp(caller, data);\n                $._consumingSchedule = false;\n            } else {\n                revert AccessManagedUnauthorized(caller);\n            }\n        }\n    }\n}\n"},{"file_path":"lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Metadata.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.4.0) (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity >=0.6.2;\n\nimport {IERC20} from \"../IERC20.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC-20 standard.\n */\ninterface IERC20Metadata is IERC20 {\n    /**\n     * @dev Returns the name of the token.\n     */\n    function name() external view returns (string memory);\n\n    /**\n     * @dev Returns the symbol of the token.\n     */\n    function symbol() external view returns (string memory);\n\n    /**\n     * @dev Returns the decimals places of the token.\n     */\n    function decimals() external view returns (uint8);\n}\n"},{"file_path":"lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/access/manager/IAccessManager.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.6.0) (access/manager/IAccessManager.sol)\n\npragma solidity >=0.8.4;\n\ninterface IAccessManager {\n    /**\n     * @dev A delayed operation was scheduled.\n     */\n    event OperationScheduled(\n        bytes32 indexed operationId,\n        uint32 indexed nonce,\n        uint48 schedule,\n        address caller,\n        address target,\n        bytes data\n    );\n\n    /**\n     * @dev A scheduled operation was executed.\n     */\n    event OperationExecuted(bytes32 indexed operationId, uint32 indexed nonce);\n\n    /**\n     * @dev A scheduled operation was canceled.\n     */\n    event OperationCanceled(bytes32 indexed operationId, uint32 indexed nonce);\n\n    /**\n     * @dev Informational labelling for a roleId.\n     */\n    event RoleLabel(uint64 indexed roleId, string label);\n\n    /**\n     * @dev Emitted when `account` is granted `roleId`.\n     *\n     * NOTE: The meaning of the `since` argument depends on the `newMember` argument.\n     * If the role is granted to a new member, the `since` argument indicates when the account becomes a member of the role,\n     * otherwise it indicates the timestamp when the execution delay update takes effect for this account and roleId.\n     */\n    event RoleGranted(uint64 indexed roleId, address indexed account, uint32 delay, uint48 since, bool newMember);\n\n    /**\n     * @dev Emitted when `account` membership or `roleId` is revoked. Unlike granting, revoking is instantaneous.\n     */\n    event RoleRevoked(uint64 indexed roleId, address indexed account);\n\n    /**\n     * @dev Role acting as admin over a given `roleId` is updated.\n     */\n    event RoleAdminChanged(uint64 indexed roleId, uint64 indexed admin);\n\n    /**\n     * @dev Role acting as guardian over a given `roleId` is updated.\n     */\n    event RoleGuardianChanged(uint64 indexed roleId, uint64 indexed guardian);\n\n    /**\n     * @dev Grant delay for a given `roleId` will be updated to `delay` when `since` is reached.\n     */\n    event RoleGrantDelayChanged(uint64 indexed roleId, uint32 delay, uint48 since);\n\n    /**\n     * @dev Target mode is updated (true = closed, false = open).\n     */\n    event TargetClosed(address indexed target, bool closed);\n\n    /**\n     * @dev Role required to invoke `selector` on `target` is updated to `roleId`.\n     */\n    event TargetFunctionRoleUpdated(address indexed target, bytes4 selector, uint64 indexed roleId);\n\n    /**\n     * @dev Admin delay for a given `target` will be updated to `delay` when `since` is reached.\n     */\n    event TargetAdminDelayUpdated(address indexed target, uint32 delay, uint48 since);\n\n    error AccessManagerAlreadyScheduled(bytes32 operationId);\n    error AccessManagerNotScheduled(bytes32 operationId);\n    error AccessManagerNotReady(bytes32 operationId);\n    error AccessManagerExpired(bytes32 operationId);\n    error AccessManagerLockedRole(uint64 roleId);\n    error AccessManagerBadConfirmation();\n    error AccessManagerUnauthorizedAccount(address msgsender, uint64 roleId);\n    error AccessManagerUnauthorizedCall(address caller, address target, bytes4 selector);\n    error AccessManagerUnauthorizedConsume(address target);\n    error AccessManagerUnauthorizedCancel(address msgsender, address caller, address target, bytes4 selector);\n    error AccessManagerInvalidInitialAdmin(address initialAdmin);\n\n    /**\n     * @dev Check if an address (`caller`) is authorised to call a given function on a given contract directly (with\n     * no restriction). Additionally, it returns the delay needed to perform the call indirectly through the {schedule}\n     * & {execute} workflow.\n     *\n     * This function is usually called by the targeted contract to control immediate execution of restricted functions.\n     * Therefore we only return true if the call can be performed without any delay. If the call is subject to a\n     * previously set delay (not zero), then the function should return false and the caller should schedule the operation\n     * for future execution.\n     *\n     * If `allowed` is true, the delay can be disregarded and the operation can be immediately executed, otherwise\n     * the operation can be executed if and only if delay is greater than 0.\n     *\n     * NOTE: The IAuthority interface does not include the `uint32` delay. This is an extension of that interface that\n     * is backward compatible. Some contracts may thus ignore the second return argument. In that case they will fail\n     * to identify the indirect workflow, and will consider calls that require a delay to be forbidden.\n     *\n     * NOTE: This function does not report the permissions of the admin functions in the manager itself. These are defined by the\n     * {AccessManager} documentation.\n     */\n    function canCall(\n        address caller,\n        address target,\n        bytes4 selector\n    ) external view returns (bool allowed, uint32 delay);\n\n    /**\n     * @dev Expiration delay for scheduled proposals. Defaults to 1 week.\n     *\n     * IMPORTANT: Avoid overriding the expiration with 0. Otherwise every contract proposal will be expired immediately,\n     * disabling any scheduling usage.\n     */\n    function expiration() external view returns (uint32);\n\n    /**\n     * @dev Minimum setback for all delay updates, with the exception of execution delays. It\n     * can be increased without setback (and reset via {revokeRole} in the event of an\n     * accidental increase). Defaults to 5 days.\n     */\n    function minSetback() external view returns (uint32);\n\n    /**\n     * @dev Get whether the contract is closed disabling any access. Otherwise role permissions are applied.\n     *\n     * NOTE: When the manager itself is closed, admin functions are still accessible to avoid locking the contract.\n     */\n    function isTargetClosed(address target) external view returns (bool);\n\n    /**\n     * @dev Get the role required to call a function.\n     */\n    function getTargetFunctionRole(address target, bytes4 selector) external view returns (uint64);\n\n    /**\n     * @dev Get the admin delay for a target contract. Changes to contract configuration are subject to this delay.\n     */\n    function getTargetAdminDelay(address target) external view returns (uint32);\n\n    /**\n     * @dev Get the id of the role that acts as an admin for the given role.\n     *\n     * The admin permission is required to grant the role, revoke the role and update the execution delay to execute\n     * an operation that is restricted to this role.\n     */\n    function getRoleAdmin(uint64 roleId) external view returns (uint64);\n\n    /**\n     * @dev Get the role that acts as a guardian for a given role.\n     *\n     * The guardian permission allows canceling operations that have been scheduled under the role.\n     */\n    function getRoleGuardian(uint64 roleId) external view returns (uint64);\n\n    /**\n     * @dev Get the role current grant delay.\n     *\n     * Its value may change at any point without an event emitted following a call to {setGrantDelay}.\n     * Changes to this value, including effect timepoint are notified in advance by the {RoleGrantDelayChanged} event.\n     */\n    function getRoleGrantDelay(uint64 roleId) external view returns (uint32);\n\n    /**\n     * @dev Get the access details for a given account for a given role. These details include the timepoint at which\n     * membership becomes active, and the delay applied to all operations by this user that requires this permission\n     * level.\n     *\n     * Returns:\n     * [0] Timestamp at which the account membership becomes valid. 0 means role is not granted.\n     * [1] Current execution delay for the account.\n     * [2] Pending execution delay for the account.\n     * [3] Timestamp at which the pending execution delay will become active. 0 means no delay update is scheduled.\n     */\n    function getAccess(\n        uint64 roleId,\n        address account\n    ) external view returns (uint48 since, uint32 currentDelay, uint32 pendingDelay, uint48 effect);\n\n    /**\n     * @dev Check if a given account currently has the permission level corresponding to a given role. Note that this\n     * permission might be associated with an execution delay. {getAccess} can provide more details.\n     */\n    function hasRole(uint64 roleId, address account) external view returns (bool isMember, uint32 executionDelay);\n\n    /**\n     * @dev Give a label to a role, for improved role discoverability by UIs.\n     *\n     * Requirements:\n     *\n     * - the caller must be a global admin\n     * - `roleId` must not be the `ADMIN_ROLE` or `PUBLIC_ROLE`\n     *\n     * Emits a {RoleLabel} event.\n     */\n    function labelRole(uint64 roleId, string calldata label) external;\n\n    /**\n     * @dev Add `account` to `roleId`, or change its execution delay.\n     *\n     * This gives the account the authorization to call any function that is restricted to this role. An optional\n     * execution delay (in seconds) can be set. If that delay is non 0, the user is required to schedule any operation\n     * that is restricted to members of this role. The user will only be able to execute the operation after the delay has\n     * passed, before it has expired. During this period, admin and guardians can cancel the operation (see {cancel}).\n     *\n     * If the account has already been granted this role, the execution delay will be updated. This update is not\n     * immediate and follows the delay rules. For example, if a user currently has a delay of 3 hours, and this is\n     * called to reduce that delay to 1 hour, the new delay will take some time to take effect, enforcing that any\n     * operation executed in the 3 hours that follows this update was indeed scheduled before this update.\n     *\n     * Requirements:\n     *\n     * - the caller must be an admin for the role (see {getRoleAdmin})\n     * - granted role must not be the `PUBLIC_ROLE`\n     *\n     * Emits a {RoleGranted} event.\n     */\n    function grantRole(uint64 roleId, address account, uint32 executionDelay) external;\n\n    /**\n     * @dev Remove an account from a role, with immediate effect. If the account does not have the role, this call has\n     * no effect.\n     *\n     * Requirements:\n     *\n     * - the caller must be an admin for the role (see {getRoleAdmin})\n     * - revoked role must not be the `PUBLIC_ROLE`\n     *\n     * Emits a {RoleRevoked} event if the account had the role.\n     */\n    function revokeRole(uint64 roleId, address account) external;\n\n    /**\n     * @dev Renounce role permissions for the calling account with immediate effect. If the sender is not in\n     * the role this call has no effect.\n     *\n     * Requirements:\n     *\n     * - the caller must be `callerConfirmation`.\n     *\n     * Emits a {RoleRevoked} event if the account had the role.\n     */\n    function renounceRole(uint64 roleId, address callerConfirmation) external;\n\n    /**\n     * @dev Change admin role for a given role.\n     *\n     * Requirements:\n     *\n     * - the caller must be a global admin\n     * - `roleId` must not be the `ADMIN_ROLE` or `PUBLIC_ROLE`\n     *\n     * Emits a {RoleAdminChanged} event\n     */\n    function setRoleAdmin(uint64 roleId, uint64 admin) external;\n\n    /**\n     * @dev Change guardian role for a given role.\n     *\n     * Requirements:\n     *\n     * - the caller must be a global admin\n     * - `roleId` must not be the `ADMIN_ROLE` or `PUBLIC_ROLE`\n     *\n     * Emits a {RoleGuardianChanged} event\n     */\n    function setRoleGuardian(uint64 roleId, uint64 guardian) external;\n\n    /**\n     * @dev Update the delay for granting a `roleId`.\n     *\n     * Requirements:\n     *\n     * - the caller must be a global admin\n     * - `roleId` must not be the `PUBLIC_ROLE`\n     *\n     * Emits a {RoleGrantDelayChanged} event.\n     */\n    function setGrantDelay(uint64 roleId, uint32 newDelay) external;\n\n    /**\n     * @dev Set the role required to call functions identified by the `selectors` in the `target` contract.\n     *\n     * Requirements:\n     *\n     * - the caller must be a global admin\n     *\n     * Emits a {TargetFunctionRoleUpdated} event per selector.\n     */\n    function setTargetFunctionRole(address target, bytes4[] calldata selectors, uint64 roleId) external;\n\n    /**\n     * @dev Set the delay for changing the configuration of a given target contract.\n     *\n     * Requirements:\n     *\n     * - the caller must be a global admin\n     *\n     * Emits a {TargetAdminDelayUpdated} event.\n     */\n    function setTargetAdminDelay(address target, uint32 newDelay) external;\n\n    /**\n     * @dev Set the closed flag for a contract.\n     *\n     * Closing the manager itself won't disable access to admin methods to avoid locking the contract.\n     *\n     * Requirements:\n     *\n     * - the caller must be a global admin\n     *\n     * Emits a {TargetClosed} event.\n     */\n    function setTargetClosed(address target, bool closed) external;\n\n    /**\n     * @dev Return the timepoint at which a scheduled operation will be ready for execution. This returns 0 if the\n     * operation is not yet scheduled, has expired, was executed, or was canceled.\n     */\n    function getSchedule(bytes32 id) external view returns (uint48);\n\n    /**\n     * @dev Return the nonce for the latest scheduled operation with a given id. Returns 0 if the operation has never\n     * been scheduled.\n     */\n    function getNonce(bytes32 id) external view returns (uint32);\n\n    /**\n     * @dev Schedule a delayed operation for future execution, and return the operation identifier. It is possible to\n     * choose the timestamp at which the operation becomes executable as long as it satisfies the execution delays\n     * required for the caller. The special value zero will automatically set the earliest possible time.\n     *\n     * Returns the `operationId` that was scheduled. Since this value is a hash of the parameters, it can reoccur when\n     * the same parameters are used; if this is relevant, the returned `nonce` can be used to uniquely identify this\n     * scheduled operation from other occurrences of the same `operationId` in invocations of {execute} and {cancel}.\n     *\n     * Emits a {OperationScheduled} event.\n     *\n     * NOTE: It is not possible to concurrently schedule more than one operation with the same `target` and `data`. If\n     * this is necessary, a random byte can be appended to `data` to act as a salt that will be ignored by the target\n     * contract if it is using standard Solidity ABI encoding.\n     */\n    function schedule(\n        address target,\n        bytes calldata data,\n        uint48 when\n    ) external returns (bytes32 operationId, uint32 nonce);\n\n    /**\n     * @dev Execute a function that is delay restricted, provided it was properly scheduled beforehand, or the\n     * execution delay is 0.\n     *\n     * Returns the nonce that identifies the previously scheduled operation that is executed, or 0 if the\n     * operation wasn't previously scheduled (if the caller doesn't have an execution delay).\n     *\n     * Emits an {OperationExecuted} event only if the call was scheduled and delayed.\n     */\n    function execute(address target, bytes calldata data) external payable returns (uint32);\n\n    /**\n     * @dev Cancel a scheduled (delayed) operation. Returns the nonce that identifies the previously scheduled\n     * operation that is cancelled.\n     *\n     * Requirements:\n     *\n     * - the caller must be the proposer, a guardian of the targeted function, or a global admin\n     *\n     * Emits a {OperationCanceled} event.\n     */\n    function cancel(address caller, address target, bytes calldata data) external returns (uint32);\n\n    /**\n     * @dev Consume a scheduled operation targeting the caller. If such an operation exists, mark it as consumed\n     * (emit an {OperationExecuted} event and clean the state). Otherwise, throw an error.\n     *\n     * This is useful for contracts that want to enforce that calls targeting them were scheduled on the manager,\n     * with all the verifications that it implies.\n     *\n     * Emit a {OperationExecuted} event.\n     */\n    function consumeScheduledOp(address caller, bytes calldata data) external;\n\n    /**\n     * @dev Hashing function for delayed operations.\n     */\n    function hashOperation(address caller, address target, bytes calldata data) external view returns (bytes32);\n\n    /**\n     * @dev Changes the authority of a target managed by this manager instance.\n     *\n     * Requirements:\n     *\n     * - the caller must be a global admin\n     */\n    function updateAuthority(address target, address newAuthority) external;\n}\n"},{"file_path":"src/interfaces/ISpokeSnapshotConsumer.sol","source_code":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.28;\n\nimport {ICreReceiver} from \"./ICreReceiver.sol\";\n\ninterface ISpokeSnapshotConsumer is ICreReceiver {\n    event CreWorkflowIdAdded(bytes32 indexed newCreWorkflowId);\n    event CreWorkflowIdRemoved(bytes32 indexed creWorkflowId);\n\n    struct SpokeSnapshotConsumerInitParams {\n        bytes32[] initialCreWorkflowIds;\n    }\n\n    /// @notice Address of the Chainlink CRE forwarder.\n    function creForwarder() external view returns (address);\n\n    /// @notice CRE workflow ID => Whether the ID is authorized.\n    function isCreWorkflowIdAuthorized(bytes32 creWorkflowId) external view returns (bool);\n\n    /// @notice Authorizes a CRE workflow ID.\n    /// @param newCreWorkflowId The CRE workflow ID to authorize.\n    function addCreWorkflowId(bytes32 newCreWorkflowId) external;\n\n    /// @notice Deauthorizes a CRE workflow ID.\n    /// @param creWorkflowId The CRE workflow ID to deauthorize.\n    function removeCreWorkflowId(bytes32 creWorkflowId) external;\n}\n"},{"file_path":"src/interfaces/ISwapModule.sol","source_code":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.28;\n\ninterface ISwapModule {\n    event Swap(\n        address indexed sender,\n        uint16 swapperId,\n        address indexed inputToken,\n        address indexed outputToken,\n        uint256 inputAmount,\n        uint256 outputAmount\n    );\n    event SwapperTargetsSet(uint16 indexed swapper, address approvalTarget, address executionTarget);\n\n    struct SwapperTargets {\n        address approvalTarget;\n        address executionTarget;\n    }\n\n    /// @notice Swap order object.\n    /// @param swapperId The ID of the external swap protocol.\n    /// @param data The swap calldata to pass to the swapper's execution target.\n    /// @param inputToken The input token.\n    /// @param outputToken The output token.\n    /// @param inputAmount The input amount.\n    /// @param minOutputAmount The minimum expected output amount.\n    struct SwapOrder {\n        uint16 swapperId;\n        bytes data;\n        address inputToken;\n        address outputToken;\n        uint256 inputAmount;\n        uint256 minOutputAmount;\n    }\n\n    /// @notice Returns approval and execution targets for a given swapper ID.\n    /// @param swapperId The swapper ID.\n    /// @return approvalTarget The approval target.\n    /// @return executionTarget The execution target.\n    function getSwapperTargets(uint16 swapperId) external view returns (address approvalTarget, address executionTarget);\n\n    /// @notice Swaps tokens using a given swapper.\n    /// @param order The swap order object.\n    function swap(SwapOrder calldata order) external returns (uint256);\n\n    /// @notice Sets approval and execution targets for a given swapper ID.\n    /// @param swapperId The swapper ID.\n    /// @param approvalTarget The approval target.\n    /// @param executionTarget The execution target.\n    function setSwapperTargets(uint16 swapperId, address approvalTarget, address executionTarget) external;\n}\n"},{"file_path":"src/interfaces/IOracleRegistry.sol","source_code":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.28;\n\n/// @notice An aggregator of Chainlink price feeds that prices tokens in a reference currency (e.g., USD) using up to two feeds.\n/// If a direct feed between a base token and the reference currency does not exist, it combines two feeds to compute the price.\n///\n/// Example:\n/// To price Token A in Token B:\n/// - If a feed for Token A -> Reference Currency exists, the registry uses that feed.\n/// - If Token B lacks a direct feed to the Reference Currency, but feeds for Token B -> Intermediate Token and\n///   Intermediate Token -> Reference Currency exist, the registry combines these feeds to derive the price.\n/// - Finally, the price Token A -> Token B is calculated using both tokens' individual prices in the reference currency.\n///\ninterface IOracleRegistry {\n    event FeedRouteCleared(address indexed token);\n    event FeedRouteRegistered(address indexed token, address indexed feed1, address indexed feed2);\n    event FeedStaleThresholdChanged(address indexed feed, uint256 oldThreshold, uint256 newThreshold);\n\n    struct FeedRoute {\n        address feed1;\n        address feed2;\n    }\n\n    /// @notice Feed => Staleness threshold in seconds\n    function getFeedStaleThreshold(address feed) external view returns (uint256);\n\n    /// @notice Token => Is feed route registered for the token\n    function isFeedRouteRegistered(address token) external view returns (bool);\n\n    /// @notice Gets the price feed route for a given token.\n    /// @param token The address of the token for which the price feed route is requested.\n    /// @return feed1 The address of the first price feed.\n    /// @return feed2 The address of the optional second price feed.\n    function getFeedRoute(address token) external view returns (address, address);\n\n    /// @notice Returns the price of one unit of baseToken in terms of quoteToken.\n    /// @param baseToken The address of the token for which the price is requested.\n    /// @param quoteToken The address of the token in which the price is quoted.\n    /// @return price The price of baseToken denominated in quoteToken (expressed in quoteToken decimals).\n    function getPrice(address baseToken, address quoteToken) external view returns (uint256);\n\n    /// @notice Sets the price feed route for a given token.\n    /// @dev Both feeds, if set, must be Chainlink-interface-compliant.\n    /// The combination of feed1 and feed2 must be able to price the token in the reference currency.\n    /// If feed2 is set to address(0), the token price in the reference currency is assumed to be returned by feed1.\n    /// @param token The address of the token for which the price feed route is set.\n    /// @param feed1 The address of the first price feed.\n    /// @param stalenessThreshold1 The staleness threshold for the first price feed.\n    /// @param feed2 The address of the second price feed. Can be set to address(0).\n    /// @param stalenessThreshold2 The staleness threshold for the second price feed. Ignored if feed2 is address(0).\n    function setFeedRoute(\n        address token,\n        address feed1,\n        uint256 stalenessThreshold1,\n        address feed2,\n        uint256 stalenessThreshold2\n    ) external;\n\n    /// @notice Clears the price feed route for a given token.\n    /// @dev Staleness thresholds for the route's feeds are preserved, as the feeds may be used by other routes.\n    /// @param token The address of the token for which the price feed route is cleared.\n    function clearFeedRoute(address token) external;\n\n    /// @notice Sets the price staleness threshold for a given feed.\n    /// @param feed The address of the price feed.\n    /// @param newThreshold The new staleness threshold in seconds.\n    function setFeedStaleThreshold(address feed, uint256 newThreshold) external;\n}\n"},{"file_path":"lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/access/manager/IAccessManaged.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.4.0) (access/manager/IAccessManaged.sol)\n\npragma solidity >=0.8.4;\n\ninterface IAccessManaged {\n    /**\n     * @dev Authority that manages this contract was updated.\n     */\n    event AuthorityUpdated(address authority);\n\n    error AccessManagedUnauthorized(address caller);\n    error AccessManagedRequiredDelay(address caller, uint32 delay);\n    error AccessManagedInvalidAuthority(address authority);\n\n    /**\n     * @dev Returns the current authority.\n     */\n    function authority() external view returns (address);\n\n    /**\n     * @dev Transfers control to a new authority. The caller must be the current authority.\n     */\n    function setAuthority(address) external;\n\n    /**\n     * @dev Returns true only in the context of a delayed restricted call, at the moment that the scheduled operation is\n     * being consumed. Prevents denial of service for delayed restricted calls in the case that the contract performs\n     * attacker controlled calls.\n     */\n    function isConsumingScheduledOp() external view returns (bytes4);\n}\n"},{"file_path":"src/libraries/Errors.sol","source_code":"// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.28;\n\nlibrary Errors {\n    error AccountingToken();\n    error ActiveUpdatePending();\n    error AlreadyAccountingAgent();\n    error AlreadyBaseToken();\n    error AlreadyDisabled();\n    error AlreadyEnabled();\n    error AlreadyPositionToken();\n    error AlreadyRootGuardian();\n    error AmountOutTooLow();\n    error BridgeAdapterAlreadySet();\n    error BridgeConfigNotSet();\n    error BridgeStateMismatch();\n    error CaliberAccountingStale(uint256 caliberChainId);\n    error CaliberAlreadySet();\n    error CaliberNotEmpty();\n    error CctpDomainNotRegistered();\n    error CctpForeignTokenNotRegistered();\n    error CctpMessageReceptionFailed();\n    error Create3ContractDeploymentFailed();\n    error Create3ProxyDeploymentFailed();\n    error CreWorkflowIdAlreadyAuthorized();\n    error CreWorkflowIdNotAuthorized();\n    error DirectManageFlashLoanCall();\n    error ExceededMaxDeposit();\n    error ExceededMaxFee(uint256 fee, uint256 max);\n    error ExceededMaxMint(uint256 shares, uint256 max);\n    error ExceededMaxWithdraw(uint256 assets, uint256 max);\n    error ForeignTokenNotRegistered(address token, uint256 foreignEvmChainId);\n    error FutureSnapshot();\n    error GroupIdNotProvided();\n    error HubBridgeAdapterAlreadySet();\n    error HubBridgeAdapterNotSet();\n    error InstructionsMismatch();\n    error InsufficientBalance();\n    error InvalidAccounting();\n    error InvalidAffectedToken();\n    error InvalidBridgeController();\n    error InvalidBridgeId();\n    error InvalidBridgeTransferRoute();\n    error InvalidCctpMessage();\n    error InvalidChainId();\n    error InvalidCreMetadataLength();\n    error InvalidCreWorkflowId();\n    error InvalidDebtFlag();\n    error InvalidDecimals();\n    error InvalidFeedRoute();\n    error InvalidInputAmount();\n    error InvalidInputToken();\n    error InvalidInstructionProof();\n    error InvalidInstructionType();\n    error InvalidLzSentAmount();\n    error InvalidOft();\n    error InvalidOutputToken();\n    error InvalidPositionChangeDirection();\n    error InvalidRecipientChainId();\n    error InvalidSpokeCaliberMailbox();\n    error InvalidTransferStatus();\n    error LocalTokenNotRegistered(address token, uint256 foreignEvmChainId);\n    error LzEndpointIdNotRegistered();\n    error LzForeignTokenNotRegistered();\n    error ManageFlashLoanReentrantCall();\n    error MaxAuthorizedPriceChangeExceeded();\n    error MaxValueLossExceeded();\n    error MessageAlreadyAuthorized();\n    error Migrated();\n    error MinOutputAmountExceedsInputAmount();\n    error MismatchedLengths();\n    error MissingInstructionForGroup(uint256 groupId);\n    error NegativeTokenPrice(address priceFeed);\n    error NonZeroBalance();\n    error NoPendingUpdate();\n    error NotAccountingAgent();\n    error NotBaseToken();\n    error NotCaliber();\n    error NotController();\n    error NotFactory();\n    error NotFactoryAuthority();\n    error NotFlashLoanModule();\n    error NotMachineEndpoint();\n    error NotMigrated();\n    error NotPendingMachine();\n    error NotPreDepositVault();\n    error NotRootGuardian();\n    error OftNotRegistered();\n    error OngoingCooldown();\n    error OutTransferNotEnabled();\n    error PendingBridgeTransfer();\n    error PositionAccountingStale(uint256 posId);\n    error PositionDoesNotExist();\n    error PositionIsGrouped();\n    error PositionToken();\n    error PositionTokenIsBaseToken();\n    error PriceFeedRouteNotRegistered(address token);\n    error PriceFeedStale(address priceFeed, uint256 updatedAt);\n    error ProtectedAccountingAgent();\n    error ProtectedCctpDomain();\n    error ProtectedChainId();\n    error ProtectedRootGuardian();\n    error RecoveryMode();\n    error SameRoot();\n    error SlippageProtection();\n    error SpokeBridgeAdapterAlreadySet();\n    error SpokeBridgeAdapterNotSet();\n    error SpokeCaliberAlreadySet();\n    error SpokeCaliberNotEnabled();\n    error StaleSnapshot();\n    error SwapFailed();\n    error SwapperTargetsNotSet();\n    error TargetAlreadyExists();\n    error UnauthorizedCaller();\n    error UnauthorizedSource();\n    error UnexpectedMessage();\n    error ZeroBridgeAdapterAddress();\n    error ZeroChainId();\n    error ZeroGroupId();\n    error ZeroLzEndpointId();\n    error ZeroOftAddress();\n    error ZeroPositionId();\n    error ZeroSalt();\n    error ZeroSpokeCaliberMailboxAddress();\n    error ZeroTokenAddress();\n}\n"},{"file_path":"lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.4.0) (token/ERC20/IERC20.sol)\n\npragma solidity >=0.4.16;\n\n/**\n * @dev Interface of the ERC-20 standard as defined in the ERC.\n */\ninterface IERC20 {\n    /**\n     * @dev Emitted when `value` tokens are moved from one account (`from`) to\n     * another (`to`).\n     *\n     * Note that `value` may be zero.\n     */\n    event Transfer(address indexed from, address indexed to, uint256 value);\n\n    /**\n     * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n     * a call to {approve}. `value` is the new allowance.\n     */\n    event Approval(address indexed owner, address indexed spender, uint256 value);\n\n    /**\n     * @dev Returns the value of tokens in existence.\n     */\n    function totalSupply() external view returns (uint256);\n\n    /**\n     * @dev Returns the value of tokens owned by `account`.\n     */\n    function balanceOf(address account) external view returns (uint256);\n\n    /**\n     * @dev Moves a `value` amount of tokens from the caller's account to `to`.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transfer(address to, uint256 value) external returns (bool);\n\n    /**\n     * @dev Returns the remaining number of tokens that `spender` will be\n     * allowed to spend on behalf of `owner` through {transferFrom}. This is\n     * zero by default.\n     *\n     * This value changes when {approve} or {transferFrom} are called.\n     */\n    function allowance(address owner, address spender) external view returns (uint256);\n\n    /**\n     * @dev Sets a `value` amount of tokens as the allowance of `spender` over the\n     * caller's tokens.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * IMPORTANT: Beware that changing an allowance with this method brings the risk\n     * that someone may use both the old and the new allowance by unfortunate\n     * transaction ordering. One possible solution to mitigate this race\n     * condition is to first reduce the spender's allowance to 0 and set the\n     * desired value afterwards:\n     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n     *\n     * Emits an {Approval} event.\n     */\n    function approve(address spender, uint256 value) external returns (bool);\n\n    /**\n     * @dev Moves a `value` amount of tokens from `from` to `to` using the\n     * allowance mechanism. `value` is then deducted from the caller's\n     * allowance.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transferFrom(address from, address to, uint256 value) external returns (bool);\n}\n"},{"file_path":"lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/utils/SlotDerivation.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.5.0) (utils/SlotDerivation.sol)\n// This file was procedurally generated from scripts/generate/templates/SlotDerivation.js.\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Library for computing storage (and transient storage) locations from namespaces and deriving slots\n * corresponding to standard patterns. The derivation method for array and mapping matches the storage layout used by\n * the solidity language / compiler.\n *\n * See https://docs.soliditylang.org/en/v0.8.20/internals/layout_in_storage.html#mappings-and-dynamic-arrays[Solidity docs for mappings and dynamic arrays.].\n *\n * Example usage:\n * ```solidity\n * contract Example {\n *     // Add the library methods\n *     using StorageSlot for bytes32;\n *     using SlotDerivation for *;\n *\n *     // Declare a namespace\n *     string private constant _NAMESPACE = \"<namespace>\"; // eg. OpenZeppelin.Slot\n *\n *     function setValueInNamespace(uint256 key, address newValue) internal {\n *         _NAMESPACE.erc7201Slot().deriveMapping(key).getAddressSlot().value = newValue;\n *     }\n *\n *     function getValueInNamespace(uint256 key) internal view returns (address) {\n *         return _NAMESPACE.erc7201Slot().deriveMapping(key).getAddressSlot().value;\n *     }\n * }\n * ```\n *\n * TIP: Consider using this library along with {StorageSlot}.\n *\n * NOTE: This library provides a way to manipulate storage locations in a non-standard way. Tooling for checking\n * upgrade safety will ignore the slots accessed through this library.\n *\n * _Available since v5.1._\n */\nlibrary SlotDerivation {\n    /**\n     * @dev Derive an ERC-7201 slot from a string (namespace).\n     */\n    function erc7201Slot(string memory namespace) internal pure returns (bytes32 slot) {\n        assembly (\"memory-safe\") {\n            mstore(0x00, sub(keccak256(add(namespace, 0x20), mload(namespace)), 1))\n            slot := and(keccak256(0x00, 0x20), not(0xff))\n        }\n    }\n\n    /**\n     * @dev Add an offset to a slot to get the n-th element of a structure or an array.\n     */\n    function offset(bytes32 slot, uint256 pos) internal pure returns (bytes32 result) {\n        unchecked {\n            return bytes32(uint256(slot) + pos);\n        }\n    }\n\n    /**\n     * @dev Derive the location of the first element in an array from the slot where the length is stored.\n     */\n    function deriveArray(bytes32 slot) internal pure returns (bytes32 result) {\n        assembly (\"memory-safe\") {\n            mstore(0x00, slot)\n            result := keccak256(0x00, 0x20)\n        }\n    }\n\n    /**\n     * @dev Derive the location of a mapping element from the key.\n     */\n    function deriveMapping(bytes32 slot, address key) internal pure returns (bytes32 result) {\n        assembly (\"memory-safe\") {\n            mstore(0x00, and(key, shr(96, not(0))))\n            mstore(0x20, slot)\n            result := keccak256(0x00, 0x40)\n        }\n    }\n\n    /**\n     * @dev Derive the location of a mapping element from the key.\n     */\n    function deriveMapping(bytes32 slot, bool key) internal pure returns (bytes32 result) {\n        assembly (\"memory-safe\") {\n            mstore(0x00, iszero(iszero(key)))\n            mstore(0x20, slot)\n            result := keccak256(0x00, 0x40)\n        }\n    }\n\n    /**\n     * @dev Derive the location of a mapping element from the key.\n     */\n    function deriveMapping(bytes32 slot, bytes32 key) internal pure returns (bytes32 result) {\n        assembly (\"memory-safe\") {\n            mstore(0x00, key)\n            mstore(0x20, slot)\n            result := keccak256(0x00, 0x40)\n        }\n    }\n\n    /**\n     * @dev Derive the location of a mapping element from the key.\n     */\n    function deriveMapping(bytes32 slot, uint256 key) internal pure returns (bytes32 result) {\n        assembly (\"memory-safe\") {\n            mstore(0x00, key)\n            mstore(0x20, slot)\n            result := keccak256(0x00, 0x40)\n        }\n    }\n\n    /**\n     * @dev Derive the location of a mapping element from the key.\n     */\n    function deriveMapping(bytes32 slot, int256 key) internal pure returns (bytes32 result) {\n        assembly (\"memory-safe\") {\n            mstore(0x00, key)\n            mstore(0x20, slot)\n            result := keccak256(0x00, 0x40)\n        }\n    }\n\n    /**\n     * @dev Derive the location of a mapping element from the key.\n     */\n    function deriveMapping(bytes32 slot, string memory key) internal pure returns (bytes32 result) {\n        assembly (\"memory-safe\") {\n            let length := mload(key)\n            let begin := add(key, 0x20)\n            let end := add(begin, length)\n            let cache := mload(end)\n            mstore(end, slot)\n            result := keccak256(begin, add(length, 0x20))\n            mstore(end, cache)\n        }\n    }\n\n    /**\n     * @dev Derive the location of a mapping element from the key.\n     */\n    function deriveMapping(bytes32 slot, bytes memory key) internal pure returns (bytes32 result) {\n        assembly (\"memory-safe\") {\n            let length := mload(key)\n            let begin := add(key, 0x20)\n            let end := add(begin, length)\n            let cache := mload(end)\n            mstore(end, slot)\n            result := keccak256(begin, add(length, 0x20))\n            mstore(end, cache)\n        }\n    }\n}\n"},{"file_path":"src/libraries/DecimalsUtils.sol","source_code":"// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.28;\n\nimport {IERC20Metadata} from \"@openzeppelin/contracts/interfaces/IERC20Metadata.sol\";\n\nimport {Errors} from \"./Errors.sol\";\n\nlibrary DecimalsUtils {\n    /// @dev Supported decimals range for assets\n    uint8 private constant MIN_DECIMALS = 6;\n    uint8 private constant MAX_DECIMALS = 18;\n\n    /// @dev Decimals and unit for machine share token.\n    uint8 internal constant SHARE_TOKEN_DECIMALS = 18;\n    uint256 internal constant SHARE_TOKEN_UNIT = 10 ** SHARE_TOKEN_DECIMALS;\n\n    /// @dev Checks that asset exposes decimals() and that it is within the supported range.\n    function _checkDecimals(address asset) internal view {\n        try IERC20Metadata(asset).decimals() returns (uint8 decimals_) {\n            if (decimals_ < MIN_DECIMALS || decimals_ > MAX_DECIMALS) {\n                revert Errors.InvalidDecimals();\n            }\n        } catch {\n            revert Errors.InvalidDecimals();\n        }\n    }\n}\n"},{"file_path":"src/interfaces/IFeeManager.sol","source_code":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.28;\n\ninterface IFeeManager {\n    /// @notice Returns the function selectors for the restricted fee configuration functions.\n    function getRestrictedFeeConfigSelectors() external view returns (bytes4[] memory);\n\n    /// @notice Calculates the fixed fee for a given share supply and elapsed time.\n    /// @dev May update internal state related to fee accrual or realization.\n    /// @param shareSupply The total supply of shares.\n    /// @param elapsedTime The elapsed time since the last fee realization.\n    /// @return fee The calculated fixed fee.\n    function calculateFixedFee(uint256 shareSupply, uint256 elapsedTime) external returns (uint256);\n\n    /// @notice Calculates the performance fee based on the share supply, share price performance and elapsed time.\n    /// @dev May update internal state related to fee accrual or realization.\n    /// @param currentShareSupply The current total supply of shares.\n    /// @param oldSharePrice The previous share price of reference.\n    /// @param newSharePrice The new share price of reference.\n    /// @param elapsedTime The elapsed time since the last fee realization.\n    /// @return fee The calculated performance fee.\n    function calculatePerformanceFee(\n        uint256 currentShareSupply,\n        uint256 oldSharePrice,\n        uint256 newSharePrice,\n        uint256 elapsedTime\n    ) external returns (uint256);\n\n    /// @notice Distributes the fees to relevant recipients.\n    /// @param fixedFee The fixed fee amount to be distributed.\n    /// @param perfFee The performance fee amount to be distributed.\n    function distributeFees(uint256 fixedFee, uint256 perfFee) external;\n}\n"},{"file_path":"lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/interfaces/IERC20.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.4.0) (interfaces/IERC20.sol)\n\npragma solidity >=0.4.16;\n\nimport {IERC20} from \"../token/ERC20/IERC20.sol\";\n"},{"file_path":"src/utils/SpokeSnapshotConsumer.sol","source_code":"// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.28;\n\nimport {\n    AccessManagedUpgradeable\n} from \"@openzeppelin/contracts-upgradeable/access/manager/AccessManagedUpgradeable.sol\";\nimport {IERC165, ERC165} from \"@openzeppelin/contracts/utils/introspection/ERC165.sol\";\nimport {EnumerableSet} from \"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\";\n\nimport {ICreReceiver} from \"../interfaces/ICreReceiver.sol\";\nimport {ISpokeSnapshotConsumer} from \"../interfaces/ISpokeSnapshotConsumer.sol\";\nimport {Errors} from \"../libraries/Errors.sol\";\n\nabstract contract SpokeSnapshotConsumer is AccessManagedUpgradeable, ERC165, ISpokeSnapshotConsumer {\n    using EnumerableSet for EnumerableSet.Bytes32Set;\n\n    /// @inheritdoc ISpokeSnapshotConsumer\n    address public immutable override creForwarder;\n\n    uint256 private constant CRE_METADATA_LENGTH = 64;\n\n    /// @custom:storage-location erc7201:makina.storage.SpokeSnapshotConsumer\n    struct SpokeSnapshotConsumerStorage {\n        EnumerableSet.Bytes32Set _creWorkflowIds;\n    }\n\n    // keccak256(abi.encode(uint256(keccak256(\"makina.storage.SpokeSnapshotConsumer\")) - 1)) & ~bytes32(uint256(0xff))\n    bytes32 private constant SpokeSnapshotConsumerStorageLocation =\n        0xb63b6c1855ef12c3ce1467dc59d74e167a3a4f63f2ecef0203e34e2727af1300;\n\n    function _getSpokeSnapshotConsumerStorage() private pure returns (SpokeSnapshotConsumerStorage storage $) {\n        assembly {\n            $.slot := SpokeSnapshotConsumerStorageLocation\n        }\n    }\n\n    constructor(address _creForwarder) {\n        creForwarder = _creForwarder;\n    }\n\n    function __SpokeSnapshotConsumer_init(SpokeSnapshotConsumerInitParams calldata sscParams)\n        internal\n        onlyInitializing\n    {\n        uint256 len = sscParams.initialCreWorkflowIds.length;\n        for (uint256 i; i < len; ++i) {\n            _addCreWorkflowId(sscParams.initialCreWorkflowIds[i]);\n        }\n    }\n\n    /// @inheritdoc ISpokeSnapshotConsumer\n    function isCreWorkflowIdAuthorized(bytes32 creWorkflowId) external view override returns (bool) {\n        return _getSpokeSnapshotConsumerStorage()._creWorkflowIds.contains(creWorkflowId);\n    }\n\n    /// @inheritdoc IERC165\n    function supportsInterface(bytes4 interfaceId) public view override(ERC165, IERC165) returns (bool) {\n        return interfaceId == type(ICreReceiver).interfaceId || super.supportsInterface(interfaceId);\n    }\n\n    /// @inheritdoc ISpokeSnapshotConsumer\n    function addCreWorkflowId(bytes32 newCreWorkflowId) external override restricted {\n        _addCreWorkflowId(newCreWorkflowId);\n    }\n\n    /// @inheritdoc ISpokeSnapshotConsumer\n    function removeCreWorkflowId(bytes32 creWorkflowId) external override restricted {\n        _removeCreWorkflowId(creWorkflowId);\n    }\n\n    /// @dev Internal logic for adding a CRE workflow ID.\n    function _addCreWorkflowId(bytes32 newCreWorkflowId) internal {\n        if (!_getSpokeSnapshotConsumerStorage()._creWorkflowIds.add(newCreWorkflowId)) {\n            revert Errors.CreWorkflowIdAlreadyAuthorized();\n        }\n        emit CreWorkflowIdAdded(newCreWorkflowId);\n    }\n\n    /// @dev Internal logic for removing a CRE workflow ID.\n    function _removeCreWorkflowId(bytes32 creWorkflowId) internal {\n        if (!_getSpokeSnapshotConsumerStorage()._creWorkflowIds.remove(creWorkflowId)) {\n            revert Errors.CreWorkflowIdNotAuthorized();\n        }\n        emit CreWorkflowIdRemoved(creWorkflowId);\n    }\n\n    /// @dev Extracts fields from a CRE report metadata and validates them against stored values if any are set.\n    function _validateMetadata(bytes calldata metadata) internal view {\n        if (metadata.length != CRE_METADATA_LENGTH) {\n            revert Errors.InvalidCreMetadataLength();\n        }\n\n        bytes32 workflowId;\n\n        // metadata (64 bytes): [0:32) id | [32:42) name | [42:62) author | [62:64) unused\n        assembly {\n            workflowId := calldataload(metadata.offset)\n        }\n\n        if (!_getSpokeSnapshotConsumerStorage()._creWorkflowIds.contains(workflowId)) {\n            revert Errors.InvalidCreWorkflowId();\n        }\n    }\n}\n"},{"file_path":"lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/interfaces/IERC1363.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.4.0) (interfaces/IERC1363.sol)\n\npragma solidity >=0.6.2;\n\nimport {IERC20} from \"./IERC20.sol\";\nimport {IERC165} from \"./IERC165.sol\";\n\n/**\n * @title IERC1363\n * @dev Interface of the ERC-1363 standard as defined in the https://eips.ethereum.org/EIPS/eip-1363[ERC-1363].\n *\n * Defines an extension interface for ERC-20 tokens that supports executing code on a recipient contract\n * after `transfer` or `transferFrom`, or code on a spender contract after `approve`, in a single transaction.\n */\ninterface IERC1363 is IERC20, IERC165 {\n    /*\n     * Note: the ERC-165 identifier for this interface is 0xb0202a11.\n     * 0xb0202a11 ===\n     *   bytes4(keccak256('transferAndCall(address,uint256)')) ^\n     *   bytes4(keccak256('transferAndCall(address,uint256,bytes)')) ^\n     *   bytes4(keccak256('transferFromAndCall(address,address,uint256)')) ^\n     *   bytes4(keccak256('transferFromAndCall(address,address,uint256,bytes)')) ^\n     *   bytes4(keccak256('approveAndCall(address,uint256)')) ^\n     *   bytes4(keccak256('approveAndCall(address,uint256,bytes)'))\n     */\n\n    /**\n     * @dev Moves a `value` amount of tokens from the caller's account to `to`\n     * and then calls {IERC1363Receiver-onTransferReceived} on `to`.\n     * @param to The address which you want to transfer to.\n     * @param value The amount of tokens to be transferred.\n     * @return A boolean value indicating whether the operation succeeded unless throwing.\n     */\n    function transferAndCall(address to, uint256 value) external returns (bool);\n\n    /**\n     * @dev Moves a `value` amount of tokens from the caller's account to `to`\n     * and then calls {IERC1363Receiver-onTransferReceived} on `to`.\n     * @param to The address which you want to transfer to.\n     * @param value The amount of tokens to be transferred.\n     * @param data Additional data with no specified format, sent in call to `to`.\n     * @return A boolean value indicating whether the operation succeeded unless throwing.\n     */\n    function transferAndCall(address to, uint256 value, bytes calldata data) external returns (bool);\n\n    /**\n     * @dev Moves a `value` amount of tokens from `from` to `to` using the allowance mechanism\n     * and then calls {IERC1363Receiver-onTransferReceived} on `to`.\n     * @param from The address which you want to send tokens from.\n     * @param to The address which you want to transfer to.\n     * @param value The amount of tokens to be transferred.\n     * @return A boolean value indicating whether the operation succeeded unless throwing.\n     */\n    function transferFromAndCall(address from, address to, uint256 value) external returns (bool);\n\n    /**\n     * @dev Moves a `value` amount of tokens from `from` to `to` using the allowance mechanism\n     * and then calls {IERC1363Receiver-onTransferReceived} on `to`.\n     * @param from The address which you want to send tokens from.\n     * @param to The address which you want to transfer to.\n     * @param value The amount of tokens to be transferred.\n     * @param data Additional data with no specified format, sent in call to `to`.\n     * @return A boolean value indicating whether the operation succeeded unless throwing.\n     */\n    function transferFromAndCall(address from, address to, uint256 value, bytes calldata data) external returns (bool);\n\n    /**\n     * @dev Sets a `value` amount of tokens as the allowance of `spender` over the\n     * caller's tokens and then calls {IERC1363Spender-onApprovalReceived} on `spender`.\n     * @param spender The address which will spend the funds.\n     * @param value The amount of tokens to be spent.\n     * @return A boolean value indicating whether the operation succeeded unless throwing.\n     */\n    function approveAndCall(address spender, uint256 value) external returns (bool);\n\n    /**\n     * @dev Sets a `value` amount of tokens as the allowance of `spender` over the\n     * caller's tokens and then calls {IERC1363Spender-onApprovalReceived} on `spender`.\n     * @param spender The address which will spend the funds.\n     * @param value The amount of tokens to be spent.\n     * @param data Additional data with no specified format, sent in call to `spender`.\n     * @return A boolean value indicating whether the operation succeeded unless throwing.\n     */\n    function approveAndCall(address spender, uint256 value, bytes calldata data) external returns (bool);\n}\n"},{"file_path":"lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/utils/ReentrancyGuard.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.5.0) (utils/ReentrancyGuard.sol)\n\npragma solidity ^0.8.20;\n\nimport {StorageSlot} from \"./StorageSlot.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 EIP-1153 (transient storage) is available on the chain you're deploying at,\n * consider using {ReentrancyGuardTransient} instead.\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 *\n * IMPORTANT: Deprecated. This storage-based reentrancy guard will be removed and replaced\n * by the {ReentrancyGuardTransient} variant in v6.0.\n *\n * @custom:stateless\n */\nabstract contract ReentrancyGuard {\n    using StorageSlot for bytes32;\n\n    // keccak256(abi.encode(uint256(keccak256(\"openzeppelin.storage.ReentrancyGuard\")) - 1)) & ~bytes32(uint256(0xff))\n    bytes32 private constant REENTRANCY_GUARD_STORAGE =\n        0x9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f00;\n\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    /**\n     * @dev Unauthorized reentrant call.\n     */\n    error ReentrancyGuardReentrantCall();\n\n    constructor() {\n        _reentrancyGuardStorageSlot().getUint256Slot().value = 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    /**\n     * @dev A `view` only version of {nonReentrant}. Use to block view functions\n     * from being called, preventing reading from inconsistent contract state.\n     *\n     * CAUTION: This is a \"view\" modifier and does not change the reentrancy\n     * status. Use it only on view functions. For payable or non-payable functions,\n     * use the standard {nonReentrant} modifier instead.\n     */\n    modifier nonReentrantView() {\n        _nonReentrantBeforeView();\n        _;\n    }\n\n    function _nonReentrantBeforeView() private view {\n        if (_reentrancyGuardEntered()) {\n            revert ReentrancyGuardReentrantCall();\n        }\n    }\n\n    function _nonReentrantBefore() private {\n        // On the first call to nonReentrant, _status will be NOT_ENTERED\n        _nonReentrantBeforeView();\n\n        // Any calls to nonReentrant after this point will fail\n        _reentrancyGuardStorageSlot().getUint256Slot().value = 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        _reentrancyGuardStorageSlot().getUint256Slot().value = 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 _reentrancyGuardStorageSlot().getUint256Slot().value == ENTERED;\n    }\n\n    function _reentrancyGuardStorageSlot() internal pure virtual returns (bytes32) {\n        return REENTRANCY_GUARD_STORAGE;\n    }\n}\n"},{"file_path":"src/interfaces/IBridgeAdapter.sol","source_code":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.28;\n\ninterface IBridgeAdapter {\n    event InBridgeTransferAuthorized(bytes32 indexed messageHash);\n    event OutBridgeTransferCancelled(uint256 indexed transferId);\n    event InBridgeTransferClaimed(uint256 indexed transferId);\n    event InBridgeTransferReceived(uint256 indexed transferId);\n    event OutBridgeTransferSent(uint256 indexed transferId);\n    event OutBridgeTransferScheduled(uint256 indexed transferId, bytes32 indexed messageHash);\n    event PendingFundsWithdrawn(address indexed token, uint256 amount);\n\n    struct OutBridgeTransfer {\n        address recipient;\n        uint256 destinationChainId;\n        address inputToken;\n        uint256 inputAmount;\n        address outputToken;\n        uint256 minOutputAmount;\n        bytes encodedMessage;\n    }\n\n    struct InBridgeTransfer {\n        address sender;\n        uint256 originChainId;\n        address inputToken;\n        uint256 inputAmount;\n        address outputToken;\n        uint256 outputAmount;\n    }\n\n    struct BridgeMessage {\n        uint256 outTransferId;\n        address sender;\n        address recipient;\n        uint256 originChainId;\n        uint256 destinationChainId;\n        address inputToken;\n        uint256 inputAmount;\n        address outputToken;\n        uint256 minOutputAmount;\n    }\n\n    /// @notice Initializer of the contract.\n    /// @param _controller The bridge controller contract.\n    /// @param initData The optional initialization data.\n    function initialize(address _controller, bytes calldata initData) external;\n\n    /// @notice Address of the bridge controller contract.\n    function controller() external view returns (address);\n\n    /// @notice ID of the adapted external bridge.\n    function bridgeId() external view returns (uint16);\n\n    /// @notice Address of the external bridge approval target contract.\n    function approvalTarget() external view returns (address);\n\n    /// @notice Address of the external bridge execution target contract.\n    function executionTarget() external view returns (address);\n\n    /// @notice Address of the external bridge contract responsible for sending output funds.\n    function receiveSource() external view returns (address);\n\n    /// @notice ID of the next outgoing transfer.\n    function nextOutTransferId() external view returns (uint256);\n\n    /// @notice ID of the next incoming transfer.\n    function nextInTransferId() external view returns (uint256);\n\n    /// @notice Schedules an outgoing bridge transfer and returns the message hash.\n    /// @dev Emits an event containing the id of the transfer and the hash of the bridge transfer message.\n    /// @param destinationChainId The ID of the destination chain.\n    /// @param recipient The address of the recipient on the destination chain.\n    /// @param inputToken The address of the input token.\n    /// @param inputAmount The amount of the input token to transfer.\n    /// @param outputToken The address of the output token on the destination chain.\n    /// @param minOutputAmount The minimum amount of the output token to receive.\n    function scheduleOutBridgeTransfer(\n        uint256 destinationChainId,\n        address recipient,\n        address inputToken,\n        uint256 inputAmount,\n        address outputToken,\n        uint256 minOutputAmount\n    ) external;\n\n    /// @notice Executes a scheduled outgoing bridge transfer.\n    /// @param transferId The ID of the transfer to execute.\n    /// @param data The optional data needed to execute the transfer.\n    function sendOutBridgeTransfer(uint256 transferId, bytes calldata data) external;\n\n    /// @notice Returns the default amount that must be transferred to the adapter to cancel an outgoing bridge transfer.\n    /// @dev If the transfer has not yet been sent, or if the full amount was refunded to this contract by the external bridge, returns 0.\n    /// @dev If the bridge retains a fee upon cancellation and only a partial refund was received, the returned value reflects that fee.\n    /// @dev In all other cases (e.g. including pending refunds or successful bridge transfers), returns the full amount of the transfer.\n    /// @param transferId The ID of the transfer to check.\n    /// @return The amount required to cancel the transfer.\n    function outBridgeTransferCancelDefault(uint256 transferId) external view returns (uint256);\n\n    /// @notice Cancels an outgoing bridge transfer.\n    /// @param transferId The ID of the transfer to cancel.\n    function cancelOutBridgeTransfer(uint256 transferId) external;\n\n    /// @notice Registers a message hash as authorized for an incoming bridge transfer.\n    /// @param messageHash The hash of the message to authorize.\n    function authorizeInBridgeTransfer(bytes32 messageHash) external;\n\n    /// @notice Transfers a received bridge transfer out of the adapter.\n    /// @param transferId The ID of the transfer to claim.\n    function claimInBridgeTransfer(uint256 transferId) external;\n\n    /// @notice Resets internal state for a given token address, and transfers token balance to associated controller.\n    /// @dev This function is intended to be used by the DAO to unlock funds stuck in the adapter, typically\n    /// in response to operator deviations or external bridge discrepancies.\n    /// @param token The address of the token.\n    function withdrawPendingFunds(address token) external;\n}\n"},{"file_path":"lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/utils/introspection/ERC165.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.4.0) (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.20;\n\nimport {IERC165} from \"./IERC165.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC-165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n *     return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n */\nabstract contract ERC165 is IERC165 {\n    /// @inheritdoc IERC165\n    function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) {\n        return interfaceId == type(IERC165).interfaceId;\n    }\n}\n"},{"file_path":"src/interfaces/ICaliberMailbox.sol","source_code":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.28;\n\nimport {IMachineEndpoint} from \"./IMachineEndpoint.sol\";\nimport {IMakinaGovernable} from \"./IMakinaGovernable.sol\";\n\ninterface ICaliberMailbox is IMachineEndpoint {\n    event CaliberSet(address indexed caliber);\n    event CooldownDurationChanged(uint256 oldDuration, uint256 newDuration);\n    event HubBridgeAdapterSet(uint256 indexed bridgeId, address indexed adapter);\n\n    /// @notice Spoke caliber accounting snapshot context.\n    /// @param chainId The chain ID of the spoke caliber.\n    /// @param mailbox The address of the spoke caliber mailbox.\n    /// @param blockNum The block number used as the snapshot reference point.\n    /// @param blockTime The block timestamp used as the snapshot reference point.\n    struct SpokeSnapshotContext {\n        uint256 chainId;\n        address mailbox;\n        uint256 blockNum;\n        uint256 blockTime;\n    }\n\n    /// @notice Spoke caliber accounting snapshot data.\n    /// @param netAum The net AUM denominated in the caliber accounting token.\n    /// @param bridgesIn The list of incoming bridge amounts, each encoded as abi.encode(token, amount).\n    /// @param bridgesOut The list of outgoing bridge amounts, each encoded as abi.encode(token, amount).\n    /// @param context The snapshot context.\n    struct SpokeCaliberAccountingData {\n        uint256 netAum;\n        bytes[] bridgesIn;\n        bytes[] bridgesOut;\n        SpokeSnapshotContext context;\n    }\n\n    /// @notice Initializer of the contract.\n    /// @param mgParams The makina governable initialization parameters.\n    /// @param initialCooldownDuration The duration of the cooldown period for outgoing bridge transfers.\n    function initialize(IMakinaGovernable.MakinaGovernableInitParams calldata mgParams, uint256 initialCooldownDuration)\n        external;\n\n    /// @notice Address of the associated caliber.\n    function caliber() external view returns (address);\n\n    /// @notice Duration of the cooldown period for outgoing bridge transfers.\n    function cooldownDuration() external view returns (uint256);\n\n    /// @notice Returns the address of the hub bridge adapter for a given bridge ID.\n    /// @param bridgeId The ID of the bridge.\n    function getHubBridgeAdapter(uint16 bridgeId) external view returns (address);\n\n    /// @notice Chain ID of the hub.\n    function hubChainId() external view returns (uint256);\n\n    /// @notice Returns the accounting data of the associated caliber.\n    /// @return data The accounting data.\n    function getSpokeCaliberAccountingData() external view returns (SpokeCaliberAccountingData memory);\n\n    /// @notice Sets the associated caliber address.\n    /// @param _caliber The address of the associated caliber.\n    function setCaliber(address _caliber) external;\n\n    /// @notice Sets the duration of the cooldown period for outgoing bridge transfers.\n    /// @param newCooldownDuration The new duration in seconds.\n    function setCooldownDuration(uint256 newCooldownDuration) external;\n\n    /// @notice Registers a hub bridge adapter.\n    /// @param bridgeId The ID of the bridge.\n    /// @param adapter The address of the hub bridge adapter.\n    function setHubBridgeAdapter(uint16 bridgeId, address adapter) external;\n}\n"},{"file_path":"src/interfaces/IHubCoreRegistry.sol","source_code":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.28;\n\nimport {ICoreRegistry} from \"./ICoreRegistry.sol\";\n\ninterface IHubCoreRegistry is ICoreRegistry {\n    event MachineBeaconChanged(address indexed oldMachineBeacon, address indexed newMachineBeacon);\n    event PreDepositVaultBeaconChanged(\n        address indexed oldPreDepositVaultBeacon, address indexed newPreDepositVaultBeacon\n    );\n\n    /// @notice Address of the machine beacon contract.\n    function machineBeacon() external view returns (address);\n\n    /// @notice Address of the pre-deposit vault beacon contract.\n    function preDepositVaultBeacon() external view returns (address);\n\n    /// @notice Sets the machine beacon address.\n    /// @param _machineBeacon The machine beacon address.\n    function setMachineBeacon(address _machineBeacon) external;\n\n    /// @notice Sets the pre-deposit vault beacon address.\n    /// @param _preDepositVaultBeacon The pre-deposit vault beacon address.\n    function setPreDepositVaultBeacon(address _preDepositVaultBeacon) external;\n}\n"},{"file_path":"src/interfaces/IBridgeController.sol","source_code":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.28;\n\ninterface IBridgeController {\n    event BridgeAdapterSet(uint16 indexed bridgeId, address indexed adapter);\n    event MaxBridgeLossBpsChanged(\n        uint16 indexed bridgeId, uint256 indexed oldMaxBridgeLossBps, uint256 indexed newMaxBridgeLossBps\n    );\n    event BridgingStateReset(address indexed token);\n    event OutTransferDisabled(uint16 indexed bridgeId);\n    event OutTransferEnabled(uint16 indexed bridgeId);\n\n    /// @notice Bridge ID => Is bridge adapter deployed.\n    function isBridgeSupported(uint16 bridgeId) external view returns (bool);\n\n    /// @notice Bridge ID => Is outgoing transfer enabled.\n    function isOutTransferEnabled(uint16 bridgeId) external view returns (bool);\n\n    /// @notice Bridge ID => Address of the associated bridge adapter.\n    function getBridgeAdapter(uint16 bridgeId) external view returns (address);\n\n    /// @notice Bridge ID => Max allowed value loss in basis points for transfers via this bridge.\n    function getMaxBridgeLossBps(uint16 bridgeId) external view returns (uint256);\n\n    /// @notice Sets a bridge adapter instance for a given bridge ID.\n    /// @param bridgeId The ID of the bridge.\n    /// @param bridgeAdapter The address of the new bridge adapter instance.\n    /// @param initialMaxBridgeLossBps The initial maximum allowed value loss in basis points for transfers via this bridge.\n    function setBridgeAdapter(uint16 bridgeId, address bridgeAdapter, uint256 initialMaxBridgeLossBps) external;\n\n    /// @notice Sets the maximum allowed value loss in basis points for transfers via this bridge.\n    /// @param bridgeId The ID of the bridge.\n    /// @param maxBridgeLossBps The maximum allowed value loss in basis points.\n    function setMaxBridgeLossBps(uint16 bridgeId, uint256 maxBridgeLossBps) external;\n\n    /// @notice Disables outgoing transfers for a bridge.\n    /// @param bridgeId The ID of the bridge.\n    function disableOutTransfer(uint16 bridgeId) external;\n\n    /// @notice Enables outgoing transfers for a bridge.\n    /// @param bridgeId The ID of the bridge.\n    function enableOutTransfer(uint16 bridgeId) external;\n\n    /// @notice Executes a scheduled outgoing bridge transfer.\n    /// @param bridgeId The ID of the bridge.\n    /// @param transferId The ID of the transfer to execute.\n    /// @param data The optional data needed to execute the transfer.\n    function sendOutBridgeTransfer(uint16 bridgeId, uint256 transferId, bytes calldata data) external;\n\n    /// @notice Registers a message hash as authorized for an incoming bridge transfer.\n    /// @param bridgeId The ID of the bridge.\n    /// @param messageHash The hash of the message to authorize.\n    function authorizeInBridgeTransfer(uint16 bridgeId, bytes32 messageHash) external;\n\n    /// @notice Transfers a received bridge transfer out of the corresponding bridge adapter.\n    /// @param bridgeId The ID of the bridge.\n    /// @param transferId The ID of the transfer to claim.\n    function claimInBridgeTransfer(uint16 bridgeId, uint256 transferId) external;\n\n    /// @notice Cancels an outgoing bridge transfer.\n    /// @param bridgeId The ID of the bridge.\n    /// @param transferId The ID of the transfer to cancel.\n    function cancelOutBridgeTransfer(uint16 bridgeId, uint256 transferId) external;\n\n    /// @notice Resets internal bridge counters for a given token, and withdraws token balances held by all bridge adapters.\n    /// @dev This function is intended to be used by the DAO to realign bridge accounting state and maintain protocol consistency,\n    ///      typically in response to operator deviations, external bridge discrepancies, or unbounded counter growth.\n    /// @param token The address of the token.\n    function resetBridgingState(address token) external;\n}\n"},{"file_path":"lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/proxy/utils/Initializable.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.3.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.20;\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 Storage of the initializable contract.\n     *\n     * It's implemented on a custom ERC-7201 namespace to reduce the risk of storage collisions\n     * when using with upgradeable contracts.\n     *\n     * @custom:storage-location erc7201:openzeppelin.storage.Initializable\n     */\n    struct InitializableStorage {\n        /**\n         * @dev Indicates that the contract has been initialized.\n         */\n        uint64 _initialized;\n        /**\n         * @dev Indicates that the contract is in the process of being initialized.\n         */\n        bool _initializing;\n    }\n\n    // keccak256(abi.encode(uint256(keccak256(\"openzeppelin.storage.Initializable\")) - 1)) & ~bytes32(uint256(0xff))\n    bytes32 private constant INITIALIZABLE_STORAGE = 0xf0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00;\n\n    /**\n     * @dev The contract is already initialized.\n     */\n    error InvalidInitialization();\n\n    /**\n     * @dev The contract is not initializing.\n     */\n    error NotInitializing();\n\n    /**\n     * @dev Triggered when the contract has been initialized or reinitialized.\n     */\n    event Initialized(uint64 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 in the context of a constructor an `initializer` may be invoked any\n     * number of times. This behavior in the constructor can be useful during testing and is not expected to be used in\n     * production.\n     *\n     * Emits an {Initialized} event.\n     */\n    modifier initializer() {\n        // solhint-disable-next-line var-name-mixedcase\n        InitializableStorage storage $ = _getInitializableStorage();\n\n        // Cache values to avoid duplicated sloads\n        bool isTopLevelCall = !$._initializing;\n        uint64 initialized = $._initialized;\n\n        // Allowed calls:\n        // - initialSetup: the contract is not in the initializing state and no previous version was\n        //                 initialized\n        // - construction: the contract is initialized at version 1 (no reinitialization) and the\n        //                 current contract is just being deployed\n        bool initialSetup = initialized == 0 && isTopLevelCall;\n        bool construction = initialized == 1 && address(this).code.length == 0;\n\n        if (!initialSetup && !construction) {\n            revert InvalidInitialization();\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 2**64 - 1 will prevent any future reinitialization.\n     *\n     * Emits an {Initialized} event.\n     */\n    modifier reinitializer(uint64 version) {\n        // solhint-disable-next-line var-name-mixedcase\n        InitializableStorage storage $ = _getInitializableStorage();\n\n        if ($._initializing || $._initialized >= version) {\n            revert InvalidInitialization();\n        }\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        _checkInitializing();\n        _;\n    }\n\n    /**\n     * @dev Reverts if the contract is not in an initializing state. See {onlyInitializing}.\n     */\n    function _checkInitializing() internal view virtual {\n        if (!_isInitializing()) {\n            revert NotInitializing();\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        // solhint-disable-next-line var-name-mixedcase\n        InitializableStorage storage $ = _getInitializableStorage();\n\n        if ($._initializing) {\n            revert InvalidInitialization();\n        }\n        if ($._initialized != type(uint64).max) {\n            $._initialized = type(uint64).max;\n            emit Initialized(type(uint64).max);\n        }\n    }\n\n    /**\n     * @dev Returns the highest version that has been initialized. See {reinitializer}.\n     */\n    function _getInitializedVersion() internal view returns (uint64) {\n        return _getInitializableStorage()._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 _getInitializableStorage()._initializing;\n    }\n\n    /**\n     * @dev Pointer to storage slot. Allows integrators to override it with a custom storage location.\n     *\n     * NOTE: Consider following the ERC-7201 formula to derive storage locations.\n     */\n    function _initializableStorageSlot() internal pure virtual returns (bytes32) {\n        return INITIALIZABLE_STORAGE;\n    }\n\n    /**\n     * @dev Returns a pointer to the storage namespace.\n     */\n    // solhint-disable-next-line var-name-mixedcase\n    function _getInitializableStorage() private pure returns (InitializableStorage storage $) {\n        bytes32 slot = _initializableStorageSlot();\n        assembly {\n            $.slot := slot\n        }\n    }\n}\n"},{"file_path":"lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/interfaces/IERC165.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.4.0) (interfaces/IERC165.sol)\n\npragma solidity >=0.4.16;\n\nimport {IERC165} from \"../utils/introspection/IERC165.sol\";\n"},{"file_path":"lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/utils/math/Math.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.6.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.20;\n\nimport {Panic} from \"../Panic.sol\";\nimport {SafeCast} from \"./SafeCast.sol\";\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary Math {\n    enum Rounding {\n        Floor, // Toward negative infinity\n        Ceil, // Toward positive infinity\n        Trunc, // Toward zero\n        Expand // Away from zero\n    }\n\n    /**\n     * @dev Return the 512-bit addition of two uint256.\n     *\n     * The result is stored in two 256 variables such that sum = high * 2²⁵⁶ + low.\n     */\n    function add512(uint256 a, uint256 b) internal pure returns (uint256 high, uint256 low) {\n        assembly (\"memory-safe\") {\n            low := add(a, b)\n            high := lt(low, a)\n        }\n    }\n\n    /**\n     * @dev Return the 512-bit multiplication of two uint256.\n     *\n     * The result is stored in two 256 variables such that product = high * 2²⁵⁶ + low.\n     */\n    function mul512(uint256 a, uint256 b) internal pure returns (uint256 high, uint256 low) {\n        // 512-bit multiply [high low] = x * y. Compute the product mod 2²⁵⁶ and mod 2²⁵⁶ - 1, then use\n        // the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\n        // variables such that product = high * 2²⁵⁶ + low.\n        assembly (\"memory-safe\") {\n            let mm := mulmod(a, b, not(0))\n            low := mul(a, b)\n            high := sub(sub(mm, low), lt(mm, low))\n        }\n    }\n\n    /**\n     * @dev Returns the addition of two unsigned integers, with a success flag (no overflow).\n     */\n    function tryAdd(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) {\n        unchecked {\n            uint256 c = a + b;\n            success = c >= a;\n            result = c * SafeCast.toUint(success);\n        }\n    }\n\n    /**\n     * @dev Returns the subtraction of two unsigned integers, with a success flag (no overflow).\n     */\n    function trySub(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) {\n        unchecked {\n            uint256 c = a - b;\n            success = c <= a;\n            result = c * SafeCast.toUint(success);\n        }\n    }\n\n    /**\n     * @dev Returns the multiplication of two unsigned integers, with a success flag (no overflow).\n     */\n    function tryMul(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) {\n        unchecked {\n            uint256 c = a * b;\n            assembly (\"memory-safe\") {\n                // Only true when the multiplication doesn't overflow\n                // (c / a == b) || (a == 0)\n                success := or(eq(div(c, a), b), iszero(a))\n            }\n            // equivalent to: success ? c : 0\n            result = c * SafeCast.toUint(success);\n        }\n    }\n\n    /**\n     * @dev Returns the division of two unsigned integers, with a success flag (no division by zero).\n     */\n    function tryDiv(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) {\n        unchecked {\n            success = b > 0;\n            assembly (\"memory-safe\") {\n                // The `DIV` opcode returns zero when the denominator is 0.\n                result := div(a, b)\n            }\n        }\n    }\n\n    /**\n     * @dev Returns the remainder of dividing two unsigned integers, with a success flag (no division by zero).\n     */\n    function tryMod(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) {\n        unchecked {\n            success = b > 0;\n            assembly (\"memory-safe\") {\n                // The `MOD` opcode returns zero when the denominator is 0.\n                result := mod(a, b)\n            }\n        }\n    }\n\n    /**\n     * @dev Unsigned saturating addition, bounds to `2²⁵⁶ - 1` instead of overflowing.\n     */\n    function saturatingAdd(uint256 a, uint256 b) internal pure returns (uint256) {\n        (bool success, uint256 result) = tryAdd(a, b);\n        return ternary(success, result, type(uint256).max);\n    }\n\n    /**\n     * @dev Unsigned saturating subtraction, bounds to zero instead of overflowing.\n     */\n    function saturatingSub(uint256 a, uint256 b) internal pure returns (uint256) {\n        (, uint256 result) = trySub(a, b);\n        return result;\n    }\n\n    /**\n     * @dev Unsigned saturating multiplication, bounds to `2²⁵⁶ - 1` instead of overflowing.\n     */\n    function saturatingMul(uint256 a, uint256 b) internal pure returns (uint256) {\n        (bool success, uint256 result) = tryMul(a, b);\n        return ternary(success, result, type(uint256).max);\n    }\n\n    /**\n     * @dev Branchless ternary evaluation for `condition ? a : b`. Gas costs are constant.\n     *\n     * IMPORTANT: This function may reduce bytecode size and consume less gas when used standalone.\n     * However, the compiler may optimize Solidity ternary operations (i.e. `condition ? a : b`) to only compute\n     * one branch when needed, making this function more expensive.\n     */\n    function ternary(bool condition, uint256 a, uint256 b) internal pure returns (uint256) {\n        unchecked {\n            // branchless ternary works because:\n            // b ^ (a ^ b) == a\n            // b ^ 0 == b\n            return b ^ ((a ^ b) * SafeCast.toUint(condition));\n        }\n    }\n\n    /**\n     * @dev Returns the largest of two numbers.\n     */\n    function max(uint256 a, uint256 b) internal pure returns (uint256) {\n        return ternary(a > b, a, b);\n    }\n\n    /**\n     * @dev Returns the smallest of two numbers.\n     */\n    function min(uint256 a, uint256 b) internal pure returns (uint256) {\n        return ternary(a < b, a, b);\n    }\n\n    /**\n     * @dev Returns the average of two numbers. The result is rounded towards\n     * zero.\n     */\n    function average(uint256 a, uint256 b) internal pure returns (uint256) {\n        unchecked {\n            // (a + b) / 2 can overflow.\n            return (a & b) + (a ^ b) / 2;\n        }\n    }\n\n    /**\n     * @dev Returns the ceiling of the division of two numbers.\n     *\n     * This differs from standard division with `/` in that it rounds towards infinity instead\n     * of rounding towards zero.\n     */\n    function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n        if (b == 0) {\n            // Guarantee the same behavior as in a regular Solidity division.\n            Panic.panic(Panic.DIVISION_BY_ZERO);\n        }\n\n        // The following calculation ensures accurate ceiling division without overflow.\n        // Since a is non-zero, (a - 1) / b will not overflow.\n        // The largest possible result occurs when (a - 1) / b is type(uint256).max,\n        // but the largest value we can obtain is type(uint256).max - 1, which happens\n        // when a = type(uint256).max and b = 1.\n        unchecked {\n            return SafeCast.toUint(a > 0) * ((a - 1) / b + 1);\n        }\n    }\n\n    /**\n     * @dev Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or\n     * denominator == 0.\n     *\n     * Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) with further edits by\n     * Uniswap Labs also under MIT license.\n     */\n    function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {\n        unchecked {\n            (uint256 high, uint256 low) = mul512(x, y);\n\n            // Handle non-overflow cases, 256 by 256 division.\n            if (high == 0) {\n                // Solidity will revert if denominator == 0, unlike the div opcode on its own.\n                // The surrounding unchecked block does not change this fact.\n                // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.\n                return low / denominator;\n            }\n\n            // Make sure the result is less than 2²⁵⁶. Also prevents denominator == 0.\n            if (denominator <= high) {\n                Panic.panic(ternary(denominator == 0, Panic.DIVISION_BY_ZERO, Panic.UNDER_OVERFLOW));\n            }\n\n            ///////////////////////////////////////////////\n            // 512 by 256 division.\n            ///////////////////////////////////////////////\n\n            // Make division exact by subtracting the remainder from [high low].\n            uint256 remainder;\n            assembly (\"memory-safe\") {\n                // Compute remainder using mulmod.\n                remainder := mulmod(x, y, denominator)\n\n                // Subtract 256 bit number from 512 bit number.\n                high := sub(high, gt(remainder, low))\n                low := sub(low, remainder)\n            }\n\n            // Factor powers of two out of denominator and compute largest power of two divisor of denominator.\n            // Always >= 1. See https://cs.stackexchange.com/q/138556/92363.\n\n            uint256 twos = denominator & (0 - denominator);\n            assembly (\"memory-safe\") {\n                // Divide denominator by twos.\n                denominator := div(denominator, twos)\n\n                // Divide [high low] by twos.\n                low := div(low, twos)\n\n                // Flip twos such that it is 2²⁵⁶ / twos. If twos is zero, then it becomes one.\n                twos := add(div(sub(0, twos), twos), 1)\n            }\n\n            // Shift in bits from high into low.\n            low |= high * twos;\n\n            // Invert denominator mod 2²⁵⁶. Now that denominator is an odd number, it has an inverse modulo 2²⁵⁶ such\n            // that denominator * inv ≡ 1 mod 2²⁵⁶. Compute the inverse by starting with a seed that is correct for\n            // four bits. That is, denominator * inv ≡ 1 mod 2⁴.\n            uint256 inverse = (3 * denominator) ^ 2;\n\n            // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also\n            // works in modular arithmetic, doubling the correct bits in each step.\n            inverse *= 2 - denominator * inverse; // inverse mod 2⁸\n            inverse *= 2 - denominator * inverse; // inverse mod 2¹⁶\n            inverse *= 2 - denominator * inverse; // inverse mod 2³²\n            inverse *= 2 - denominator * inverse; // inverse mod 2⁶⁴\n            inverse *= 2 - denominator * inverse; // inverse mod 2¹²⁸\n            inverse *= 2 - denominator * inverse; // inverse mod 2²⁵⁶\n\n            // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n            // This will give us the correct result modulo 2²⁵⁶. Since the preconditions guarantee that the outcome is\n            // less than 2²⁵⁶, this is the final result. We don't need to compute the high bits of the result and high\n            // is no longer required.\n            result = low * inverse;\n            return result;\n        }\n    }\n\n    /**\n     * @dev Calculates x * y / denominator with full precision, following the selected rounding direction.\n     */\n    function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {\n        return mulDiv(x, y, denominator) + SafeCast.toUint(unsignedRoundsUp(rounding) && mulmod(x, y, denominator) > 0);\n    }\n\n    /**\n     * @dev Calculates floor(x * y >> n) with full precision. Throws if result overflows a uint256.\n     */\n    function mulShr(uint256 x, uint256 y, uint8 n) internal pure returns (uint256 result) {\n        unchecked {\n            (uint256 high, uint256 low) = mul512(x, y);\n            if (high >= 1 << n) {\n                Panic.panic(Panic.UNDER_OVERFLOW);\n            }\n            return (high << (256 - n)) | (low >> n);\n        }\n    }\n\n    /**\n     * @dev Calculates x * y >> n with full precision, following the selected rounding direction.\n     */\n    function mulShr(uint256 x, uint256 y, uint8 n, Rounding rounding) internal pure returns (uint256) {\n        return mulShr(x, y, n) + SafeCast.toUint(unsignedRoundsUp(rounding) && mulmod(x, y, 1 << n) > 0);\n    }\n\n    /**\n     * @dev Calculate the modular multiplicative inverse of a number in Z/nZ.\n     *\n     * If n is a prime, then Z/nZ is a field. In that case all elements are inversible, except 0.\n     * If n is not a prime, then Z/nZ is not a field, and some elements might not be inversible.\n     *\n     * If the input value is not inversible, 0 is returned.\n     *\n     * NOTE: If you know for sure that n is (big) a prime, it may be cheaper to use Fermat's little theorem and get the\n     * inverse using `Math.modExp(a, n - 2, n)`. See {invModPrime}.\n     */\n    function invMod(uint256 a, uint256 n) internal pure returns (uint256) {\n        unchecked {\n            if (n == 0) return 0;\n\n            // The inverse modulo is calculated using the Extended Euclidean Algorithm (iterative version)\n            // Used to compute integers x and y such that: ax + ny = gcd(a, n).\n            // When the gcd is 1, then the inverse of a modulo n exists and it's x.\n            // ax + ny = 1\n            // ax = 1 + (-y)n\n            // ax ≡ 1 (mod n) # x is the inverse of a modulo n\n\n            // If the remainder is 0 the gcd is n right away.\n            uint256 remainder = a % n;\n            uint256 gcd = n;\n\n            // Therefore the initial coefficients are:\n            // ax + ny = gcd(a, n) = n\n            // 0a + 1n = n\n            int256 x = 0;\n            int256 y = 1;\n\n            while (remainder != 0) {\n                uint256 quotient = gcd / remainder;\n\n                (gcd, remainder) = (\n                    // The old remainder is the next gcd to try.\n                    remainder,\n                    // Compute the next remainder.\n                    // Can't overflow given that (a % gcd) * (gcd // (a % gcd)) <= gcd\n                    // where gcd is at most n (capped to type(uint256).max)\n                    gcd - remainder * quotient\n                );\n\n                (x, y) = (\n                    // Increment the coefficient of a.\n                    y,\n                    // Decrement the coefficient of n.\n                    // Can overflow, but the result is casted to uint256 so that the\n                    // next value of y is \"wrapped around\" to a value between 0 and n - 1.\n                    x - y * int256(quotient)\n                );\n            }\n\n            if (gcd != 1) return 0; // No inverse exists.\n            return ternary(x < 0, n - uint256(-x), uint256(x)); // Wrap the result if it's negative.\n        }\n    }\n\n    /**\n     * @dev Variant of {invMod}. More efficient, but only works if `p` is known to be a prime greater than `2`.\n     *\n     * From https://en.wikipedia.org/wiki/Fermat%27s_little_theorem[Fermat's little theorem], we know that if p is\n     * prime, then `a**(p-1) ≡ 1 mod p`. As a consequence, we have `a * a**(p-2) ≡ 1 mod p`, which means that\n     * `a**(p-2)` is the modular multiplicative inverse of a in Fp.\n     *\n     * NOTE: this function does NOT check that `p` is a prime greater than `2`.\n     */\n    function invModPrime(uint256 a, uint256 p) internal view returns (uint256) {\n        unchecked {\n            return Math.modExp(a, p - 2, p);\n        }\n    }\n\n    /**\n     * @dev Returns the modular exponentiation of the specified base, exponent and modulus (b ** e % m)\n     *\n     * Requirements:\n     * - modulus can't be zero\n     * - underlying staticcall to precompile must succeed\n     *\n     * IMPORTANT: The result is only valid if the underlying call succeeds. When using this function, make\n     * sure the chain you're using it on supports the precompiled contract for modular exponentiation\n     * at address 0x05 as specified in https://eips.ethereum.org/EIPS/eip-198[EIP-198]. Otherwise,\n     * the underlying function will succeed given the lack of a revert, but the result may be incorrectly\n     * interpreted as 0.\n     */\n    function modExp(uint256 b, uint256 e, uint256 m) internal view returns (uint256) {\n        (bool success, uint256 result) = tryModExp(b, e, m);\n        if (!success) {\n            Panic.panic(Panic.DIVISION_BY_ZERO);\n        }\n        return result;\n    }\n\n    /**\n     * @dev Returns the modular exponentiation of the specified base, exponent and modulus (b ** e % m).\n     * It includes a success flag indicating if the operation succeeded. Operation will be marked as failed if trying\n     * to operate modulo 0 or if the underlying precompile reverted.\n     *\n     * IMPORTANT: The result is only valid if the success flag is true. When using this function, make sure the chain\n     * you're using it on supports the precompiled contract for modular exponentiation at address 0x05 as specified in\n     * https://eips.ethereum.org/EIPS/eip-198[EIP-198]. Otherwise, the underlying function will succeed given the lack\n     * of a revert, but the result may be incorrectly interpreted as 0.\n     */\n    function tryModExp(uint256 b, uint256 e, uint256 m) internal view returns (bool success, uint256 result) {\n        if (m == 0) return (false, 0);\n        assembly (\"memory-safe\") {\n            let ptr := mload(0x40)\n            // | Offset    | Content    | Content (Hex)                                                      |\n            // |-----------|------------|--------------------------------------------------------------------|\n            // | 0x00:0x1f | size of b  | 0x0000000000000000000000000000000000000000000000000000000000000020 |\n            // | 0x20:0x3f | size of e  | 0x0000000000000000000000000000000000000000000000000000000000000020 |\n            // | 0x40:0x5f | size of m  | 0x0000000000000000000000000000000000000000000000000000000000000020 |\n            // | 0x60:0x7f | value of b | 0x<.............................................................b> |\n            // | 0x80:0x9f | value of e | 0x<.............................................................e> |\n            // | 0xa0:0xbf | value of m | 0x<.............................................................m> |\n            mstore(ptr, 0x20)\n            mstore(add(ptr, 0x20), 0x20)\n            mstore(add(ptr, 0x40), 0x20)\n            mstore(add(ptr, 0x60), b)\n            mstore(add(ptr, 0x80), e)\n            mstore(add(ptr, 0xa0), m)\n\n            // Given the result < m, it's guaranteed to fit in 32 bytes,\n            // so we can use the memory scratch space located at offset 0.\n            success := staticcall(gas(), 0x05, ptr, 0xc0, 0x00, 0x20)\n            result := mload(0x00)\n        }\n    }\n\n    /**\n     * @dev Variant of {modExp} that supports inputs of arbitrary length.\n     */\n    function modExp(bytes memory b, bytes memory e, bytes memory m) internal view returns (bytes memory) {\n        (bool success, bytes memory result) = tryModExp(b, e, m);\n        if (!success) {\n            Panic.panic(Panic.DIVISION_BY_ZERO);\n        }\n        return result;\n    }\n\n    /**\n     * @dev Variant of {tryModExp} that supports inputs of arbitrary length.\n     */\n    function tryModExp(\n        bytes memory b,\n        bytes memory e,\n        bytes memory m\n    ) internal view returns (bool success, bytes memory result) {\n        if (_zeroBytes(m)) return (false, new bytes(0));\n\n        uint256 mLen = m.length;\n\n        // Encode call args in result and move the free memory pointer\n        result = abi.encodePacked(b.length, e.length, mLen, b, e, m);\n\n        assembly (\"memory-safe\") {\n            let dataPtr := add(result, 0x20)\n            // Write result on top of args to avoid allocating extra memory.\n            success := staticcall(gas(), 0x05, dataPtr, mload(result), dataPtr, mLen)\n            // Overwrite the length.\n            // result.length > returndatasize() is guaranteed because returndatasize() == m.length\n            mstore(result, mLen)\n            // Set the memory pointer after the returned data.\n            mstore(0x40, add(dataPtr, mLen))\n        }\n    }\n\n    /**\n     * @dev Returns whether the provided byte array is zero.\n     */\n    function _zeroBytes(bytes memory buffer) private pure returns (bool) {\n        uint256 chunk;\n        for (uint256 i = 0; i < buffer.length; i += 0x20) {\n            // See _unsafeReadBytesOffset from utils/Bytes.sol\n            assembly (\"memory-safe\") {\n                chunk := mload(add(add(buffer, 0x20), i))\n            }\n            if (chunk >> (8 * saturatingSub(i + 0x20, buffer.length)) != 0) {\n                return false;\n            }\n        }\n        return true;\n    }\n\n    /**\n     * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded\n     * towards zero.\n     *\n     * This method is based on Newton's method for computing square roots; the algorithm is restricted to only\n     * using integer operations.\n     */\n    function sqrt(uint256 a) internal pure returns (uint256) {\n        unchecked {\n            // Take care of easy edge cases when a == 0 or a == 1\n            if (a <= 1) {\n                return a;\n            }\n\n            // In this function, we use Newton's method to get a root of `f(x) := x² - a`. It involves building a\n            // sequence x_n that converges toward sqrt(a). For each iteration x_n, we also define the error between\n            // the current value as `ε_n = | x_n - sqrt(a) |`.\n            //\n            // For our first estimation, we consider `e` the smallest power of 2 which is bigger than the square root\n            // of the target. (i.e. `2**(e-1) ≤ sqrt(a) < 2**e`). We know that `e ≤ 128` because `(2¹²⁸)² = 2²⁵⁶` is\n            // bigger than any uint256.\n            //\n            // By noticing that\n            // `2**(e-1) ≤ sqrt(a) < 2**e → (2**(e-1))² ≤ a < (2**e)² → 2**(2*e-2) ≤ a < 2**(2*e)`\n            // we can deduce that `e - 1` is `log2(a) / 2`. We can thus compute `x_n = 2**(e-1)` using a method similar\n            // to the msb function.\n            uint256 aa = a;\n            uint256 xn = 1;\n\n            if (aa >= (1 << 128)) {\n                aa >>= 128;\n                xn <<= 64;\n            }\n            if (aa >= (1 << 64)) {\n                aa >>= 64;\n                xn <<= 32;\n            }\n            if (aa >= (1 << 32)) {\n                aa >>= 32;\n                xn <<= 16;\n            }\n            if (aa >= (1 << 16)) {\n                aa >>= 16;\n                xn <<= 8;\n            }\n            if (aa >= (1 << 8)) {\n                aa >>= 8;\n                xn <<= 4;\n            }\n            if (aa >= (1 << 4)) {\n                aa >>= 4;\n                xn <<= 2;\n            }\n            if (aa >= (1 << 2)) {\n                xn <<= 1;\n            }\n\n            // We now have x_n such that `x_n = 2**(e-1) ≤ sqrt(a) < 2**e = 2 * x_n`. This implies ε_n ≤ 2**(e-1).\n            //\n            // We can refine our estimation by noticing that the middle of that interval minimizes the error.\n            // If we move x_n to equal 2**(e-1) + 2**(e-2), then we reduce the error to ε_n ≤ 2**(e-2).\n            // This is going to be our x_0 (and ε_0)\n            xn = (3 * xn) >> 1; // ε_0 := | x_0 - sqrt(a) | ≤ 2**(e-2)\n\n            // From here, Newton's method give us:\n            // x_{n+1} = (x_n + a / x_n) / 2\n            //\n            // One should note that:\n            // x_{n+1}² - a = ((x_n + a / x_n) / 2)² - a\n            //              = ((x_n² + a) / (2 * x_n))² - a\n            //              = (x_n⁴ + 2 * a * x_n² + a²) / (4 * x_n²) - a\n            //              = (x_n⁴ + 2 * a * x_n² + a² - 4 * a * x_n²) / (4 * x_n²)\n            //              = (x_n⁴ - 2 * a * x_n² + a²) / (4 * x_n²)\n            //              = (x_n² - a)² / (2 * x_n)²\n            //              = ((x_n² - a) / (2 * x_n))²\n            //              ≥ 0\n            // Which proves that for all n ≥ 1, sqrt(a) ≤ x_n\n            //\n            // This gives us the proof of quadratic convergence of the sequence:\n            // ε_{n+1} = | x_{n+1} - sqrt(a) |\n            //         = | (x_n + a / x_n) / 2 - sqrt(a) |\n            //         = | (x_n² + a - 2*x_n*sqrt(a)) / (2 * x_n) |\n            //         = | (x_n - sqrt(a))² / (2 * x_n) |\n            //         = | ε_n² / (2 * x_n) |\n            //         = ε_n² / | (2 * x_n) |\n            //\n            // For the first iteration, we have a special case where x_0 is known:\n            // ε_1 = ε_0² / | (2 * x_0) |\n            //     ≤ (2**(e-2))² / (2 * (2**(e-1) + 2**(e-2)))\n            //     ≤ 2**(2*e-4) / (3 * 2**(e-1))\n            //     ≤ 2**(e-3) / 3\n            //     ≤ 2**(e-3-log2(3))\n            //     ≤ 2**(e-4.5)\n            //\n            // For the following iterations, we use the fact that, 2**(e-1) ≤ sqrt(a) ≤ x_n:\n            // ε_{n+1} = ε_n² / | (2 * x_n) |\n            //         ≤ (2**(e-k))² / (2 * 2**(e-1))\n            //         ≤ 2**(2*e-2*k) / 2**e\n            //         ≤ 2**(e-2*k)\n            xn = (xn + a / xn) >> 1; // ε_1 := | x_1 - sqrt(a) | ≤ 2**(e-4.5)  -- special case, see above\n            xn = (xn + a / xn) >> 1; // ε_2 := | x_2 - sqrt(a) | ≤ 2**(e-9)    -- general case with k = 4.5\n            xn = (xn + a / xn) >> 1; // ε_3 := | x_3 - sqrt(a) | ≤ 2**(e-18)   -- general case with k = 9\n            xn = (xn + a / xn) >> 1; // ε_4 := | x_4 - sqrt(a) | ≤ 2**(e-36)   -- general case with k = 18\n            xn = (xn + a / xn) >> 1; // ε_5 := | x_5 - sqrt(a) | ≤ 2**(e-72)   -- general case with k = 36\n            xn = (xn + a / xn) >> 1; // ε_6 := | x_6 - sqrt(a) | ≤ 2**(e-144)  -- general case with k = 72\n\n            // Because e ≤ 128 (as discussed during the first estimation phase), we know have reached a precision\n            // ε_6 ≤ 2**(e-144) < 1. Given we're operating on integers, then we can ensure that xn is now either\n            // sqrt(a) or sqrt(a) + 1.\n            return xn - SafeCast.toUint(xn > a / xn);\n        }\n    }\n\n    /**\n     * @dev Calculates sqrt(a), following the selected rounding direction.\n     */\n    function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\n        unchecked {\n            uint256 result = sqrt(a);\n            return result + SafeCast.toUint(unsignedRoundsUp(rounding) && result * result < a);\n        }\n    }\n\n    /**\n     * @dev Return the log in base 2 of a positive value rounded towards zero.\n     * Returns 0 if given 0.\n     */\n    function log2(uint256 x) internal pure returns (uint256 r) {\n        // If value has upper 128 bits set, log2 result is at least 128\n        r = SafeCast.toUint(x > 0xffffffffffffffffffffffffffffffff) << 7;\n        // If upper 64 bits of 128-bit half set, add 64 to result\n        r |= SafeCast.toUint((x >> r) > 0xffffffffffffffff) << 6;\n        // If upper 32 bits of 64-bit half set, add 32 to result\n        r |= SafeCast.toUint((x >> r) > 0xffffffff) << 5;\n        // If upper 16 bits of 32-bit half set, add 16 to result\n        r |= SafeCast.toUint((x >> r) > 0xffff) << 4;\n        // If upper 8 bits of 16-bit half set, add 8 to result\n        r |= SafeCast.toUint((x >> r) > 0xff) << 3;\n        // If upper 4 bits of 8-bit half set, add 4 to result\n        r |= SafeCast.toUint((x >> r) > 0xf) << 2;\n\n        // Shifts value right by the current result and use it as an index into this lookup table:\n        //\n        // | x (4 bits) |  index  | table[index] = MSB position |\n        // |------------|---------|-----------------------------|\n        // |    0000    |    0    |        table[0] = 0         |\n        // |    0001    |    1    |        table[1] = 0         |\n        // |    0010    |    2    |        table[2] = 1         |\n        // |    0011    |    3    |        table[3] = 1         |\n        // |    0100    |    4    |        table[4] = 2         |\n        // |    0101    |    5    |        table[5] = 2         |\n        // |    0110    |    6    |        table[6] = 2         |\n        // |    0111    |    7    |        table[7] = 2         |\n        // |    1000    |    8    |        table[8] = 3         |\n        // |    1001    |    9    |        table[9] = 3         |\n        // |    1010    |   10    |        table[10] = 3        |\n        // |    1011    |   11    |        table[11] = 3        |\n        // |    1100    |   12    |        table[12] = 3        |\n        // |    1101    |   13    |        table[13] = 3        |\n        // |    1110    |   14    |        table[14] = 3        |\n        // |    1111    |   15    |        table[15] = 3        |\n        //\n        // The lookup table is represented as a 32-byte value with the MSB positions for 0-15 in the first 16 bytes (most significant half).\n        assembly (\"memory-safe\") {\n            r := or(r, byte(shr(r, x), 0x0000010102020202030303030303030300000000000000000000000000000000))\n        }\n    }\n\n    /**\n     * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\n     * Returns 0 if given 0.\n     */\n    function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\n        unchecked {\n            uint256 result = log2(value);\n            return result + SafeCast.toUint(unsignedRoundsUp(rounding) && 1 << result < value);\n        }\n    }\n\n    /**\n     * @dev Return the log in base 10 of a positive value rounded towards zero.\n     * Returns 0 if given 0.\n     */\n    function log10(uint256 value) internal pure returns (uint256) {\n        uint256 result = 0;\n        unchecked {\n            if (value >= 10 ** 64) {\n                value /= 10 ** 64;\n                result += 64;\n            }\n            if (value >= 10 ** 32) {\n                value /= 10 ** 32;\n                result += 32;\n            }\n            if (value >= 10 ** 16) {\n                value /= 10 ** 16;\n                result += 16;\n            }\n            if (value >= 10 ** 8) {\n                value /= 10 ** 8;\n                result += 8;\n            }\n            if (value >= 10 ** 4) {\n                value /= 10 ** 4;\n                result += 4;\n            }\n            if (value >= 10 ** 2) {\n                value /= 10 ** 2;\n                result += 2;\n            }\n            if (value >= 10 ** 1) {\n                result += 1;\n            }\n        }\n        return result;\n    }\n\n    /**\n     * @dev Return the log in base 10, following the selected rounding direction, of a positive value.\n     * Returns 0 if given 0.\n     */\n    function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {\n        unchecked {\n            uint256 result = log10(value);\n            return result + SafeCast.toUint(unsignedRoundsUp(rounding) && 10 ** result < value);\n        }\n    }\n\n    /**\n     * @dev Return the log in base 256 of a positive value rounded towards zero.\n     * Returns 0 if given 0.\n     *\n     * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\n     */\n    function log256(uint256 x) internal pure returns (uint256 r) {\n        // If value has upper 128 bits set, log2 result is at least 128\n        r = SafeCast.toUint(x > 0xffffffffffffffffffffffffffffffff) << 7;\n        // If upper 64 bits of 128-bit half set, add 64 to result\n        r |= SafeCast.toUint((x >> r) > 0xffffffffffffffff) << 6;\n        // If upper 32 bits of 64-bit half set, add 32 to result\n        r |= SafeCast.toUint((x >> r) > 0xffffffff) << 5;\n        // If upper 16 bits of 32-bit half set, add 16 to result\n        r |= SafeCast.toUint((x >> r) > 0xffff) << 4;\n        // Add 1 if upper 8 bits of 16-bit half set, and divide accumulated result by 8\n        return (r >> 3) | SafeCast.toUint((x >> r) > 0xff);\n    }\n\n    /**\n     * @dev Return the log in base 256, following the selected rounding direction, of a positive value.\n     * Returns 0 if given 0.\n     */\n    function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\n        unchecked {\n            uint256 result = log256(value);\n            return result + SafeCast.toUint(unsignedRoundsUp(rounding) && 1 << (result << 3) < value);\n        }\n    }\n\n    /**\n     * @dev Returns whether a provided rounding mode is considered rounding up for unsigned integers.\n     */\n    function unsignedRoundsUp(Rounding rounding) internal pure returns (bool) {\n        return uint8(rounding) % 2 == 1;\n    }\n\n    /**\n     * @dev Counts the number of leading zero bits in a uint256.\n     */\n    function clz(uint256 x) internal pure returns (uint256) {\n        return ternary(x == 0, 256, 255 - log2(x));\n    }\n}\n"},{"file_path":"lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/utils/structs/EnumerableSet.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.6.0) (utils/structs/EnumerableSet.sol)\n// This file was procedurally generated from scripts/generate/templates/EnumerableSet.js.\n\npragma solidity ^0.8.24;\n\nimport {Arrays} from \"../Arrays.sol\";\nimport {Math} from \"../math/Math.sol\";\n\n/**\n * @dev Library for managing\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\n * types.\n *\n * Sets have the following properties:\n *\n * - Elements are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\n * - Set can be cleared (all elements removed) in O(n).\n *\n * ```solidity\n * contract Example {\n *     // Add the library methods\n *     using EnumerableSet for EnumerableSet.AddressSet;\n *\n *     // Declare a set state variable\n *     EnumerableSet.AddressSet private mySet;\n * }\n * ```\n *\n * The following types are supported:\n *\n * - `bytes32` (`Bytes32Set`) since v3.3.0\n * - `address` (`AddressSet`) since v3.3.0\n * - `uint256` (`UintSet`) since v3.3.0\n * - `string` (`StringSet`) since v5.4.0\n * - `bytes` (`BytesSet`) since v5.4.0\n * - `bytes4` (`Bytes4Set`) since v5.6.0\n *\n * [WARNING]\n * ====\n * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure\n * unusable.\n * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.\n *\n * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an\n * array of EnumerableSet.\n * ====\n */\nlibrary EnumerableSet {\n    // To implement this library for multiple types with as little code\n    // repetition as possible, we write it in terms of a generic Set type with\n    // bytes32 values.\n    // The Set implementation uses private functions, and user-facing\n    // implementations (such as AddressSet) are just wrappers around the\n    // underlying Set.\n    // This means that we can only create new EnumerableSets for types that fit\n    // in bytes32.\n\n    struct Set {\n        // Storage of set values\n        bytes32[] _values;\n        // Position is the index of the value in the `values` array plus 1.\n        // Position 0 is used to mean a value is not in the set.\n        mapping(bytes32 value => uint256) _positions;\n    }\n\n    /**\n     * @dev Add a value to a set. O(1).\n     *\n     * Returns true if the value was added to the set, that is if it was not\n     * already present.\n     */\n    function _add(Set storage set, bytes32 value) private returns (bool) {\n        if (!_contains(set, value)) {\n            set._values.push(value);\n            // The value is stored at length-1, but we add 1 to all indexes\n            // and use 0 as a sentinel value\n            set._positions[value] = set._values.length;\n            return true;\n        } else {\n            return false;\n        }\n    }\n\n    /**\n     * @dev Removes a value from a set. O(1).\n     *\n     * Returns true if the value was removed from the set, that is if it was\n     * present.\n     */\n    function _remove(Set storage set, bytes32 value) private returns (bool) {\n        // We cache the value's position to prevent multiple reads from the same storage slot\n        uint256 position = set._positions[value];\n\n        if (position != 0) {\n            // Equivalent to contains(set, value)\n            // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n            // the array, and then remove the last element (sometimes called as 'swap and pop').\n            // This modifies the order of the array, as noted in {at}.\n\n            uint256 valueIndex = position - 1;\n            uint256 lastIndex = set._values.length - 1;\n\n            if (valueIndex != lastIndex) {\n                bytes32 lastValue = set._values[lastIndex];\n\n                // Move the lastValue to the index where the value to delete is\n                set._values[valueIndex] = lastValue;\n                // Update the tracked position of the lastValue (that was just moved)\n                set._positions[lastValue] = position;\n            }\n\n            // Delete the slot where the moved value was stored\n            set._values.pop();\n\n            // Delete the tracked position for the deleted slot\n            delete set._positions[value];\n\n            return true;\n        } else {\n            return false;\n        }\n    }\n\n    /**\n     * @dev Removes all the values from a set. O(n).\n     *\n     * WARNING: This function has an unbounded cost that scales with set size. Developers should keep in mind that\n     * using it may render the function uncallable if the set grows to the point where clearing it consumes too much\n     * gas to fit in a block.\n     */\n    function _clear(Set storage set) private {\n        uint256 len = _length(set);\n        for (uint256 i = 0; i < len; ++i) {\n            delete set._positions[set._values[i]];\n        }\n        Arrays.unsafeSetLength(set._values, 0);\n    }\n\n    /**\n     * @dev Returns true if the value is in the set. O(1).\n     */\n    function _contains(Set storage set, bytes32 value) private view returns (bool) {\n        return set._positions[value] != 0;\n    }\n\n    /**\n     * @dev Returns the number of values on the set. O(1).\n     */\n    function _length(Set storage set) private view returns (uint256) {\n        return set._values.length;\n    }\n\n    /**\n     * @dev Returns the value stored at position `index` in the set. O(1).\n     *\n     * Note that there are no guarantees on the ordering of values inside the\n     * array, and it may change when more values are added or removed.\n     *\n     * Requirements:\n     *\n     * - `index` must be strictly less than {length}.\n     */\n    function _at(Set storage set, uint256 index) private view returns (bytes32) {\n        return set._values[index];\n    }\n\n    /**\n     * @dev Return the entire set in an array\n     *\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n     */\n    function _values(Set storage set) private view returns (bytes32[] memory) {\n        return set._values;\n    }\n\n    /**\n     * @dev Return a slice of the set in an array\n     *\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n     */\n    function _values(Set storage set, uint256 start, uint256 end) private view returns (bytes32[] memory) {\n        unchecked {\n            end = Math.min(end, _length(set));\n            start = Math.min(start, end);\n\n            uint256 len = end - start;\n            bytes32[] memory result = new bytes32[](len);\n            for (uint256 i = 0; i < len; ++i) {\n                result[i] = Arrays.unsafeAccess(set._values, start + i).value;\n            }\n            return result;\n        }\n    }\n\n    // Bytes32Set\n\n    struct Bytes32Set {\n        Set _inner;\n    }\n\n    /**\n     * @dev Add a value to a set. O(1).\n     *\n     * Returns true if the value was added to the set, that is if it was not\n     * already present.\n     */\n    function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n        return _add(set._inner, value);\n    }\n\n    /**\n     * @dev Removes a value from a set. O(1).\n     *\n     * Returns true if the value was removed from the set, that is if it was\n     * present.\n     */\n    function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n        return _remove(set._inner, value);\n    }\n\n    /**\n     * @dev Removes all the values from a set. O(n).\n     *\n     * WARNING: Developers should keep in mind that this function has an unbounded cost and using it may render the\n     * function uncallable if the set grows to the point where clearing it consumes too much gas to fit in a block.\n     */\n    function clear(Bytes32Set storage set) internal {\n        _clear(set._inner);\n    }\n\n    /**\n     * @dev Returns true if the value is in the set. O(1).\n     */\n    function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n        return _contains(set._inner, value);\n    }\n\n    /**\n     * @dev Returns the number of values in the set. O(1).\n     */\n    function length(Bytes32Set storage set) internal view returns (uint256) {\n        return _length(set._inner);\n    }\n\n    /**\n     * @dev Returns the value stored at position `index` in the set. O(1).\n     *\n     * Note that there are no guarantees on the ordering of values inside the\n     * array, and it may change when more values are added or removed.\n     *\n     * Requirements:\n     *\n     * - `index` must be strictly less than {length}.\n     */\n    function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n        return _at(set._inner, index);\n    }\n\n    /**\n     * @dev Return the entire set in an array\n     *\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n     */\n    function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n        bytes32[] memory store = _values(set._inner);\n        bytes32[] memory result;\n\n        assembly (\"memory-safe\") {\n            result := store\n        }\n\n        return result;\n    }\n\n    /**\n     * @dev Return a slice of the set in an array\n     *\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n     */\n    function values(Bytes32Set storage set, uint256 start, uint256 end) internal view returns (bytes32[] memory) {\n        bytes32[] memory store = _values(set._inner, start, end);\n        bytes32[] memory result;\n\n        assembly (\"memory-safe\") {\n            result := store\n        }\n\n        return result;\n    }\n\n    // Bytes4Set\n\n    struct Bytes4Set {\n        Set _inner;\n    }\n\n    /**\n     * @dev Add a value to a set. O(1).\n     *\n     * Returns true if the value was added to the set, that is if it was not\n     * already present.\n     */\n    function add(Bytes4Set storage set, bytes4 value) internal returns (bool) {\n        return _add(set._inner, bytes32(value));\n    }\n\n    /**\n     * @dev Removes a value from a set. O(1).\n     *\n     * Returns true if the value was removed from the set, that is if it was\n     * present.\n     */\n    function remove(Bytes4Set storage set, bytes4 value) internal returns (bool) {\n        return _remove(set._inner, bytes32(value));\n    }\n\n    /**\n     * @dev Removes all the values from a set. O(n).\n     *\n     * WARNING: Developers should keep in mind that this function has an unbounded cost and using it may render the\n     * function uncallable if the set grows to the point where clearing it consumes too much gas to fit in a block.\n     */\n    function clear(Bytes4Set storage set) internal {\n        _clear(set._inner);\n    }\n\n    /**\n     * @dev Returns true if the value is in the set. O(1).\n     */\n    function contains(Bytes4Set storage set, bytes4 value) internal view returns (bool) {\n        return _contains(set._inner, bytes32(value));\n    }\n\n    /**\n     * @dev Returns the number of values in the set. O(1).\n     */\n    function length(Bytes4Set storage set) internal view returns (uint256) {\n        return _length(set._inner);\n    }\n\n    /**\n     * @dev Returns the value stored at position `index` in the set. O(1).\n     *\n     * Note that there are no guarantees on the ordering of values inside the\n     * array, and it may change when more values are added or removed.\n     *\n     * Requirements:\n     *\n     * - `index` must be strictly less than {length}.\n     */\n    function at(Bytes4Set storage set, uint256 index) internal view returns (bytes4) {\n        return bytes4(_at(set._inner, index));\n    }\n\n    /**\n     * @dev Return the entire set in an array\n     *\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n     */\n    function values(Bytes4Set storage set) internal view returns (bytes4[] memory) {\n        bytes32[] memory store = _values(set._inner);\n        bytes4[] memory result;\n\n        assembly (\"memory-safe\") {\n            result := store\n        }\n\n        return result;\n    }\n\n    /**\n     * @dev Return a slice of the set in an array\n     *\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n     */\n    function values(Bytes4Set storage set, uint256 start, uint256 end) internal view returns (bytes4[] memory) {\n        bytes32[] memory store = _values(set._inner, start, end);\n        bytes4[] memory result;\n\n        assembly (\"memory-safe\") {\n            result := store\n        }\n\n        return result;\n    }\n\n    // AddressSet\n\n    struct AddressSet {\n        Set _inner;\n    }\n\n    /**\n     * @dev Add a value to a set. O(1).\n     *\n     * Returns true if the value was added to the set, that is if it was not\n     * already present.\n     */\n    function add(AddressSet storage set, address value) internal returns (bool) {\n        return _add(set._inner, bytes32(uint256(uint160(value))));\n    }\n\n    /**\n     * @dev Removes a value from a set. O(1).\n     *\n     * Returns true if the value was removed from the set, that is if it was\n     * present.\n     */\n    function remove(AddressSet storage set, address value) internal returns (bool) {\n        return _remove(set._inner, bytes32(uint256(uint160(value))));\n    }\n\n    /**\n     * @dev Removes all the values from a set. O(n).\n     *\n     * WARNING: Developers should keep in mind that this function has an unbounded cost and using it may render the\n     * function uncallable if the set grows to the point where clearing it consumes too much gas to fit in a block.\n     */\n    function clear(AddressSet storage set) internal {\n        _clear(set._inner);\n    }\n\n    /**\n     * @dev Returns true if the value is in the set. O(1).\n     */\n    function contains(AddressSet storage set, address value) internal view returns (bool) {\n        return _contains(set._inner, bytes32(uint256(uint160(value))));\n    }\n\n    /**\n     * @dev Returns the number of values in the set. O(1).\n     */\n    function length(AddressSet storage set) internal view returns (uint256) {\n        return _length(set._inner);\n    }\n\n    /**\n     * @dev Returns the value stored at position `index` in the set. O(1).\n     *\n     * Note that there are no guarantees on the ordering of values inside the\n     * array, and it may change when more values are added or removed.\n     *\n     * Requirements:\n     *\n     * - `index` must be strictly less than {length}.\n     */\n    function at(AddressSet storage set, uint256 index) internal view returns (address) {\n        return address(uint160(uint256(_at(set._inner, index))));\n    }\n\n    /**\n     * @dev Return the entire set in an array\n     *\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n     */\n    function values(AddressSet storage set) internal view returns (address[] memory) {\n        bytes32[] memory store = _values(set._inner);\n        address[] memory result;\n\n        assembly (\"memory-safe\") {\n            result := store\n        }\n\n        return result;\n    }\n\n    /**\n     * @dev Return a slice of the set in an array\n     *\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n     */\n    function values(AddressSet storage set, uint256 start, uint256 end) internal view returns (address[] memory) {\n        bytes32[] memory store = _values(set._inner, start, end);\n        address[] memory result;\n\n        assembly (\"memory-safe\") {\n            result := store\n        }\n\n        return result;\n    }\n\n    // UintSet\n\n    struct UintSet {\n        Set _inner;\n    }\n\n    /**\n     * @dev Add a value to a set. O(1).\n     *\n     * Returns true if the value was added to the set, that is if it was not\n     * already present.\n     */\n    function add(UintSet storage set, uint256 value) internal returns (bool) {\n        return _add(set._inner, bytes32(value));\n    }\n\n    /**\n     * @dev Removes a value from a set. O(1).\n     *\n     * Returns true if the value was removed from the set, that is if it was\n     * present.\n     */\n    function remove(UintSet storage set, uint256 value) internal returns (bool) {\n        return _remove(set._inner, bytes32(value));\n    }\n\n    /**\n     * @dev Removes all the values from a set. O(n).\n     *\n     * WARNING: Developers should keep in mind that this function has an unbounded cost and using it may render the\n     * function uncallable if the set grows to the point where clearing it consumes too much gas to fit in a block.\n     */\n    function clear(UintSet storage set) internal {\n        _clear(set._inner);\n    }\n\n    /**\n     * @dev Returns true if the value is in the set. O(1).\n     */\n    function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n        return _contains(set._inner, bytes32(value));\n    }\n\n    /**\n     * @dev Returns the number of values in the set. O(1).\n     */\n    function length(UintSet storage set) internal view returns (uint256) {\n        return _length(set._inner);\n    }\n\n    /**\n     * @dev Returns the value stored at position `index` in the set. O(1).\n     *\n     * Note that there are no guarantees on the ordering of values inside the\n     * array, and it may change when more values are added or removed.\n     *\n     * Requirements:\n     *\n     * - `index` must be strictly less than {length}.\n     */\n    function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n        return uint256(_at(set._inner, index));\n    }\n\n    /**\n     * @dev Return the entire set in an array\n     *\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n     */\n    function values(UintSet storage set) internal view returns (uint256[] memory) {\n        bytes32[] memory store = _values(set._inner);\n        uint256[] memory result;\n\n        assembly (\"memory-safe\") {\n            result := store\n        }\n\n        return result;\n    }\n\n    /**\n     * @dev Return a slice of the set in an array\n     *\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n     */\n    function values(UintSet storage set, uint256 start, uint256 end) internal view returns (uint256[] memory) {\n        bytes32[] memory store = _values(set._inner, start, end);\n        uint256[] memory result;\n\n        assembly (\"memory-safe\") {\n            result := store\n        }\n\n        return result;\n    }\n\n    struct StringSet {\n        // Storage of set values\n        string[] _values;\n        // Position is the index of the value in the `values` array plus 1.\n        // Position 0 is used to mean a value is not in the set.\n        mapping(string value => uint256) _positions;\n    }\n\n    /**\n     * @dev Add a value to a set. O(1).\n     *\n     * Returns true if the value was added to the set, that is if it was not\n     * already present.\n     */\n    function add(StringSet storage set, string memory value) internal returns (bool) {\n        if (!contains(set, value)) {\n            set._values.push(value);\n            // The value is stored at length-1, but we add 1 to all indexes\n            // and use 0 as a sentinel value\n            set._positions[value] = set._values.length;\n            return true;\n        } else {\n            return false;\n        }\n    }\n\n    /**\n     * @dev Removes a value from a set. O(1).\n     *\n     * Returns true if the value was removed from the set, that is if it was\n     * present.\n     */\n    function remove(StringSet storage set, string memory value) internal returns (bool) {\n        // We cache the value's position to prevent multiple reads from the same storage slot\n        uint256 position = set._positions[value];\n\n        if (position != 0) {\n            // Equivalent to contains(set, value)\n            // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n            // the array, and then remove the last element (sometimes called as 'swap and pop').\n            // This modifies the order of the array, as noted in {at}.\n\n            uint256 valueIndex = position - 1;\n            uint256 lastIndex = set._values.length - 1;\n\n            if (valueIndex != lastIndex) {\n                string memory lastValue = set._values[lastIndex];\n\n                // Move the lastValue to the index where the value to delete is\n                set._values[valueIndex] = lastValue;\n                // Update the tracked position of the lastValue (that was just moved)\n                set._positions[lastValue] = position;\n            }\n\n            // Delete the slot where the moved value was stored\n            set._values.pop();\n\n            // Delete the tracked position for the deleted slot\n            delete set._positions[value];\n\n            return true;\n        } else {\n            return false;\n        }\n    }\n\n    /**\n     * @dev Removes all the values from a set. O(n).\n     *\n     * WARNING: Developers should keep in mind that this function has an unbounded cost and using it may render the\n     * function uncallable if the set grows to the point where clearing it consumes too much gas to fit in a block.\n     */\n    function clear(StringSet storage set) internal {\n        uint256 len = length(set);\n        for (uint256 i = 0; i < len; ++i) {\n            delete set._positions[set._values[i]];\n        }\n        Arrays.unsafeSetLength(set._values, 0);\n    }\n\n    /**\n     * @dev Returns true if the value is in the set. O(1).\n     */\n    function contains(StringSet storage set, string memory value) internal view returns (bool) {\n        return set._positions[value] != 0;\n    }\n\n    /**\n     * @dev Returns the number of values on the set. O(1).\n     */\n    function length(StringSet storage set) internal view returns (uint256) {\n        return set._values.length;\n    }\n\n    /**\n     * @dev Returns the value stored at position `index` in the set. O(1).\n     *\n     * Note that there are no guarantees on the ordering of values inside the\n     * array, and it may change when more values are added or removed.\n     *\n     * Requirements:\n     *\n     * - `index` must be strictly less than {length}.\n     */\n    function at(StringSet storage set, uint256 index) internal view returns (string memory) {\n        return set._values[index];\n    }\n\n    /**\n     * @dev Return the entire set in an array\n     *\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n     */\n    function values(StringSet storage set) internal view returns (string[] memory) {\n        return set._values;\n    }\n\n    /**\n     * @dev Return a slice of the set in an array\n     *\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n     */\n    function values(StringSet storage set, uint256 start, uint256 end) internal view returns (string[] memory) {\n        unchecked {\n            end = Math.min(end, length(set));\n            start = Math.min(start, end);\n\n            uint256 len = end - start;\n            string[] memory result = new string[](len);\n            for (uint256 i = 0; i < len; ++i) {\n                result[i] = Arrays.unsafeAccess(set._values, start + i).value;\n            }\n            return result;\n        }\n    }\n\n    struct BytesSet {\n        // Storage of set values\n        bytes[] _values;\n        // Position is the index of the value in the `values` array plus 1.\n        // Position 0 is used to mean a value is not in the set.\n        mapping(bytes value => uint256) _positions;\n    }\n\n    /**\n     * @dev Add a value to a set. O(1).\n     *\n     * Returns true if the value was added to the set, that is if it was not\n     * already present.\n     */\n    function add(BytesSet storage set, bytes memory value) internal returns (bool) {\n        if (!contains(set, value)) {\n            set._values.push(value);\n            // The value is stored at length-1, but we add 1 to all indexes\n            // and use 0 as a sentinel value\n            set._positions[value] = set._values.length;\n            return true;\n        } else {\n            return false;\n        }\n    }\n\n    /**\n     * @dev Removes a value from a set. O(1).\n     *\n     * Returns true if the value was removed from the set, that is if it was\n     * present.\n     */\n    function remove(BytesSet storage set, bytes memory value) internal returns (bool) {\n        // We cache the value's position to prevent multiple reads from the same storage slot\n        uint256 position = set._positions[value];\n\n        if (position != 0) {\n            // Equivalent to contains(set, value)\n            // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n            // the array, and then remove the last element (sometimes called as 'swap and pop').\n            // This modifies the order of the array, as noted in {at}.\n\n            uint256 valueIndex = position - 1;\n            uint256 lastIndex = set._values.length - 1;\n\n            if (valueIndex != lastIndex) {\n                bytes memory lastValue = set._values[lastIndex];\n\n                // Move the lastValue to the index where the value to delete is\n                set._values[valueIndex] = lastValue;\n                // Update the tracked position of the lastValue (that was just moved)\n                set._positions[lastValue] = position;\n            }\n\n            // Delete the slot where the moved value was stored\n            set._values.pop();\n\n            // Delete the tracked position for the deleted slot\n            delete set._positions[value];\n\n            return true;\n        } else {\n            return false;\n        }\n    }\n\n    /**\n     * @dev Removes all the values from a set. O(n).\n     *\n     * WARNING: Developers should keep in mind that this function has an unbounded cost and using it may render the\n     * function uncallable if the set grows to the point where clearing it consumes too much gas to fit in a block.\n     */\n    function clear(BytesSet storage set) internal {\n        uint256 len = length(set);\n        for (uint256 i = 0; i < len; ++i) {\n            delete set._positions[set._values[i]];\n        }\n        Arrays.unsafeSetLength(set._values, 0);\n    }\n\n    /**\n     * @dev Returns true if the value is in the set. O(1).\n     */\n    function contains(BytesSet storage set, bytes memory value) internal view returns (bool) {\n        return set._positions[value] != 0;\n    }\n\n    /**\n     * @dev Returns the number of values on the set. O(1).\n     */\n    function length(BytesSet storage set) internal view returns (uint256) {\n        return set._values.length;\n    }\n\n    /**\n     * @dev Returns the value stored at position `index` in the set. O(1).\n     *\n     * Note that there are no guarantees on the ordering of values inside the\n     * array, and it may change when more values are added or removed.\n     *\n     * Requirements:\n     *\n     * - `index` must be strictly less than {length}.\n     */\n    function at(BytesSet storage set, uint256 index) internal view returns (bytes memory) {\n        return set._values[index];\n    }\n\n    /**\n     * @dev Return the entire set in an array\n     *\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n     */\n    function values(BytesSet storage set) internal view returns (bytes[] memory) {\n        return set._values;\n    }\n\n    /**\n     * @dev Return a slice of the set in an array\n     *\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n     */\n    function values(BytesSet storage set, uint256 start, uint256 end) internal view returns (bytes[] memory) {\n        unchecked {\n            end = Math.min(end, length(set));\n            start = Math.min(start, end);\n\n            uint256 len = end - start;\n            bytes[] memory result = new bytes[](len);\n            for (uint256 i = 0; i < len; ++i) {\n                result[i] = Arrays.unsafeAccess(set._values, start + i).value;\n            }\n            return result;\n        }\n    }\n}\n"},{"file_path":"src/interfaces/ITokenRegistry.sol","source_code":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.28;\n\n/// @notice This interface is used to map token addresses from one EVM chain to another.\ninterface ITokenRegistry {\n    event TokenRegistered(address indexed localToken, uint256 indexed evmChainId, address indexed foreignToken);\n\n    /// @notice Local token address => Foreign EVM chain ID => Foreign Token address\n    function getForeignToken(address localToken, uint256 foreignEvmChainId) external view returns (address);\n\n    /// @notice Foreign token address => Foreign EVM chain ID => Local Token address\n    function getLocalToken(address foreignToken, uint256 foreignEvmChainId) external view returns (address);\n\n    /// @notice Associates a local and a foreign token address.\n    /// @param localToken The local token address.\n    /// @param foreignEvmChainId The foreign EVM chain ID.\n    /// @param foreignToken The foreign token address.\n    function setToken(address localToken, uint256 foreignEvmChainId, address foreignToken) external;\n}\n"},{"file_path":"src/interfaces/ICoreRegistry.sol","source_code":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.28;\n\ninterface ICoreRegistry {\n    event BridgeAdapterBeaconChanged(\n        uint256 indexed bridgeId, address indexed oldBridgeAdapterBeacon, address indexed newBridgeAdapterBeacon\n    );\n    event BridgeConfigChanged(\n        uint256 indexed bridgeId, address indexed oldBridgeConfig, address indexed newBridgeConfig\n    );\n    event CaliberBeaconChanged(address indexed oldCaliberBeacon, address indexed newCaliberBeacon);\n    event CoreFactoryChanged(address indexed oldCoreFactory, address indexed newCoreFactory);\n    event FlashLoanModuleChanged(address indexed oldFlashLoanModule, address indexed newFlashLoanModule);\n    event OracleRegistryChanged(address indexed oldOracleRegistry, address indexed newOracleRegistry);\n    event SwapModuleChanged(address indexed oldSwapModule, address indexed newSwapModule);\n    event TokenRegistryChanged(address indexed oldTokenRegistry, address indexed newTokenRegistry);\n\n    /// @notice Address of the core factory.\n    function coreFactory() external view returns (address);\n\n    /// @notice Address of the oracle registry.\n    function oracleRegistry() external view returns (address);\n\n    /// @notice Address of the token registry.\n    function tokenRegistry() external view returns (address);\n\n    /// @notice Address of the swap module.\n    function swapModule() external view returns (address);\n\n    /// @notice Address of the flash loan module.\n    function flashLoanModule() external view returns (address);\n\n    /// @notice Address of the caliber beacon contract.\n    function caliberBeacon() external view returns (address);\n\n    /// @notice Bridge ID => Address of the bridge adapter beacon contract.\n    function bridgeAdapterBeacon(uint16 bridgeId) external view returns (address);\n\n    /// @notice Bridge ID => Address of the bridge config contract.\n    function bridgeConfig(uint16 bridgeId) external view returns (address);\n\n    /// @notice Sets the core factory address.\n    /// @param _coreFactory The core factory address.\n    function setCoreFactory(address _coreFactory) external;\n\n    /// @notice Sets the oracle registry address.\n    /// @param _oracleRegistry The oracle registry address.\n    function setOracleRegistry(address _oracleRegistry) external;\n\n    /// @notice Sets the token registry address.\n    /// @param _tokenRegistry The token registry address.\n    function setTokenRegistry(address _tokenRegistry) external;\n\n    /// @notice Sets the swap module address.\n    /// @param _swapModule The swap module address.\n    function setSwapModule(address _swapModule) external;\n\n    /// @notice Sets the flash loan module address.\n    /// @param _flashLoanModule The flash loan module address.\n    function setFlashLoanModule(address _flashLoanModule) external;\n\n    /// @notice Sets the caliber beacon address.\n    /// @param _caliberBeacon The caliber beacon address.\n    function setCaliberBeacon(address _caliberBeacon) external;\n\n    /// @notice Sets the bridge adapter beacon address.\n    /// @param bridgeId The bridge ID.\n    /// @param _bridgeAdapterBeacon The bridge adapter beacon address.\n    function setBridgeAdapterBeacon(uint16 bridgeId, address _bridgeAdapterBeacon) external;\n\n    /// @notice Sets the bridge config address.\n    /// @param bridgeId The bridge ID.\n    /// @param _bridgeConfig The bridge config address.\n    function setBridgeConfig(uint16 bridgeId, address _bridgeConfig) external;\n}\n"},{"file_path":"lib/openzeppelin-contracts-upgradeable/contracts/utils/ContextUpgradeable.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)\n\npragma solidity ^0.8.20;\nimport {Initializable} from \"@openzeppelin/contracts/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"},{"file_path":"src/libraries/MachineUtils.sol","source_code":"// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.28;\n\nimport {EnumerableMap} from \"@openzeppelin/contracts/utils/structs/EnumerableMap.sol\";\nimport {EnumerableSet} from \"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\";\nimport {IERC20Metadata} from \"@openzeppelin/contracts/interfaces/IERC20Metadata.sol\";\nimport {Math} from \"@openzeppelin/contracts/utils/math/Math.sol\";\n\nimport {ICaliber} from \"../interfaces/ICaliber.sol\";\nimport {ICaliberMailbox} from \"../interfaces/ICaliberMailbox.sol\";\nimport {IFeeManager} from \"../interfaces/IFeeManager.sol\";\nimport {IMachine} from \"../interfaces/IMachine.sol\";\nimport {IMachineShare} from \"../interfaces/IMachineShare.sol\";\nimport {IOracleRegistry} from \"../interfaces/IOracleRegistry.sol\";\nimport {IPreDepositVault} from \"../interfaces/IPreDepositVault.sol\";\nimport {ITokenRegistry} from \"../interfaces/ITokenRegistry.sol\";\nimport {Errors} from \"./Errors.sol\";\nimport {DecimalsUtils} from \"./DecimalsUtils.sol\";\nimport {Machine} from \"../machine/Machine.sol\";\n\nlibrary MachineUtils {\n    using Math for uint256;\n    using EnumerableMap for EnumerableMap.AddressToUintMap;\n    using EnumerableSet for EnumerableSet.AddressSet;\n\n    uint256 private constant RATE_SCALE = 1e18;\n\n    /// @dev Max seconds a snapshot timestamp may be ahead of the current hub block timestamp and still be accepted, to absorb cross-chain clock skew.\n    uint256 private constant MAX_SNAPSHOT_FUTURE_TOLERANCE = 60;\n\n    /// @dev Updates the total AUM of the machine and performs share price change check.\n    /// @param $ The machine storage struct.\n    /// @param oracleRegistry The address of the oracle registry.\n    /// @param sharePriceChangeCheck True to perform share price change check, false to bypass it.\n    /// @return The updated total AUM.\n    function updateTotalAum(Machine.MachineStorage storage $, address oracleRegistry, bool sharePriceChangeCheck)\n        external\n        returns (uint256)\n    {\n        uint256 _supply = IERC20Metadata($._shareToken).totalSupply();\n        uint256 _previousSharePrice = getSharePrice($._lastTotalAum, _supply, $._shareTokenDecimalsOffset);\n\n        $._lastTotalAum = _getTotalAum($, oracleRegistry);\n\n        uint256 _newSharePrice = getSharePrice($._lastTotalAum, _supply, $._shareTokenDecimalsOffset);\n\n        if (sharePriceChangeCheck) {\n            _checkMaxRelativeChange(\n                _previousSharePrice,\n                _newSharePrice,\n                $._maxSharePriceChangeRate,\n                block.timestamp - $._lastGlobalAccountingTime\n            );\n        }\n\n        $._lastGlobalAccountingTime = block.timestamp;\n\n        return $._lastTotalAum;\n    }\n\n    /// @dev Manages the fee minting process, including calculating and minting fixed and performance fees.\n    /// @param $ The machine storage struct.\n    /// @return The fees minted in share tokens.\n    function manageFees(Machine.MachineStorage storage $) external returns (uint256) {\n        uint256 currentTimestamp = block.timestamp;\n        uint256 elapsedTime = currentTimestamp - $._lastMintedFeesTime;\n\n        if (elapsedTime >= $._feeMintCooldown) {\n            address _feeManager = $._feeManager;\n            address _shareToken = $._shareToken;\n            uint256 currentShareSupply = IERC20Metadata(_shareToken).totalSupply();\n\n            uint256 fixedFee = Math.min(\n                IFeeManager(_feeManager).calculateFixedFee(currentShareSupply, elapsedTime),\n                (currentShareSupply * elapsedTime).mulDiv($._maxFixedFeeAccrualRate, RATE_SCALE)\n            );\n\n            // offset fixed fee from the share price performance on which the performance fee is calculated.\n            uint256 netSharePrice =\n                getSharePrice($._lastTotalAum, currentShareSupply + fixedFee, $._shareTokenDecimalsOffset);\n            uint256 perfFee = Math.min(\n                IFeeManager(_feeManager)\n                    .calculatePerformanceFee(\n                        currentShareSupply, $._lastMintedFeesSharePrice, netSharePrice, elapsedTime\n                    ),\n                (currentShareSupply * elapsedTime).mulDiv($._maxPerfFeeAccrualRate, RATE_SCALE)\n            );\n\n            uint256 totalFee = fixedFee + perfFee;\n            if (totalFee != 0) {\n                uint256 balBefore = IMachineShare(_shareToken).balanceOf(address(this));\n\n                IMachineShare(_shareToken).mint(address(this), totalFee);\n                IMachineShare(_shareToken).approve(_feeManager, totalFee);\n\n                IFeeManager(_feeManager).distributeFees(fixedFee, perfFee);\n\n                IMachineShare(_shareToken).approve(_feeManager, 0);\n\n                uint256 balAfter = IMachineShare(_shareToken).balanceOf(address(this));\n                if (balAfter > balBefore) {\n                    uint256 dust = balAfter - balBefore;\n                    IMachineShare(_shareToken).burn(address(this), dust);\n                    totalFee -= dust;\n                }\n            }\n\n            $._lastMintedFeesTime = currentTimestamp;\n            $._lastMintedFeesSharePrice =\n                getSharePrice($._lastTotalAum, IERC20Metadata(_shareToken).totalSupply(), $._shareTokenDecimalsOffset);\n\n            return totalFee;\n        }\n        return 0;\n    }\n\n    /// @dev Reports spoke caliber accounting snapshots by decoding the report payload and updating the machine storage accordingly.\n    /// @param $ The machine storage struct.\n    /// @param tokenRegistry The address of the token registry.\n    /// @param report The report payload containing the accounting data.\n    function reportSpokeAccountingSnapshots(\n        Machine.MachineStorage storage $,\n        address tokenRegistry,\n        bytes calldata report\n    ) external {\n        ICaliberMailbox.SpokeCaliberAccountingData[] memory snapshots =\n            abi.decode(report, (ICaliberMailbox.SpokeCaliberAccountingData[]));\n\n        uint256 len = snapshots.length;\n        for (uint256 i; i < len; ++i) {\n            _handlePerChainSnapshot($, tokenRegistry, snapshots[i]);\n        }\n    }\n\n    /// @dev Manages the migration from a pre-deposit vault to a machine, and initializes the machine's AUM.\n    /// @param $ The machine storage struct.\n    /// @param preDepositVault The address of the pre-deposit vault.\n    /// @param oracleRegistry The address of the oracle registry.\n    function migrateFromPreDeposit(Machine.MachineStorage storage $, address preDepositVault, address oracleRegistry)\n        external\n    {\n        IPreDepositVault(preDepositVault).migrateToMachine();\n\n        address preDepositToken = IPreDepositVault(preDepositVault).depositToken();\n        uint256 pdtBal = IERC20Metadata(preDepositToken).balanceOf(address(this));\n        if (pdtBal != 0) {\n            $._idleTokens.add(preDepositToken);\n            $._lastTotalAum = _accountingValueOf(oracleRegistry, $._accountingToken, preDepositToken, pdtBal);\n        }\n    }\n\n    /// @dev Checks that there are no pending bridge transfers between the machine and a spoke caliber.\n    /// @param spokeCaliberData The spoke caliber data struct containing the bridge transfer records.\n    function checkBridgeTransfersSettled(IMachine.SpokeCaliberData storage spokeCaliberData) external view {\n        // check for funds sent by machine but not yet received by spoke caliber\n        uint256 len = spokeCaliberData.machineBridgesOut.length();\n        for (uint256 i; i < len; ++i) {\n            (address token, uint256 mOut) = spokeCaliberData.machineBridgesOut.at(i);\n            (, uint256 cIn) = spokeCaliberData.caliberBridgesIn.tryGet(token);\n            if (mOut > cIn) {\n                revert Errors.PendingBridgeTransfer();\n            }\n        }\n\n        // check for funds sent by spoke caliber but not yet received by machine\n        len = spokeCaliberData.caliberBridgesOut.length();\n        for (uint256 i; i < len; ++i) {\n            (address token, uint256 cOut) = spokeCaliberData.caliberBridgesOut.at(i);\n            (, uint256 mIn) = spokeCaliberData.machineBridgesIn.tryGet(token);\n            if (cOut > mIn) {\n                revert Errors.PendingBridgeTransfer();\n            }\n        }\n    }\n\n    /// @dev Calculates the share price based on given AUM, share supply and share token decimals offset.\n    /// @param aum The AUM of the machine.\n    /// @param supply The supply of the share token.\n    /// @param shareTokenDecimalsOffset The decimals offset between share token and accounting token.\n    /// @return The calculated share price.\n    function getSharePrice(uint256 aum, uint256 supply, uint256 shareTokenDecimalsOffset)\n        public\n        pure\n        returns (uint256)\n    {\n        return DecimalsUtils.SHARE_TOKEN_UNIT.mulDiv(aum + 1, supply + 10 ** shareTokenDecimalsOffset);\n    }\n\n    /// @dev Handles an accounting snapshot received from a spoke chain and updates the corresponding accounting state stored in the machine.\n    /// @param $ The machine storage struct.\n    /// @param tokenRegistry The address of the token registry.\n    /// @param snapshot The accounting snapshot data.\n    function _handlePerChainSnapshot(\n        Machine.MachineStorage storage $,\n        address tokenRegistry,\n        ICaliberMailbox.SpokeCaliberAccountingData memory snapshot\n    ) private {\n        uint256 _spokeChainId = snapshot.context.chainId;\n\n        IMachine.SpokeCaliberData storage caliberData = $._spokeCalibersData[_spokeChainId];\n\n        if (caliberData.mailbox == address(0)) {\n            revert Errors.InvalidChainId();\n        }\n\n        if (snapshot.context.mailbox != caliberData.mailbox) {\n            revert Errors.InvalidSpokeCaliberMailbox();\n        }\n\n        // Validate that snapshot is not too far ahead of the hub block timestamp, not older than current chain last update, nor stale.\n        uint256 snapshotTimestamp = snapshot.context.blockTime;\n        if (snapshotTimestamp > block.timestamp + MAX_SNAPSHOT_FUTURE_TOLERANCE) {\n            revert Errors.FutureSnapshot();\n        }\n        if (\n            snapshotTimestamp <= caliberData.timestamp\n                || (block.timestamp > snapshotTimestamp\n                    && block.timestamp - snapshotTimestamp >= $._caliberStaleThreshold)\n        ) {\n            revert Errors.StaleSnapshot();\n        }\n\n        // Update the spoke caliber data in the machine storage.\n        caliberData.netAum = snapshot.netAum;\n        caliberData.timestamp = snapshotTimestamp;\n        _decodeAndMapBridgeAmounts(_spokeChainId, snapshot.bridgesIn, caliberData.caliberBridgesIn, tokenRegistry);\n        _decodeAndMapBridgeAmounts(_spokeChainId, snapshot.bridgesOut, caliberData.caliberBridgesOut, tokenRegistry);\n    }\n\n    /// @dev Decodes (foreignToken, amount) pairs, resolves local tokens, and stores amounts in the map.\n    function _decodeAndMapBridgeAmounts(\n        uint256 chainId,\n        bytes[] memory data,\n        EnumerableMap.AddressToUintMap storage map,\n        address tokenRegistry\n    ) private {\n        uint256 len = data.length;\n        for (uint256 i; i < len; ++i) {\n            (address foreignToken, uint256 amount) = abi.decode(data[i], (address, uint256));\n            address localToken = ITokenRegistry(tokenRegistry).getLocalToken(foreignToken, chainId);\n            map.set(localToken, amount);\n        }\n    }\n\n    /// @dev Computes the total AUM of the machine.\n    /// @param $ The machine storage struct.\n    /// @param oracleRegistry The address of the oracle registry.\n    function _getTotalAum(Machine.MachineStorage storage $, address oracleRegistry) private view returns (uint256) {\n        uint256 totalAum;\n\n        // spoke calibers net AUM\n        uint256 currentTimestamp = block.timestamp;\n        uint256 len = $._spokeChainIds.length;\n        for (uint256 i; i < len; ++i) {\n            uint256 chainId = $._spokeChainIds[i];\n            IMachine.SpokeCaliberData storage spokeCaliberData = $._spokeCalibersData[chainId];\n\n            if (spokeCaliberData.disabled) {\n                continue;\n            }\n\n            if (\n                currentTimestamp > spokeCaliberData.timestamp\n                    && currentTimestamp - spokeCaliberData.timestamp >= $._caliberStaleThreshold\n            ) {\n                revert Errors.CaliberAccountingStale(chainId);\n            }\n\n            totalAum += spokeCaliberData.netAum;\n\n            // check for funds received by machine but not declared by spoke caliber\n            _checkBridgeState(spokeCaliberData.machineBridgesIn, spokeCaliberData.caliberBridgesOut);\n\n            // check for funds received by spoke caliber but not declared by machine\n            _checkBridgeState(spokeCaliberData.caliberBridgesIn, spokeCaliberData.machineBridgesOut);\n\n            // check for funds sent by machine but not yet received by spoke caliber\n            uint256 len2 = spokeCaliberData.machineBridgesOut.length();\n            for (uint256 j; j < len2; ++j) {\n                (address token, uint256 mOut) = spokeCaliberData.machineBridgesOut.at(j);\n                (, uint256 cIn) = spokeCaliberData.caliberBridgesIn.tryGet(token);\n                if (mOut > cIn) {\n                    totalAum += _accountingValueOf(oracleRegistry, $._accountingToken, token, mOut - cIn);\n                }\n            }\n\n            // check for funds sent by spoke caliber but not yet received by machine\n            len2 = spokeCaliberData.caliberBridgesOut.length();\n            for (uint256 j; j < len2; ++j) {\n                (address token, uint256 cOut) = spokeCaliberData.caliberBridgesOut.at(j);\n                (, uint256 mIn) = spokeCaliberData.machineBridgesIn.tryGet(token);\n                if (cOut > mIn) {\n                    totalAum += _accountingValueOf(oracleRegistry, $._accountingToken, token, cOut - mIn);\n                }\n            }\n        }\n\n        // hub caliber net AUM\n        totalAum += ICaliber($._hubCaliber).getNetAum();\n\n        // idle tokens\n        len = $._idleTokens.length();\n        for (uint256 i; i < len; ++i) {\n            address token = $._idleTokens.at(i);\n            totalAum += _accountingValueOf(\n                oracleRegistry, $._accountingToken, token, IERC20Metadata(token).balanceOf(address(this))\n            );\n        }\n\n        return totalAum;\n    }\n\n    /// @dev Checks if the bridge state is consistent between the machine and spoke caliber.\n    function _checkBridgeState(\n        EnumerableMap.AddressToUintMap storage insMap,\n        EnumerableMap.AddressToUintMap storage outsMap\n    ) private view {\n        uint256 len = insMap.length();\n        for (uint256 i; i < len; ++i) {\n            (address token, uint256 amountIn) = insMap.at(i);\n            (, uint256 amountOut) = outsMap.tryGet(token);\n            if (amountIn > amountOut) {\n                revert Errors.BridgeStateMismatch();\n            }\n        }\n    }\n\n    /// @dev Computes the accounting value of a given token amount.\n    function _accountingValueOf(address oracleRegistry, address accountingToken, address token, uint256 amount)\n        private\n        view\n        returns (uint256)\n    {\n        if (token == accountingToken) {\n            return amount;\n        }\n        uint256 price = IOracleRegistry(oracleRegistry).getPrice(token, accountingToken);\n        return amount.mulDiv(price, 10 ** IERC20Metadata(token).decimals());\n    }\n\n    /// @dev Checks that the relative change between two values does not exceed the maximum allowed rate over elapsed time.\n    function _checkMaxRelativeChange(\n        uint256 previousValue,\n        uint256 newValue,\n        uint256 maxPercentDeltaPerSecond,\n        uint256 elapsedTime\n    ) private pure {\n        if (previousValue == 0) {\n            return;\n        }\n\n        uint256 absChange = previousValue > newValue ? previousValue - newValue : newValue - previousValue;\n        uint256 relChange = absChange.mulDiv(RATE_SCALE, previousValue);\n\n        if (relChange > maxPercentDeltaPerSecond.saturatingMul(elapsedTime)) {\n            revert Errors.MaxAuthorizedPriceChangeExceeded();\n        }\n    }\n}\n"},{"file_path":"src/utils/MakinaGovernable.sol","source_code":"// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.28;\n\nimport {\n    AccessManagedUpgradeable\n} from \"@openzeppelin/contracts-upgradeable/access/manager/AccessManagedUpgradeable.sol\";\nimport {EnumerableSet} from \"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\";\n\nimport {IMakinaGovernable} from \"../interfaces/IMakinaGovernable.sol\";\nimport {Errors} from \"../libraries/Errors.sol\";\n\nabstract contract MakinaGovernable is AccessManagedUpgradeable, IMakinaGovernable {\n    using EnumerableSet for EnumerableSet.AddressSet;\n\n    /// @custom:storage-location erc7201:makina.storage.MakinaGovernable\n    struct MakinaGovernableStorage {\n        address _mechanic;\n        address _securityCouncil;\n        address _riskManager;\n        address _riskManagerTimelock;\n        bool _recoveryMode;\n        bool _restrictedAccountingMode;\n        mapping(address user => bool isAccountingAgent) _isAccountingAgent;\n    }\n\n    // keccak256(abi.encode(uint256(keccak256(\"makina.storage.MakinaGovernable\")) - 1)) & ~bytes32(uint256(0xff))\n    bytes32 private constant MakinaGovernableStorageLocation =\n        0x7e702089668346e906996be6de3dfc0cb2b0c125fc09b3c0391871825913e000;\n\n    function _getMakinaGovernableStorage() internal pure returns (MakinaGovernableStorage storage $) {\n        assembly {\n            $.slot := MakinaGovernableStorageLocation\n        }\n    }\n\n    constructor() {\n        _disableInitializers();\n    }\n\n    function __MakinaGovernable_init(MakinaGovernableInitParams calldata params) internal onlyInitializing {\n        MakinaGovernableStorage storage $ = _getMakinaGovernableStorage();\n        $._mechanic = params.initialMechanic;\n        $._securityCouncil = params.initialSecurityCouncil;\n        $._riskManager = params.initialRiskManager;\n        $._riskManagerTimelock = params.initialRiskManagerTimelock;\n        $._restrictedAccountingMode = params.initialRestrictedAccountingMode;\n        for (uint256 i; i < params.initialAccountingAgents.length; ++i) {\n            _addAccountingAgent(params.initialAccountingAgents[i]);\n        }\n        __AccessManaged_init(params.initialAuthority);\n    }\n\n    modifier onlyOperator() {\n        if (msg.sender != operator()) {\n            revert Errors.UnauthorizedCaller();\n        }\n        _;\n    }\n\n    modifier onlyMechanic() {\n        if (msg.sender != _getMakinaGovernableStorage()._mechanic) {\n            revert Errors.UnauthorizedCaller();\n        }\n        _;\n    }\n\n    modifier onlySecurityCouncil() {\n        if (msg.sender != _getMakinaGovernableStorage()._securityCouncil) {\n            revert Errors.UnauthorizedCaller();\n        }\n        _;\n    }\n\n    modifier onlyRiskManager() {\n        if (msg.sender != _getMakinaGovernableStorage()._riskManager) {\n            revert Errors.UnauthorizedCaller();\n        }\n        _;\n    }\n\n    modifier onlyRiskManagerTimelock() {\n        if (msg.sender != _getMakinaGovernableStorage()._riskManagerTimelock) {\n            revert Errors.UnauthorizedCaller();\n        }\n        _;\n    }\n\n    modifier notRecoveryMode() {\n        if (_getMakinaGovernableStorage()._recoveryMode) {\n            revert Errors.RecoveryMode();\n        }\n        _;\n    }\n\n    modifier onlyAccountingAuthorized() {\n        if (!isAccountingAuthorized(msg.sender)) {\n            revert Errors.UnauthorizedCaller();\n        }\n        _;\n    }\n\n    /// @inheritdoc IMakinaGovernable\n    function operator() public view override returns (address) {\n        MakinaGovernableStorage storage $ = _getMakinaGovernableStorage();\n        return $._recoveryMode ? $._securityCouncil : $._mechanic;\n    }\n\n    /// @inheritdoc IMakinaGovernable\n    function mechanic() external view override returns (address) {\n        return _getMakinaGovernableStorage()._mechanic;\n    }\n\n    /// @inheritdoc IMakinaGovernable\n    function securityCouncil() public view override returns (address) {\n        return _getMakinaGovernableStorage()._securityCouncil;\n    }\n\n    /// @inheritdoc IMakinaGovernable\n    function riskManager() external view override returns (address) {\n        return _getMakinaGovernableStorage()._riskManager;\n    }\n\n    /// @inheritdoc IMakinaGovernable\n    function riskManagerTimelock() external view override returns (address) {\n        return _getMakinaGovernableStorage()._riskManagerTimelock;\n    }\n\n    /// @inheritdoc IMakinaGovernable\n    function recoveryMode() external view override returns (bool) {\n        return _getMakinaGovernableStorage()._recoveryMode;\n    }\n\n    /// @inheritdoc IMakinaGovernable\n    function restrictedAccountingMode() external view override returns (bool) {\n        return _getMakinaGovernableStorage()._restrictedAccountingMode;\n    }\n\n    /// @inheritdoc IMakinaGovernable\n    function isAccountingAgent(address user) external view override returns (bool) {\n        MakinaGovernableStorage storage $ = _getMakinaGovernableStorage();\n        return user == $._mechanic || user == $._securityCouncil || $._isAccountingAgent[user];\n    }\n\n    /// @inheritdoc IMakinaGovernable\n    function isAccountingAuthorized(address user) public view override returns (bool) {\n        MakinaGovernableStorage storage $ = _getMakinaGovernableStorage();\n        return (!$._recoveryMode && (!$._restrictedAccountingMode || user == $._mechanic || $._isAccountingAgent[user]))\n            || user == $._securityCouncil;\n    }\n\n    /// @inheritdoc IMakinaGovernable\n    function setMechanic(address newMechanic) external override restricted {\n        MakinaGovernableStorage storage $ = _getMakinaGovernableStorage();\n        emit MechanicChanged($._mechanic, newMechanic);\n        $._mechanic = newMechanic;\n    }\n\n    /// @inheritdoc IMakinaGovernable\n    function setSecurityCouncil(address newSecurityCouncil) external override restricted {\n        MakinaGovernableStorage storage $ = _getMakinaGovernableStorage();\n        emit SecurityCouncilChanged($._securityCouncil, newSecurityCouncil);\n        $._securityCouncil = newSecurityCouncil;\n    }\n\n    /// @inheritdoc IMakinaGovernable\n    function setRiskManager(address newRiskManager) external override restricted {\n        MakinaGovernableStorage storage $ = _getMakinaGovernableStorage();\n        emit RiskManagerChanged($._riskManager, newRiskManager);\n        $._riskManager = newRiskManager;\n    }\n\n    /// @inheritdoc IMakinaGovernable\n    function setRiskManagerTimelock(address newRiskManagerTimelock) external override restricted {\n        MakinaGovernableStorage storage $ = _getMakinaGovernableStorage();\n        emit RiskManagerTimelockChanged($._riskManagerTimelock, newRiskManagerTimelock);\n        $._riskManagerTimelock = newRiskManagerTimelock;\n    }\n\n    /// @inheritdoc IMakinaGovernable\n    function setRecoveryMode(bool enabled) external override onlySecurityCouncil {\n        MakinaGovernableStorage storage $ = _getMakinaGovernableStorage();\n        if ($._recoveryMode != enabled) {\n            $._recoveryMode = enabled;\n            emit RecoveryModeChanged(enabled);\n        }\n    }\n\n    /// @inheritdoc IMakinaGovernable\n    function setRestrictedAccountingMode(bool enabled) external override restricted {\n        MakinaGovernableStorage storage $ = _getMakinaGovernableStorage();\n        if ($._restrictedAccountingMode != enabled) {\n            $._restrictedAccountingMode = enabled;\n            emit RestrictedAccountingModeChanged(enabled);\n        }\n    }\n\n    /// @inheritdoc IMakinaGovernable\n    function addAccountingAgent(address newAgent) external override restricted {\n        _addAccountingAgent(newAgent);\n    }\n\n    /// @inheritdoc IMakinaGovernable\n    function removeAccountingAgent(address agent) external override restricted {\n        _removeAccountingAgent(agent);\n    }\n\n    /// @dev Internal logic for adding an accounting agent.\n    function _addAccountingAgent(address newAgent) internal {\n        MakinaGovernableStorage storage $ = _getMakinaGovernableStorage();\n        if (newAgent == $._mechanic || newAgent == $._securityCouncil || $._isAccountingAgent[newAgent]) {\n            revert Errors.AlreadyAccountingAgent();\n        }\n        $._isAccountingAgent[newAgent] = true;\n        emit AccountingAgentAdded(newAgent);\n    }\n\n    /// @dev Internal logic for removing an accounting agent.\n    function _removeAccountingAgent(address agent) internal {\n        MakinaGovernableStorage storage $ = _getMakinaGovernableStorage();\n        if (agent == $._mechanic || agent == $._securityCouncil) {\n            revert Errors.ProtectedAccountingAgent();\n        }\n        if (!$._isAccountingAgent[agent]) {\n            revert Errors.NotAccountingAgent();\n        }\n        $._isAccountingAgent[agent] = false;\n        emit AccountingAgentRemoved(agent);\n    }\n}\n"},{"file_path":"lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/token/ERC20/utils/SafeERC20.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.5.0) (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.20;\n\nimport {IERC20} from \"../IERC20.sol\";\nimport {IERC1363} from \"../../../interfaces/IERC1363.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC-20 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    /**\n     * @dev An operation with an ERC-20 token failed.\n     */\n    error SafeERC20FailedOperation(address token);\n\n    /**\n     * @dev Indicates a failed `decreaseAllowance` request.\n     */\n    error SafeERC20FailedDecreaseAllowance(address spender, uint256 currentAllowance, uint256 requestedDecrease);\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        if (!_safeTransfer(token, to, value, true)) {\n            revert SafeERC20FailedOperation(address(token));\n        }\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        if (!_safeTransferFrom(token, from, to, value, true)) {\n            revert SafeERC20FailedOperation(address(token));\n        }\n    }\n\n    /**\n     * @dev Variant of {safeTransfer} that returns a bool instead of reverting if the operation is not successful.\n     */\n    function trySafeTransfer(IERC20 token, address to, uint256 value) internal returns (bool) {\n        return _safeTransfer(token, to, value, false);\n    }\n\n    /**\n     * @dev Variant of {safeTransferFrom} that returns a bool instead of reverting if the operation is not successful.\n     */\n    function trySafeTransferFrom(IERC20 token, address from, address to, uint256 value) internal returns (bool) {\n        return _safeTransferFrom(token, from, to, value, false);\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     * IMPORTANT: If the token implements ERC-7674 (ERC-20 with temporary allowance), and if the \"client\"\n     * smart contract uses ERC-7674 to set temporary allowances, then the \"client\" smart contract should avoid using\n     * this function. Performing a {safeIncreaseAllowance} or {safeDecreaseAllowance} operation on a token contract\n     * that has a non-zero temporary allowance (for that particular owner-spender) will result in unexpected behavior.\n     */\n    function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n        uint256 oldAllowance = token.allowance(address(this), spender);\n        forceApprove(token, spender, oldAllowance + value);\n    }\n\n    /**\n     * @dev Decrease the calling contract's allowance toward `spender` by `requestedDecrease`. If `token` returns no\n     * value, non-reverting calls are assumed to be successful.\n     *\n     * IMPORTANT: If the token implements ERC-7674 (ERC-20 with temporary allowance), and if the \"client\"\n     * smart contract uses ERC-7674 to set temporary allowances, then the \"client\" smart contract should avoid using\n     * this function. Performing a {safeIncreaseAllowance} or {safeDecreaseAllowance} operation on a token contract\n     * that has a non-zero temporary allowance (for that particular owner-spender) will result in unexpected behavior.\n     */\n    function safeDecreaseAllowance(IERC20 token, address spender, uint256 requestedDecrease) internal {\n        unchecked {\n            uint256 currentAllowance = token.allowance(address(this), spender);\n            if (currentAllowance < requestedDecrease) {\n                revert SafeERC20FailedDecreaseAllowance(spender, currentAllowance, requestedDecrease);\n            }\n            forceApprove(token, spender, currentAllowance - requestedDecrease);\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     * NOTE: If the token implements ERC-7674, this function will not modify any temporary allowance. This function\n     * only sets the \"standard\" allowance. Any temporary allowance will remain active, in addition to the value being\n     * set here.\n     */\n    function forceApprove(IERC20 token, address spender, uint256 value) internal {\n        if (!_safeApprove(token, spender, value, false)) {\n            if (!_safeApprove(token, spender, 0, true)) revert SafeERC20FailedOperation(address(token));\n            if (!_safeApprove(token, spender, value, true)) revert SafeERC20FailedOperation(address(token));\n        }\n    }\n\n    /**\n     * @dev Performs an {ERC1363} transferAndCall, with a fallback to the simple {ERC20} transfer if the target has no\n     * code. This can be used to implement an {ERC721}-like safe transfer that relies on {ERC1363} checks when\n     * targeting contracts.\n     *\n     * Reverts if the returned value is other than `true`.\n     */\n    function transferAndCallRelaxed(IERC1363 token, address to, uint256 value, bytes memory data) internal {\n        if (to.code.length == 0) {\n            safeTransfer(token, to, value);\n        } else if (!token.transferAndCall(to, value, data)) {\n            revert SafeERC20FailedOperation(address(token));\n        }\n    }\n\n    /**\n     * @dev Performs an {ERC1363} transferFromAndCall, with a fallback to the simple {ERC20} transferFrom if the target\n     * has no code. This can be used to implement an {ERC721}-like safe transfer that relies on {ERC1363} checks when\n     * targeting contracts.\n     *\n     * Reverts if the returned value is other than `true`.\n     */\n    function transferFromAndCallRelaxed(\n        IERC1363 token,\n        address from,\n        address to,\n        uint256 value,\n        bytes memory data\n    ) internal {\n        if (to.code.length == 0) {\n            safeTransferFrom(token, from, to, value);\n        } else if (!token.transferFromAndCall(from, to, value, data)) {\n            revert SafeERC20FailedOperation(address(token));\n        }\n    }\n\n    /**\n     * @dev Performs an {ERC1363} approveAndCall, with a fallback to the simple {ERC20} approve if the target has no\n     * code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when\n     * targeting contracts.\n     *\n     * NOTE: When the recipient address (`to`) has no code (i.e. is an EOA), this function behaves as {forceApprove}.\n     * Oppositely, when the recipient address (`to`) has code, this function only attempts to call {ERC1363-approveAndCall}\n     * once without retrying, and relies on the returned value to be true.\n     *\n     * Reverts if the returned value is other than `true`.\n     */\n    function approveAndCallRelaxed(IERC1363 token, address to, uint256 value, bytes memory data) internal {\n        if (to.code.length == 0) {\n            forceApprove(token, to, value);\n        } else if (!token.approveAndCall(to, value, data)) {\n            revert SafeERC20FailedOperation(address(token));\n        }\n    }\n\n    /**\n     * @dev Imitates a Solidity `token.transfer(to, value)` call, relaxing the requirement on the return value: the\n     * return value is optional (but if data is returned, it must not be false).\n     *\n     * @param token The token targeted by the call.\n     * @param to The recipient of the tokens\n     * @param value The amount of token to transfer\n     * @param bubble Behavior switch if the transfer call reverts: bubble the revert reason or return a false boolean.\n     */\n    function _safeTransfer(IERC20 token, address to, uint256 value, bool bubble) private returns (bool success) {\n        bytes4 selector = IERC20.transfer.selector;\n\n        assembly (\"memory-safe\") {\n            let fmp := mload(0x40)\n            mstore(0x00, selector)\n            mstore(0x04, and(to, shr(96, not(0))))\n            mstore(0x24, value)\n            success := call(gas(), token, 0, 0x00, 0x44, 0x00, 0x20)\n            // if call success and return is true, all is good.\n            // otherwise (not success or return is not true), we need to perform further checks\n            if iszero(and(success, eq(mload(0x00), 1))) {\n                // if the call was a failure and bubble is enabled, bubble the error\n                if and(iszero(success), bubble) {\n                    returndatacopy(fmp, 0x00, returndatasize())\n                    revert(fmp, returndatasize())\n                }\n                // if the return value is not true, then the call is only successful if:\n                // - the token address has code\n                // - the returndata is empty\n                success := and(success, and(iszero(returndatasize()), gt(extcodesize(token), 0)))\n            }\n            mstore(0x40, fmp)\n        }\n    }\n\n    /**\n     * @dev Imitates a Solidity `token.transferFrom(from, to, value)` call, relaxing the requirement on the return\n     * value: the return value is optional (but if data is returned, it must not be false).\n     *\n     * @param token The token targeted by the call.\n     * @param from The sender of the tokens\n     * @param to The recipient of the tokens\n     * @param value The amount of token to transfer\n     * @param bubble Behavior switch if the transfer call reverts: bubble the revert reason or return a false boolean.\n     */\n    function _safeTransferFrom(\n        IERC20 token,\n        address from,\n        address to,\n        uint256 value,\n        bool bubble\n    ) private returns (bool success) {\n        bytes4 selector = IERC20.transferFrom.selector;\n\n        assembly (\"memory-safe\") {\n            let fmp := mload(0x40)\n            mstore(0x00, selector)\n            mstore(0x04, and(from, shr(96, not(0))))\n            mstore(0x24, and(to, shr(96, not(0))))\n            mstore(0x44, value)\n            success := call(gas(), token, 0, 0x00, 0x64, 0x00, 0x20)\n            // if call success and return is true, all is good.\n            // otherwise (not success or return is not true), we need to perform further checks\n            if iszero(and(success, eq(mload(0x00), 1))) {\n                // if the call was a failure and bubble is enabled, bubble the error\n                if and(iszero(success), bubble) {\n                    returndatacopy(fmp, 0x00, returndatasize())\n                    revert(fmp, returndatasize())\n                }\n                // if the return value is not true, then the call is only successful if:\n                // - the token address has code\n                // - the returndata is empty\n                success := and(success, and(iszero(returndatasize()), gt(extcodesize(token), 0)))\n            }\n            mstore(0x40, fmp)\n            mstore(0x60, 0)\n        }\n    }\n\n    /**\n     * @dev Imitates a Solidity `token.approve(spender, value)` call, relaxing the requirement on the return value:\n     * the return value is optional (but if data is returned, it must not be false).\n     *\n     * @param token The token targeted by the call.\n     * @param spender The spender of the tokens\n     * @param value The amount of token to transfer\n     * @param bubble Behavior switch if the transfer call reverts: bubble the revert reason or return a false boolean.\n     */\n    function _safeApprove(IERC20 token, address spender, uint256 value, bool bubble) private returns (bool success) {\n        bytes4 selector = IERC20.approve.selector;\n\n        assembly (\"memory-safe\") {\n            let fmp := mload(0x40)\n            mstore(0x00, selector)\n            mstore(0x04, and(spender, shr(96, not(0))))\n            mstore(0x24, value)\n            success := call(gas(), token, 0, 0x00, 0x44, 0x00, 0x20)\n            // if call success and return is true, all is good.\n            // otherwise (not success or return is not true), we need to perform further checks\n            if iszero(and(success, eq(mload(0x00), 1))) {\n                // if the call was a failure and bubble is enabled, bubble the error\n                if and(iszero(success), bubble) {\n                    returndatacopy(fmp, 0x00, returndatasize())\n                    revert(fmp, returndatasize())\n                }\n                // if the return value is not true, then the call is only successful if:\n                // - the token address has code\n                // - the returndata is empty\n                success := and(success, and(iszero(returndatasize()), gt(extcodesize(token), 0)))\n            }\n            mstore(0x40, fmp)\n        }\n    }\n}\n"},{"file_path":"lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/access/manager/AuthorityUtils.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.3.0) (access/manager/AuthorityUtils.sol)\n\npragma solidity ^0.8.20;\n\nimport {IAuthority} from \"./IAuthority.sol\";\n\nlibrary AuthorityUtils {\n    /**\n     * @dev Since `AccessManager` implements an extended IAuthority interface, invoking `canCall` with backwards compatibility\n     * for the preexisting `IAuthority` interface requires special care to avoid reverting on insufficient return data.\n     * This helper function takes care of invoking `canCall` in a backwards compatible way without reverting.\n     */\n    function canCallWithDelay(\n        address authority,\n        address caller,\n        address target,\n        bytes4 selector\n    ) internal view returns (bool immediate, uint32 delay) {\n        bytes memory data = abi.encodeCall(IAuthority.canCall, (caller, target, selector));\n\n        assembly (\"memory-safe\") {\n            mstore(0x00, 0x00)\n            mstore(0x20, 0x00)\n\n            if staticcall(gas(), authority, add(data, 0x20), mload(data), 0x00, 0x40) {\n                immediate := mload(0x00)\n                delay := mload(0x20)\n\n                // If delay does not fit in a uint32, return 0 (no delay)\n                // equivalent to: if gt(delay, 0xFFFFFFFF) { delay := 0 }\n                delay := mul(delay, iszero(shr(32, delay)))\n            }\n        }\n    }\n}\n"},{"file_path":"lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/utils/Panic.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.1.0) (utils/Panic.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Helper library for emitting standardized panic codes.\n *\n * ```solidity\n * contract Example {\n *      using Panic for uint256;\n *\n *      // Use any of the declared internal constants\n *      function foo() { Panic.GENERIC.panic(); }\n *\n *      // Alternatively\n *      function foo() { Panic.panic(Panic.GENERIC); }\n * }\n * ```\n *\n * Follows the list from https://github.com/ethereum/solidity/blob/v0.8.24/libsolutil/ErrorCodes.h[libsolutil].\n *\n * _Available since v5.1._\n */\n// slither-disable-next-line unused-state\nlibrary Panic {\n    /// @dev generic / unspecified error\n    uint256 internal constant GENERIC = 0x00;\n    /// @dev used by the assert() builtin\n    uint256 internal constant ASSERT = 0x01;\n    /// @dev arithmetic underflow or overflow\n    uint256 internal constant UNDER_OVERFLOW = 0x11;\n    /// @dev division or modulo by zero\n    uint256 internal constant DIVISION_BY_ZERO = 0x12;\n    /// @dev enum conversion error\n    uint256 internal constant ENUM_CONVERSION_ERROR = 0x21;\n    /// @dev invalid encoding in storage\n    uint256 internal constant STORAGE_ENCODING_ERROR = 0x22;\n    /// @dev empty array pop\n    uint256 internal constant EMPTY_ARRAY_POP = 0x31;\n    /// @dev array out of bounds access\n    uint256 internal constant ARRAY_OUT_OF_BOUNDS = 0x32;\n    /// @dev resource error (too large allocation or too large array)\n    uint256 internal constant RESOURCE_ERROR = 0x41;\n    /// @dev calling invalid internal function\n    uint256 internal constant INVALID_INTERNAL_FUNCTION = 0x51;\n\n    /// @dev Reverts with a panic code. Recommended to use with\n    /// the internal constants with predefined codes.\n    function panic(uint256 code) internal pure {\n        assembly (\"memory-safe\") {\n            mstore(0x00, 0x4e487b71)\n            mstore(0x20, code)\n            revert(0x1c, 0x24)\n        }\n    }\n}\n"},{"file_path":"lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/utils/math/SafeCast.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.6.0) (utils/math/SafeCast.sol)\n// This file was procedurally generated from scripts/generate/templates/SafeCast.js.\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Wrappers over Solidity's uintXX/intXX/bool 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 */\nlibrary SafeCast {\n    /**\n     * @dev Value doesn't fit in a uint of `bits` size.\n     */\n    error SafeCastOverflowedUintDowncast(uint8 bits, uint256 value);\n\n    /**\n     * @dev An int value doesn't fit in a uint of `bits` size.\n     */\n    error SafeCastOverflowedIntToUint(int256 value);\n\n    /**\n     * @dev Value doesn't fit in an int of `bits` size.\n     */\n    error SafeCastOverflowedIntDowncast(uint8 bits, int256 value);\n\n    /**\n     * @dev A uint value doesn't fit in an int of `bits` size.\n     */\n    error SafeCastOverflowedUintToInt(uint256 value);\n\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    function toUint248(uint256 value) internal pure returns (uint248) {\n        if (value > type(uint248).max) {\n            revert SafeCastOverflowedUintDowncast(248, value);\n        }\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    function toUint240(uint256 value) internal pure returns (uint240) {\n        if (value > type(uint240).max) {\n            revert SafeCastOverflowedUintDowncast(240, value);\n        }\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    function toUint232(uint256 value) internal pure returns (uint232) {\n        if (value > type(uint232).max) {\n            revert SafeCastOverflowedUintDowncast(232, value);\n        }\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    function toUint224(uint256 value) internal pure returns (uint224) {\n        if (value > type(uint224).max) {\n            revert SafeCastOverflowedUintDowncast(224, value);\n        }\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    function toUint216(uint256 value) internal pure returns (uint216) {\n        if (value > type(uint216).max) {\n            revert SafeCastOverflowedUintDowncast(216, value);\n        }\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    function toUint208(uint256 value) internal pure returns (uint208) {\n        if (value > type(uint208).max) {\n            revert SafeCastOverflowedUintDowncast(208, value);\n        }\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    function toUint200(uint256 value) internal pure returns (uint200) {\n        if (value > type(uint200).max) {\n            revert SafeCastOverflowedUintDowncast(200, value);\n        }\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    function toUint192(uint256 value) internal pure returns (uint192) {\n        if (value > type(uint192).max) {\n            revert SafeCastOverflowedUintDowncast(192, value);\n        }\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    function toUint184(uint256 value) internal pure returns (uint184) {\n        if (value > type(uint184).max) {\n            revert SafeCastOverflowedUintDowncast(184, value);\n        }\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    function toUint176(uint256 value) internal pure returns (uint176) {\n        if (value > type(uint176).max) {\n            revert SafeCastOverflowedUintDowncast(176, value);\n        }\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    function toUint168(uint256 value) internal pure returns (uint168) {\n        if (value > type(uint168).max) {\n            revert SafeCastOverflowedUintDowncast(168, value);\n        }\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    function toUint160(uint256 value) internal pure returns (uint160) {\n        if (value > type(uint160).max) {\n            revert SafeCastOverflowedUintDowncast(160, value);\n        }\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    function toUint152(uint256 value) internal pure returns (uint152) {\n        if (value > type(uint152).max) {\n            revert SafeCastOverflowedUintDowncast(152, value);\n        }\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    function toUint144(uint256 value) internal pure returns (uint144) {\n        if (value > type(uint144).max) {\n            revert SafeCastOverflowedUintDowncast(144, value);\n        }\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    function toUint136(uint256 value) internal pure returns (uint136) {\n        if (value > type(uint136).max) {\n            revert SafeCastOverflowedUintDowncast(136, value);\n        }\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    function toUint128(uint256 value) internal pure returns (uint128) {\n        if (value > type(uint128).max) {\n            revert SafeCastOverflowedUintDowncast(128, value);\n        }\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    function toUint120(uint256 value) internal pure returns (uint120) {\n        if (value > type(uint120).max) {\n            revert SafeCastOverflowedUintDowncast(120, value);\n        }\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    function toUint112(uint256 value) internal pure returns (uint112) {\n        if (value > type(uint112).max) {\n            revert SafeCastOverflowedUintDowncast(112, value);\n        }\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    function toUint104(uint256 value) internal pure returns (uint104) {\n        if (value > type(uint104).max) {\n            revert SafeCastOverflowedUintDowncast(104, value);\n        }\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    function toUint96(uint256 value) internal pure returns (uint96) {\n        if (value > type(uint96).max) {\n            revert SafeCastOverflowedUintDowncast(96, value);\n        }\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    function toUint88(uint256 value) internal pure returns (uint88) {\n        if (value > type(uint88).max) {\n            revert SafeCastOverflowedUintDowncast(88, value);\n        }\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    function toUint80(uint256 value) internal pure returns (uint80) {\n        if (value > type(uint80).max) {\n            revert SafeCastOverflowedUintDowncast(80, value);\n        }\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    function toUint72(uint256 value) internal pure returns (uint72) {\n        if (value > type(uint72).max) {\n            revert SafeCastOverflowedUintDowncast(72, value);\n        }\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    function toUint64(uint256 value) internal pure returns (uint64) {\n        if (value > type(uint64).max) {\n            revert SafeCastOverflowedUintDowncast(64, value);\n        }\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    function toUint56(uint256 value) internal pure returns (uint56) {\n        if (value > type(uint56).max) {\n            revert SafeCastOverflowedUintDowncast(56, value);\n        }\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    function toUint48(uint256 value) internal pure returns (uint48) {\n        if (value > type(uint48).max) {\n            revert SafeCastOverflowedUintDowncast(48, value);\n        }\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    function toUint40(uint256 value) internal pure returns (uint40) {\n        if (value > type(uint40).max) {\n            revert SafeCastOverflowedUintDowncast(40, value);\n        }\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    function toUint32(uint256 value) internal pure returns (uint32) {\n        if (value > type(uint32).max) {\n            revert SafeCastOverflowedUintDowncast(32, value);\n        }\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    function toUint24(uint256 value) internal pure returns (uint24) {\n        if (value > type(uint24).max) {\n            revert SafeCastOverflowedUintDowncast(24, value);\n        }\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    function toUint16(uint256 value) internal pure returns (uint16) {\n        if (value > type(uint16).max) {\n            revert SafeCastOverflowedUintDowncast(16, value);\n        }\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    function toUint8(uint256 value) internal pure returns (uint8) {\n        if (value > type(uint8).max) {\n            revert SafeCastOverflowedUintDowncast(8, value);\n        }\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    function toUint256(int256 value) internal pure returns (uint256) {\n        if (value < 0) {\n            revert SafeCastOverflowedIntToUint(value);\n        }\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    function toInt248(int256 value) internal pure returns (int248 downcasted) {\n        downcasted = int248(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(248, value);\n        }\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    function toInt240(int256 value) internal pure returns (int240 downcasted) {\n        downcasted = int240(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(240, value);\n        }\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    function toInt232(int256 value) internal pure returns (int232 downcasted) {\n        downcasted = int232(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(232, value);\n        }\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    function toInt224(int256 value) internal pure returns (int224 downcasted) {\n        downcasted = int224(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(224, value);\n        }\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    function toInt216(int256 value) internal pure returns (int216 downcasted) {\n        downcasted = int216(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(216, value);\n        }\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    function toInt208(int256 value) internal pure returns (int208 downcasted) {\n        downcasted = int208(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(208, value);\n        }\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    function toInt200(int256 value) internal pure returns (int200 downcasted) {\n        downcasted = int200(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(200, value);\n        }\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    function toInt192(int256 value) internal pure returns (int192 downcasted) {\n        downcasted = int192(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(192, value);\n        }\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    function toInt184(int256 value) internal pure returns (int184 downcasted) {\n        downcasted = int184(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(184, value);\n        }\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    function toInt176(int256 value) internal pure returns (int176 downcasted) {\n        downcasted = int176(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(176, value);\n        }\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    function toInt168(int256 value) internal pure returns (int168 downcasted) {\n        downcasted = int168(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(168, value);\n        }\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    function toInt160(int256 value) internal pure returns (int160 downcasted) {\n        downcasted = int160(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(160, value);\n        }\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    function toInt152(int256 value) internal pure returns (int152 downcasted) {\n        downcasted = int152(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(152, value);\n        }\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    function toInt144(int256 value) internal pure returns (int144 downcasted) {\n        downcasted = int144(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(144, value);\n        }\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    function toInt136(int256 value) internal pure returns (int136 downcasted) {\n        downcasted = int136(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(136, value);\n        }\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    function toInt128(int256 value) internal pure returns (int128 downcasted) {\n        downcasted = int128(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(128, value);\n        }\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    function toInt120(int256 value) internal pure returns (int120 downcasted) {\n        downcasted = int120(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(120, value);\n        }\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    function toInt112(int256 value) internal pure returns (int112 downcasted) {\n        downcasted = int112(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(112, value);\n        }\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    function toInt104(int256 value) internal pure returns (int104 downcasted) {\n        downcasted = int104(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(104, value);\n        }\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    function toInt96(int256 value) internal pure returns (int96 downcasted) {\n        downcasted = int96(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(96, value);\n        }\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    function toInt88(int256 value) internal pure returns (int88 downcasted) {\n        downcasted = int88(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(88, value);\n        }\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    function toInt80(int256 value) internal pure returns (int80 downcasted) {\n        downcasted = int80(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(80, value);\n        }\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    function toInt72(int256 value) internal pure returns (int72 downcasted) {\n        downcasted = int72(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(72, value);\n        }\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    function toInt64(int256 value) internal pure returns (int64 downcasted) {\n        downcasted = int64(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(64, value);\n        }\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    function toInt56(int256 value) internal pure returns (int56 downcasted) {\n        downcasted = int56(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(56, value);\n        }\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    function toInt48(int256 value) internal pure returns (int48 downcasted) {\n        downcasted = int48(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(48, value);\n        }\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    function toInt40(int256 value) internal pure returns (int40 downcasted) {\n        downcasted = int40(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(40, value);\n        }\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    function toInt32(int256 value) internal pure returns (int32 downcasted) {\n        downcasted = int32(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(32, value);\n        }\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    function toInt24(int256 value) internal pure returns (int24 downcasted) {\n        downcasted = int24(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(24, value);\n        }\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    function toInt16(int256 value) internal pure returns (int16 downcasted) {\n        downcasted = int16(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(16, value);\n        }\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    function toInt8(int256 value) internal pure returns (int8 downcasted) {\n        downcasted = int8(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(8, value);\n        }\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    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        if (value > uint256(type(int256).max)) {\n            revert SafeCastOverflowedUintToInt(value);\n        }\n        return int256(value);\n    }\n\n    /**\n     * @dev Cast a boolean (false or true) to a uint256 (0 or 1) with no jump.\n     */\n    function toUint(bool b) internal pure returns (uint256 u) {\n        assembly (\"memory-safe\") {\n            u := iszero(iszero(b))\n        }\n    }\n}\n"},{"file_path":"lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/utils/introspection/IERC165.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.4.0) (utils/introspection/IERC165.sol)\n\npragma solidity >=0.4.16;\n\n/**\n * @dev Interface of the ERC-165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[ERC].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165 {\n    /**\n     * @dev Returns true if this contract implements the interface defined by\n     * `interfaceId`. See the corresponding\n     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[ERC section]\n     * to learn more about how these ids are created.\n     *\n     * This function call must use less than 30 000 gas.\n     */\n    function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n"},{"file_path":"src/interfaces/IMachineEndpoint.sol","source_code":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.28;\n\nimport {IBridgeController} from \"./IBridgeController.sol\";\nimport {IMakinaGovernable} from \"./IMakinaGovernable.sol\";\n\ninterface IMachineEndpoint is IBridgeController, IMakinaGovernable {\n    /// @notice Manages the transfer of tokens between a machine and a caliber. The transfer direction depends on the caller.\n    /// @param token The address of the token.\n    /// @param amount The amount of tokens to transfer.\n    /// @param data ABI-encoded parameters required for bridge-related transfers. Ignored for transfers between a machine and its hub caliber.\n    function manageTransfer(address token, uint256 amount, bytes calldata data) external;\n}\n"},{"file_path":"src/interfaces/IMachine.sol","source_code":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.28;\n\nimport {EnumerableMap} from \"@openzeppelin/contracts/utils/structs/EnumerableMap.sol\";\n\nimport {IMachineEndpoint} from \"./IMachineEndpoint.sol\";\nimport {ISpokeSnapshotConsumer} from \"./ISpokeSnapshotConsumer.sol\";\n\ninterface IMachine is IMachineEndpoint, ISpokeSnapshotConsumer {\n    event CaliberStaleThresholdChanged(uint256 indexed oldThreshold, uint256 indexed newThreshold);\n    event Deposit(\n        address indexed sender, address indexed receiver, uint256 assets, uint256 shares, bytes32 indexed referralKey\n    );\n    event DepositorChanged(address indexed oldDepositor, address indexed newDepositor);\n    event FeeManagerChanged(address indexed oldFeeManager, address indexed newFeeManager);\n    event FeeMintCooldownChanged(uint256 indexed oldFeeMintCooldown, uint256 indexed newFeeMintCooldown);\n    event FeesMinted(uint256 shares);\n    event MaxFixedFeeAccrualRateChanged(uint256 indexed oldMaxAccrualRate, uint256 indexed newMaxAccrualRate);\n    event MaxPerfFeeAccrualRateChanged(uint256 indexed oldMaxAccrualRate, uint256 indexed newMaxAccrualRate);\n    event MaxSharePriceChangeRateChanged(uint256 indexed oldMaxChangeRate, uint256 indexed newMaxChangeRate);\n    event Redeem(address indexed owner, address indexed receiver, uint256 assets, uint256 shares);\n    event RedeemerChanged(address indexed oldRedeemer, address indexed newRedeemer);\n    event ShareLimitChanged(uint256 indexed oldShareLimit, uint256 indexed newShareLimit);\n    event SpokeBridgeAdapterSet(uint256 indexed chainId, uint256 indexed bridgeId, address indexed adapter);\n    event SpokeCaliberDisabled(uint256 indexed chainId);\n    event SpokeCaliberEnabled(uint256 indexed chainId);\n    event SpokeCaliberMailboxSet(uint256 indexed chainId, address indexed caliberMailbox);\n    event TotalAumUpdated(uint256 totalAum);\n    event TransferToCaliber(uint256 indexed chainId, address indexed token, uint256 amount);\n\n    /// @notice Initialization parameters.\n    /// @param initialDepositor The address of the initial depositor.\n    /// @param initialRedeemer The address of the initial redeemer.\n    /// @param initialFeeManager The address of the initial fee manager.\n    /// @param initialCaliberStaleThreshold The caliber accounting staleness threshold in seconds.\n    /// @param initialMaxFixedFeeAccrualRate The maximum fixed fee accrual rate per second, 1e18 = 100%.\n    /// @param initialMaxPerfFeeAccrualRate The maximum performance fee accrual rate per second, 1e18 = 100%.\n    /// @param initialFeeMintCooldown The minimum time that must elapse between two fee minting events in seconds.\n    /// @param initialShareLimit The share cap value.\n    /// @param initialMaxSharePriceChangeRate The maximum relative share price change rate per second during total AUM updates, 1e18 = 100%.\n    struct MachineInitParams {\n        address initialDepositor;\n        address initialRedeemer;\n        address initialFeeManager;\n        uint256 initialCaliberStaleThreshold;\n        uint256 initialMaxFixedFeeAccrualRate;\n        uint256 initialMaxPerfFeeAccrualRate;\n        uint256 initialFeeMintCooldown;\n        uint256 initialShareLimit;\n        uint256 initialMaxSharePriceChangeRate;\n    }\n\n    /// @dev State data for each spoke caliber.\n    /// @param mailbox The address of the spoke caliber mailbox.\n    /// @param bridgeAdapters The mapping of bridge IDs to their corresponding adapters.\n    /// @param timestamp The timestamp of the last accounting.\n    /// @param netAum The net AUM of the spoke caliber.\n    /// @param deprecated_4 Deprecated field.\n    /// @param deprecated_5 Deprecated field.\n    /// @param caliberBridgesIn The mapping of spoke caliber incoming bridge amounts.\n    /// @param caliberBridgesOut The mapping of spoke caliber outgoing bridge amounts.\n    /// @param machineBridgesIn The mapping of machine incoming bridge amounts.\n    /// @param machineBridgesOut The mapping of machine outgoing bridge amounts.\n    /// @param disabled Whether the spoke caliber is disabled (ignored in AUM calculations and ineligible for machine transfers until re-enabled).\n    struct SpokeCaliberData {\n        address mailbox;\n        mapping(uint16 bridgeId => address adapter) bridgeAdapters;\n        uint256 timestamp;\n        uint256 netAum;\n        bytes[] deprecated_4;\n        bytes[] deprecated_5;\n        EnumerableMap.AddressToUintMap caliberBridgesIn;\n        EnumerableMap.AddressToUintMap caliberBridgesOut;\n        EnumerableMap.AddressToUintMap machineBridgesIn;\n        EnumerableMap.AddressToUintMap machineBridgesOut;\n        bool disabled;\n    }\n\n    /// @notice Initializer of the contract.\n    /// @param mParams The machine initialization parameters.\n    /// @param mgParams The makina governable initialization parameters.\n    /// @param sscParams The spoke snapshot consumer initialization parameters.\n    /// @param _preDepositVault The address of the pre-deposit vault.\n    /// @param _shareToken The address of the share token.\n    /// @param _accountingToken The address of the accounting token.\n    /// @param _hubCaliber The address of the hub caliber.\n    function initialize(\n        MachineInitParams calldata mParams,\n        MakinaGovernableInitParams calldata mgParams,\n        SpokeSnapshotConsumerInitParams calldata sscParams,\n        address _preDepositVault,\n        address _shareToken,\n        address _accountingToken,\n        address _hubCaliber\n    ) external;\n\n    /// @notice Address of the depositor.\n    function depositor() external view returns (address);\n\n    /// @notice Address of the redeemer.\n    function redeemer() external view returns (address);\n\n    /// @notice Address of the share token.\n    function shareToken() external view returns (address);\n\n    /// @notice Address of the accounting token.\n    function accountingToken() external view returns (address);\n\n    /// @notice Address of the hub caliber.\n    function hubCaliber() external view returns (address);\n\n    /// @notice Address of the fee manager.\n    function feeManager() external view returns (address);\n\n    /// @notice Maximum duration a caliber can remain unaccounted for before it is considered stale.\n    function caliberStaleThreshold() external view returns (uint256);\n\n    /// @notice Maximum fixed fee accrual rate per second used to compute an upper bound on shares to be minted, 1e18 = 100%.\n    function maxFixedFeeAccrualRate() external view returns (uint256);\n\n    /// @notice Maximum performance fee accrual rate per second used to compute an upper bound on shares to be minted, 1e18 = 100%.\n    function maxPerfFeeAccrualRate() external view returns (uint256);\n\n    /// @notice Minimum time that must elapse between two fee minting events.\n    function feeMintCooldown() external view returns (uint256);\n\n    /// @notice Share token supply limit that cannot be exceeded by new deposits.\n    function shareLimit() external view returns (uint256);\n\n    /// @notice Maximum relative share price change rate per second during total AUM updates, 1e18 = 100%.\n    function maxSharePriceChangeRate() external view returns (uint256);\n\n    /// @notice Maximum amount of shares that can currently be minted through asset deposits.\n    function maxMint() external view returns (uint256);\n\n    /// @notice Maximum amount of accounting tokens that can currently be withdrawn through share redemptions.\n    function maxWithdraw() external view returns (uint256);\n\n    /// @notice Last total machine AUM.\n    function lastTotalAum() external view returns (uint256);\n\n    /// @notice Timestamp of the last global machine accounting.\n    function lastGlobalAccountingTime() external view returns (uint256);\n\n    /// @notice Token => Is the token registered as an idle token in this machine.\n    function isIdleToken(address token) external view returns (bool);\n\n    /// @notice Length of the idle tokens list.\n    function getIdleTokensLength() external view returns (uint256);\n\n    /// @notice Idle token index => Idle token address.\n    /// @dev There are no guarantees on the ordering of values inside the idle tokens list,\n    ///      and it may change when values are added or removed.\n    function getIdleToken(uint256 idx) external view returns (address);\n\n    /// @notice Number of calibers associated with the machine.\n    function getSpokeCalibersLength() external view returns (uint256);\n\n    /// @notice Spoke caliber index => Spoke chain ID.\n    function getSpokeChainId(uint256 idx) external view returns (uint256);\n\n    /// @notice Spoke chain ID => Spoke caliber's net AUM and accounting timestamp.\n    function getSpokeCaliberNetAum(uint256 chainId) external view returns (uint256, uint256);\n\n    /// @notice Spoke chain ID => Spoke caliber mailbox address.\n    function getSpokeCaliberMailbox(uint256 chainId) external view returns (address);\n\n    /// @notice Spoke chain ID => Whether the spoke caliber is enabled.\n    function isSpokeCaliberEnabled(uint256 chainId) external view returns (bool);\n\n    /// @notice Spoke chain ID => Spoke bridge ID => Spoke bridge adapter.\n    function getSpokeBridgeAdapter(uint256 chainId, uint16 bridgeId) external view returns (address);\n\n    /// @notice Returns the amount of shares that the machine would exchange for the amount of accounting tokens provided.\n    /// @param assets The amount of accounting tokens.\n    /// @return shares The amount of shares.\n    function convertToShares(uint256 assets) external view returns (uint256);\n\n    /// @notice Returns the amount of accounting tokens that the machine would exchange for the amount of shares provided.\n    /// @param shares The amount of shares.\n    /// @return assets The amount of accounting tokens.\n    function convertToAssets(uint256 shares) external view returns (uint256);\n\n    /// @notice Initiates a token transfer to the hub caliber.\n    /// @param token The address of the token to transfer.\n    /// @param amount The amount of token to transfer.\n    function transferToHubCaliber(address token, uint256 amount) external;\n\n    /// @notice Initiates a token transfer to the spoke caliber.\n    /// @param bridgeId The ID of the bridge to use for the transfer.\n    /// @param chainId The chain ID of the spoke caliber.\n    /// @param token The address of the token to transfer.\n    /// @param amount The amount of token to transfer.\n    /// @param minOutputAmount The minimum output amount expected from the transfer.\n    function transferToSpokeCaliber(\n        uint16 bridgeId,\n        uint256 chainId,\n        address token,\n        uint256 amount,\n        uint256 minOutputAmount\n    ) external;\n\n    /// @notice Updates the total AUM of the machine.\n    /// @return totalAum The updated total AUM.\n    function updateTotalAum() external returns (uint256);\n\n    /// @notice Deposits accounting tokens into the machine and mints shares to the receiver.\n    /// @param assets The amount of accounting tokens to deposit.\n    /// @param receiver The receiver of minted shares.\n    /// @param minShares The minimum amount of shares to be minted.\n    /// @param referralKey The optional identifier used to track a referral source.\n    /// @return shares The amount of shares minted.\n    function deposit(uint256 assets, address receiver, uint256 minShares, bytes32 referralKey)\n        external\n        returns (uint256);\n\n    /// @notice Redeems shares from the machine and transfers accounting tokens to the receiver.\n    /// @param shares The amount of shares to redeem.\n    /// @param receiver The receiver of the accounting tokens.\n    /// @param minAssets The minimum amount of accounting tokens to be transferred.\n    /// @return assets The amount of accounting tokens transferred.\n    function redeem(uint256 shares, address receiver, uint256 minAssets) external returns (uint256);\n\n    /// @notice Registers a spoke caliber mailbox and related bridge adapters.\n    /// @param chainId The chain ID of the spoke caliber.\n    /// @param spokeCaliberMailbox The address of the spoke caliber mailbox.\n    /// @param bridges The list of bridges supported with the spoke caliber mailbox.\n    /// @param adapters The list of corresponding spoke adapters for each bridge. Must be the same length as `bridges`.\n    function setSpokeCaliber(\n        uint256 chainId,\n        address spokeCaliberMailbox,\n        uint16[] calldata bridges,\n        address[] calldata adapters\n    ) external;\n\n    /// @notice Disables a spoke caliber.\n    /// @param chainId The chain ID of the spoke caliber to disable.\n    function disableSpokeCaliber(uint256 chainId) external;\n\n    /// @notice Re-enables a spoke caliber.\n    /// @param chainId The chain ID of the spoke caliber to enable.\n    function enableSpokeCaliber(uint256 chainId) external;\n\n    /// @notice Registers a spoke bridge adapter.\n    /// @param chainId The chain ID of the spoke bridge adapter.\n    /// @param bridgeId The ID of the bridge.\n    /// @param adapter The address of the spoke bridge adapter.\n    function setSpokeBridgeAdapter(uint256 chainId, uint16 bridgeId, address adapter) external;\n\n    /// @notice Sets the depositor address.\n    /// @param newDepositor The address of the new depositor.\n    function setDepositor(address newDepositor) external;\n\n    /// @notice Sets the redeemer address.\n    /// @param newRedeemer The address of the new redeemer.\n    function setRedeemer(address newRedeemer) external;\n\n    /// @notice Sets the fee manager address.\n    /// @param newFeeManager The address of the new fee manager.\n    function setFeeManager(address newFeeManager) external;\n\n    /// @notice Sets the caliber accounting staleness threshold.\n    /// @param newCaliberStaleThreshold The new threshold in seconds.\n    function setCaliberStaleThreshold(uint256 newCaliberStaleThreshold) external;\n\n    /// @notice Sets the maximum fixed fee accrual rate.\n    /// @param newMaxAccrualRate The new maximum fixed fee accrual rate per second, 1e18 = 100%.\n    function setMaxFixedFeeAccrualRate(uint256 newMaxAccrualRate) external;\n\n    /// @notice Sets the maximum performance fee accrual rate.\n    /// @param newMaxAccrualRate The new maximum performance fee accrual rate per second, 1e18 = 100%.\n    function setMaxPerfFeeAccrualRate(uint256 newMaxAccrualRate) external;\n\n    /// @notice Sets the minimum time to be elapsed between two fee minting events.\n    /// @param newFeeMintCooldown The new cooldown in seconds.\n    function setFeeMintCooldown(uint256 newFeeMintCooldown) external;\n\n    /// @notice Sets the new share token supply limit that cannot be exceeded by new deposits.\n    /// @param newShareLimit The new share limit.\n    function setShareLimit(uint256 newShareLimit) external;\n\n    /// @notice Sets the new maximum relative share price change rate per second during total AUM updates, 1e18 = 100%.\n    /// @param newMaxSharePriceChangeRate The new maximum relative share price change rate.\n    function setMaxSharePriceChangeRate(uint256 newMaxSharePriceChangeRate) external;\n}\n"},{"file_path":"lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/utils/Comparators.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.1.0) (utils/Comparators.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Provides a set of functions to compare values.\n *\n * _Available since v5.1._\n */\nlibrary Comparators {\n    function lt(uint256 a, uint256 b) internal pure returns (bool) {\n        return a < b;\n    }\n\n    function gt(uint256 a, uint256 b) internal pure returns (bool) {\n        return a > b;\n    }\n}\n"},{"file_path":"src/interfaces/ICaliber.sol","source_code":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.28;\n\nimport {ISwapModule} from \"./ISwapModule.sol\";\n\ninterface ICaliber {\n    event AllowedInstrRootSet(bytes32 indexed newAllowedInstrRoot);\n    event BaseTokenAdded(address indexed token);\n    event BaseTokenRemoved(address indexed token);\n    event CooldownDurationChanged(uint256 indexed oldDuration, uint256 indexed newDuration);\n    event IncomingTransfer(address indexed token, uint256 amount);\n    event InstrRootGuardianAdded(address indexed newGuardian);\n    event InstrRootGuardianRemoved(address indexed guardian);\n    event MaxPositionDecreaseLossBpsChanged(\n        uint256 indexed oldMaxPositionDecreaseLossBps, uint256 indexed newMaxPositionDecreaseLossBps\n    );\n    event MaxPositionIncreaseLossBpsChanged(\n        uint256 indexed oldMaxPositionIncreaseLossBps, uint256 indexed newMaxPositionIncreaseLossBps\n    );\n    event MaxSwapLossBpsChanged(uint256 indexed oldMaxSwapLossBps, uint256 indexed newMaxSwapLossBps);\n    event NewAllowedInstrRootCancelled(bytes32 indexed cancelledMerkleRoot);\n    event NewAllowedInstrRootScheduled(bytes32 indexed newMerkleRoot, uint256 indexed effectiveTime);\n    event PositionClosed(uint256 indexed id);\n    event PositionCreated(uint256 indexed id, uint256 value);\n    event PositionUpdated(uint256 indexed id, uint256 value);\n    event PositionStaleThresholdChanged(uint256 indexed oldThreshold, uint256 indexed newThreshold);\n    event TimelockDurationChanged(uint256 indexed oldDuration, uint256 indexed newDuration);\n    event TransferToHubMachine(address indexed token, uint256 amount);\n\n    enum InstructionType {\n        MANAGEMENT,\n        ACCOUNTING,\n        HARVEST,\n        FLASHLOAN_MANAGEMENT\n    }\n\n    /// @notice Initialization parameters.\n    /// @param initialPositionStaleThreshold The position accounting staleness threshold in seconds.\n    /// @param initialAllowedInstrRoot The root of the Merkle tree containing allowed instructions.\n    /// @param initialTimelockDuration The duration of the allowedInstrRoot update timelock.\n    /// @param initialMaxPositionIncreaseLossBps The max allowed value loss (in basis points) for position increases.\n    /// @param initialMaxPositionDecreaseLossBps The max allowed value loss (in basis points) for position decreases.\n    /// @param initialMaxSwapLossBps The max allowed value loss (in basis points) for base token swaps.\n    /// @param initialCooldownDuration The duration of the cooldown period for swaps and position management.\n    /// @param initialBaseTokens The array of initial base tokens.\n    struct CaliberInitParams {\n        uint256 initialPositionStaleThreshold;\n        bytes32 initialAllowedInstrRoot;\n        uint256 initialTimelockDuration;\n        uint256 initialMaxPositionIncreaseLossBps;\n        uint256 initialMaxPositionDecreaseLossBps;\n        uint256 initialMaxSwapLossBps;\n        uint256 initialCooldownDuration;\n        address[] initialBaseTokens;\n    }\n\n    /// @notice Instruction parameters.\n    /// @param positionId The ID of the involved position.\n    /// @param isDebt Whether the position is a debt.\n    /// @param groupId The ID of the position accounting group.\n    ///        Set to 0 if the instruction is not of type ACCOUNTING, or if the involved position is ungrouped.\n    /// @param instructionType The type of the instruction.\n    /// @param affectedTokens The array of affected tokens.\n    /// @param positionTokens The array of position tokens.\n    /// @param commands The array of commands.\n    /// @param state The array of state.\n    /// @param stateBitmap The state bitmap.\n    /// @param merkleProof The array of Merkle proof elements.\n    struct Instruction {\n        uint256 positionId;\n        bool isDebt;\n        uint256 groupId;\n        InstructionType instructionType;\n        address[] affectedTokens;\n        address[] positionTokens;\n        bytes32[] commands;\n        bytes[] state;\n        uint128 stateBitmap;\n        bytes32[] merkleProof;\n    }\n\n    /// @notice Position data.\n    /// @param lastAccountingTime The last block timestamp when the position was accounted for.\n    /// @param value The value of the position denominated in accounting token.\n    /// @param isDebt Whether the position is a debt.\n    struct Position {\n        uint256 lastAccountingTime;\n        uint256 value;\n        bool isDebt;\n    }\n\n    /// @notice Initializer of the contract.\n    /// @param cParams The caliber initialization parameters.\n    /// @param _accountingToken The address of the accounting token.\n    /// @param _hubMachineEndpoint The address of the hub machine endpoint.\n    function initialize(CaliberInitParams calldata cParams, address _accountingToken, address _hubMachineEndpoint)\n        external;\n\n    /// @notice Address of the Weiroll VM.\n    function weirollVm() external view returns (address);\n\n    /// @notice Address of the hub machine endpoint.\n    function hubMachineEndpoint() external view returns (address);\n\n    /// @notice Address of the accounting token.\n    function accountingToken() external view returns (address);\n\n    /// @notice Maximum duration a position can remain unaccounted for before it is considered stale.\n    function positionStaleThreshold() external view returns (uint256);\n\n    /// @notice Root of the Merkle tree containing allowed instructions.\n    function allowedInstrRoot() external view returns (bytes32);\n\n    /// @notice Duration of the allowedInstrRoot update timelock.\n    function timelockDuration() external view returns (uint256);\n\n    /// @notice Value of the pending allowedInstrRoot, if any.\n    function pendingAllowedInstrRoot() external view returns (bytes32);\n\n    /// @notice Effective time of the last scheduled allowedInstrRoot update.\n    function pendingTimelockExpiry() external view returns (uint256);\n\n    /// @notice Max allowed value loss (in basis points) when increasing a position.\n    function maxPositionIncreaseLossBps() external view returns (uint256);\n\n    /// @notice Max allowed value loss (in basis points) when decreasing a position.\n    function maxPositionDecreaseLossBps() external view returns (uint256);\n\n    /// @notice Max allowed value loss (in basis points) for base token swaps.\n    function maxSwapLossBps() external view returns (uint256);\n\n    /// @notice Duration of the cooldown period for swaps and position management.\n    function cooldownDuration() external view returns (uint256);\n\n    /// @notice Length of the position IDs list.\n    function getPositionsLength() external view returns (uint256);\n\n    /// @notice Position index => Position ID\n    /// @dev There are no guarantees on the ordering of values inside the Position ID list,\n    ///      and it may change when values are added or removed.\n    function getPositionId(uint256 idx) external view returns (uint256);\n\n    /// @notice Position ID => Position data\n    function getPosition(uint256 posId) external view returns (Position memory);\n\n    /// @notice Token => Registered as base token in this caliber\n    function isBaseToken(address token) external view returns (bool);\n\n    /// @notice Length of the base tokens list.\n    function getBaseTokensLength() external view returns (uint256);\n\n    /// @notice Base token index => Base token address\n    /// @dev There are no guarantees on the ordering of values inside the base tokens list,\n    ///      and it may change when values are added or removed.\n    function getBaseToken(uint256 idx) external view returns (address);\n\n    /// @notice User => Whether the user is a root guardian\n    ///      Guardians have veto power over updates of the Merkle root.\n    function isInstrRootGuardian(address user) external view returns (bool);\n\n    /// @notice Checks if the accounting age of each position is below the position staleness threshold.\n    function isAccountingFresh() external view returns (bool);\n\n    /// @notice Returns the caliber's net AUM denominated in the accounting token.\n    /// @dev Reverts if any position's accounting is stale.\n    function getNetAum() external view returns (uint256);\n\n    /// @notice Returns the caliber's net AUM along with detailed position and base token breakdowns.\n    /// @dev Does not revert on stale positions. Staleness is surfaced per position via the isStale flag instead.\n    /// @return netAum The total value of all base token balances and positive positions, minus total debts.\n    /// @return positions The array of encoded tuples of the form (positionId, value, isDebt, isStale).\n    /// @return baseTokens The array of encoded tuples of the form (token, value).\n    function getDetailedAum()\n        external\n        view\n        returns (uint256 netAum, bytes[] memory positions, bytes[] memory baseTokens);\n\n    /// @notice Adds a new base token.\n    /// @param token The address of the base token.\n    function addBaseToken(address token) external;\n\n    /// @notice Removes a base token.\n    /// @param token The address of the base token.\n    function removeBaseToken(address token) external;\n\n    /// @notice Accounts for a position.\n    /// @dev If the position value goes to zero, it is closed.\n    /// @param instruction The accounting instruction.\n    /// @return value The new position value.\n    /// @return change The change in the position value.\n    function accountForPosition(Instruction calldata instruction) external returns (uint256 value, int256 change);\n\n    /// @notice Accounts for a batch of positions.\n    /// @param instructions The array of accounting instructions.\n    /// @param groupIds The array of position group IDs.\n    ///        An accounting instruction must be provided for every open position in each specified group.\n    ///        If an instruction's groupId corresponds to a group of open positions of size greater than 1,\n    ///        the group ID must be included in this array.\n    /// @return values The new position values.\n    /// @return changes The changes in the position values.\n    function accountForPositionBatch(Instruction[] calldata instructions, uint256[] calldata groupIds)\n        external\n        returns (uint256[] memory values, int256[] memory changes);\n\n    /// @notice Manages a position's state through paired management and accounting instructions.\n    /// @dev Performs accounting updates and modifies contract storage by:\n    /// - Adding new positions to storage when created.\n    /// - Removing positions from storage when value reaches zero.\n    /// @dev Applies value preservation checks using a validation matrix to prevent\n    /// economic inconsistencies between position changes and token flows.\n    ///\n    /// The matrix evaluates three factors to determine required validations:\n    /// - Base Tokens flow - Whether the contract globally spent or received base tokens during operation\n    /// - Debt Position - Whether position represents protocol liability (true) vs asset (false)\n    /// - Position Δ direction - Direction of position value change (increase/decrease/null)\n    ///\n    /// ┌──────────────────┬───────────────┬──────────────────────┬───────────────────────────┐\n    /// │ Base Tokens flow │ Debt Position │ Position Δ direction │ Action                    │\n    /// ├──────────────────┼───────────────┼──────────────────────┼───────────────────────────┤\n    /// │ Outflow          │ No            │ Decrease             │ Revert: Invalid direction │\n    /// │ Outflow          │ Yes           │ Increase             │ Revert: Invalid direction │\n    /// │ Outflow          │ No            │ Increase / Null      │ Minimum Δ Check           │\n    /// │ Outflow          │ Yes           │ Decrease / Null      │ Minimum Δ Check           │\n    /// │ Inflow / Null    │ No            │ Decrease             │ Maximum Δ Check           │\n    /// │ Inflow / Null    │ Yes           │ Increase             │ Maximum Δ Check           │\n    /// │ Inflow / Null    │ No            │ Increase / Null      │ No check (favorable move) │\n    /// │ Inflow / Null    │ Yes           │ Decrease / Null      │ No check (favorable move) │\n    /// └──────────────────┴───────────────┴──────────────────────┴───────────────────────────┘\n    ///\n    /// @param mgmtInstruction The management instruction.\n    /// @param acctInstruction The accounting instruction.\n    /// @return value The new position value.\n    /// @return change The signed position value delta.\n    function managePosition(Instruction calldata mgmtInstruction, Instruction calldata acctInstruction)\n        external\n        returns (uint256 value, int256 change);\n\n    /// @notice Manages a batch of positions.\n    /// @dev Convenience function to manage multiple positions in a single transaction.\n    /// @param mgmtInstructions The array of management instructions.\n    /// @param acctInstructions The array of accounting instructions.\n    /// @return values The new position values.\n    /// @return changes The changes in the position values.\n    function managePositionBatch(Instruction[] calldata mgmtInstructions, Instruction[] calldata acctInstructions)\n        external\n        returns (uint256[] memory values, int256[] memory changes);\n\n    /// @notice Manages flash loan funds.\n    /// @param instruction The flash loan management instruction.\n    /// @param token The loan token.\n    /// @param amount The loan amount.\n    function manageFlashLoan(Instruction calldata instruction, address token, uint256 amount) external;\n\n    /// @notice Harvests one or multiple positions.\n    /// @param instruction The harvest instruction.\n    /// @param swapOrders The array of swap orders to be executed after the harvest.\n    function harvest(Instruction calldata instruction, ISwapModule.SwapOrder[] calldata swapOrders) external;\n\n    /// @notice Performs a swap via the swap module.\n    /// @param order The swap order parameters.\n    function swap(ISwapModule.SwapOrder calldata order) external;\n\n    /// @notice Initiates a token transfer to the hub machine.\n    /// @param token The address of the token to transfer.\n    /// @param amount The amount of tokens to transfer.\n    /// @param data ABI-encoded parameters required for bridge-related transfers. Ignored when called from a hub caliber.\n    function transferToHubMachine(address token, uint256 amount, bytes calldata data) external;\n\n    /// @notice Instructs the Caliber to pull the specified token amount from the calling hub machine endpoint.\n    /// @param token The address of the token being transferred.\n    /// @param amount The amount of tokens being transferred.\n    function notifyIncomingTransfer(address token, uint256 amount) external;\n\n    /// @notice Sets the position accounting staleness threshold.\n    /// @param newPositionStaleThreshold The new threshold in seconds.\n    function setPositionStaleThreshold(uint256 newPositionStaleThreshold) external;\n\n    /// @notice Sets the duration of the allowedInstrRoot update timelock.\n    /// @param newTimelockDuration The new duration in seconds.\n    function setTimelockDuration(uint256 newTimelockDuration) external;\n\n    /// @notice Schedules an update of the root of the Merkle tree containing allowed instructions.\n    /// @dev The update will take effect after the timelock duration stored in the contract\n    /// at the time of the call.\n    /// @param newAllowedInstrRoot The new Merkle root.\n    function scheduleAllowedInstrRootUpdate(bytes32 newAllowedInstrRoot) external;\n\n    /// @notice Cancels a scheduled update of the root of the Merkle tree containing allowed instructions.\n    /// @dev Reverts if no pending update exists or if the timelock has expired.\n    function cancelAllowedInstrRootUpdate() external;\n\n    /// @notice Sets the max allowed value loss for position increases.\n    /// @param newMaxPositionIncreaseLossBps The new max value loss in basis points.\n    function setMaxPositionIncreaseLossBps(uint256 newMaxPositionIncreaseLossBps) external;\n\n    /// @notice Sets the max allowed value loss for position decreases.\n    /// @param newMaxPositionDecreaseLossBps The new max value loss in basis points.\n    function setMaxPositionDecreaseLossBps(uint256 newMaxPositionDecreaseLossBps) external;\n\n    /// @notice Sets the max allowed value loss for base token swaps.\n    /// @param newMaxSwapLossBps The new max value loss in basis points.\n    function setMaxSwapLossBps(uint256 newMaxSwapLossBps) external;\n\n    /// @notice Sets the duration of the cooldown period for swaps and position management.\n    /// @param newCooldownDuration The new duration in seconds.\n    function setCooldownDuration(uint256 newCooldownDuration) external;\n\n    /// @notice Adds a new guardian for the Merkle tree containing allowed instructions.\n    /// @param newGuardian The address of the new guardian.\n    function addInstrRootGuardian(address newGuardian) external;\n\n    /// @notice Removes a guardian for the Merkle tree containing allowed instructions.\n    /// @param guardian The address of the guardian to remove.\n    function removeInstrRootGuardian(address guardian) external;\n}\n"},{"file_path":"src/interfaces/IMachineShare.sol","source_code":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.28;\n\nimport {IERC20Metadata} from \"@openzeppelin/contracts/interfaces/IERC20Metadata.sol\";\n\ninterface IMachineShare is IERC20Metadata {\n    /// @notice Address of the authorized minter and burner.\n    function minter() external view returns (address);\n\n    /// @notice Mints new shares to the specified address.\n    /// @param to The recipient of the minted shares.\n    /// @param amount The amount of shares to mint.\n    function mint(address to, uint256 amount) external;\n\n    /// @notice Burns shares from the specified address.\n    /// @param from The owner of the shares to burn.\n    /// @param amount The amount of shares to burn.\n    function burn(address from, uint256 amount) external;\n}\n"},{"file_path":"src/interfaces/IOwnable2Step.sol","source_code":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.28;\n\ninterface IOwnable2Step {\n    function owner() external view returns (address);\n    function pendingOwner() external view returns (address);\n    function transferOwnership(address newOwner) external;\n    function acceptOwnership() external;\n}\n"},{"file_path":"src/interfaces/IPreDepositVault.sol","source_code":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.28;\n\ninterface IPreDepositVault {\n    event Deposit(\n        address indexed sender, address indexed receiver, uint256 assets, uint256 shares, bytes32 indexed referralKey\n    );\n    event MigrateToMachine(address indexed machine);\n    event Redeem(address indexed owner, address indexed receiver, uint256 assets, uint256 shares);\n    event RiskManagerChanged(address indexed oldRiskManager, address indexed newRiskManager);\n    event ShareLimitChanged(uint256 indexed oldShareLimit, uint256 indexed newShareLimit);\n    event UserWhitelistingChanged(address indexed user, bool indexed whitelisted);\n    event WhitelistModeChanged(bool indexed enabled);\n\n    struct PreDepositVaultInitParams {\n        uint256 initialShareLimit;\n        bool initialWhitelistMode;\n        address initialRiskManager;\n        address initialAuthority;\n    }\n\n    /// @notice Initializer of the contract.\n    /// @param params The initialization parameters.\n    /// @param _shareToken The address of the share token.\n    /// @param _depositToken The address of the deposit token.\n    /// @param _accountingToken The address of the accounting token.\n    function initialize(\n        PreDepositVaultInitParams calldata params,\n        address _shareToken,\n        address _depositToken,\n        address _accountingToken\n    ) external;\n\n    /// @notice True if the vault has migrated to a machine instance, false otherwise.\n    function migrated() external view returns (bool);\n\n    /// @notice Address of the machine, set during migration.\n    function machine() external view returns (address);\n\n    /// @notice Address of the risk manager.\n    function riskManager() external view returns (address);\n\n    /// @notice True if the vault is in whitelist mode, false otherwise.\n    function whitelistMode() external view returns (bool);\n\n    /// @notice User => Whitelisting status.\n    function isWhitelistedUser(address user) external view returns (bool);\n\n    /// @notice Address of the deposit token.\n    function depositToken() external view returns (address);\n\n    /// @notice Address of the accounting token.\n    function accountingToken() external view returns (address);\n\n    /// @notice Address of the share token.\n    function shareToken() external view returns (address);\n\n    /// @notice Share token supply limit that cannot be exceeded by new deposits.\n    function shareLimit() external view returns (uint256);\n\n    /// @notice Maximum amount of deposit tokens that can currently be deposited in the vault.\n    function maxDeposit() external view returns (uint256);\n\n    /// @notice Total amount of deposit tokens managed by the vault.\n    function totalAssets() external view returns (uint256);\n\n    /// @notice Amount of shares minted against a given amount of deposit tokens.\n    /// @param assets The amount of deposit tokens to be deposited.\n    function previewDeposit(uint256 assets) external view returns (uint256);\n\n    /// @notice Amount of deposit tokens that can be withdrawn against a given amount of shares.\n    /// @param shares The amount of shares to be redeemed.\n    function previewRedeem(uint256 shares) external view returns (uint256);\n\n    /// @notice Deposits a given amount of deposit tokens and mints shares to the receiver.\n    /// @param assets The amount of deposit tokens to be deposited.\n    /// @param receiver The receiver of the shares.\n    /// @param minShares The minimum amount of shares to be minted.\n    /// @param referralKey The optional identifier used to track a referral source.\n    /// @return shares The amount of shares minted.\n    function deposit(uint256 assets, address receiver, uint256 minShares, bytes32 referralKey)\n        external\n        returns (uint256);\n\n    /// @notice Burns exactly shares from caller and transfers the corresponding amount of deposit tokens to the receiver.\n    /// @param shares The amount of shares to be redeemed.\n    /// @param receiver The receiver of withdrawn deposit tokens.\n    /// @param minAssets The minimum amount of deposit tokens to be transferred.\n    /// @return assets The amount of deposit tokens transferred.\n    function redeem(uint256 shares, address receiver, uint256 minAssets) external returns (uint256);\n\n    /// @notice Migrates the pre-deposit vault to the machine.\n    function migrateToMachine() external;\n\n    /// @notice Sets the machine address to migrate to.\n    /// @param machine The address of the machine.\n    function setPendingMachine(address machine) external;\n\n    /// @notice Sets the new share token supply limit that cannot be exceeded by new deposits.\n    /// @param newShareLimit The new share limit.\n    function setShareLimit(uint256 newShareLimit) external;\n\n    /// @notice Sets the risk manager address.\n    /// @param newRiskManager The address of the new risk manager.\n    function setRiskManager(address newRiskManager) external;\n\n    /// @notice Whitelist or unwhitelist a list of users.\n    /// @param users The addresses of the users to update.\n    /// @param whitelisted True to whitelist the users, false to unwhitelist.\n    function setWhitelistedUsers(address[] calldata users, bool whitelisted) external;\n\n    /// @notice Sets the whitelist mode for the vault.\n    /// @dev In whitelist mode, only whitelisted users can deposit.\n    /// @param enabled True to enable whitelist mode, false to disable.\n    function setWhitelistMode(bool enabled) external;\n}\n"},{"file_path":"lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/utils/StorageSlot.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.1.0) (utils/StorageSlot.sol)\n// This file was procedurally generated from scripts/generate/templates/StorageSlot.js.\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Library for reading and writing primitive types to specific storage slots.\n *\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\n * This library helps with reading and writing to such slots without the need for inline assembly.\n *\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\n *\n * Example usage to set ERC-1967 implementation slot:\n * ```solidity\n * contract ERC1967 {\n *     // Define the slot. Alternatively, use the SlotDerivation library to derive the slot.\n *     bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n *\n *     function _getImplementation() internal view returns (address) {\n *         return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\n *     }\n *\n *     function _setImplementation(address newImplementation) internal {\n *         require(newImplementation.code.length > 0);\n *         StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\n *     }\n * }\n * ```\n *\n * TIP: Consider using this library along with {SlotDerivation}.\n */\nlibrary StorageSlot {\n    struct AddressSlot {\n        address value;\n    }\n\n    struct BooleanSlot {\n        bool value;\n    }\n\n    struct Bytes32Slot {\n        bytes32 value;\n    }\n\n    struct Uint256Slot {\n        uint256 value;\n    }\n\n    struct Int256Slot {\n        int256 value;\n    }\n\n    struct StringSlot {\n        string value;\n    }\n\n    struct BytesSlot {\n        bytes value;\n    }\n\n    /**\n     * @dev Returns an `AddressSlot` with member `value` located at `slot`.\n     */\n    function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\n        assembly (\"memory-safe\") {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns a `BooleanSlot` with member `value` located at `slot`.\n     */\n    function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\n        assembly (\"memory-safe\") {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns a `Bytes32Slot` with member `value` located at `slot`.\n     */\n    function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\n        assembly (\"memory-safe\") {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns a `Uint256Slot` with member `value` located at `slot`.\n     */\n    function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\n        assembly (\"memory-safe\") {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns a `Int256Slot` with member `value` located at `slot`.\n     */\n    function getInt256Slot(bytes32 slot) internal pure returns (Int256Slot storage r) {\n        assembly (\"memory-safe\") {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns a `StringSlot` with member `value` located at `slot`.\n     */\n    function getStringSlot(bytes32 slot) internal pure returns (StringSlot storage r) {\n        assembly (\"memory-safe\") {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns an `StringSlot` representation of the string storage pointer `store`.\n     */\n    function getStringSlot(string storage store) internal pure returns (StringSlot storage r) {\n        assembly (\"memory-safe\") {\n            r.slot := store.slot\n        }\n    }\n\n    /**\n     * @dev Returns a `BytesSlot` with member `value` located at `slot`.\n     */\n    function getBytesSlot(bytes32 slot) internal pure returns (BytesSlot storage r) {\n        assembly (\"memory-safe\") {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns an `BytesSlot` representation of the bytes storage pointer `store`.\n     */\n    function getBytesSlot(bytes storage store) internal pure returns (BytesSlot storage r) {\n        assembly (\"memory-safe\") {\n            r.slot := store.slot\n        }\n    }\n}\n"},{"file_path":"lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/interfaces/IERC20Metadata.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.4.0) (interfaces/IERC20Metadata.sol)\n\npragma solidity >=0.6.2;\n\nimport {IERC20Metadata} from \"../token/ERC20/extensions/IERC20Metadata.sol\";\n"},{"file_path":"src/interfaces/IMakinaContext.sol","source_code":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.28;\n\ninterface IMakinaContext {\n    /// @notice Address of the registry.\n    function registry() external view returns (address);\n}\n"},{"file_path":"lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/access/manager/IAuthority.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.4.0) (access/manager/IAuthority.sol)\n\npragma solidity >=0.4.16;\n\n/**\n * @dev Standard interface for permissioning originally defined in Dappsys.\n */\ninterface IAuthority {\n    /**\n     * @dev Returns true if the caller can invoke on a target the function identified by a function selector.\n     */\n    function canCall(address caller, address target, bytes4 selector) external view returns (bool allowed);\n}\n"},{"file_path":"src/utils/MakinaContext.sol","source_code":"// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.28;\n\nimport {IMakinaContext} from \"../interfaces/IMakinaContext.sol\";\n\nabstract contract MakinaContext is IMakinaContext {\n    /// @inheritdoc IMakinaContext\n    address public immutable override registry;\n\n    constructor(address _registry) {\n        registry = _registry;\n    }\n}\n"},{"file_path":"src/interfaces/ICreReceiver.sol","source_code":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.28;\n\nimport {IERC165} from \"@openzeppelin/contracts/interfaces/IERC165.sol\";\n\ninterface ICreReceiver is IERC165 {\n    function onReport(bytes calldata metadata, bytes calldata report) external;\n}\n"},{"file_path":"src/interfaces/IMakinaGovernable.sol","source_code":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.28;\n\ninterface IMakinaGovernable {\n    event AccountingAgentAdded(address indexed newAgent);\n    event AccountingAgentRemoved(address indexed agent);\n    event MechanicChanged(address indexed oldMechanic, address indexed newMechanic);\n    event RecoveryModeChanged(bool recoveryMode);\n    event RestrictedAccountingModeChanged(bool restrictedAccountingMode);\n    event RiskManagerChanged(address indexed oldRiskManager, address indexed newRiskManager);\n    event RiskManagerTimelockChanged(address indexed oldRiskManagerTimelock, address indexed newRiskManagerTimelock);\n    event SecurityCouncilChanged(address indexed oldSecurityCouncil, address indexed newSecurityCouncil);\n\n    /// @notice Initialization parameters.\n    /// @param initialMechanic The address of the initial mechanic.\n    /// @param initialSecurityCouncil The address of the initial security council.\n    /// @param initialRiskManager The address of the initial risk manager.\n    /// @param initialRiskManagerTimelock The address of the initial risk manager timelock.\n    /// @param initialAuthority The address of the initial authority.\n    /// @param initialRestrictedAccountingMode The initial value for the restricted accounting mode.\n    /// @param initialAccountingAgents The addresses of the initial accounting agents.\n    struct MakinaGovernableInitParams {\n        address initialMechanic;\n        address initialSecurityCouncil;\n        address initialRiskManager;\n        address initialRiskManagerTimelock;\n        address initialAuthority;\n        bool initialRestrictedAccountingMode;\n        address[] initialAccountingAgents;\n    }\n\n    /// @notice Address of the current operator (mechanic or security council).\n    function operator() external view returns (address);\n\n    /// @notice Address of the mechanic.\n    function mechanic() external view returns (address);\n\n    /// @notice Address of the security council.\n    function securityCouncil() external view returns (address);\n\n    /// @notice Address of the risk manager.\n    function riskManager() external view returns (address);\n\n    /// @notice Address of the risk manager timelock.\n    function riskManagerTimelock() external view returns (address);\n\n    /// @notice True if the contract is in recovery mode, false otherwise.\n    function recoveryMode() external view returns (bool);\n\n    /// @notice True if the contract is in restricted accounting mode, false otherwise.\n    function restrictedAccountingMode() external view returns (bool);\n\n    /// @notice User => Whether the user is an accounting agent\n    function isAccountingAgent(address user) external view returns (bool);\n\n    /// @notice User => Whether the user is authorized to perform accounting operations under current settings\n    function isAccountingAuthorized(address user) external view returns (bool);\n\n    /// @notice Sets a new mechanic.\n    /// @param newMechanic The address of the new mechanic.\n    function setMechanic(address newMechanic) external;\n\n    /// @notice Sets a new security council.\n    /// @param newSecurityCouncil The address of the new security council.\n    function setSecurityCouncil(address newSecurityCouncil) external;\n\n    /// @notice Sets a new risk manager.\n    /// @param newRiskManager The address of the new risk manager.\n    function setRiskManager(address newRiskManager) external;\n\n    /// @notice Sets a new risk manager timelock.\n    /// @param newRiskManagerTimelock The address of the new risk manager timelock.\n    function setRiskManagerTimelock(address newRiskManagerTimelock) external;\n\n    /// @notice Sets the recovery mode.\n    /// @param enabled True to enable recovery mode, false to disable it.\n    function setRecoveryMode(bool enabled) external;\n\n    /// @notice Sets the restricted accounting mode.\n    /// @param enabled True to enable restricted accounting mode, false to disable it.\n    function setRestrictedAccountingMode(bool enabled) external;\n\n    /// @notice Adds a new accounting agent.\n    /// @param newAgent The address of the new accounting agent.\n    function addAccountingAgent(address newAgent) external;\n\n    /// @notice Removes an accounting agent.\n    /// @param agent The address of the accounting agent to remove.\n    function removeAccountingAgent(address agent) external;\n}\n"},{"file_path":"lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/utils/Arrays.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.6.0) (utils/Arrays.sol)\n// This file was procedurally generated from scripts/generate/templates/Arrays.js.\n\npragma solidity ^0.8.24;\n\nimport {Comparators} from \"./Comparators.sol\";\nimport {SlotDerivation} from \"./SlotDerivation.sol\";\nimport {StorageSlot} from \"./StorageSlot.sol\";\nimport {Math} from \"./math/Math.sol\";\n\n/**\n * @dev Collection of functions related to array types.\n */\nlibrary Arrays {\n    using SlotDerivation for bytes32;\n    using StorageSlot for bytes32;\n\n    /**\n     * @dev Sort an array of uint256 (in memory) following the provided comparator function.\n     *\n     * This function does the sorting \"in place\", meaning that it overrides the input. The object is returned for\n     * convenience, but that returned value can be discarded safely if the caller has a memory pointer to the array.\n     *\n     * NOTE: this function's cost is `O(n · log(n))` in average and `O(n²)` in the worst case, with n the length of the\n     * array. Using it in view functions that are executed through `eth_call` is safe, but one should be very careful\n     * when executing this as part of a transaction. If the array being sorted is too large, the sort operation may\n     * consume more gas than is available in a block, leading to potential DoS.\n     *\n     * IMPORTANT: Consider memory side-effects when using custom comparator functions that access memory in an unsafe way.\n     */\n    function sort(\n        uint256[] memory array,\n        function(uint256, uint256) pure returns (bool) comp\n    ) internal pure returns (uint256[] memory) {\n        _quickSort(_begin(array), _end(array), comp);\n        return array;\n    }\n\n    /**\n     * @dev Variant of {sort} that sorts an array of uint256 in increasing order.\n     */\n    function sort(uint256[] memory array) internal pure returns (uint256[] memory) {\n        sort(array, Comparators.lt);\n        return array;\n    }\n\n    /**\n     * @dev Sort an array of address (in memory) following the provided comparator function.\n     *\n     * This function does the sorting \"in place\", meaning that it overrides the input. The object is returned for\n     * convenience, but that returned value can be discarded safely if the caller has a memory pointer to the array.\n     *\n     * NOTE: this function's cost is `O(n · log(n))` in average and `O(n²)` in the worst case, with n the length of the\n     * array. Using it in view functions that are executed through `eth_call` is safe, but one should be very careful\n     * when executing this as part of a transaction. If the array being sorted is too large, the sort operation may\n     * consume more gas than is available in a block, leading to potential DoS.\n     *\n     * IMPORTANT: Consider memory side-effects when using custom comparator functions that access memory in an unsafe way.\n     */\n    function sort(\n        address[] memory array,\n        function(address, address) pure returns (bool) comp\n    ) internal pure returns (address[] memory) {\n        sort(_castToUint256Array(array), _castToUint256Comp(comp));\n        return array;\n    }\n\n    /**\n     * @dev Variant of {sort} that sorts an array of address in increasing order.\n     */\n    function sort(address[] memory array) internal pure returns (address[] memory) {\n        sort(_castToUint256Array(array), Comparators.lt);\n        return array;\n    }\n\n    /**\n     * @dev Sort an array of bytes32 (in memory) following the provided comparator function.\n     *\n     * This function does the sorting \"in place\", meaning that it overrides the input. The object is returned for\n     * convenience, but that returned value can be discarded safely if the caller has a memory pointer to the array.\n     *\n     * NOTE: this function's cost is `O(n · log(n))` in average and `O(n²)` in the worst case, with n the length of the\n     * array. Using it in view functions that are executed through `eth_call` is safe, but one should be very careful\n     * when executing this as part of a transaction. If the array being sorted is too large, the sort operation may\n     * consume more gas than is available in a block, leading to potential DoS.\n     *\n     * IMPORTANT: Consider memory side-effects when using custom comparator functions that access memory in an unsafe way.\n     */\n    function sort(\n        bytes32[] memory array,\n        function(bytes32, bytes32) pure returns (bool) comp\n    ) internal pure returns (bytes32[] memory) {\n        sort(_castToUint256Array(array), _castToUint256Comp(comp));\n        return array;\n    }\n\n    /**\n     * @dev Variant of {sort} that sorts an array of bytes32 in increasing order.\n     */\n    function sort(bytes32[] memory array) internal pure returns (bytes32[] memory) {\n        sort(_castToUint256Array(array), Comparators.lt);\n        return array;\n    }\n\n    /**\n     * @dev Performs a quick sort of a segment of memory. The segment sorted starts at `begin` (inclusive), and stops\n     * at end (exclusive). Sorting follows the `comp` comparator.\n     *\n     * Invariant: `begin <= end`. This is the case when initially called by {sort} and is preserved in subcalls.\n     *\n     * IMPORTANT: Memory locations between `begin` and `end` are not validated/zeroed. This function should\n     * be used only if the limits are within a memory array.\n     */\n    function _quickSort(uint256 begin, uint256 end, function(uint256, uint256) pure returns (bool) comp) private pure {\n        unchecked {\n            if (end - begin < 0x40) return;\n\n            // Use first element as pivot\n            uint256 pivot = _mload(begin);\n            // Position where the pivot should be at the end of the loop\n            uint256 pos = begin;\n\n            for (uint256 it = begin + 0x20; it < end; it += 0x20) {\n                if (comp(_mload(it), pivot)) {\n                    // If the value stored at the iterator's position comes before the pivot, we increment the\n                    // position of the pivot and move the value there.\n                    pos += 0x20;\n                    _swap(pos, it);\n                }\n            }\n\n            _swap(begin, pos); // Swap pivot into place\n            _quickSort(begin, pos, comp); // Sort the left side of the pivot\n            _quickSort(pos + 0x20, end, comp); // Sort the right side of the pivot\n        }\n    }\n\n    /**\n     * @dev Pointer to the memory location of the first element of `array`.\n     */\n    function _begin(uint256[] memory array) private pure returns (uint256 ptr) {\n        assembly (\"memory-safe\") {\n            ptr := add(array, 0x20)\n        }\n    }\n\n    /**\n     * @dev Pointer to the memory location of the first memory word (32bytes) after `array`. This is the memory word\n     * that comes just after the last element of the array.\n     */\n    function _end(uint256[] memory array) private pure returns (uint256 ptr) {\n        unchecked {\n            return _begin(array) + array.length * 0x20;\n        }\n    }\n\n    /**\n     * @dev Load memory word (as a uint256) at location `ptr`.\n     */\n    function _mload(uint256 ptr) private pure returns (uint256 value) {\n        assembly {\n            value := mload(ptr)\n        }\n    }\n\n    /**\n     * @dev Swaps the elements memory location `ptr1` and `ptr2`.\n     */\n    function _swap(uint256 ptr1, uint256 ptr2) private pure {\n        assembly {\n            let value1 := mload(ptr1)\n            let value2 := mload(ptr2)\n            mstore(ptr1, value2)\n            mstore(ptr2, value1)\n        }\n    }\n\n    /// @dev Helper: low level cast address memory array to uint256 memory array\n    function _castToUint256Array(address[] memory input) private pure returns (uint256[] memory output) {\n        assembly {\n            output := input\n        }\n    }\n\n    /// @dev Helper: low level cast bytes32 memory array to uint256 memory array\n    function _castToUint256Array(bytes32[] memory input) private pure returns (uint256[] memory output) {\n        assembly {\n            output := input\n        }\n    }\n\n    /// @dev Helper: low level cast address comp function to uint256 comp function\n    function _castToUint256Comp(\n        function(address, address) pure returns (bool) input\n    ) private pure returns (function(uint256, uint256) pure returns (bool) output) {\n        assembly {\n            output := input\n        }\n    }\n\n    /// @dev Helper: low level cast bytes32 comp function to uint256 comp function\n    function _castToUint256Comp(\n        function(bytes32, bytes32) pure returns (bool) input\n    ) private pure returns (function(uint256, uint256) pure returns (bool) output) {\n        assembly {\n            output := input\n        }\n    }\n\n    /**\n     * @dev Searches a sorted `array` and returns the first index that contains\n     * a value greater or equal to `element`. If no such index exists (i.e. all\n     * values in the array are strictly less than `element`), the array length is\n     * returned. Time complexity O(log n).\n     *\n     * NOTE: The `array` is expected to be sorted in ascending order, and to\n     * contain no repeated elements.\n     *\n     * IMPORTANT: Deprecated. This implementation behaves as {lowerBound} but lacks\n     * support for repeated elements in the array. The {lowerBound} function should\n     * be used instead.\n     */\n    function findUpperBound(uint256[] storage array, uint256 element) internal view returns (uint256) {\n        uint256 low = 0;\n        uint256 high = array.length;\n\n        if (high == 0) {\n            return 0;\n        }\n\n        while (low < high) {\n            uint256 mid = Math.average(low, high);\n\n            // Note that mid will always be strictly less than high (i.e. it will be a valid array index)\n            // because Math.average rounds towards zero (it does integer division with truncation).\n            if (unsafeAccess(array, mid).value > element) {\n                high = mid;\n            } else {\n                low = mid + 1;\n            }\n        }\n\n        // At this point `low` is the exclusive upper bound. We will return the inclusive upper bound.\n        if (low > 0 && unsafeAccess(array, low - 1).value == element) {\n            return low - 1;\n        } else {\n            return low;\n        }\n    }\n\n    /**\n     * @dev Searches an `array` sorted in ascending order and returns the first\n     * index that contains a value greater or equal than `element`. If no such index\n     * exists (i.e. all values in the array are strictly less than `element`), the array\n     * length is returned. Time complexity O(log n).\n     *\n     * See C++'s https://en.cppreference.com/w/cpp/algorithm/lower_bound[lower_bound].\n     */\n    function lowerBound(uint256[] storage array, uint256 element) internal view returns (uint256) {\n        uint256 low = 0;\n        uint256 high = array.length;\n\n        if (high == 0) {\n            return 0;\n        }\n\n        while (low < high) {\n            uint256 mid = Math.average(low, high);\n\n            // Note that mid will always be strictly less than high (i.e. it will be a valid array index)\n            // because Math.average rounds towards zero (it does integer division with truncation).\n            if (unsafeAccess(array, mid).value < element) {\n                // this cannot overflow because mid < high\n                unchecked {\n                    low = mid + 1;\n                }\n            } else {\n                high = mid;\n            }\n        }\n\n        return low;\n    }\n\n    /**\n     * @dev Searches an `array` sorted in ascending order and returns the first\n     * index that contains a value strictly greater than `element`. If no such index\n     * exists (i.e. all values in the array are strictly less than `element`), the array\n     * length is returned. Time complexity O(log n).\n     *\n     * See C++'s https://en.cppreference.com/w/cpp/algorithm/upper_bound[upper_bound].\n     */\n    function upperBound(uint256[] storage array, uint256 element) internal view returns (uint256) {\n        uint256 low = 0;\n        uint256 high = array.length;\n\n        if (high == 0) {\n            return 0;\n        }\n\n        while (low < high) {\n            uint256 mid = Math.average(low, high);\n\n            // Note that mid will always be strictly less than high (i.e. it will be a valid array index)\n            // because Math.average rounds towards zero (it does integer division with truncation).\n            if (unsafeAccess(array, mid).value > element) {\n                high = mid;\n            } else {\n                // this cannot overflow because mid < high\n                unchecked {\n                    low = mid + 1;\n                }\n            }\n        }\n\n        return low;\n    }\n\n    /**\n     * @dev Same as {lowerBound}, but with an array in memory.\n     */\n    function lowerBoundMemory(uint256[] memory array, uint256 element) internal pure returns (uint256) {\n        uint256 low = 0;\n        uint256 high = array.length;\n\n        if (high == 0) {\n            return 0;\n        }\n\n        while (low < high) {\n            uint256 mid = Math.average(low, high);\n\n            // Note that mid will always be strictly less than high (i.e. it will be a valid array index)\n            // because Math.average rounds towards zero (it does integer division with truncation).\n            if (unsafeMemoryAccess(array, mid) < element) {\n                // this cannot overflow because mid < high\n                unchecked {\n                    low = mid + 1;\n                }\n            } else {\n                high = mid;\n            }\n        }\n\n        return low;\n    }\n\n    /**\n     * @dev Same as {upperBound}, but with an array in memory.\n     */\n    function upperBoundMemory(uint256[] memory array, uint256 element) internal pure returns (uint256) {\n        uint256 low = 0;\n        uint256 high = array.length;\n\n        if (high == 0) {\n            return 0;\n        }\n\n        while (low < high) {\n            uint256 mid = Math.average(low, high);\n\n            // Note that mid will always be strictly less than high (i.e. it will be a valid array index)\n            // because Math.average rounds towards zero (it does integer division with truncation).\n            if (unsafeMemoryAccess(array, mid) > element) {\n                high = mid;\n            } else {\n                // this cannot overflow because mid < high\n                unchecked {\n                    low = mid + 1;\n                }\n            }\n        }\n\n        return low;\n    }\n\n    /**\n     * @dev Copies the content of `array`, from `start` (included) to the end of `array` into a new address array in\n     * memory.\n     *\n     * NOTE: replicates the behavior of https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice[Javascript's `Array.slice`]\n     */\n    function slice(address[] memory array, uint256 start) internal pure returns (address[] memory) {\n        return slice(array, start, array.length);\n    }\n\n    /**\n     * @dev Copies the content of `array`, from `start` (included) to `end` (excluded) into a new address array in\n     * memory. The `end` argument is truncated to the length of the `array`.\n     *\n     * NOTE: replicates the behavior of https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice[Javascript's `Array.slice`]\n     */\n    function slice(address[] memory array, uint256 start, uint256 end) internal pure returns (address[] memory) {\n        // sanitize\n        end = Math.min(end, array.length);\n        start = Math.min(start, end);\n\n        // allocate and copy\n        address[] memory result = new address[](end - start);\n        assembly (\"memory-safe\") {\n            mcopy(add(result, 0x20), add(add(array, 0x20), mul(start, 0x20)), mul(sub(end, start), 0x20))\n        }\n\n        return result;\n    }\n\n    /**\n     * @dev Copies the content of `array`, from `start` (included) to the end of `array` into a new bytes32 array in\n     * memory.\n     *\n     * NOTE: replicates the behavior of https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice[Javascript's `Array.slice`]\n     */\n    function slice(bytes32[] memory array, uint256 start) internal pure returns (bytes32[] memory) {\n        return slice(array, start, array.length);\n    }\n\n    /**\n     * @dev Copies the content of `array`, from `start` (included) to `end` (excluded) into a new bytes32 array in\n     * memory. The `end` argument is truncated to the length of the `array`.\n     *\n     * NOTE: replicates the behavior of https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice[Javascript's `Array.slice`]\n     */\n    function slice(bytes32[] memory array, uint256 start, uint256 end) internal pure returns (bytes32[] memory) {\n        // sanitize\n        end = Math.min(end, array.length);\n        start = Math.min(start, end);\n\n        // allocate and copy\n        bytes32[] memory result = new bytes32[](end - start);\n        assembly (\"memory-safe\") {\n            mcopy(add(result, 0x20), add(add(array, 0x20), mul(start, 0x20)), mul(sub(end, start), 0x20))\n        }\n\n        return result;\n    }\n\n    /**\n     * @dev Copies the content of `array`, from `start` (included) to the end of `array` into a new uint256 array in\n     * memory.\n     *\n     * NOTE: replicates the behavior of https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice[Javascript's `Array.slice`]\n     */\n    function slice(uint256[] memory array, uint256 start) internal pure returns (uint256[] memory) {\n        return slice(array, start, array.length);\n    }\n\n    /**\n     * @dev Copies the content of `array`, from `start` (included) to `end` (excluded) into a new uint256 array in\n     * memory. The `end` argument is truncated to the length of the `array`.\n     *\n     * NOTE: replicates the behavior of https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice[Javascript's `Array.slice`]\n     */\n    function slice(uint256[] memory array, uint256 start, uint256 end) internal pure returns (uint256[] memory) {\n        // sanitize\n        end = Math.min(end, array.length);\n        start = Math.min(start, end);\n\n        // allocate and copy\n        uint256[] memory result = new uint256[](end - start);\n        assembly (\"memory-safe\") {\n            mcopy(add(result, 0x20), add(add(array, 0x20), mul(start, 0x20)), mul(sub(end, start), 0x20))\n        }\n\n        return result;\n    }\n\n    /**\n     * @dev Moves the content of `array`, from `start` (included) to the end of `array` to the start of that array,\n     * and shrinks the array length accordingly, effectively overwriting the array with array[start:].\n     *\n     * NOTE: This function modifies the provided array in place. If you need to preserve the original array, use {slice} instead.\n     */\n    function splice(address[] memory array, uint256 start) internal pure returns (address[] memory) {\n        return splice(array, start, array.length);\n    }\n\n    /**\n     * @dev Moves the content of `array`, from `start` (included) to `end` (excluded) to the start of that array,\n     * and shrinks the array length accordingly, effectively overwriting the array with array[start:end]. The\n     * `end` argument is truncated to the length of the `array`.\n     *\n     * NOTE: This function modifies the provided array in place. If you need to preserve the original array, use {slice} instead.\n     */\n    function splice(address[] memory array, uint256 start, uint256 end) internal pure returns (address[] memory) {\n        // sanitize\n        end = Math.min(end, array.length);\n        start = Math.min(start, end);\n\n        // move and resize\n        assembly (\"memory-safe\") {\n            mcopy(add(array, 0x20), add(add(array, 0x20), mul(start, 0x20)), mul(sub(end, start), 0x20))\n            mstore(array, sub(end, start))\n        }\n\n        return array;\n    }\n\n    /**\n     * @dev Replaces elements in `array` starting at `pos` with all elements from `replacement`.\n     *\n     * Parameters are clamped to valid ranges (e.g. `pos` is clamped to `[0, array.length]`).\n     * If `pos >= array.length`, no replacement occurs and the array is returned unchanged.\n     *\n     * NOTE: This function modifies the provided array in place.\n     */\n    function replace(\n        address[] memory array,\n        uint256 pos,\n        address[] memory replacement\n    ) internal pure returns (address[] memory) {\n        return replace(array, pos, replacement, 0, replacement.length);\n    }\n\n    /**\n     * @dev Replaces elements in `array` starting at `pos` with elements from `replacement` starting at `offset`.\n     * Copies at most `length` elements from `replacement` to `array`.\n     *\n     * Parameters are clamped to valid ranges (i.e. `pos` is clamped to `[0, array.length]`, `offset` is\n     * clamped to `[0, replacement.length]`, and `length` is clamped to `min(length, replacement.length - offset,\n     * array.length - pos)`). If `pos >= array.length` or `offset >= replacement.length`, no replacement occurs\n     * and the array is returned unchanged.\n     *\n     * NOTE: This function modifies the provided array in place.\n     */\n    function replace(\n        address[] memory array,\n        uint256 pos,\n        address[] memory replacement,\n        uint256 offset,\n        uint256 length\n    ) internal pure returns (address[] memory) {\n        // sanitize\n        pos = Math.min(pos, array.length);\n        offset = Math.min(offset, replacement.length);\n        length = Math.min(length, Math.min(replacement.length - offset, array.length - pos));\n\n        // replace\n        assembly (\"memory-safe\") {\n            mcopy(\n                add(add(array, 0x20), mul(pos, 0x20)),\n                add(add(replacement, 0x20), mul(offset, 0x20)),\n                mul(length, 0x20)\n            )\n        }\n\n        return array;\n    }\n\n    /**\n     * @dev Moves the content of `array`, from `start` (included) to the end of `array` to the start of that array,\n     * and shrinks the array length accordingly, effectively overwriting the array with array[start:].\n     *\n     * NOTE: This function modifies the provided array in place. If you need to preserve the original array, use {slice} instead.\n     */\n    function splice(bytes32[] memory array, uint256 start) internal pure returns (bytes32[] memory) {\n        return splice(array, start, array.length);\n    }\n\n    /**\n     * @dev Moves the content of `array`, from `start` (included) to `end` (excluded) to the start of that array,\n     * and shrinks the array length accordingly, effectively overwriting the array with array[start:end]. The\n     * `end` argument is truncated to the length of the `array`.\n     *\n     * NOTE: This function modifies the provided array in place. If you need to preserve the original array, use {slice} instead.\n     */\n    function splice(bytes32[] memory array, uint256 start, uint256 end) internal pure returns (bytes32[] memory) {\n        // sanitize\n        end = Math.min(end, array.length);\n        start = Math.min(start, end);\n\n        // move and resize\n        assembly (\"memory-safe\") {\n            mcopy(add(array, 0x20), add(add(array, 0x20), mul(start, 0x20)), mul(sub(end, start), 0x20))\n            mstore(array, sub(end, start))\n        }\n\n        return array;\n    }\n\n    /**\n     * @dev Replaces elements in `array` starting at `pos` with all elements from `replacement`.\n     *\n     * Parameters are clamped to valid ranges (e.g. `pos` is clamped to `[0, array.length]`).\n     * If `pos >= array.length`, no replacement occurs and the array is returned unchanged.\n     *\n     * NOTE: This function modifies the provided array in place.\n     */\n    function replace(\n        bytes32[] memory array,\n        uint256 pos,\n        bytes32[] memory replacement\n    ) internal pure returns (bytes32[] memory) {\n        return replace(array, pos, replacement, 0, replacement.length);\n    }\n\n    /**\n     * @dev Replaces elements in `array` starting at `pos` with elements from `replacement` starting at `offset`.\n     * Copies at most `length` elements from `replacement` to `array`.\n     *\n     * Parameters are clamped to valid ranges (i.e. `pos` is clamped to `[0, array.length]`, `offset` is\n     * clamped to `[0, replacement.length]`, and `length` is clamped to `min(length, replacement.length - offset,\n     * array.length - pos)`). If `pos >= array.length` or `offset >= replacement.length`, no replacement occurs\n     * and the array is returned unchanged.\n     *\n     * NOTE: This function modifies the provided array in place.\n     */\n    function replace(\n        bytes32[] memory array,\n        uint256 pos,\n        bytes32[] memory replacement,\n        uint256 offset,\n        uint256 length\n    ) internal pure returns (bytes32[] memory) {\n        // sanitize\n        pos = Math.min(pos, array.length);\n        offset = Math.min(offset, replacement.length);\n        length = Math.min(length, Math.min(replacement.length - offset, array.length - pos));\n\n        // replace\n        assembly (\"memory-safe\") {\n            mcopy(\n                add(add(array, 0x20), mul(pos, 0x20)),\n                add(add(replacement, 0x20), mul(offset, 0x20)),\n                mul(length, 0x20)\n            )\n        }\n\n        return array;\n    }\n\n    /**\n     * @dev Moves the content of `array`, from `start` (included) to the end of `array` to the start of that array,\n     * and shrinks the array length accordingly, effectively overwriting the array with array[start:].\n     *\n     * NOTE: This function modifies the provided array in place. If you need to preserve the original array, use {slice} instead.\n     */\n    function splice(uint256[] memory array, uint256 start) internal pure returns (uint256[] memory) {\n        return splice(array, start, array.length);\n    }\n\n    /**\n     * @dev Moves the content of `array`, from `start` (included) to `end` (excluded) to the start of that array,\n     * and shrinks the array length accordingly, effectively overwriting the array with array[start:end]. The\n     * `end` argument is truncated to the length of the `array`.\n     *\n     * NOTE: This function modifies the provided array in place. If you need to preserve the original array, use {slice} instead.\n     */\n    function splice(uint256[] memory array, uint256 start, uint256 end) internal pure returns (uint256[] memory) {\n        // sanitize\n        end = Math.min(end, array.length);\n        start = Math.min(start, end);\n\n        // move and resize\n        assembly (\"memory-safe\") {\n            mcopy(add(array, 0x20), add(add(array, 0x20), mul(start, 0x20)), mul(sub(end, start), 0x20))\n            mstore(array, sub(end, start))\n        }\n\n        return array;\n    }\n\n    /**\n     * @dev Replaces elements in `array` starting at `pos` with all elements from `replacement`.\n     *\n     * Parameters are clamped to valid ranges (e.g. `pos` is clamped to `[0, array.length]`).\n     * If `pos >= array.length`, no replacement occurs and the array is returned unchanged.\n     *\n     * NOTE: This function modifies the provided array in place.\n     */\n    function replace(\n        uint256[] memory array,\n        uint256 pos,\n        uint256[] memory replacement\n    ) internal pure returns (uint256[] memory) {\n        return replace(array, pos, replacement, 0, replacement.length);\n    }\n\n    /**\n     * @dev Replaces elements in `array` starting at `pos` with elements from `replacement` starting at `offset`.\n     * Copies at most `length` elements from `replacement` to `array`.\n     *\n     * Parameters are clamped to valid ranges (i.e. `pos` is clamped to `[0, array.length]`, `offset` is\n     * clamped to `[0, replacement.length]`, and `length` is clamped to `min(length, replacement.length - offset,\n     * array.length - pos)`). If `pos >= array.length` or `offset >= replacement.length`, no replacement occurs\n     * and the array is returned unchanged.\n     *\n     * NOTE: This function modifies the provided array in place.\n     */\n    function replace(\n        uint256[] memory array,\n        uint256 pos,\n        uint256[] memory replacement,\n        uint256 offset,\n        uint256 length\n    ) internal pure returns (uint256[] memory) {\n        // sanitize\n        pos = Math.min(pos, array.length);\n        offset = Math.min(offset, replacement.length);\n        length = Math.min(length, Math.min(replacement.length - offset, array.length - pos));\n\n        // replace\n        assembly (\"memory-safe\") {\n            mcopy(\n                add(add(array, 0x20), mul(pos, 0x20)),\n                add(add(replacement, 0x20), mul(offset, 0x20)),\n                mul(length, 0x20)\n            )\n        }\n\n        return array;\n    }\n\n    /**\n     * @dev Access an array in an \"unsafe\" way. Skips solidity \"index-out-of-range\" check.\n     *\n     * WARNING: Only use if you are certain `pos` is lower than the array length.\n     */\n    function unsafeAccess(address[] storage arr, uint256 pos) internal pure returns (StorageSlot.AddressSlot storage) {\n        bytes32 slot;\n        assembly (\"memory-safe\") {\n            slot := arr.slot\n        }\n        return slot.deriveArray().offset(pos).getAddressSlot();\n    }\n\n    /**\n     * @dev Access an array in an \"unsafe\" way. Skips solidity \"index-out-of-range\" check.\n     *\n     * WARNING: Only use if you are certain `pos` is lower than the array length.\n     */\n    function unsafeAccess(bytes32[] storage arr, uint256 pos) internal pure returns (StorageSlot.Bytes32Slot storage) {\n        bytes32 slot;\n        assembly (\"memory-safe\") {\n            slot := arr.slot\n        }\n        return slot.deriveArray().offset(pos).getBytes32Slot();\n    }\n\n    /**\n     * @dev Access an array in an \"unsafe\" way. Skips solidity \"index-out-of-range\" check.\n     *\n     * WARNING: Only use if you are certain `pos` is lower than the array length.\n     */\n    function unsafeAccess(uint256[] storage arr, uint256 pos) internal pure returns (StorageSlot.Uint256Slot storage) {\n        bytes32 slot;\n        assembly (\"memory-safe\") {\n            slot := arr.slot\n        }\n        return slot.deriveArray().offset(pos).getUint256Slot();\n    }\n\n    /**\n     * @dev Access an array in an \"unsafe\" way. Skips solidity \"index-out-of-range\" check.\n     *\n     * WARNING: Only use if you are certain `pos` is lower than the array length.\n     */\n    function unsafeAccess(bytes[] storage arr, uint256 pos) internal pure returns (StorageSlot.BytesSlot storage) {\n        bytes32 slot;\n        assembly (\"memory-safe\") {\n            slot := arr.slot\n        }\n        return slot.deriveArray().offset(pos).getBytesSlot();\n    }\n\n    /**\n     * @dev Access an array in an \"unsafe\" way. Skips solidity \"index-out-of-range\" check.\n     *\n     * WARNING: Only use if you are certain `pos` is lower than the array length.\n     */\n    function unsafeAccess(string[] storage arr, uint256 pos) internal pure returns (StorageSlot.StringSlot storage) {\n        bytes32 slot;\n        assembly (\"memory-safe\") {\n            slot := arr.slot\n        }\n        return slot.deriveArray().offset(pos).getStringSlot();\n    }\n\n    /**\n     * @dev Access an array in an \"unsafe\" way. Skips solidity \"index-out-of-range\" check.\n     *\n     * WARNING: Only use if you are certain `pos` is lower than the array length.\n     */\n    function unsafeMemoryAccess(address[] memory arr, uint256 pos) internal pure returns (address res) {\n        assembly {\n            res := mload(add(add(arr, 0x20), mul(pos, 0x20)))\n        }\n    }\n\n    /**\n     * @dev Access an array in an \"unsafe\" way. Skips solidity \"index-out-of-range\" check.\n     *\n     * WARNING: Only use if you are certain `pos` is lower than the array length.\n     */\n    function unsafeMemoryAccess(bytes32[] memory arr, uint256 pos) internal pure returns (bytes32 res) {\n        assembly {\n            res := mload(add(add(arr, 0x20), mul(pos, 0x20)))\n        }\n    }\n\n    /**\n     * @dev Access an array in an \"unsafe\" way. Skips solidity \"index-out-of-range\" check.\n     *\n     * WARNING: Only use if you are certain `pos` is lower than the array length.\n     */\n    function unsafeMemoryAccess(uint256[] memory arr, uint256 pos) internal pure returns (uint256 res) {\n        assembly {\n            res := mload(add(add(arr, 0x20), mul(pos, 0x20)))\n        }\n    }\n\n    /**\n     * @dev Access an array in an \"unsafe\" way. Skips solidity \"index-out-of-range\" check.\n     *\n     * WARNING: Only use if you are certain `pos` is lower than the array length.\n     */\n    function unsafeMemoryAccess(bytes[] memory arr, uint256 pos) internal pure returns (bytes memory res) {\n        assembly {\n            res := mload(add(add(arr, 0x20), mul(pos, 0x20)))\n        }\n    }\n\n    /**\n     * @dev Access an array in an \"unsafe\" way. Skips solidity \"index-out-of-range\" check.\n     *\n     * WARNING: Only use if you are certain `pos` is lower than the array length.\n     */\n    function unsafeMemoryAccess(string[] memory arr, uint256 pos) internal pure returns (string memory res) {\n        assembly {\n            res := mload(add(add(arr, 0x20), mul(pos, 0x20)))\n        }\n    }\n\n    /**\n     * @dev Helper to set the length of a dynamic array. Directly writing to `.length` is forbidden.\n     *\n     * WARNING: this does not clear elements if length is reduced, or initialize elements if length is increased.\n     */\n    function unsafeSetLength(address[] storage array, uint256 len) internal {\n        assembly (\"memory-safe\") {\n            sstore(array.slot, len)\n        }\n    }\n\n    /**\n     * @dev Helper to set the length of a dynamic array. Directly writing to `.length` is forbidden.\n     *\n     * WARNING: this does not clear elements if length is reduced, or initialize elements if length is increased.\n     */\n    function unsafeSetLength(bytes32[] storage array, uint256 len) internal {\n        assembly (\"memory-safe\") {\n            sstore(array.slot, len)\n        }\n    }\n\n    /**\n     * @dev Helper to set the length of a dynamic array. Directly writing to `.length` is forbidden.\n     *\n     * WARNING: this does not clear elements if length is reduced, or initialize elements if length is increased.\n     */\n    function unsafeSetLength(uint256[] storage array, uint256 len) internal {\n        assembly (\"memory-safe\") {\n            sstore(array.slot, len)\n        }\n    }\n\n    /**\n     * @dev Helper to set the length of a dynamic array. Directly writing to `.length` is forbidden.\n     *\n     * WARNING: this does not clear elements if length is reduced, or initialize elements if length is increased.\n     */\n    function unsafeSetLength(bytes[] storage array, uint256 len) internal {\n        assembly (\"memory-safe\") {\n            sstore(array.slot, len)\n        }\n    }\n\n    /**\n     * @dev Helper to set the length of a dynamic array. Directly writing to `.length` is forbidden.\n     *\n     * WARNING: this does not clear elements if length is reduced, or initialize elements if length is increased.\n     */\n    function unsafeSetLength(string[] storage array, uint256 len) internal {\n        assembly (\"memory-safe\") {\n            sstore(array.slot, len)\n        }\n    }\n}\n"},{"file_path":"src/bridge/controller/BridgeController.sol","source_code":"// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.28;\n\nimport {IERC20} from \"@openzeppelin/contracts/interfaces/IERC20.sol\";\nimport {Math} from \"@openzeppelin/contracts/utils/math/Math.sol\";\nimport {SafeERC20} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\nimport {ICoreRegistry} from \"../../interfaces/ICoreRegistry.sol\";\nimport {IBridgeAdapter} from \"../../interfaces/IBridgeAdapter.sol\";\nimport {IBridgeController} from \"../../interfaces/IBridgeController.sol\";\nimport {ITokenRegistry} from \"../../interfaces/ITokenRegistry.sol\";\nimport {Errors} from \"../../libraries/Errors.sol\";\nimport {MakinaContext} from \"../../utils/MakinaContext.sol\";\n\nabstract contract BridgeController is MakinaContext, IBridgeController {\n    using Math for uint256;\n    using SafeERC20 for IERC20;\n\n    /// @dev Full scale value in basis points\n    uint256 private constant MAX_BPS = 10_000;\n\n    /// @custom:storage-location erc7201:makina.storage.BridgeController\n    struct BridgeControllerStorage {\n        uint16[] _supportedBridges;\n        mapping(uint16 bridgeId => address adapter) _bridgeAdapters;\n        mapping(uint16 bridgeId => uint256 maxBridgeLossBps) _maxBridgeLossBps;\n        mapping(uint16 bridgeId => bool isOutTransferEnabled) _isOutTransferEnabled;\n        mapping(address addr => bool isAdapter) _isBridgeAdapter;\n    }\n\n    // keccak256(abi.encode(uint256(keccak256(\"makina.storage.BridgeController\")) - 1)) & ~bytes32(uint256(0xff))\n    bytes32 private constant BridgeControllerStorageLocation =\n        0x7363d524082cdf545f1ac33985598b84d2470b8b4fbcc6cb47698cc1b2a03500;\n\n    function _getBridgeControllerStorage() internal pure returns (BridgeControllerStorage storage $) {\n        assembly {\n            $.slot := BridgeControllerStorageLocation\n        }\n    }\n\n    modifier onlyFactory() {\n        if (msg.sender != ICoreRegistry(registry).coreFactory()) {\n            revert Errors.NotFactory();\n        }\n        _;\n    }\n\n    /// @inheritdoc IBridgeController\n    function isBridgeSupported(uint16 bridgeId) external view override returns (bool) {\n        return _getBridgeControllerStorage()._bridgeAdapters[bridgeId] != address(0);\n    }\n\n    /// @inheritdoc IBridgeController\n    function isOutTransferEnabled(uint16 bridgeId) external view override returns (bool) {\n        return _getBridgeControllerStorage()._isOutTransferEnabled[bridgeId];\n    }\n\n    /// @inheritdoc IBridgeController\n    function getBridgeAdapter(uint16 bridgeId) public view override returns (address) {\n        address adapter = _getBridgeControllerStorage()._bridgeAdapters[bridgeId];\n        if (adapter == address(0)) {\n            revert Errors.InvalidBridgeId();\n        }\n        return adapter;\n    }\n\n    /// @inheritdoc IBridgeController\n    function getMaxBridgeLossBps(uint16 bridgeId) external view override returns (uint256) {\n        BridgeControllerStorage storage $ = _getBridgeControllerStorage();\n        if ($._bridgeAdapters[bridgeId] == address(0)) {\n            revert Errors.InvalidBridgeId();\n        }\n        return $._maxBridgeLossBps[bridgeId];\n    }\n\n    /// @inheritdoc IBridgeController\n    function setBridgeAdapter(uint16 bridgeId, address bridgeAdapter, uint256 initialMaxBridgeLossBps)\n        external\n        override\n        onlyFactory\n    {\n        BridgeControllerStorage storage $ = _getBridgeControllerStorage();\n\n        if ($._bridgeAdapters[bridgeId] != address(0)) {\n            revert Errors.BridgeAdapterAlreadySet();\n        }\n        if (bridgeAdapter == address(0)) {\n            revert Errors.ZeroBridgeAdapterAddress();\n        }\n\n        $._bridgeAdapters[bridgeId] = bridgeAdapter;\n        $._maxBridgeLossBps[bridgeId] = initialMaxBridgeLossBps;\n        $._isOutTransferEnabled[bridgeId] = true;\n        $._isBridgeAdapter[bridgeAdapter] = true;\n        $._supportedBridges.push(bridgeId);\n\n        emit BridgeAdapterSet(bridgeId, bridgeAdapter);\n    }\n\n    /// @dev Internal logic to disable outgoing transfers for a given bridge.\n    function _disableOutTransfer(uint16 bridgeId) internal {\n        BridgeControllerStorage storage $ = _getBridgeControllerStorage();\n        if ($._bridgeAdapters[bridgeId] == address(0)) {\n            revert Errors.InvalidBridgeId();\n        }\n        if (!$._isOutTransferEnabled[bridgeId]) {\n            revert Errors.AlreadyDisabled();\n        }\n        $._isOutTransferEnabled[bridgeId] = false;\n        emit OutTransferDisabled(bridgeId);\n    }\n\n    /// @dev Internal logic to enable outgoing transfers for a given bridge.\n    function _enableOutTransfer(uint16 bridgeId) internal {\n        BridgeControllerStorage storage $ = _getBridgeControllerStorage();\n        if ($._bridgeAdapters[bridgeId] == address(0)) {\n            revert Errors.InvalidBridgeId();\n        }\n        if ($._isOutTransferEnabled[bridgeId]) {\n            revert Errors.AlreadyEnabled();\n        }\n        $._isOutTransferEnabled[bridgeId] = true;\n        emit OutTransferEnabled(bridgeId);\n    }\n\n    /// @dev Internal logic to set the max allowed value loss in basis points for transfers via a given bridge.\n    function _setMaxBridgeLossBps(uint16 bridgeId, uint256 maxBridgeLossBps) internal {\n        BridgeControllerStorage storage $ = _getBridgeControllerStorage();\n        if ($._bridgeAdapters[bridgeId] == address(0)) {\n            revert Errors.InvalidBridgeId();\n        }\n        emit MaxBridgeLossBpsChanged(bridgeId, $._maxBridgeLossBps[bridgeId], maxBridgeLossBps);\n        $._maxBridgeLossBps[bridgeId] = maxBridgeLossBps;\n    }\n\n    /// @dev Returns whether the given address is a registered bridge adapter.\n    function _isBridgeAdapter(address adapter) internal view returns (bool) {\n        return _getBridgeControllerStorage()._isBridgeAdapter[adapter];\n    }\n\n    /// @dev Internal logic to schedule an outgoing bridge transfer.\n    function _scheduleOutBridgeTransfer(\n        uint16 bridgeId,\n        uint256 destinationChainId,\n        address recipient,\n        address inputToken,\n        uint256 inputAmount,\n        uint256 minOutputAmount\n    ) internal {\n        BridgeControllerStorage storage $ = _getBridgeControllerStorage();\n        address adapter = getBridgeAdapter(bridgeId);\n        if (!$._isOutTransferEnabled[bridgeId]) {\n            revert Errors.OutTransferNotEnabled();\n        }\n        if (minOutputAmount < inputAmount.mulDiv(MAX_BPS - $._maxBridgeLossBps[bridgeId], MAX_BPS, Math.Rounding.Ceil))\n        {\n            revert Errors.MaxValueLossExceeded();\n        }\n        if (minOutputAmount > inputAmount) {\n            revert Errors.MinOutputAmountExceedsInputAmount();\n        }\n        address outputToken =\n            ITokenRegistry(ICoreRegistry(registry).tokenRegistry()).getForeignToken(inputToken, destinationChainId);\n        IERC20(inputToken).forceApprove(adapter, inputAmount);\n        IBridgeAdapter(adapter)\n            .scheduleOutBridgeTransfer(\n                destinationChainId, recipient, inputToken, inputAmount, outputToken, minOutputAmount\n            );\n    }\n\n    /// @dev Internal logic to execute a scheduled outgoing bridge transfer.\n    function _sendOutBridgeTransfer(uint16 bridgeId, uint256 transferId, bytes calldata data) internal {\n        address adapter = getBridgeAdapter(bridgeId);\n        if (!_getBridgeControllerStorage()._isOutTransferEnabled[bridgeId]) {\n            revert Errors.OutTransferNotEnabled();\n        }\n        IBridgeAdapter(adapter).sendOutBridgeTransfer(transferId, data);\n    }\n\n    /// @dev Internal logic to register a message hash as authorized for an incoming bridge transfer.\n    function _authorizeInBridgeTransfer(uint16 bridgeId, bytes32 messageHash) internal {\n        address adapter = getBridgeAdapter(bridgeId);\n        IBridgeAdapter(adapter).authorizeInBridgeTransfer(messageHash);\n    }\n\n    /// @dev Internal logic to transfer a received bridge transfer out of the corresponding bridge adapter.\n    function _claimInBridgeTransfer(uint16 bridgeId, uint256 transferId) internal {\n        address adapter = getBridgeAdapter(bridgeId);\n        IBridgeAdapter(adapter).claimInBridgeTransfer(transferId);\n    }\n\n    /// @dev Internal logic to cancel an outgoing bridge transfer.\n    function _cancelOutBridgeTransfer(uint16 bridgeId, uint256 transferId) internal {\n        address adapter = getBridgeAdapter(bridgeId);\n        IBridgeAdapter(adapter).cancelOutBridgeTransfer(transferId);\n    }\n}\n"},{"file_path":"lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/utils/structs/EnumerableMap.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.6.0) (utils/structs/EnumerableMap.sol)\n// This file was procedurally generated from scripts/generate/templates/EnumerableMap.js.\n\npragma solidity ^0.8.24;\n\nimport {EnumerableSet} from \"./EnumerableSet.sol\";\n\n/**\n * @dev Library for managing an enumerable variant of Solidity's\n * https://solidity.readthedocs.io/en/latest/types.html#mapping-types[`mapping`]\n * type.\n *\n * Maps have the following properties:\n *\n * - Entries are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Entries are enumerated in O(n). No guarantees are made on the ordering.\n * - Map can be cleared (all entries removed) in O(n).\n *\n * ```solidity\n * contract Example {\n *     // Add the library methods\n *     using EnumerableMap for EnumerableMap.UintToAddressMap;\n *\n *     // Declare a set state variable\n *     EnumerableMap.UintToAddressMap private myMap;\n * }\n * ```\n *\n * The following map types are supported:\n *\n * - `uint256 -> address` (`UintToAddressMap`) since v3.0.0\n * - `address -> uint256` (`AddressToUintMap`) since v4.6.0\n * - `bytes32 -> bytes32` (`Bytes32ToBytes32Map`) since v4.6.0\n * - `uint256 -> uint256` (`UintToUintMap`) since v4.7.0\n * - `bytes32 -> uint256` (`Bytes32ToUintMap`) since v4.7.0\n * - `uint256 -> bytes32` (`UintToBytes32Map`) since v5.1.0\n * - `address -> address` (`AddressToAddressMap`) since v5.1.0\n * - `address -> bytes32` (`AddressToBytes32Map`) since v5.1.0\n * - `bytes32 -> address` (`Bytes32ToAddressMap`) since v5.1.0\n * - `bytes -> bytes` (`BytesToBytesMap`) since v5.4.0\n * - `bytes4 -> address` (`Bytes4ToAddressMap`) since v5.6.0\n *\n * [WARNING]\n * ====\n * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure\n * unusable.\n * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.\n *\n * In order to clean an EnumerableMap, you can either remove all elements one by one or create a fresh instance using an\n * array of EnumerableMap.\n * ====\n */\nlibrary EnumerableMap {\n    using EnumerableSet for *;\n\n    // To implement this library for multiple types with as little code repetition as possible, we write it in\n    // terms of a generic Map type with bytes32 keys and values. The Map implementation uses private functions,\n    // and user-facing implementations such as `UintToAddressMap` are just wrappers around the underlying Map.\n    // This means that we can only create new EnumerableMaps for types that fit in bytes32.\n\n    /**\n     * @dev Query for a nonexistent map key.\n     */\n    error EnumerableMapNonexistentKey(bytes32 key);\n\n    struct Bytes32ToBytes32Map {\n        // Storage of keys\n        EnumerableSet.Bytes32Set _keys;\n        mapping(bytes32 key => bytes32) _values;\n    }\n\n    /**\n     * @dev Adds a key-value pair to a map, or updates the value for an existing\n     * key. O(1).\n     *\n     * Returns true if the key was added to the map, that is if it was not\n     * already present.\n     */\n    function set(Bytes32ToBytes32Map storage map, bytes32 key, bytes32 value) internal returns (bool) {\n        map._values[key] = value;\n        return map._keys.add(key);\n    }\n\n    /**\n     * @dev Removes a key-value pair from a map. O(1).\n     *\n     * Returns true if the key was removed from the map, that is if it was present.\n     */\n    function remove(Bytes32ToBytes32Map storage map, bytes32 key) internal returns (bool) {\n        delete map._values[key];\n        return map._keys.remove(key);\n    }\n\n    /**\n     * @dev Removes all the entries from a map. O(n).\n     *\n     * WARNING: Developers should keep in mind that this function has an unbounded cost and using it may render the\n     * function uncallable if the map grows to the point where clearing it consumes too much gas to fit in a block.\n     */\n    function clear(Bytes32ToBytes32Map storage map) internal {\n        uint256 len = length(map);\n        for (uint256 i = 0; i < len; ++i) {\n            delete map._values[map._keys.at(i)];\n        }\n        map._keys.clear();\n    }\n\n    /**\n     * @dev Returns true if the key is in the map. O(1).\n     */\n    function contains(Bytes32ToBytes32Map storage map, bytes32 key) internal view returns (bool) {\n        return map._keys.contains(key);\n    }\n\n    /**\n     * @dev Returns the number of key-value pairs in the map. O(1).\n     */\n    function length(Bytes32ToBytes32Map storage map) internal view returns (uint256) {\n        return map._keys.length();\n    }\n\n    /**\n     * @dev Returns the key-value pair stored at position `index` in the map. O(1).\n     *\n     * Note that there are no guarantees on the ordering of entries inside the\n     * array, and it may change when more entries are added or removed.\n     *\n     * Requirements:\n     *\n     * - `index` must be strictly less than {length}.\n     */\n    function at(Bytes32ToBytes32Map storage map, uint256 index) internal view returns (bytes32 key, bytes32 value) {\n        bytes32 atKey = map._keys.at(index);\n        return (atKey, map._values[atKey]);\n    }\n\n    /**\n     * @dev Tries to return the value associated with `key`. O(1).\n     * Does not revert if `key` is not in the map.\n     */\n    function tryGet(Bytes32ToBytes32Map storage map, bytes32 key) internal view returns (bool exists, bytes32 value) {\n        bytes32 val = map._values[key];\n        if (val == bytes32(0)) {\n            return (contains(map, key), bytes32(0));\n        } else {\n            return (true, val);\n        }\n    }\n\n    /**\n     * @dev Returns the value associated with `key`. O(1).\n     *\n     * Requirements:\n     *\n     * - `key` must be in the map.\n     */\n    function get(Bytes32ToBytes32Map storage map, bytes32 key) internal view returns (bytes32) {\n        bytes32 value = map._values[key];\n        if (value == 0 && !contains(map, key)) {\n            revert EnumerableMapNonexistentKey(key);\n        }\n        return value;\n    }\n\n    /**\n     * @dev Returns an array containing all the keys\n     *\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n     * uncallable if the map grows to a point where copying to memory consumes too much gas to fit in a block.\n     */\n    function keys(Bytes32ToBytes32Map storage map) internal view returns (bytes32[] memory) {\n        return map._keys.values();\n    }\n\n    /**\n     * @dev Returns an array containing a slice of the keys\n     *\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n     * uncallable if the map grows to a point where copying to memory consumes too much gas to fit in a block.\n     */\n    function keys(\n        Bytes32ToBytes32Map storage map,\n        uint256 start,\n        uint256 end\n    ) internal view returns (bytes32[] memory) {\n        return map._keys.values(start, end);\n    }\n\n    // UintToUintMap\n\n    struct UintToUintMap {\n        Bytes32ToBytes32Map _inner;\n    }\n\n    /**\n     * @dev Adds a key-value pair to a map, or updates the value for an existing\n     * key. O(1).\n     *\n     * Returns true if the key was added to the map, that is if it was not\n     * already present.\n     */\n    function set(UintToUintMap storage map, uint256 key, uint256 value) internal returns (bool) {\n        return set(map._inner, bytes32(key), bytes32(value));\n    }\n\n    /**\n     * @dev Removes a value from a map. O(1).\n     *\n     * Returns true if the key was removed from the map, that is if it was present.\n     */\n    function remove(UintToUintMap storage map, uint256 key) internal returns (bool) {\n        return remove(map._inner, bytes32(key));\n    }\n\n    /**\n     * @dev Removes all the entries from a map. O(n).\n     *\n     * WARNING: This function has an unbounded cost that scales with map size. Developers should keep in mind that\n     * using it may render the function uncallable if the map grows to the point where clearing it consumes too much\n     * gas to fit in a block.\n     */\n    function clear(UintToUintMap storage map) internal {\n        clear(map._inner);\n    }\n\n    /**\n     * @dev Returns true if the key is in the map. O(1).\n     */\n    function contains(UintToUintMap storage map, uint256 key) internal view returns (bool) {\n        return contains(map._inner, bytes32(key));\n    }\n\n    /**\n     * @dev Returns the number of elements in the map. O(1).\n     */\n    function length(UintToUintMap storage map) internal view returns (uint256) {\n        return length(map._inner);\n    }\n\n    /**\n     * @dev Returns the element stored at position `index` in the map. O(1).\n     * Note that there are no guarantees on the ordering of values inside the\n     * array, and it may change when more values are added or removed.\n     *\n     * Requirements:\n     *\n     * - `index` must be strictly less than {length}.\n     */\n    function at(UintToUintMap storage map, uint256 index) internal view returns (uint256 key, uint256 value) {\n        (bytes32 atKey, bytes32 val) = at(map._inner, index);\n        return (uint256(atKey), uint256(val));\n    }\n\n    /**\n     * @dev Tries to return the value associated with `key`. O(1).\n     * Does not revert if `key` is not in the map.\n     */\n    function tryGet(UintToUintMap storage map, uint256 key) internal view returns (bool exists, uint256 value) {\n        (bool success, bytes32 val) = tryGet(map._inner, bytes32(key));\n        return (success, uint256(val));\n    }\n\n    /**\n     * @dev Returns the value associated with `key`. O(1).\n     *\n     * Requirements:\n     *\n     * - `key` must be in the map.\n     */\n    function get(UintToUintMap storage map, uint256 key) internal view returns (uint256) {\n        return uint256(get(map._inner, bytes32(key)));\n    }\n\n    /**\n     * @dev Returns an array containing all the keys\n     *\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n     * uncallable if the map grows to a point where copying to memory consumes too much gas to fit in a block.\n     */\n    function keys(UintToUintMap storage map) internal view returns (uint256[] memory) {\n        bytes32[] memory store = keys(map._inner);\n        uint256[] memory result;\n\n        assembly (\"memory-safe\") {\n            result := store\n        }\n\n        return result;\n    }\n\n    /**\n     * @dev Returns an array containing a slice of the keys\n     *\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n     * uncallable if the map grows to a point where copying to memory consumes too much gas to fit in a block.\n     */\n    function keys(UintToUintMap storage map, uint256 start, uint256 end) internal view returns (uint256[] memory) {\n        bytes32[] memory store = keys(map._inner, start, end);\n        uint256[] memory result;\n\n        assembly (\"memory-safe\") {\n            result := store\n        }\n\n        return result;\n    }\n\n    // UintToAddressMap\n\n    struct UintToAddressMap {\n        Bytes32ToBytes32Map _inner;\n    }\n\n    /**\n     * @dev Adds a key-value pair to a map, or updates the value for an existing\n     * key. O(1).\n     *\n     * Returns true if the key was added to the map, that is if it was not\n     * already present.\n     */\n    function set(UintToAddressMap storage map, uint256 key, address value) internal returns (bool) {\n        return set(map._inner, bytes32(key), bytes32(uint256(uint160(value))));\n    }\n\n    /**\n     * @dev Removes a value from a map. O(1).\n     *\n     * Returns true if the key was removed from the map, that is if it was present.\n     */\n    function remove(UintToAddressMap storage map, uint256 key) internal returns (bool) {\n        return remove(map._inner, bytes32(key));\n    }\n\n    /**\n     * @dev Removes all the entries from a map. O(n).\n     *\n     * WARNING: This function has an unbounded cost that scales with map size. Developers should keep in mind that\n     * using it may render the function uncallable if the map grows to the point where clearing it consumes too much\n     * gas to fit in a block.\n     */\n    function clear(UintToAddressMap storage map) internal {\n        clear(map._inner);\n    }\n\n    /**\n     * @dev Returns true if the key is in the map. O(1).\n     */\n    function contains(UintToAddressMap storage map, uint256 key) internal view returns (bool) {\n        return contains(map._inner, bytes32(key));\n    }\n\n    /**\n     * @dev Returns the number of elements in the map. O(1).\n     */\n    function length(UintToAddressMap storage map) internal view returns (uint256) {\n        return length(map._inner);\n    }\n\n    /**\n     * @dev Returns the element stored at position `index` in the map. O(1).\n     * Note that there are no guarantees on the ordering of values inside the\n     * array, and it may change when more values are added or removed.\n     *\n     * Requirements:\n     *\n     * - `index` must be strictly less than {length}.\n     */\n    function at(UintToAddressMap storage map, uint256 index) internal view returns (uint256 key, address value) {\n        (bytes32 atKey, bytes32 val) = at(map._inner, index);\n        return (uint256(atKey), address(uint160(uint256(val))));\n    }\n\n    /**\n     * @dev Tries to return the value associated with `key`. O(1).\n     * Does not revert if `key` is not in the map.\n     */\n    function tryGet(UintToAddressMap storage map, uint256 key) internal view returns (bool exists, address value) {\n        (bool success, bytes32 val) = tryGet(map._inner, bytes32(key));\n        return (success, address(uint160(uint256(val))));\n    }\n\n    /**\n     * @dev Returns the value associated with `key`. O(1).\n     *\n     * Requirements:\n     *\n     * - `key` must be in the map.\n     */\n    function get(UintToAddressMap storage map, uint256 key) internal view returns (address) {\n        return address(uint160(uint256(get(map._inner, bytes32(key)))));\n    }\n\n    /**\n     * @dev Returns an array containing all the keys\n     *\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n     * uncallable if the map grows to a point where copying to memory consumes too much gas to fit in a block.\n     */\n    function keys(UintToAddressMap storage map) internal view returns (uint256[] memory) {\n        bytes32[] memory store = keys(map._inner);\n        uint256[] memory result;\n\n        assembly (\"memory-safe\") {\n            result := store\n        }\n\n        return result;\n    }\n\n    /**\n     * @dev Returns an array containing a slice of the keys\n     *\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n     * uncallable if the map grows to a point where copying to memory consumes too much gas to fit in a block.\n     */\n    function keys(UintToAddressMap storage map, uint256 start, uint256 end) internal view returns (uint256[] memory) {\n        bytes32[] memory store = keys(map._inner, start, end);\n        uint256[] memory result;\n\n        assembly (\"memory-safe\") {\n            result := store\n        }\n\n        return result;\n    }\n\n    // UintToBytes32Map\n\n    struct UintToBytes32Map {\n        Bytes32ToBytes32Map _inner;\n    }\n\n    /**\n     * @dev Adds a key-value pair to a map, or updates the value for an existing\n     * key. O(1).\n     *\n     * Returns true if the key was added to the map, that is if it was not\n     * already present.\n     */\n    function set(UintToBytes32Map storage map, uint256 key, bytes32 value) internal returns (bool) {\n        return set(map._inner, bytes32(key), value);\n    }\n\n    /**\n     * @dev Removes a value from a map. O(1).\n     *\n     * Returns true if the key was removed from the map, that is if it was present.\n     */\n    function remove(UintToBytes32Map storage map, uint256 key) internal returns (bool) {\n        return remove(map._inner, bytes32(key));\n    }\n\n    /**\n     * @dev Removes all the entries from a map. O(n).\n     *\n     * WARNING: This function has an unbounded cost that scales with map size. Developers should keep in mind that\n     * using it may render the function uncallable if the map grows to the point where clearing it consumes too much\n     * gas to fit in a block.\n     */\n    function clear(UintToBytes32Map storage map) internal {\n        clear(map._inner);\n    }\n\n    /**\n     * @dev Returns true if the key is in the map. O(1).\n     */\n    function contains(UintToBytes32Map storage map, uint256 key) internal view returns (bool) {\n        return contains(map._inner, bytes32(key));\n    }\n\n    /**\n     * @dev Returns the number of elements in the map. O(1).\n     */\n    function length(UintToBytes32Map storage map) internal view returns (uint256) {\n        return length(map._inner);\n    }\n\n    /**\n     * @dev Returns the element stored at position `index` in the map. O(1).\n     * Note that there are no guarantees on the ordering of values inside the\n     * array, and it may change when more values are added or removed.\n     *\n     * Requirements:\n     *\n     * - `index` must be strictly less than {length}.\n     */\n    function at(UintToBytes32Map storage map, uint256 index) internal view returns (uint256 key, bytes32 value) {\n        (bytes32 atKey, bytes32 val) = at(map._inner, index);\n        return (uint256(atKey), val);\n    }\n\n    /**\n     * @dev Tries to return the value associated with `key`. O(1).\n     * Does not revert if `key` is not in the map.\n     */\n    function tryGet(UintToBytes32Map storage map, uint256 key) internal view returns (bool exists, bytes32 value) {\n        (bool success, bytes32 val) = tryGet(map._inner, bytes32(key));\n        return (success, val);\n    }\n\n    /**\n     * @dev Returns the value associated with `key`. O(1).\n     *\n     * Requirements:\n     *\n     * - `key` must be in the map.\n     */\n    function get(UintToBytes32Map storage map, uint256 key) internal view returns (bytes32) {\n        return get(map._inner, bytes32(key));\n    }\n\n    /**\n     * @dev Returns an array containing all the keys\n     *\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n     * uncallable if the map grows to a point where copying to memory consumes too much gas to fit in a block.\n     */\n    function keys(UintToBytes32Map storage map) internal view returns (uint256[] memory) {\n        bytes32[] memory store = keys(map._inner);\n        uint256[] memory result;\n\n        assembly (\"memory-safe\") {\n            result := store\n        }\n\n        return result;\n    }\n\n    /**\n     * @dev Returns an array containing a slice of the keys\n     *\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n     * uncallable if the map grows to a point where copying to memory consumes too much gas to fit in a block.\n     */\n    function keys(UintToBytes32Map storage map, uint256 start, uint256 end) internal view returns (uint256[] memory) {\n        bytes32[] memory store = keys(map._inner, start, end);\n        uint256[] memory result;\n\n        assembly (\"memory-safe\") {\n            result := store\n        }\n\n        return result;\n    }\n\n    // AddressToUintMap\n\n    struct AddressToUintMap {\n        Bytes32ToBytes32Map _inner;\n    }\n\n    /**\n     * @dev Adds a key-value pair to a map, or updates the value for an existing\n     * key. O(1).\n     *\n     * Returns true if the key was added to the map, that is if it was not\n     * already present.\n     */\n    function set(AddressToUintMap storage map, address key, uint256 value) internal returns (bool) {\n        return set(map._inner, bytes32(uint256(uint160(key))), bytes32(value));\n    }\n\n    /**\n     * @dev Removes a value from a map. O(1).\n     *\n     * Returns true if the key was removed from the map, that is if it was present.\n     */\n    function remove(AddressToUintMap storage map, address key) internal returns (bool) {\n        return remove(map._inner, bytes32(uint256(uint160(key))));\n    }\n\n    /**\n     * @dev Removes all the entries from a map. O(n).\n     *\n     * WARNING: This function has an unbounded cost that scales with map size. Developers should keep in mind that\n     * using it may render the function uncallable if the map grows to the point where clearing it consumes too much\n     * gas to fit in a block.\n     */\n    function clear(AddressToUintMap storage map) internal {\n        clear(map._inner);\n    }\n\n    /**\n     * @dev Returns true if the key is in the map. O(1).\n     */\n    function contains(AddressToUintMap storage map, address key) internal view returns (bool) {\n        return contains(map._inner, bytes32(uint256(uint160(key))));\n    }\n\n    /**\n     * @dev Returns the number of elements in the map. O(1).\n     */\n    function length(AddressToUintMap storage map) internal view returns (uint256) {\n        return length(map._inner);\n    }\n\n    /**\n     * @dev Returns the element stored at position `index` in the map. O(1).\n     * Note that there are no guarantees on the ordering of values inside the\n     * array, and it may change when more values are added or removed.\n     *\n     * Requirements:\n     *\n     * - `index` must be strictly less than {length}.\n     */\n    function at(AddressToUintMap storage map, uint256 index) internal view returns (address key, uint256 value) {\n        (bytes32 atKey, bytes32 val) = at(map._inner, index);\n        return (address(uint160(uint256(atKey))), uint256(val));\n    }\n\n    /**\n     * @dev Tries to return the value associated with `key`. O(1).\n     * Does not revert if `key` is not in the map.\n     */\n    function tryGet(AddressToUintMap storage map, address key) internal view returns (bool exists, uint256 value) {\n        (bool success, bytes32 val) = tryGet(map._inner, bytes32(uint256(uint160(key))));\n        return (success, uint256(val));\n    }\n\n    /**\n     * @dev Returns the value associated with `key`. O(1).\n     *\n     * Requirements:\n     *\n     * - `key` must be in the map.\n     */\n    function get(AddressToUintMap storage map, address key) internal view returns (uint256) {\n        return uint256(get(map._inner, bytes32(uint256(uint160(key)))));\n    }\n\n    /**\n     * @dev Returns an array containing all the keys\n     *\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n     * uncallable if the map grows to a point where copying to memory consumes too much gas to fit in a block.\n     */\n    function keys(AddressToUintMap storage map) internal view returns (address[] memory) {\n        bytes32[] memory store = keys(map._inner);\n        address[] memory result;\n\n        assembly (\"memory-safe\") {\n            result := store\n        }\n\n        return result;\n    }\n\n    /**\n     * @dev Returns an array containing a slice of the keys\n     *\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n     * uncallable if the map grows to a point where copying to memory consumes too much gas to fit in a block.\n     */\n    function keys(AddressToUintMap storage map, uint256 start, uint256 end) internal view returns (address[] memory) {\n        bytes32[] memory store = keys(map._inner, start, end);\n        address[] memory result;\n\n        assembly (\"memory-safe\") {\n            result := store\n        }\n\n        return result;\n    }\n\n    // AddressToAddressMap\n\n    struct AddressToAddressMap {\n        Bytes32ToBytes32Map _inner;\n    }\n\n    /**\n     * @dev Adds a key-value pair to a map, or updates the value for an existing\n     * key. O(1).\n     *\n     * Returns true if the key was added to the map, that is if it was not\n     * already present.\n     */\n    function set(AddressToAddressMap storage map, address key, address value) internal returns (bool) {\n        return set(map._inner, bytes32(uint256(uint160(key))), bytes32(uint256(uint160(value))));\n    }\n\n    /**\n     * @dev Removes a value from a map. O(1).\n     *\n     * Returns true if the key was removed from the map, that is if it was present.\n     */\n    function remove(AddressToAddressMap storage map, address key) internal returns (bool) {\n        return remove(map._inner, bytes32(uint256(uint160(key))));\n    }\n\n    /**\n     * @dev Removes all the entries from a map. O(n).\n     *\n     * WARNING: This function has an unbounded cost that scales with map size. Developers should keep in mind that\n     * using it may render the function uncallable if the map grows to the point where clearing it consumes too much\n     * gas to fit in a block.\n     */\n    function clear(AddressToAddressMap storage map) internal {\n        clear(map._inner);\n    }\n\n    /**\n     * @dev Returns true if the key is in the map. O(1).\n     */\n    function contains(AddressToAddressMap storage map, address key) internal view returns (bool) {\n        return contains(map._inner, bytes32(uint256(uint160(key))));\n    }\n\n    /**\n     * @dev Returns the number of elements in the map. O(1).\n     */\n    function length(AddressToAddressMap storage map) internal view returns (uint256) {\n        return length(map._inner);\n    }\n\n    /**\n     * @dev Returns the element stored at position `index` in the map. O(1).\n     * Note that there are no guarantees on the ordering of values inside the\n     * array, and it may change when more values are added or removed.\n     *\n     * Requirements:\n     *\n     * - `index` must be strictly less than {length}.\n     */\n    function at(AddressToAddressMap storage map, uint256 index) internal view returns (address key, address value) {\n        (bytes32 atKey, bytes32 val) = at(map._inner, index);\n        return (address(uint160(uint256(atKey))), address(uint160(uint256(val))));\n    }\n\n    /**\n     * @dev Tries to return the value associated with `key`. O(1).\n     * Does not revert if `key` is not in the map.\n     */\n    function tryGet(AddressToAddressMap storage map, address key) internal view returns (bool exists, address value) {\n        (bool success, bytes32 val) = tryGet(map._inner, bytes32(uint256(uint160(key))));\n        return (success, address(uint160(uint256(val))));\n    }\n\n    /**\n     * @dev Returns the value associated with `key`. O(1).\n     *\n     * Requirements:\n     *\n     * - `key` must be in the map.\n     */\n    function get(AddressToAddressMap storage map, address key) internal view returns (address) {\n        return address(uint160(uint256(get(map._inner, bytes32(uint256(uint160(key)))))));\n    }\n\n    /**\n     * @dev Returns an array containing all the keys\n     *\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n     * uncallable if the map grows to a point where copying to memory consumes too much gas to fit in a block.\n     */\n    function keys(AddressToAddressMap storage map) internal view returns (address[] memory) {\n        bytes32[] memory store = keys(map._inner);\n        address[] memory result;\n\n        assembly (\"memory-safe\") {\n            result := store\n        }\n\n        return result;\n    }\n\n    /**\n     * @dev Returns an array containing a slice of the keys\n     *\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n     * uncallable if the map grows to a point where copying to memory consumes too much gas to fit in a block.\n     */\n    function keys(\n        AddressToAddressMap storage map,\n        uint256 start,\n        uint256 end\n    ) internal view returns (address[] memory) {\n        bytes32[] memory store = keys(map._inner, start, end);\n        address[] memory result;\n\n        assembly (\"memory-safe\") {\n            result := store\n        }\n\n        return result;\n    }\n\n    // AddressToBytes32Map\n\n    struct AddressToBytes32Map {\n        Bytes32ToBytes32Map _inner;\n    }\n\n    /**\n     * @dev Adds a key-value pair to a map, or updates the value for an existing\n     * key. O(1).\n     *\n     * Returns true if the key was added to the map, that is if it was not\n     * already present.\n     */\n    function set(AddressToBytes32Map storage map, address key, bytes32 value) internal returns (bool) {\n        return set(map._inner, bytes32(uint256(uint160(key))), value);\n    }\n\n    /**\n     * @dev Removes a value from a map. O(1).\n     *\n     * Returns true if the key was removed from the map, that is if it was present.\n     */\n    function remove(AddressToBytes32Map storage map, address key) internal returns (bool) {\n        return remove(map._inner, bytes32(uint256(uint160(key))));\n    }\n\n    /**\n     * @dev Removes all the entries from a map. O(n).\n     *\n     * WARNING: This function has an unbounded cost that scales with map size. Developers should keep in mind that\n     * using it may render the function uncallable if the map grows to the point where clearing it consumes too much\n     * gas to fit in a block.\n     */\n    function clear(AddressToBytes32Map storage map) internal {\n        clear(map._inner);\n    }\n\n    /**\n     * @dev Returns true if the key is in the map. O(1).\n     */\n    function contains(AddressToBytes32Map storage map, address key) internal view returns (bool) {\n        return contains(map._inner, bytes32(uint256(uint160(key))));\n    }\n\n    /**\n     * @dev Returns the number of elements in the map. O(1).\n     */\n    function length(AddressToBytes32Map storage map) internal view returns (uint256) {\n        return length(map._inner);\n    }\n\n    /**\n     * @dev Returns the element stored at position `index` in the map. O(1).\n     * Note that there are no guarantees on the ordering of values inside the\n     * array, and it may change when more values are added or removed.\n     *\n     * Requirements:\n     *\n     * - `index` must be strictly less than {length}.\n     */\n    function at(AddressToBytes32Map storage map, uint256 index) internal view returns (address key, bytes32 value) {\n        (bytes32 atKey, bytes32 val) = at(map._inner, index);\n        return (address(uint160(uint256(atKey))), val);\n    }\n\n    /**\n     * @dev Tries to return the value associated with `key`. O(1).\n     * Does not revert if `key` is not in the map.\n     */\n    function tryGet(AddressToBytes32Map storage map, address key) internal view returns (bool exists, bytes32 value) {\n        (bool success, bytes32 val) = tryGet(map._inner, bytes32(uint256(uint160(key))));\n        return (success, val);\n    }\n\n    /**\n     * @dev Returns the value associated with `key`. O(1).\n     *\n     * Requirements:\n     *\n     * - `key` must be in the map.\n     */\n    function get(AddressToBytes32Map storage map, address key) internal view returns (bytes32) {\n        return get(map._inner, bytes32(uint256(uint160(key))));\n    }\n\n    /**\n     * @dev Returns an array containing all the keys\n     *\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n     * uncallable if the map grows to a point where copying to memory consumes too much gas to fit in a block.\n     */\n    function keys(AddressToBytes32Map storage map) internal view returns (address[] memory) {\n        bytes32[] memory store = keys(map._inner);\n        address[] memory result;\n\n        assembly (\"memory-safe\") {\n            result := store\n        }\n\n        return result;\n    }\n\n    /**\n     * @dev Returns an array containing a slice of the keys\n     *\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n     * uncallable if the map grows to a point where copying to memory consumes too much gas to fit in a block.\n     */\n    function keys(\n        AddressToBytes32Map storage map,\n        uint256 start,\n        uint256 end\n    ) internal view returns (address[] memory) {\n        bytes32[] memory store = keys(map._inner, start, end);\n        address[] memory result;\n\n        assembly (\"memory-safe\") {\n            result := store\n        }\n\n        return result;\n    }\n\n    // Bytes32ToUintMap\n\n    struct Bytes32ToUintMap {\n        Bytes32ToBytes32Map _inner;\n    }\n\n    /**\n     * @dev Adds a key-value pair to a map, or updates the value for an existing\n     * key. O(1).\n     *\n     * Returns true if the key was added to the map, that is if it was not\n     * already present.\n     */\n    function set(Bytes32ToUintMap storage map, bytes32 key, uint256 value) internal returns (bool) {\n        return set(map._inner, key, bytes32(value));\n    }\n\n    /**\n     * @dev Removes a value from a map. O(1).\n     *\n     * Returns true if the key was removed from the map, that is if it was present.\n     */\n    function remove(Bytes32ToUintMap storage map, bytes32 key) internal returns (bool) {\n        return remove(map._inner, key);\n    }\n\n    /**\n     * @dev Removes all the entries from a map. O(n).\n     *\n     * WARNING: This function has an unbounded cost that scales with map size. Developers should keep in mind that\n     * using it may render the function uncallable if the map grows to the point where clearing it consumes too much\n     * gas to fit in a block.\n     */\n    function clear(Bytes32ToUintMap storage map) internal {\n        clear(map._inner);\n    }\n\n    /**\n     * @dev Returns true if the key is in the map. O(1).\n     */\n    function contains(Bytes32ToUintMap storage map, bytes32 key) internal view returns (bool) {\n        return contains(map._inner, key);\n    }\n\n    /**\n     * @dev Returns the number of elements in the map. O(1).\n     */\n    function length(Bytes32ToUintMap storage map) internal view returns (uint256) {\n        return length(map._inner);\n    }\n\n    /**\n     * @dev Returns the element stored at position `index` in the map. O(1).\n     * Note that there are no guarantees on the ordering of values inside the\n     * array, and it may change when more values are added or removed.\n     *\n     * Requirements:\n     *\n     * - `index` must be strictly less than {length}.\n     */\n    function at(Bytes32ToUintMap storage map, uint256 index) internal view returns (bytes32 key, uint256 value) {\n        (bytes32 atKey, bytes32 val) = at(map._inner, index);\n        return (atKey, uint256(val));\n    }\n\n    /**\n     * @dev Tries to return the value associated with `key`. O(1).\n     * Does not revert if `key` is not in the map.\n     */\n    function tryGet(Bytes32ToUintMap storage map, bytes32 key) internal view returns (bool exists, uint256 value) {\n        (bool success, bytes32 val) = tryGet(map._inner, key);\n        return (success, uint256(val));\n    }\n\n    /**\n     * @dev Returns the value associated with `key`. O(1).\n     *\n     * Requirements:\n     *\n     * - `key` must be in the map.\n     */\n    function get(Bytes32ToUintMap storage map, bytes32 key) internal view returns (uint256) {\n        return uint256(get(map._inner, key));\n    }\n\n    /**\n     * @dev Returns an array containing all the keys\n     *\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n     * uncallable if the map grows to a point where copying to memory consumes too much gas to fit in a block.\n     */\n    function keys(Bytes32ToUintMap storage map) internal view returns (bytes32[] memory) {\n        bytes32[] memory store = keys(map._inner);\n        bytes32[] memory result;\n\n        assembly (\"memory-safe\") {\n            result := store\n        }\n\n        return result;\n    }\n\n    /**\n     * @dev Returns an array containing a slice of the keys\n     *\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n     * uncallable if the map grows to a point where copying to memory consumes too much gas to fit in a block.\n     */\n    function keys(Bytes32ToUintMap storage map, uint256 start, uint256 end) internal view returns (bytes32[] memory) {\n        bytes32[] memory store = keys(map._inner, start, end);\n        bytes32[] memory result;\n\n        assembly (\"memory-safe\") {\n            result := store\n        }\n\n        return result;\n    }\n\n    // Bytes32ToAddressMap\n\n    struct Bytes32ToAddressMap {\n        Bytes32ToBytes32Map _inner;\n    }\n\n    /**\n     * @dev Adds a key-value pair to a map, or updates the value for an existing\n     * key. O(1).\n     *\n     * Returns true if the key was added to the map, that is if it was not\n     * already present.\n     */\n    function set(Bytes32ToAddressMap storage map, bytes32 key, address value) internal returns (bool) {\n        return set(map._inner, key, bytes32(uint256(uint160(value))));\n    }\n\n    /**\n     * @dev Removes a value from a map. O(1).\n     *\n     * Returns true if the key was removed from the map, that is if it was present.\n     */\n    function remove(Bytes32ToAddressMap storage map, bytes32 key) internal returns (bool) {\n        return remove(map._inner, key);\n    }\n\n    /**\n     * @dev Removes all the entries from a map. O(n).\n     *\n     * WARNING: This function has an unbounded cost that scales with map size. Developers should keep in mind that\n     * using it may render the function uncallable if the map grows to the point where clearing it consumes too much\n     * gas to fit in a block.\n     */\n    function clear(Bytes32ToAddressMap storage map) internal {\n        clear(map._inner);\n    }\n\n    /**\n     * @dev Returns true if the key is in the map. O(1).\n     */\n    function contains(Bytes32ToAddressMap storage map, bytes32 key) internal view returns (bool) {\n        return contains(map._inner, key);\n    }\n\n    /**\n     * @dev Returns the number of elements in the map. O(1).\n     */\n    function length(Bytes32ToAddressMap storage map) internal view returns (uint256) {\n        return length(map._inner);\n    }\n\n    /**\n     * @dev Returns the element stored at position `index` in the map. O(1).\n     * Note that there are no guarantees on the ordering of values inside the\n     * array, and it may change when more values are added or removed.\n     *\n     * Requirements:\n     *\n     * - `index` must be strictly less than {length}.\n     */\n    function at(Bytes32ToAddressMap storage map, uint256 index) internal view returns (bytes32 key, address value) {\n        (bytes32 atKey, bytes32 val) = at(map._inner, index);\n        return (atKey, address(uint160(uint256(val))));\n    }\n\n    /**\n     * @dev Tries to return the value associated with `key`. O(1).\n     * Does not revert if `key` is not in the map.\n     */\n    function tryGet(Bytes32ToAddressMap storage map, bytes32 key) internal view returns (bool exists, address value) {\n        (bool success, bytes32 val) = tryGet(map._inner, key);\n        return (success, address(uint160(uint256(val))));\n    }\n\n    /**\n     * @dev Returns the value associated with `key`. O(1).\n     *\n     * Requirements:\n     *\n     * - `key` must be in the map.\n     */\n    function get(Bytes32ToAddressMap storage map, bytes32 key) internal view returns (address) {\n        return address(uint160(uint256(get(map._inner, key))));\n    }\n\n    /**\n     * @dev Returns an array containing all the keys\n     *\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n     * uncallable if the map grows to a point where copying to memory consumes too much gas to fit in a block.\n     */\n    function keys(Bytes32ToAddressMap storage map) internal view returns (bytes32[] memory) {\n        bytes32[] memory store = keys(map._inner);\n        bytes32[] memory result;\n\n        assembly (\"memory-safe\") {\n            result := store\n        }\n\n        return result;\n    }\n\n    /**\n     * @dev Returns an array containing a slice of the keys\n     *\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n     * uncallable if the map grows to a point where copying to memory consumes too much gas to fit in a block.\n     */\n    function keys(\n        Bytes32ToAddressMap storage map,\n        uint256 start,\n        uint256 end\n    ) internal view returns (bytes32[] memory) {\n        bytes32[] memory store = keys(map._inner, start, end);\n        bytes32[] memory result;\n\n        assembly (\"memory-safe\") {\n            result := store\n        }\n\n        return result;\n    }\n\n    // Bytes4ToAddressMap\n\n    struct Bytes4ToAddressMap {\n        Bytes32ToBytes32Map _inner;\n    }\n\n    /**\n     * @dev Adds a key-value pair to a map, or updates the value for an existing\n     * key. O(1).\n     *\n     * Returns true if the key was added to the map, that is if it was not\n     * already present.\n     */\n    function set(Bytes4ToAddressMap storage map, bytes4 key, address value) internal returns (bool) {\n        return set(map._inner, bytes32(key), bytes32(uint256(uint160(value))));\n    }\n\n    /**\n     * @dev Removes a value from a map. O(1).\n     *\n     * Returns true if the key was removed from the map, that is if it was present.\n     */\n    function remove(Bytes4ToAddressMap storage map, bytes4 key) internal returns (bool) {\n        return remove(map._inner, bytes32(key));\n    }\n\n    /**\n     * @dev Removes all the entries from a map. O(n).\n     *\n     * WARNING: This function has an unbounded cost that scales with map size. Developers should keep in mind that\n     * using it may render the function uncallable if the map grows to the point where clearing it consumes too much\n     * gas to fit in a block.\n     */\n    function clear(Bytes4ToAddressMap storage map) internal {\n        clear(map._inner);\n    }\n\n    /**\n     * @dev Returns true if the key is in the map. O(1).\n     */\n    function contains(Bytes4ToAddressMap storage map, bytes4 key) internal view returns (bool) {\n        return contains(map._inner, bytes32(key));\n    }\n\n    /**\n     * @dev Returns the number of elements in the map. O(1).\n     */\n    function length(Bytes4ToAddressMap storage map) internal view returns (uint256) {\n        return length(map._inner);\n    }\n\n    /**\n     * @dev Returns the element stored at position `index` in the map. O(1).\n     * Note that there are no guarantees on the ordering of values inside the\n     * array, and it may change when more values are added or removed.\n     *\n     * Requirements:\n     *\n     * - `index` must be strictly less than {length}.\n     */\n    function at(Bytes4ToAddressMap storage map, uint256 index) internal view returns (bytes4 key, address value) {\n        (bytes32 atKey, bytes32 val) = at(map._inner, index);\n        return (bytes4(atKey), address(uint160(uint256(val))));\n    }\n\n    /**\n     * @dev Tries to return the value associated with `key`. O(1).\n     * Does not revert if `key` is not in the map.\n     */\n    function tryGet(Bytes4ToAddressMap storage map, bytes4 key) internal view returns (bool exists, address value) {\n        (bool success, bytes32 val) = tryGet(map._inner, bytes32(key));\n        return (success, address(uint160(uint256(val))));\n    }\n\n    /**\n     * @dev Returns the value associated with `key`. O(1).\n     *\n     * Requirements:\n     *\n     * - `key` must be in the map.\n     */\n    function get(Bytes4ToAddressMap storage map, bytes4 key) internal view returns (address) {\n        return address(uint160(uint256(get(map._inner, bytes32(key)))));\n    }\n\n    /**\n     * @dev Returns an array containing all the keys\n     *\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n     * uncallable if the map grows to a point where copying to memory consumes too much gas to fit in a block.\n     */\n    function keys(Bytes4ToAddressMap storage map) internal view returns (bytes4[] memory) {\n        bytes32[] memory store = keys(map._inner);\n        bytes4[] memory result;\n\n        assembly (\"memory-safe\") {\n            result := store\n        }\n\n        return result;\n    }\n\n    /**\n     * @dev Returns an array containing a slice of the keys\n     *\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n     * uncallable if the map grows to a point where copying to memory consumes too much gas to fit in a block.\n     */\n    function keys(Bytes4ToAddressMap storage map, uint256 start, uint256 end) internal view returns (bytes4[] memory) {\n        bytes32[] memory store = keys(map._inner, start, end);\n        bytes4[] memory result;\n\n        assembly (\"memory-safe\") {\n            result := store\n        }\n\n        return result;\n    }\n\n    /**\n     * @dev Query for a nonexistent map key.\n     */\n    error EnumerableMapNonexistentBytesKey(bytes key);\n\n    struct BytesToBytesMap {\n        // Storage of keys\n        EnumerableSet.BytesSet _keys;\n        mapping(bytes key => bytes) _values;\n    }\n\n    /**\n     * @dev Adds a key-value pair to a map, or updates the value for an existing\n     * key. O(1).\n     *\n     * Returns true if the key was added to the map, that is if it was not\n     * already present.\n     */\n    function set(BytesToBytesMap storage map, bytes memory key, bytes memory value) internal returns (bool) {\n        map._values[key] = value;\n        return map._keys.add(key);\n    }\n\n    /**\n     * @dev Removes a key-value pair from a map. O(1).\n     *\n     * Returns true if the key was removed from the map, that is if it was present.\n     */\n    function remove(BytesToBytesMap storage map, bytes memory key) internal returns (bool) {\n        delete map._values[key];\n        return map._keys.remove(key);\n    }\n\n    /**\n     * @dev Removes all the entries from a map. O(n).\n     *\n     * WARNING: Developers should keep in mind that this function has an unbounded cost and using it may render the\n     * function uncallable if the map grows to the point where clearing it consumes too much gas to fit in a block.\n     */\n    function clear(BytesToBytesMap storage map) internal {\n        uint256 len = length(map);\n        for (uint256 i = 0; i < len; ++i) {\n            delete map._values[map._keys.at(i)];\n        }\n        map._keys.clear();\n    }\n\n    /**\n     * @dev Returns true if the key is in the map. O(1).\n     */\n    function contains(BytesToBytesMap storage map, bytes memory key) internal view returns (bool) {\n        return map._keys.contains(key);\n    }\n\n    /**\n     * @dev Returns the number of key-value pairs in the map. O(1).\n     */\n    function length(BytesToBytesMap storage map) internal view returns (uint256) {\n        return map._keys.length();\n    }\n\n    /**\n     * @dev Returns the key-value pair stored at position `index` in the map. O(1).\n     *\n     * Note that there are no guarantees on the ordering of entries inside the\n     * array, and it may change when more entries are added or removed.\n     *\n     * Requirements:\n     *\n     * - `index` must be strictly less than {length}.\n     */\n    function at(\n        BytesToBytesMap storage map,\n        uint256 index\n    ) internal view returns (bytes memory key, bytes memory value) {\n        key = map._keys.at(index);\n        value = map._values[key];\n    }\n\n    /**\n     * @dev Tries to return the value associated with `key`. O(1).\n     * Does not revert if `key` is not in the map.\n     */\n    function tryGet(\n        BytesToBytesMap storage map,\n        bytes memory key\n    ) internal view returns (bool exists, bytes memory value) {\n        value = map._values[key];\n        exists = bytes(value).length != 0 || contains(map, key);\n    }\n\n    /**\n     * @dev Returns the value associated with `key`. O(1).\n     *\n     * Requirements:\n     *\n     * - `key` must be in the map.\n     */\n    function get(BytesToBytesMap storage map, bytes memory key) internal view returns (bytes memory value) {\n        bool exists;\n        (exists, value) = tryGet(map, key);\n        if (!exists) {\n            revert EnumerableMapNonexistentBytesKey(key);\n        }\n    }\n\n    /**\n     * @dev Returns an array containing all the keys\n     *\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n     * uncallable if the map grows to a point where copying to memory consumes too much gas to fit in a block.\n     */\n    function keys(BytesToBytesMap storage map) internal view returns (bytes[] memory) {\n        return map._keys.values();\n    }\n\n    /**\n     * @dev Returns an array containing a slice of the keys\n     *\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n     * uncallable if the map grows to a point where copying to memory consumes too much gas to fit in a block.\n     */\n    function keys(BytesToBytesMap storage map, uint256 start, uint256 end) internal view returns (bytes[] memory) {\n        return map._keys.values(start, end);\n    }\n}\n"}],"certified":false,"conflicting_implementations":null,"abi":[{"inputs":[{"internalType":"address","name":"_registry","type":"address"},{"internalType":"address","name":"_creForwarder","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"authority","type":"address"}],"name":"AccessManagedInvalidAuthority","type":"error"},{"inputs":[{"internalType":"address","name":"caller","type":"address"},{"internalType":"uint32","name":"delay","type":"uint32"}],"name":"AccessManagedRequiredDelay","type":"error"},{"inputs":[{"internalType":"address","name":"caller","type":"address"}],"name":"AccessManagedUnauthorized","type":"error"},{"inputs":[],"name":"AlreadyAccountingAgent","type":"error"},{"inputs":[],"name":"AlreadyDisabled","type":"error"},{"inputs":[],"name":"AlreadyEnabled","type":"error"},{"inputs":[],"name":"BridgeAdapterAlreadySet","type":"error"},{"inputs":[],"name":"BridgeStateMismatch","type":"error"},{"inputs":[],"name":"CaliberNotEmpty","type":"error"},{"inputs":[],"name":"CreWorkflowIdAlreadyAuthorized","type":"error"},{"inputs":[],"name":"CreWorkflowIdNotAuthorized","type":"error"},{"inputs":[{"internalType":"bytes32","name":"key","type":"bytes32"}],"name":"EnumerableMapNonexistentKey","type":"error"},{"inputs":[{"internalType":"uint256","name":"shares","type":"uint256"},{"internalType":"uint256","name":"max","type":"uint256"}],"name":"ExceededMaxMint","type":"error"},{"inputs":[{"internalType":"uint256","name":"assets","type":"uint256"},{"internalType":"uint256","name":"max","type":"uint256"}],"name":"ExceededMaxWithdraw","type":"error"},{"inputs":[],"name":"InvalidBridgeId","type":"error"},{"inputs":[],"name":"InvalidChainId","type":"error"},{"inputs":[],"name":"InvalidCreMetadataLength","type":"error"},{"inputs":[],"name":"InvalidCreWorkflowId","type":"error"},{"inputs":[],"name":"InvalidInitialization","type":"error"},{"inputs":[],"name":"MaxValueLossExceeded","type":"error"},{"inputs":[],"name":"MinOutputAmountExceedsInputAmount","type":"error"},{"inputs":[],"name":"MismatchedLengths","type":"error"},{"inputs":[],"name":"NotAccountingAgent","type":"error"},{"inputs":[],"name":"NotFactory","type":"error"},{"inputs":[],"name":"NotInitializing","type":"error"},{"inputs":[],"name":"OutTransferNotEnabled","type":"error"},{"inputs":[],"name":"PendingBridgeTransfer","type":"error"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"PriceFeedRouteNotRegistered","type":"error"},{"inputs":[],"name":"ProtectedAccountingAgent","type":"error"},{"inputs":[],"name":"ProtectedChainId","type":"error"},{"inputs":[],"name":"RecoveryMode","type":"error"},{"inputs":[],"name":"ReentrancyGuardReentrantCall","type":"error"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"SafeERC20FailedOperation","type":"error"},{"inputs":[],"name":"SlippageProtection","type":"error"},{"inputs":[],"name":"SpokeBridgeAdapterAlreadySet","type":"error"},{"inputs":[],"name":"SpokeBridgeAdapterNotSet","type":"error"},{"inputs":[],"name":"SpokeCaliberAlreadySet","type":"error"},{"inputs":[],"name":"SpokeCaliberNotEnabled","type":"error"},{"inputs":[],"name":"UnauthorizedCaller","type":"error"},{"inputs":[],"name":"ZeroBridgeAdapterAddress","type":"error"},{"inputs":[],"name":"ZeroChainId","type":"error"},{"inputs":[],"name":"ZeroSpokeCaliberMailboxAddress","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"newAgent","type":"address"}],"name":"AccountingAgentAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"agent","type":"address"}],"name":"AccountingAgentRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"authority","type":"address"}],"name":"AuthorityUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint16","name":"bridgeId","type":"uint16"},{"indexed":true,"internalType":"address","name":"adapter","type":"address"}],"name":"BridgeAdapterSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token","type":"address"}],"name":"BridgingStateReset","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"oldThreshold","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"newThreshold","type":"uint256"}],"name":"CaliberStaleThresholdChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"newCreWorkflowId","type":"bytes32"}],"name":"CreWorkflowIdAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"creWorkflowId","type":"bytes32"}],"name":"CreWorkflowIdRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":true,"internalType":"address","name":"receiver","type":"address"},{"indexed":false,"internalType":"uint256","name":"assets","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"shares","type":"uint256"},{"indexed":true,"internalType":"bytes32","name":"referralKey","type":"bytes32"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"oldDepositor","type":"address"},{"indexed":true,"internalType":"address","name":"newDepositor","type":"address"}],"name":"DepositorChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"oldFeeManager","type":"address"},{"indexed":true,"internalType":"address","name":"newFeeManager","type":"address"}],"name":"FeeManagerChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"oldFeeMintCooldown","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"newFeeMintCooldown","type":"uint256"}],"name":"FeeMintCooldownChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"shares","type":"uint256"}],"name":"FeesMinted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint64","name":"version","type":"uint64"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint16","name":"bridgeId","type":"uint16"},{"indexed":true,"internalType":"uint256","name":"oldMaxBridgeLossBps","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"newMaxBridgeLossBps","type":"uint256"}],"name":"MaxBridgeLossBpsChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"oldMaxAccrualRate","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"newMaxAccrualRate","type":"uint256"}],"name":"MaxFixedFeeAccrualRateChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"oldMaxAccrualRate","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"newMaxAccrualRate","type":"uint256"}],"name":"MaxPerfFeeAccrualRateChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"oldMaxChangeRate","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"newMaxChangeRate","type":"uint256"}],"name":"MaxSharePriceChangeRateChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"oldMechanic","type":"address"},{"indexed":true,"internalType":"address","name":"newMechanic","type":"address"}],"name":"MechanicChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint16","name":"bridgeId","type":"uint16"}],"name":"OutTransferDisabled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint16","name":"bridgeId","type":"uint16"}],"name":"OutTransferEnabled","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"recoveryMode","type":"bool"}],"name":"RecoveryModeChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"receiver","type":"address"},{"indexed":false,"internalType":"uint256","name":"assets","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"shares","type":"uint256"}],"name":"Redeem","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"oldRedeemer","type":"address"},{"indexed":true,"internalType":"address","name":"newRedeemer","type":"address"}],"name":"RedeemerChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"restrictedAccountingMode","type":"bool"}],"name":"RestrictedAccountingModeChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"oldRiskManager","type":"address"},{"indexed":true,"internalType":"address","name":"newRiskManager","type":"address"}],"name":"RiskManagerChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"oldRiskManagerTimelock","type":"address"},{"indexed":true,"internalType":"address","name":"newRiskManagerTimelock","type":"address"}],"name":"RiskManagerTimelockChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"oldSecurityCouncil","type":"address"},{"indexed":true,"internalType":"address","name":"newSecurityCouncil","type":"address"}],"name":"SecurityCouncilChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"oldShareLimit","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"newShareLimit","type":"uint256"}],"name":"ShareLimitChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"chainId","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"bridgeId","type":"uint256"},{"indexed":true,"internalType":"address","name":"adapter","type":"address"}],"name":"SpokeBridgeAdapterSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"chainId","type":"uint256"}],"name":"SpokeCaliberDisabled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"chainId","type":"uint256"}],"name":"SpokeCaliberEnabled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"chainId","type":"uint256"},{"indexed":true,"internalType":"address","name":"caliberMailbox","type":"address"}],"name":"SpokeCaliberMailboxSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"totalAum","type":"uint256"}],"name":"TotalAumUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"chainId","type":"uint256"},{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"TransferToCaliber","type":"event"},{"inputs":[],"name":"accountingToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newAgent","type":"address"}],"name":"addAccountingAgent","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"newCreWorkflowId","type":"bytes32"}],"name":"addCreWorkflowId","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"authority","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"bridgeId","type":"uint16"},{"internalType":"bytes32","name":"messageHash","type":"bytes32"}],"name":"authorizeInBridgeTransfer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"caliberStaleThreshold","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"bridgeId","type":"uint16"},{"internalType":"uint256","name":"transferId","type":"uint256"}],"name":"cancelOutBridgeTransfer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"bridgeId","type":"uint16"},{"internalType":"uint256","name":"transferId","type":"uint256"}],"name":"claimInBridgeTransfer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"shares","type":"uint256"}],"name":"convertToAssets","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"assets","type":"uint256"}],"name":"convertToShares","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"creForwarder","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"assets","type":"uint256"},{"internalType":"address","name":"receiver","type":"address"},{"internalType":"uint256","name":"minShares","type":"uint256"},{"internalType":"bytes32","name":"referralKey","type":"bytes32"}],"name":"deposit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"depositor","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"bridgeId","type":"uint16"}],"name":"disableOutTransfer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"chainId","type":"uint256"}],"name":"disableSpokeCaliber","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"bridgeId","type":"uint16"}],"name":"enableOutTransfer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"chainId","type":"uint256"}],"name":"enableSpokeCaliber","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"feeManager","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"feeMintCooldown","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"bridgeId","type":"uint16"}],"name":"getBridgeAdapter","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"idx","type":"uint256"}],"name":"getIdleToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getIdleTokensLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"bridgeId","type":"uint16"}],"name":"getMaxBridgeLossBps","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"chainId","type":"uint256"},{"internalType":"uint16","name":"bridgeId","type":"uint16"}],"name":"getSpokeBridgeAdapter","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"chainId","type":"uint256"}],"name":"getSpokeCaliberMailbox","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"chainId","type":"uint256"}],"name":"getSpokeCaliberNetAum","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getSpokeCalibersLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"idx","type":"uint256"}],"name":"getSpokeChainId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"hubCaliber","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"initialDepositor","type":"address"},{"internalType":"address","name":"initialRedeemer","type":"address"},{"internalType":"address","name":"initialFeeManager","type":"address"},{"internalType":"uint256","name":"initialCaliberStaleThreshold","type":"uint256"},{"internalType":"uint256","name":"initialMaxFixedFeeAccrualRate","type":"uint256"},{"internalType":"uint256","name":"initialMaxPerfFeeAccrualRate","type":"uint256"},{"internalType":"uint256","name":"initialFeeMintCooldown","type":"uint256"},{"internalType":"uint256","name":"initialShareLimit","type":"uint256"},{"internalType":"uint256","name":"initialMaxSharePriceChangeRate","type":"uint256"}],"internalType":"struct IMachine.MachineInitParams","name":"mParams","type":"tuple"},{"components":[{"internalType":"address","name":"initialMechanic","type":"address"},{"internalType":"address","name":"initialSecurityCouncil","type":"address"},{"internalType":"address","name":"initialRiskManager","type":"address"},{"internalType":"address","name":"initialRiskManagerTimelock","type":"address"},{"internalType":"address","name":"initialAuthority","type":"address"},{"internalType":"bool","name":"initialRestrictedAccountingMode","type":"bool"},{"internalType":"address[]","name":"initialAccountingAgents","type":"address[]"}],"internalType":"struct IMakinaGovernable.MakinaGovernableInitParams","name":"mgParams","type":"tuple"},{"components":[{"internalType":"bytes32[]","name":"initialCreWorkflowIds","type":"bytes32[]"}],"internalType":"struct ISpokeSnapshotConsumer.SpokeSnapshotConsumerInitParams","name":"sscParams","type":"tuple"},{"internalType":"address","name":"_preDepositVault","type":"address"},{"internalType":"address","name":"_shareToken","type":"address"},{"internalType":"address","name":"_accountingToken","type":"address"},{"internalType":"address","name":"_hubCaliber","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"isAccountingAgent","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"isAccountingAuthorized","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"bridgeId","type":"uint16"}],"name":"isBridgeSupported","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isConsumingScheduledOp","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"creWorkflowId","type":"bytes32"}],"name":"isCreWorkflowIdAuthorized","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"isIdleToken","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"bridgeId","type":"uint16"}],"name":"isOutTransferEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"chainId","type":"uint256"}],"name":"isSpokeCaliberEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastGlobalAccountingTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastTotalAum","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"manageTransfer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"maxFixedFeeAccrualRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxMint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxPerfFeeAccrualRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxSharePriceChangeRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxWithdraw","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"mechanic","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"metadata","type":"bytes"},{"internalType":"bytes","name":"report","type":"bytes"}],"name":"onReport","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"operator","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"recoveryMode","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"shares","type":"uint256"},{"internalType":"address","name":"receiver","type":"address"},{"internalType":"uint256","name":"minAssets","type":"uint256"}],"name":"redeem","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"redeemer","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"registry","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"agent","type":"address"}],"name":"removeAccountingAgent","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"creWorkflowId","type":"bytes32"}],"name":"removeCreWorkflowId","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"resetBridgingState","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"restrictedAccountingMode","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"riskManager","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"riskManagerTimelock","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"securityCouncil","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"bridgeId","type":"uint16"},{"internalType":"uint256","name":"transferId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"sendOutBridgeTransfer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newAuthority","type":"address"}],"name":"setAuthority","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"bridgeId","type":"uint16"},{"internalType":"address","name":"bridgeAdapter","type":"address"},{"internalType":"uint256","name":"initialMaxBridgeLossBps","type":"uint256"}],"name":"setBridgeAdapter","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newCaliberStaleThreshold","type":"uint256"}],"name":"setCaliberStaleThreshold","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newDepositor","type":"address"}],"name":"setDepositor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newFeeManager","type":"address"}],"name":"setFeeManager","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newFeeMintCooldown","type":"uint256"}],"name":"setFeeMintCooldown","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"bridgeId","type":"uint16"},{"internalType":"uint256","name":"maxBridgeLossBps","type":"uint256"}],"name":"setMaxBridgeLossBps","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newMaxAccrualRate","type":"uint256"}],"name":"setMaxFixedFeeAccrualRate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newMaxAccrualRate","type":"uint256"}],"name":"setMaxPerfFeeAccrualRate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newMaxSharePriceChangeRate","type":"uint256"}],"name":"setMaxSharePriceChangeRate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newMechanic","type":"address"}],"name":"setMechanic","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"enabled","type":"bool"}],"name":"setRecoveryMode","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newRedeemer","type":"address"}],"name":"setRedeemer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"enabled","type":"bool"}],"name":"setRestrictedAccountingMode","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newRiskManager","type":"address"}],"name":"setRiskManager","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newRiskManagerTimelock","type":"address"}],"name":"setRiskManagerTimelock","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newSecurityCouncil","type":"address"}],"name":"setSecurityCouncil","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newShareLimit","type":"uint256"}],"name":"setShareLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"chainId","type":"uint256"},{"internalType":"uint16","name":"bridgeId","type":"uint16"},{"internalType":"address","name":"adapter","type":"address"}],"name":"setSpokeBridgeAdapter","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"chainId","type":"uint256"},{"internalType":"address","name":"spokeCaliberMailbox","type":"address"},{"internalType":"uint16[]","name":"bridges","type":"uint16[]"},{"internalType":"address[]","name":"adapters","type":"address[]"}],"name":"setSpokeCaliber","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"shareLimit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"shareToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferToHubCaliber","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"bridgeId","type":"uint16"},{"internalType":"uint256","name":"chainId","type":"uint256"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"minOutputAmount","type":"uint256"}],"name":"transferToSpokeCaliber","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"updateTotalAum","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"}],"is_changed_bytecode":false,"is_partially_verified":true,"constructor_args":"0x0000000000000000000000000faeeceab0bcb63be2fe984ea8c77778989d53ea0000000000000000000000000b93082d9b3c7c97facd250082899bacf3af3885"}