{"file_path":"contracts/Pool.sol","creation_status":"success","source_code":"// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.24;\n\nimport {Initializable} from \"./dependencies/openzeppelin-upgradeable/proxy/utils/Initializable.sol\";\nimport {SafeERC20} from \"./dependencies/openzeppelin/token/ERC20/utils/SafeERC20.sol\";\nimport {IERC20} from \"./dependencies/openzeppelin/token/ERC20/IERC20.sol\";\nimport {EnumerableSet} from \"./dependencies/openzeppelin/utils/structs/EnumerableSet.sol\";\nimport {Context, SynthContext} from \"./utils/SynthContext.sol\";\nimport {Pauseable} from \"./utils/Pauseable.sol\";\nimport {ReentrancyGuardDeprecated} from \"./utils/ReentrancyGuardDeprecated.sol\";\nimport {ReentrancyGuardTransient} from \"./utils/ReentrancyGuardTransient.sol\";\nimport {MappedEnumerableSet} from \"./lib/MappedEnumerableSet.sol\";\nimport {WadRayMath} from \"./lib/WadRayMath.sol\";\nimport {IMasterOracle} from \"./interfaces/external/IMasterOracle.sol\";\nimport {ISyntheticToken} from \"./interfaces/ISyntheticToken.sol\";\nimport {IPool} from \"./interfaces/IPool.sol\";\nimport {ISmartFarmingManager} from \"./interfaces/ISmartFarmingManager.sol\";\nimport {IPoolRegistry} from \"./interfaces/IPoolRegistry.sol\";\nimport {ITreasury} from \"./interfaces/ITreasury.sol\";\nimport {IDepositToken} from \"./interfaces/IDepositToken.sol\";\nimport {IRewardsDistributor} from \"./interfaces/IRewardsDistributor.sol\";\nimport {IDebtToken} from \"./interfaces/IDebtToken.sol\";\nimport {IFeeProvider} from \"./interfaces/IFeeProvider.sol\";\nimport {IPauseable} from \"./interfaces/IPauseable.sol\";\nimport {IManageable} from \"./interfaces/IManageable.sol\";\nimport {PoolStorageV4} from \"./storage/PoolStorage.sol\";\n\nerror SyntheticDoesNotExist();\nerror SenderIsNotDebtToken();\nerror SenderIsNotDepositToken();\nerror UserReachedMaxTokens();\nerror PoolRegistryIsNull();\nerror DebtTokenAlreadyExists();\nerror DepositTokenAlreadyExists();\nerror AmountIsZero();\nerror CanNotLiquidateOwnPosition();\nerror PositionIsHealthy();\nerror AmountGreaterThanMaxLiquidable();\nerror RemainingDebtIsLowerThanTheFloor();\nerror AmountIsTooHigh();\nerror DebtTokenDoesNotExist();\nerror DepositTokenDoesNotExist();\nerror SwapFeatureIsInactive();\nerror AmountInIsInvalid();\nerror AddressIsNull();\nerror SyntheticIsNull();\nerror SyntheticIsInUse();\nerror UnderlyingAssetInUse();\nerror ReachedMaxDepositTokens();\nerror RewardDistributorAlreadyExists();\nerror RewardDistributorDoesNotExist();\nerror TotalSupplyIsNotZero();\nerror NewValueIsSameAsCurrent();\nerror MaxLiquidableTooHigh();\nerror CollateralFactorTooHigh();\nerror InvalidDepositToken();\n\n/**\n * @title Pool contract\n */\ncontract Pool is\n    SynthContext,\n    Initializable,\n    ReentrancyGuardDeprecated,\n    ReentrancyGuardTransient,\n    Pauseable,\n    PoolStorageV4\n{\n    using SafeERC20 for IERC20;\n    using SafeERC20 for ISyntheticToken;\n    using WadRayMath for uint256;\n    using EnumerableSet for EnumerableSet.AddressSet;\n    using MappedEnumerableSet for MappedEnumerableSet.AddressSet;\n\n    string public constant VERSION = \"1.4.1\";\n\n    /**\n     * @notice Maximum tokens per pool a user may have\n     */\n    uint256 public constant MAX_TOKENS_PER_USER = 30;\n\n    // Note: Upper bound on `collateralFactor * (1 + liquidationFees)`. The `< 1e36` form only\n    // guarantees liquidation *eventually* helps; at exactly 1e36 it closes 0 wei of the health\n    // gap. This leaves a margin so every liquidation closes >= 2% of the amount repaid.\n    uint256 internal constant MAX_CF_TIMES_LIQUIDATION_FEES = 0.98e36;\n\n    /// @notice Emitted when protocol liquidation fee is updated\n    event DebtFloorUpdated(uint256 oldDebtFloorInUsd, uint256 newDebtFloorInUsd);\n\n    /// @notice Emitted when debt token is enabled\n    event DebtTokenAdded(IDebtToken indexed debtToken);\n\n    /// @notice Emitted when debt token is disabled\n    event DebtTokenRemoved(IDebtToken indexed debtToken);\n\n    /// @notice Emitted when deposit token is enabled\n    event DepositTokenAdded(address indexed depositToken);\n\n    /// @notice Emitted when deposit token is disabled\n    event DepositTokenRemoved(IDepositToken indexed depositToken);\n\n    /// @notice Emitted when fee provider contract is updated\n    event FeeProviderUpdated(IFeeProvider indexed oldFeeProvider, IFeeProvider indexed newFeeProvider);\n\n    /// @notice Emitted when maxLiquidable (liquidation cap) is updated\n    event MaxLiquidableUpdated(uint256 oldMaxLiquidable, uint256 newMaxLiquidable);\n\n    /// @notice Emitted when a position is liquidated\n    event PositionLiquidated(\n        address indexed liquidator,\n        address indexed account,\n        ISyntheticToken indexed syntheticToken,\n        uint256 amountRepaid,\n        uint256 depositSeized,\n        uint256 fee\n    );\n\n    /// @notice Emitted when rewards distributor contract is added\n    event RewardsDistributorAdded(IRewardsDistributor indexed _distributor);\n\n    /// @notice Emitted when rewards distributor contract is removed\n    event RewardsDistributorRemoved(IRewardsDistributor _distributor);\n\n    /// @notice Emitted when SmartFarmingManager contract is updated\n    event SmartFarmingManagerUpdated(\n        ISmartFarmingManager oldSmartFarmingManager,\n        ISmartFarmingManager newSmartFarmingManager\n    );\n\n    /// @notice Emitted when the swap active flag is updated\n    event SwapActiveUpdated(bool newActive);\n\n    /// @notice Emitted when synthetic token is swapped\n    event SyntheticTokenSwapped(\n        address indexed account,\n        ISyntheticToken indexed syntheticTokenIn,\n        ISyntheticToken indexed syntheticTokenOut,\n        uint256 amountIn,\n        uint256 amountOut,\n        uint256 fee\n    );\n\n    /// @notice Emitted when treasury contract is updated\n    event TreasuryUpdated(ITreasury indexed oldTreasury, ITreasury indexed newTreasury);\n\n    /**\n     * @dev Throws if token addition will reach the `account_`'s max\n     */\n    modifier onlyIfAdditionWillNotReachMaxTokens(address account_) {\n        if (debtTokensOfAccount.length(account_) + depositTokensOfAccount.length(account_) >= MAX_TOKENS_PER_USER) {\n            revert UserReachedMaxTokens();\n        }\n        _;\n    }\n\n    /**\n     * @dev Throws if deposit token doesn't exist\n     */\n    modifier onlyIfDepositTokenExists(IDepositToken depositToken_) {\n        if (!doesDepositTokenExist(depositToken_)) revert DepositTokenDoesNotExist();\n        _;\n    }\n\n    /**\n     * @dev Throws if synthetic token doesn't exist\n     */\n    modifier onlyIfSyntheticTokenExists(ISyntheticToken syntheticToken_) {\n        if (!doesSyntheticTokenExist(syntheticToken_)) revert SyntheticDoesNotExist();\n        _;\n    }\n\n    constructor() {\n        _disableInitializers();\n    }\n\n    /// @inheritdoc Context\n    function _msgSender() internal view virtual override(Context, SynthContext) returns (address) {\n        return SynthContext._msgSender();\n    }\n\n    function initialize(IPoolRegistry poolRegistry_) public initializer {\n        if (address(poolRegistry_) == address(0)) revert PoolRegistryIsNull();\n        __Pauseable_init();\n\n        _poolRegistry = poolRegistry_;\n        isSwapActive = true;\n        maxLiquidable = 0.5e18; // 50%\n    }\n\n    /**\n     * @dev Returns the sum of the liquidator incentive and protocol fee of a fee provider\n     */\n    function _liquidationFees(IFeeProvider feeProvider_) private view returns (uint256) {\n        (uint128 _liquidatorIncentive, uint128 _protocolFee) = feeProvider_.liquidationFees();\n        return uint256(_liquidatorIncentive) + _protocolFee;\n    }\n\n    /**\n     * @dev Throws if `_msgSender()` isn't a debt token\n     */\n    function _revertIfSenderIsNotDebtToken(address sender_) private view {\n        if (!doesDebtTokenExist(IDebtToken(sender_))) revert SenderIsNotDebtToken();\n    }\n\n    /**\n     * @dev Throws if `_msgSender()` isn't a deposit token\n     */\n    function _revertIfSenderIsNotDepositToken(address sender_) private view {\n        if (!doesDepositTokenExist(IDepositToken(sender_))) revert SenderIsNotDepositToken();\n    }\n\n    /**\n     * @notice Add a debt token to the per-account list\n     * @dev This function is called from `DebtToken` when user's balance changes from `0`\n     * @dev The caller should ensure to not pass `address(0)` as `_account`\n     * @param account_ The account address\n     */\n    function addToDebtTokensOfAccount(address account_) external onlyIfAdditionWillNotReachMaxTokens(account_) {\n        address _debtToken = _msgSender();\n        _revertIfSenderIsNotDebtToken(_debtToken);\n        if (!debtTokensOfAccount.add(account_, _debtToken)) revert DebtTokenAlreadyExists();\n    }\n\n    /**\n     * @notice Add a deposit token to the per-account list\n     * @dev This function is called from `DepositToken` when user's balance changes from `0`\n     * @dev The caller should ensure to not pass `address(0)` as `_account`\n     * @param account_ The account address\n     */\n    function addToDepositTokensOfAccount(address account_) external onlyIfAdditionWillNotReachMaxTokens(account_) {\n        address _depositToken = _msgSender();\n        _revertIfSenderIsNotDepositToken(_depositToken);\n        if (!depositTokensOfAccount.add(account_, _depositToken)) revert DepositTokenAlreadyExists();\n    }\n\n    /**\n     * @notice Get account's debt by querying latest prices from oracles\n     * @param account_ The account to check\n     * @return _debtInUsd The debt value in USD\n     */\n    function debtOf(address account_) public view override returns (uint256 _debtInUsd) {\n        IMasterOracle _masterOracle = masterOracle();\n        uint256 _length = debtTokensOfAccount.length(account_);\n        for (uint256 i; i < _length; ++i) {\n            IDebtToken _debtToken = IDebtToken(debtTokensOfAccount.at(account_, i));\n            _debtInUsd += _masterOracle.quoteTokenToUsd(\n                address(_debtToken.syntheticToken()),\n                _debtToken.balanceOf(account_)\n            );\n        }\n    }\n\n    /**\n     * @notice Returns whether the debt position from an account is healthy\n     * @param account_ The account to check\n     * @return _isHealthy Whether the account's position is healthy\n     * @return _depositInUsd The total collateral deposited in USD\n     * @return _debtInUsd The total debt in USD\n     * @return _issuableLimitInUsd The max amount of debt (is USD) that can be created (considering collateral factors)\n     * @return _issuableInUsd The amount of debt (is USD) that is free (i.e. can be used to issue synthetic tokens)\n     */\n    function debtPositionOf(\n        address account_\n    )\n        public\n        view\n        override\n        returns (\n            bool _isHealthy,\n            uint256 _depositInUsd,\n            uint256 _debtInUsd,\n            uint256 _issuableLimitInUsd,\n            uint256 _issuableInUsd\n        )\n    {\n        _debtInUsd = debtOf(account_);\n        (_depositInUsd, _issuableLimitInUsd) = depositOf(account_);\n        _isHealthy = _debtInUsd <= _issuableLimitInUsd;\n        _issuableInUsd = _debtInUsd < _issuableLimitInUsd ? _issuableLimitInUsd - _debtInUsd : 0;\n    }\n\n    /**\n     * @notice Get account's total collateral deposited by querying latest prices from oracles\n     * @param account_ The account to check\n     * @return _depositInUsd The total deposit value in USD among all collaterals\n     * @return _issuableLimitInUsd The max value in USD that can be used to issue synthetic tokens\n     */\n    function depositOf(\n        address account_\n    ) public view override returns (uint256 _depositInUsd, uint256 _issuableLimitInUsd) {\n        IMasterOracle _masterOracle = masterOracle();\n        uint256 _length = depositTokensOfAccount.length(account_);\n        for (uint256 i; i < _length; ++i) {\n            IDepositToken _depositToken = IDepositToken(depositTokensOfAccount.at(account_, i));\n            uint256 _amountInUsd = _masterOracle.quoteTokenToUsd(\n                address(_depositToken.underlying()),\n                _depositToken.balanceOf(account_)\n            );\n            _depositInUsd += _amountInUsd;\n            _issuableLimitInUsd += _amountInUsd.wadMul(_depositToken.collateralFactor());\n        }\n    }\n\n    /**\n     * @inheritdoc Pauseable\n     */\n    function everythingStopped() public view override(IPauseable, Pauseable) returns (bool) {\n        return super.everythingStopped() || _poolRegistry.everythingStopped();\n    }\n\n    /**\n     * @notice Returns fee collector address\n     */\n    function feeCollector() external view override returns (address) {\n        return _poolRegistry.feeCollector();\n    }\n\n    /**\n     * @notice Get all debt tokens\n     * @dev 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.\n     */\n    function getDebtTokens() external view override returns (address[] memory) {\n        return debtTokens.values();\n    }\n\n    /**\n     * @notice Get all debt tokens\n     * @dev 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.\n     */\n    function getDebtTokensOfAccount(address account_) external view override returns (address[] memory) {\n        return debtTokensOfAccount.values(account_);\n    }\n\n    /**\n     * @notice Get all deposit tokens\n     * @dev 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.\n     */\n    function getDepositTokens() external view override returns (address[] memory) {\n        return depositTokens.values();\n    }\n\n    /**\n     * @notice Get deposit tokens of an account\n     * @dev 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.\n     */\n    function getDepositTokensOfAccount(address account_) external view override returns (address[] memory) {\n        return depositTokensOfAccount.values(account_);\n    }\n\n    /**\n     * @notice Get all rewards distributors\n     */\n    function getRewardsDistributors() external view override returns (address[] memory) {\n        return rewardsDistributors.values();\n    }\n\n    /**\n     * @notice Check if token is part of the debt offerings\n     * @param debtToken_ Asset to check\n     * @return true if exist\n     */\n    function doesDebtTokenExist(IDebtToken debtToken_) public view override returns (bool) {\n        return debtTokens.contains(address(debtToken_));\n    }\n\n    /**\n     * @notice Check if collateral is supported\n     * @param depositToken_ Asset to check\n     * @return true if exist\n     */\n    function doesDepositTokenExist(IDepositToken depositToken_) public view override returns (bool) {\n        return depositTokens.contains(address(depositToken_));\n    }\n\n    /**\n     * @notice Check if token is part of the synthetic offerings\n     * @param syntheticToken_ Asset to check\n     * @return true if exist\n     */\n    function doesSyntheticTokenExist(ISyntheticToken syntheticToken_) public view override returns (bool) {\n        return address(debtTokenOf[syntheticToken_]) != address(0);\n    }\n\n    /**\n     * @notice Quote synth  `_amountToRepay` in order to seize `totalToSeized_`\n     * @param syntheticToken_ Synth for repayment\n     * @param totalToSeize_ Collateral total amount to size\n     * @param depositToken_ Collateral's deposit token\n     * @return _amountToRepay Synth amount to burn\n     * @return _toLiquidator Seized amount to the liquidator\n     * @return _fee The fee amount to collect\n     */\n    function quoteLiquidateIn(\n        ISyntheticToken syntheticToken_,\n        uint256 totalToSeize_,\n        IDepositToken depositToken_\n    ) public view override returns (uint256 _amountToRepay, uint256 _toLiquidator, uint256 _fee) {\n        (uint128 _liquidatorIncentive, uint128 _protocolFee) = feeProvider.liquidationFees();\n        uint256 _totalFees = _protocolFee + _liquidatorIncentive;\n        uint256 _repayAmountInCollateral = totalToSeize_;\n\n        if (_totalFees > 0) {\n            _repayAmountInCollateral = _repayAmountInCollateral.wadDiv(1e18 + _totalFees);\n        }\n\n        _amountToRepay = masterOracle().quote(\n            address(depositToken_.underlying()),\n            address(syntheticToken_),\n            _repayAmountInCollateral\n        );\n\n        if (_protocolFee > 0) {\n            _fee = _repayAmountInCollateral.wadMul(_protocolFee);\n        }\n\n        if (_liquidatorIncentive > 0) {\n            _toLiquidator = _repayAmountInCollateral.wadMul(1e18 + _liquidatorIncentive);\n        }\n    }\n\n    /**\n     * @notice Quote max allowed synth to repay\n     * @dev I.e. Considers the min amount between collateral's balance and `maxLiquidable` param\n     * @param syntheticToken_ Synth for repayment\n     * @param account_ The account to liquidate\n     * @param depositToken_ Collateral's deposit token\n     * @return _maxAmountToRepay Synth amount to burn\n     */\n    function quoteLiquidateMax(\n        ISyntheticToken syntheticToken_,\n        address account_,\n        IDepositToken depositToken_\n    ) external view override returns (uint256 _maxAmountToRepay) {\n        (bool _isHealthy, , , , ) = debtPositionOf(account_);\n        if (_isHealthy) {\n            return 0;\n        }\n\n        (uint256 _amountToRepay, , ) = quoteLiquidateIn(\n            syntheticToken_,\n            depositToken_.balanceOf(account_),\n            depositToken_\n        );\n\n        _maxAmountToRepay = debtTokenOf[syntheticToken_].balanceOf(account_).wadMul(maxLiquidable);\n\n        if (_amountToRepay < _maxAmountToRepay) {\n            _maxAmountToRepay = _amountToRepay;\n        }\n    }\n\n    /**\n     * @notice Quote collateral  `totalToSeized_` by repaying `amountToRepay_`\n     * @param syntheticToken_ Synth for repayment\n     * @param amountToRepay_ Synth amount to burn\n     * @param depositToken_ Collateral's deposit token\n     * @return _totalToSeize Collateral total amount to size\n     * @return _toLiquidator Seized amount to the liquidator\n     * @return _fee The fee amount to collect\n     */\n    function quoteLiquidateOut(\n        ISyntheticToken syntheticToken_,\n        uint256 amountToRepay_,\n        IDepositToken depositToken_\n    ) public view override returns (uint256 _totalToSeize, uint256 _toLiquidator, uint256 _fee) {\n        _toLiquidator = masterOracle().quote(\n            address(syntheticToken_),\n            address(depositToken_.underlying()),\n            amountToRepay_\n        );\n\n        (uint128 _liquidatorIncentive, uint128 _protocolFee) = feeProvider.liquidationFees();\n\n        if (_protocolFee > 0) {\n            _fee = _toLiquidator.wadMul(_protocolFee);\n        }\n        if (_liquidatorIncentive > 0) {\n            _toLiquidator += _toLiquidator.wadMul(_liquidatorIncentive);\n        }\n\n        _totalToSeize = _fee + _toLiquidator;\n    }\n\n    /**\n     * @notice Quote `_amountIn` to get `amountOut_`\n     * @param syntheticTokenIn_ Synth in\n     * @param syntheticTokenOut_ Synth out\n     * @param amountOut_ Amount out\n     * @return _amountIn Amount in\n     * @return _fee Fee to charge in `syntheticTokenOut_`\n     */\n    function quoteSwapIn(\n        ISyntheticToken syntheticTokenIn_,\n        ISyntheticToken syntheticTokenOut_,\n        uint256 amountOut_\n    ) external view override returns (uint256 _amountIn, uint256 _fee) {\n        uint256 _swapFee = feeProvider.swapFees(address(syntheticTokenIn_), address(syntheticTokenOut_));\n        if (_swapFee > 0) {\n            amountOut_ = amountOut_.wadDiv(1e18 - _swapFee);\n            _fee = amountOut_.wadMul(_swapFee);\n        }\n\n        _amountIn = _poolRegistry.masterOracle().quote(\n            address(syntheticTokenOut_),\n            address(syntheticTokenIn_),\n            amountOut_\n        );\n    }\n\n    /**\n     * @notice Quote `amountOut_` get from `amountIn_`\n     * @param syntheticTokenIn_ Synth in\n     * @param syntheticTokenOut_ Synth out\n     * @param amountIn_ Amount in\n     * @return _amountOut Amount out\n     * @return _fee Fee to charge in `syntheticTokenOut_`\n     */\n    function quoteSwapOut(\n        ISyntheticToken syntheticTokenIn_,\n        ISyntheticToken syntheticTokenOut_,\n        uint256 amountIn_\n    ) public view override returns (uint256 _amountOut, uint256 _fee) {\n        _amountOut = _poolRegistry.masterOracle().quote(\n            address(syntheticTokenIn_),\n            address(syntheticTokenOut_),\n            amountIn_\n        );\n\n        uint256 _swapFee = feeProvider.swapFees(address(syntheticTokenIn_), address(syntheticTokenOut_));\n\n        if (_swapFee > 0) {\n            _fee = _amountOut.wadMul(_swapFee);\n            _amountOut -= _fee;\n        }\n    }\n\n    /**\n     * @notice Burn synthetic token, unlock deposit token and send liquidator incentive\n     * @param syntheticToken_ The msAsset to use for repayment\n     * @param account_ The account with an unhealthy position\n     * @param amountToRepay_ The amount to repay in synthetic token\n     * @param depositToken_ The collateral to seize from\n     * @return _totalSeized Total deposit amount seized from the liquidated account\n     * @return _toLiquidator Share of `_totalSeized` sent to the liquidator\n     * @return _fee Share of `_totalSeized` collected as fee\n     */\n    function liquidate(\n        ISyntheticToken syntheticToken_,\n        address account_,\n        uint256 amountToRepay_,\n        IDepositToken depositToken_\n    )\n        external\n        override\n        whenNotShutdown\n        nonReentrant\n        onlyIfSyntheticTokenExists(syntheticToken_)\n        onlyIfDepositTokenExists(depositToken_)\n        returns (uint256 _totalSeized, uint256 _toLiquidator, uint256 _fee)\n    {\n        address _msgSender = _msgSender();\n\n        if (amountToRepay_ == 0) revert AmountIsZero();\n        if (_msgSender == account_) revert CanNotLiquidateOwnPosition();\n\n        IDebtToken _debtToken = debtTokenOf[syntheticToken_];\n        _debtToken.accrueInterest();\n\n        (bool _isHealthy, , , , ) = debtPositionOf(account_);\n\n        if (_isHealthy) {\n            revert PositionIsHealthy();\n        }\n\n        uint256 _debtTokenBalance = _debtToken.balanceOf(account_);\n\n        if (amountToRepay_.wadDiv(_debtTokenBalance) > maxLiquidable) {\n            revert AmountGreaterThanMaxLiquidable();\n        }\n\n        if (debtFloorInUsd > 0) {\n            uint256 _newDebtInUsd = masterOracle().quoteTokenToUsd(\n                address(syntheticToken_),\n                _debtTokenBalance - amountToRepay_\n            );\n            if (_newDebtInUsd > 0 && _newDebtInUsd < debtFloorInUsd) {\n                revert RemainingDebtIsLowerThanTheFloor();\n            }\n        }\n\n        (_totalSeized, _toLiquidator, _fee) = quoteLiquidateOut(syntheticToken_, amountToRepay_, depositToken_);\n\n        if (_totalSeized > depositToken_.balanceOf(account_)) {\n            revert AmountIsTooHigh();\n        }\n\n        syntheticToken_.burnFor(_msgSender, amountToRepay_);\n        _debtToken.burnFor(account_, amountToRepay_);\n        depositToken_.seize(account_, _msgSender, _toLiquidator);\n\n        if (_fee > 0) {\n            depositToken_.seize(account_, _poolRegistry.feeCollector(), _fee);\n        }\n\n        emit PositionLiquidated(_msgSender, account_, syntheticToken_, amountToRepay_, _totalSeized, _fee);\n    }\n\n    /**\n     * @notice Get MasterOracle contract\n     */\n    function masterOracle() public view override returns (IMasterOracle) {\n        return _poolRegistry.masterOracle();\n    }\n\n    /**\n     * @inheritdoc Pauseable\n     */\n    function paused() public view override(IPauseable, Pauseable) returns (bool) {\n        return super.paused() || _poolRegistry.paused();\n    }\n\n    /**\n     * @notice Remove a debt token from the per-account list\n     * @dev This function is called from `DebtToken` when user's balance changes to `0`\n     * @dev The caller should ensure to not pass `address(0)` as `_account`\n     * @param account_ The account address\n     */\n    function removeFromDebtTokensOfAccount(address account_) external {\n        address _debtToken = _msgSender();\n        _revertIfSenderIsNotDebtToken(_debtToken);\n        if (!debtTokensOfAccount.remove(account_, _debtToken)) revert DebtTokenDoesNotExist();\n    }\n\n    /**\n     * @notice Remove a deposit token from the per-account list\n     * @dev This function is called from `DepositToken` when user's balance changes to `0`\n     * @dev The caller should ensure to not pass `address(0)` as `_account`\n     * @param account_ The account address\n     */\n    function removeFromDepositTokensOfAccount(address account_) external {\n        address _depositToken = _msgSender();\n        _revertIfSenderIsNotDepositToken(_depositToken);\n        if (!depositTokensOfAccount.remove(account_, _depositToken)) revert DepositTokenDoesNotExist();\n    }\n\n    /**\n     * @notice Swap synthetic tokens\n     * @param syntheticTokenIn_ Synthetic token to sell\n     * @param syntheticTokenOut_ Synthetic token to buy\n     * @param amountIn_ Amount to swap\n     */\n    function swap(\n        ISyntheticToken syntheticTokenIn_,\n        ISyntheticToken syntheticTokenOut_,\n        uint256 amountIn_\n    )\n        external\n        override\n        whenNotShutdown\n        nonReentrant\n        onlyIfSyntheticTokenExists(syntheticTokenIn_)\n        onlyIfSyntheticTokenExists(syntheticTokenOut_)\n        returns (uint256 _amountOut, uint256 _fee)\n    {\n        address _msgSender = _msgSender();\n\n        if (!isSwapActive) revert SwapFeatureIsInactive();\n        if (amountIn_ == 0 || amountIn_ > syntheticTokenIn_.balanceOf(_msgSender)) revert AmountInIsInvalid();\n\n        syntheticTokenIn_.burnFor(_msgSender, amountIn_);\n\n        (_amountOut, _fee) = quoteSwapOut(syntheticTokenIn_, syntheticTokenOut_, amountIn_);\n\n        if (_fee > 0) {\n            syntheticTokenOut_.mint(_poolRegistry.feeCollector(), _fee);\n        }\n\n        syntheticTokenOut_.mint(_msgSender, _amountOut);\n\n        emit SyntheticTokenSwapped(_msgSender, syntheticTokenIn_, syntheticTokenOut_, amountIn_, _amountOut, _fee);\n    }\n\n    /// @inheritdoc SynthContext\n    function poolRegistry() public view override(IPool, SynthContext) returns (IPoolRegistry) {\n        return _poolRegistry;\n    }\n\n    /**\n     * @notice Add debt token to offerings\n     * @dev Must keep `debtTokenOf` mapping updated\n     */\n    function addDebtToken(IDebtToken debtToken_) external onlyGovernor {\n        if (address(debtToken_) == address(0)) revert AddressIsNull();\n        ISyntheticToken _syntheticToken = debtToken_.syntheticToken();\n        if (address(_syntheticToken) == address(0)) revert SyntheticIsNull();\n        if (address(debtTokenOf[_syntheticToken]) != address(0)) revert SyntheticIsInUse();\n\n        if (!debtTokens.add(address(debtToken_))) revert DebtTokenAlreadyExists();\n\n        debtTokenOf[_syntheticToken] = debtToken_;\n\n        emit DebtTokenAdded(debtToken_);\n    }\n\n    /**\n     * @notice Add deposit token (i.e. collateral) to Synth\n     */\n    function addDepositToken(address depositToken_) external onlyGovernor {\n        if (depositToken_ == address(0)) revert AddressIsNull();\n        if (IManageable(depositToken_).pool() != IPool(address(this))) revert InvalidDepositToken();\n        IERC20 _underlying = IDepositToken(depositToken_).underlying();\n        if (address(depositTokenOf[_underlying]) != address(0)) revert UnderlyingAssetInUse();\n        // Note: The `CF * (1 + liquidationFees) < 1` invariant must hold, with a margin (see the constant)\n        if (\n            IDepositToken(depositToken_).collateralFactor() * (1e18 + _liquidationFees(feeProvider)) >=\n            MAX_CF_TIMES_LIQUIDATION_FEES\n        ) {\n            revert CollateralFactorTooHigh();\n        }\n        // Note: Fee collector collects deposit tokens as fee\n        if (depositTokens.length() >= MAX_TOKENS_PER_USER) revert ReachedMaxDepositTokens();\n\n        if (!depositTokens.add(depositToken_)) revert DepositTokenAlreadyExists();\n\n        depositTokenOf[_underlying] = IDepositToken(depositToken_);\n\n        emit DepositTokenAdded(depositToken_);\n    }\n\n    /**\n     * @notice Add a RewardsDistributor contract\n     */\n    function addRewardsDistributor(IRewardsDistributor distributor_) external onlyGovernor {\n        if (address(distributor_) == address(0)) revert AddressIsNull();\n        if (!rewardsDistributors.add(address(distributor_))) revert RewardDistributorAlreadyExists();\n        emit RewardsDistributorAdded(distributor_);\n    }\n\n    /**\n     * @notice Remove debt token from offerings\n     * @dev Must keep `debtTokenOf` mapping updated\n     */\n    function removeDebtToken(IDebtToken debtToken_) external onlyGovernor {\n        if (debtToken_.totalSupply() > 0) revert TotalSupplyIsNotZero();\n        if (!debtTokens.remove(address(debtToken_))) revert DebtTokenDoesNotExist();\n\n        delete debtTokenOf[debtToken_.syntheticToken()];\n\n        emit DebtTokenRemoved(debtToken_);\n    }\n\n    /**\n     * @notice Remove deposit token (i.e. collateral) from Synth\n     */\n    function removeDepositToken(IDepositToken depositToken_) external onlyGovernor {\n        if (depositToken_.totalSupply() > 0) revert TotalSupplyIsNotZero();\n\n        if (!depositTokens.remove(address(depositToken_))) revert DepositTokenDoesNotExist();\n        delete depositTokenOf[depositToken_.underlying()];\n\n        emit DepositTokenRemoved(depositToken_);\n    }\n\n    /**\n     * @notice Remove a RewardsDistributor contract\n     */\n    function removeRewardsDistributor(IRewardsDistributor distributor_) external onlyGovernor {\n        if (address(distributor_) == address(0)) revert AddressIsNull();\n        if (!rewardsDistributors.remove(address(distributor_))) revert RewardDistributorDoesNotExist();\n\n        emit RewardsDistributorRemoved(distributor_);\n    }\n\n    /**\n     * @notice Turn swap on/off\n     */\n    function toggleIsSwapActive() external onlyGovernor {\n        bool _newIsSwapActive = !isSwapActive;\n        emit SwapActiveUpdated(_newIsSwapActive);\n        isSwapActive = _newIsSwapActive;\n    }\n\n    /**\n     * @notice Update debt floor\n     */\n    function updateDebtFloor(uint256 newDebtFloorInUsd_) external onlyGovernor {\n        uint256 _currentDebtFloorInUsd = debtFloorInUsd;\n        if (newDebtFloorInUsd_ == _currentDebtFloorInUsd) revert NewValueIsSameAsCurrent();\n        emit DebtFloorUpdated(_currentDebtFloorInUsd, newDebtFloorInUsd_);\n        debtFloorInUsd = newDebtFloorInUsd_;\n    }\n\n    /**\n     * @notice Update maxLiquidable (liquidation cap)\n     */\n    function updateMaxLiquidable(uint256 newMaxLiquidable_) external onlyGovernor {\n        if (newMaxLiquidable_ > 1e18) revert MaxLiquidableTooHigh();\n        uint256 _currentMaxLiquidable = maxLiquidable;\n        if (newMaxLiquidable_ == _currentMaxLiquidable) revert NewValueIsSameAsCurrent();\n        emit MaxLiquidableUpdated(_currentMaxLiquidable, newMaxLiquidable_);\n        maxLiquidable = newMaxLiquidable_;\n    }\n\n    /**\n     * @notice Update treasury contract - will migrate funds to the new contract\n     */\n    function updateTreasury(ITreasury newTreasury_) external onlyGovernor {\n        if (address(newTreasury_) == address(0)) revert AddressIsNull();\n        ITreasury _currentTreasury = treasury;\n        if (newTreasury_ == _currentTreasury) revert NewValueIsSameAsCurrent();\n\n        if (address(_currentTreasury) != address(0)) {\n            _currentTreasury.migrateTo(address(newTreasury_));\n        }\n\n        emit TreasuryUpdated(_currentTreasury, newTreasury_);\n        treasury = newTreasury_;\n    }\n\n    /**\n     * @notice Update FeeProvider contract\n     */\n    function updateFeeProvider(IFeeProvider feeProvider_) external onlyGovernor {\n        if (address(feeProvider_) == address(0)) revert AddressIsNull();\n        IFeeProvider _current = feeProvider;\n        if (feeProvider_ == _current) revert NewValueIsSameAsCurrent();\n        uint256 _fees = _liquidationFees(feeProvider_);\n        // Note: Validate only when the new provider charges more. Lowering fees can never break the\n        // invariant, a like-for-like swap must not be blocked by collateral already above the bound,\n        // and a fresh pool has no current provider to compare against (nor any deposit token yet).\n        if (address(_current) != address(0) && _fees > _liquidationFees(_current)) {\n            uint256 _length = depositTokens.length();\n            for (uint256 i; i < _length; ++i) {\n                if (\n                    IDepositToken(depositTokens.at(i)).collateralFactor() * (1e18 + _fees) >=\n                    MAX_CF_TIMES_LIQUIDATION_FEES\n                ) revert CollateralFactorTooHigh();\n            }\n        }\n        emit FeeProviderUpdated(_current, feeProvider_);\n        feeProvider = feeProvider_;\n    }\n\n    /**\n     * @notice Update SmartFarmingManager contract\n     */\n    function updateSmartFarmingManager(ISmartFarmingManager newSmartFarmingManager_) external onlyGovernor {\n        if (address(newSmartFarmingManager_) == address(0)) revert AddressIsNull();\n        ISmartFarmingManager _current = smartFarmingManager;\n        if (newSmartFarmingManager_ == _current) revert NewValueIsSameAsCurrent();\n\n        emit SmartFarmingManagerUpdated(_current, newSmartFarmingManager_);\n        smartFarmingManager = newSmartFarmingManager_;\n    }\n\n    /**\n     * @inheritdoc Pauseable\n     */\n    function isGuardian(address sender_) public view override returns (bool) {\n        return _poolRegistry.isGuardian(sender_);\n    }\n}\n","deployed_bytecode":"0x60806040526004361061039a575f3560e01c80637f51bb1f116101db578063d283e75f11610101578063f0c80d3b1161009f578063fb01600d1161006e578063fb01600d14610af3578063fc0e74d114610b07578063fcfff16f14610b1b578063ffa1ad7414610b2f576103b8565b8063f0c80d3b14610a8c578063f3b27bc314610aab578063f609280914610abf578063f8977b8414610ad4576103b8565b8063df791e50116100db578063df791e5014610a25578063e35bff9614610a44578063eaada38214610a64578063ecf3a3f914610a78576103b8565b8063d283e75f1461099e578063dbe466b1146109bd578063dde3ab95146109dc576103b8565b80639ab620dd11610179578063c415b95c11610148578063c415b95c1461092d578063c4d66de814610941578063c4d68a1a14610960578063d176e05f1461097f576103b8565b80639ab620dd146108a95780639f8f0fa8146108bd578063afcff50f146108f1578063b6aa515b1461090e576103b8565b8063892d522a116101b5578063892d522a1461082d5780638a11a3701461084c57806396aaccfe1461086b578063984a68b51461088a576103b8565b80637f51bb1f146107c65780638456cb59146107e557806387cddc86146107f9576103b8565b80634066fdea116102c057806363c56d421161025e57806375c6f8ec1161022d57806375c6f8ec1461074a578063770b69b41461076957806379e40cba146107885780637d355163146107a7576103b8565b806363c56d42146106d957806369c5dfd8146106f85780636b4f41af1461070c5780636c3393671461072b576103b8565b806356aaee2d1161029a57806356aaee2d146106685780635c975abb1461068757806361d027b31461069b57806362c06767146106ba576103b8565b80634066fdea14610616578063450058f8146106355780634ff9b74a14610654576103b8565b80632adcb0c6116103385780633c2dc254116103075780633c2dc2541461058a5780633de2f6b2146105c45780633f4ba83a146105e35780633f5fc131146105f7576103b8565b80632adcb0c6146105085780632bcb849c146105275780632dd6adb5146105465780633605b51b14610569576103b8565b80631a4660ce116103745780631a4660ce146104755780631ccfbc4f1461049657806323e3fbd5146104ca578063275038d0146104e9576103b8565b80630c340a24146103d15780630c68ba211461040d5780631a0dd00b1461043c576103b8565b366103b857604051636436c22d60e11b815260040160405180910390fd5b60405163a0152e6360e01b815260040160405180910390fd5b3480156103dc575f80fd5b506002546103f0906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b348015610418575f80fd5b5061042c610427366004614630565b610b6c565b6040519015158152602001610404565b348015610447575f80fd5b5061042c610456366004614630565b6001600160a01b039081165f9081526016602052604090205416151590565b348015610480575f80fd5b5061049461048f36600461464b565b610bde565b005b3480156104a1575f80fd5b506104b56104b0366004614662565b610c76565b60408051928352602083019190915201610404565b3480156104d5575f80fd5b506104b56104e4366004614630565b610e10565b3480156104f4575f80fd5b50610494610503366004614630565b611020565b348015610513575f80fd5b506104b5610522366004614662565b611061565b348015610532575f80fd5b50610494610541366004614630565b6111e5565b348015610551575f80fd5b5061055b600b5481565b604051908152602001610404565b348015610574575f80fd5b5061057d6113dd565b60405161040491906146a0565b348015610595575f80fd5b506105a96105a43660046146ec565b6113ee565b60408051938452602084019290925290820152606001610404565b3480156105cf575f80fd5b506105a96105de36600461472b565b6115de565b3480156105ee575f80fd5b50610494611bc9565b348015610602575f80fd5b50610494610611366004614630565b611c96565b348015610621575f80fd5b506018546103f0906001600160a01b031681565b348015610640575f80fd5b5061042c61064f366004614630565b611d19565b34801561065f575f80fd5b5061057d611d25565b348015610673575f80fd5b50610494610682366004614630565b611d31565b348015610692575f80fd5b5061042c611dec565b3480156106a6575f80fd5b50600d546103f0906001600160a01b031681565b3480156106c5575f80fd5b506104946106d4366004614662565b611e75565b3480156106e4575f80fd5b506104946106f3366004614630565b611ea9565b348015610703575f80fd5b5061055b601e81565b348015610717575f80fd5b50610494610726366004614630565b611f6d565b348015610736575f80fd5b506105a96107453660046146ec565b61210a565b348015610755575f80fd5b50610494610764366004614630565b6122be565b348015610774575f80fd5b50610494610783366004614630565b6122fb565b348015610793575f80fd5b506104946107a2366004614630565b612379565b3480156107b2575f80fd5b5061057d6107c1366004614630565b61266a565b3480156107d1575f80fd5b506104946107e0366004614630565b612677565b3480156107f0575f80fd5b506104946127ce565b348015610804575f80fd5b506103f0610813366004614630565b60106020525f90815260409020546001600160a01b031681565b348015610838575f80fd5b50610494610847366004614630565b61287c565b348015610857575f80fd5b506003546103f0906001600160a01b031681565b348015610876575f80fd5b50601b546103f0906001600160a01b031681565b348015610895575f80fd5b5061055b6108a436600461477b565b612970565b3480156108b4575f80fd5b50610494612aab565b3480156108c8575f80fd5b506103f06108d7366004614630565b60166020525f90815260409020546001600160a01b031681565b3480156108fc575f80fd5b50600c546001600160a01b03166103f0565b348015610919575f80fd5b50610494610928366004614630565b612b42565b348015610938575f80fd5b506103f0612bc1565b34801561094c575f80fd5b5061049461095b366004614630565b612c2c565b34801561096b575f80fd5b5061049461097a366004614630565b612cf2565b34801561098a575f80fd5b5061057d610999366004614630565b612e8c565b3480156109a9575f80fd5b5061055b6109b8366004614630565b612e99565b3480156109c8575f80fd5b506104946109d7366004614630565b61302b565b3480156109e7575f80fd5b506109fb6109f6366004614630565b6131c5565b6040805195151586526020860194909452928401919091526060830152608082015260a001610404565b348015610a30575f80fd5b506104b5610a3f366004614662565b61320b565b348015610a4f575f80fd5b50600c5461042c90600160a01b900460ff1681565b348015610a6f575f80fd5b506103f061358a565b348015610a83575f80fd5b5061042c6135d1565b348015610a97575f80fd5b50610494610aa636600461464b565b613636565b348015610ab6575f80fd5b506104946136f7565b348015610aca575f80fd5b5061055b60045481565b348015610adf575f80fd5b5061042c610aee366004614630565b613795565b348015610afe575f80fd5b5061057d6137a1565b348015610b12575f80fd5b506104946137ad565b348015610b26575f80fd5b50610494613878565b348015610b3a575f80fd5b50610b5f60405180604001604052806005815260200164312e342e3160d81b81525081565b60405161040491906147da565b600c54604051630c68ba2160e01b81526001600160a01b0383811660048301525f921690630c68ba2190602401602060405180830381865afa158015610bb4573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610bd8919061480c565b92915050565b610be661391f565b6002546001600160a01b03908116911614610c1457604051634b98449160e11b815260040160405180910390fd5b600454808203610c3757604051630333a68160e41b815260040160405180910390fd5b60408051828152602081018490527f0662703672e57800b9439de3a419c9155283ad25ea7776c139c876bd8b93bb98910160405180910390a150600455565b601854604051634c6bf1d360e11b81526001600160a01b03858116600483015284811660248301525f9283928392909116906398d7e3a690604401602060405180830381865afa158015610ccc573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610cf0919061482b565b90508015610d2357610d14610d0d82670de0b6b3a7640000614856565b8590613928565b9350610d20848261395b565b91505b600c5f9054906101000a90046001600160a01b03166001600160a01b031663eaada3826040518163ffffffff1660e01b8152600401602060405180830381865afa158015610d73573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610d979190614869565b6001600160a01b031663b64663848688876040518463ffffffff1660e01b8152600401610dc693929190614884565b602060405180830381865afa158015610de1573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610e05919061482b565b925050935093915050565b5f805f610e1b61358a565b90505f610e29601386613991565b90505f5b81811015611018575f610e42601388846139ae565b90505f846001600160a01b0316638d0dba00836001600160a01b0316636f307dc36040518163ffffffff1660e01b8152600401602060405180830381865afa158015610e90573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610eb49190614869565b6040516370a0823160e01b81526001600160a01b038c811660048301528616906370a0823190602401602060405180830381865afa158015610ef8573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610f1c919061482b565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401602060405180830381865afa158015610f63573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610f87919061482b565b9050610f9381886148a8565b9650610fff826001600160a01b031663df011c416040518163ffffffff1660e01b8152600401602060405180830381865afa158015610fd4573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610ff8919061482b565b829061395b565b61100990876148a8565b95505050806001019050610e2d565b505050915091565b5f61102961391f565b9050611034816139c2565b611040601383836139eb565b61105d5760405163a67d528360e01b815260040160405180910390fd5b5050565b5f80600c5f9054906101000a90046001600160a01b03166001600160a01b031663eaada3826040518163ffffffff1660e01b8152600401602060405180830381865afa1580156110b3573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906110d79190614869565b6001600160a01b031663b64663848686866040518463ffffffff1660e01b815260040161110693929190614884565b602060405180830381865afa158015611121573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611145919061482b565b601854604051634c6bf1d360e11b81526001600160a01b03888116600483015287811660248301529294505f92909116906398d7e3a690604401602060405180830381865afa15801561119a573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111be919061482b565b905080156111dc576111d0838261395b565b9150610e058284614856565b50935093915050565b6111ed61391f565b6002546001600160a01b0390811691161461121b57604051634b98449160e11b815260040160405180910390fd5b6001600160a01b0381166112425760405163fb7566d760e01b815260040160405180910390fd5b6018546001600160a01b0390811690821681900361127357604051630333a68160e41b815260040160405180910390fd5b5f61127d836139f7565b90506001600160a01b0382161580159061129e575061129b826139f7565b81115b15611379575f6112ae600e613a7b565b90505f5b81811015611376576ebcbdbafe6df79544308248000000006112dc84670de0b6b3a76400006148a8565b6112e7600e84613a84565b6001600160a01b031663df011c416040518163ffffffff1660e01b8152600401602060405180830381865afa158015611322573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611346919061482b565b61135091906148bb565b1061136e57604051639479a57160e01b815260040160405180910390fd5b6001016112b2565b50505b826001600160a01b0316826001600160a01b03167f66fa9df7ccacf7a0c110fd7dd4591f59c76a798409b4aeaf850002679baca45560405160405180910390a35050601880546001600160a01b0319166001600160a01b0392909216919091179055565b60606113e96019613a8f565b905090565b6018546040805163cfc0c69f60e01b815281515f9384938493849384936001600160a01b03169263cfc0c69f92600480820193918290030181865afa158015611439573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061145d91906148e8565b90925090505f61146d8383614919565b6001600160801b0316905087811561149e5761149b61149483670de0b6b3a76400006148a8565b8290613928565b90505b6114a661358a565b6001600160a01b031663b6466384896001600160a01b0316636f307dc36040518163ffffffff1660e01b8152600401602060405180830381865afa1580156114f0573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906115149190614869565b8c846040518463ffffffff1660e01b815260040161153493929190614884565b602060405180830381865afa15801561154f573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611573919061482b565b96506001600160801b0383161561159a57611597816001600160801b03851661395b565b94505b6001600160801b038416156115d1576115ce6115be85670de0b6b3a7640000614919565b82906001600160801b031661395b565b95505b5050505093509350939050565b5f805f6115e96135d1565b1561160757604051631b0e923f60e11b815260040160405180910390fd5b61160f613a9b565b6001600160a01b038088165f908152601660205260409020548891166116485760405163a596698b60e01b815260040160405180910390fd5b8461165281613795565b61166f5760405163a67d528360e01b815260040160405180910390fd5b5f61167861391f565b9050875f0361169a576040516310eb483f60e21b815260040160405180910390fd5b886001600160a01b0316816001600160a01b0316036116cc57604051630ecda8a760e01b815260040160405180910390fd5b6001600160a01b03808b165f9081526016602052604080822054815163a6afed9560e01b81529151931692839263a6afed95926004808201939182900301818387803b15801561171a575f80fd5b505af115801561172c573d5f803e3d5ffd5b505050505f61173a8b6131c5565b505050509050801561175f5760405163202881bd60e11b815260040160405180910390fd5b6040516370a0823160e01b81526001600160a01b038c811660048301525f91908416906370a0823190602401602060405180830381865afa1580156117a6573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906117ca919061482b565b600b549091506117da8c83613928565b11156117f95760405163e292f24f60e01b815260040160405180910390fd5b600454156118c0575f61180a61358a565b6001600160a01b0316638d0dba008f6118238f86614856565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401602060405180830381865afa15801561186a573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061188e919061482b565b90505f811180156118a0575060045481105b156118be576040516332b9d47360e01b815260040160405180910390fd5b505b6118cb8d8c8c61210a565b6040516370a0823160e01b8152929b5090995097506001600160a01b038b16906370a082319061190e908f906004016001600160a01b0391909116815260200190565b602060405180830381865afa158015611929573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061194d919061482b565b89111561196d57604051635de1e54160e01b815260040160405180910390fd5b604051631dd319cb60e01b81526001600160a01b038581166004830152602482018d90528e1690631dd319cb906044015f604051808303815f87803b1580156119b4575f80fd5b505af11580156119c6573d5f803e3d5ffd5b5050604051631dd319cb60e01b81526001600160a01b038f81166004830152602482018f905286169250631dd319cb91506044015f604051808303815f87803b158015611a11575f80fd5b505af1158015611a23573d5f803e3d5ffd5b505060405163b2a02ff160e01b81526001600160a01b038d16925063b2a02ff19150611a57908f9088908d90600401614884565b5f604051808303815f87803b158015611a6e575f80fd5b505af1158015611a80573d5f803e3d5ffd5b505050505f871115611b5d57896001600160a01b031663b2a02ff18d600c5f9054906101000a90046001600160a01b03166001600160a01b031663c415b95c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611aec573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611b109190614869565b8a6040518463ffffffff1660e01b8152600401611b2f93929190614884565b5f604051808303815f87803b158015611b46575f80fd5b505af1158015611b58573d5f803e3d5ffd5b505050505b604080518c8152602081018b90529081018890526001600160a01b03808f16918e8216918716907fe1c3870e3d7d5199a16d200133088e6e3f7012d28571e442a110b4c83b5e3b949060600160405180910390a4505050505050611bbf613b0a565b9450945094915050565b611bd1611dec565b611bee5760405163bc871ce560e01b815260040160405180910390fd5b611bf66135d1565b15611c1457604051631b0e923f60e11b815260040160405180910390fd5b611c1c61391f565b6002546001600160a01b03908116911614611c4a57604051634b98449160e11b815260040160405180910390fd5b6003805460ff60a01b19169055611c5f61391f565b6001600160a01b03167f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa60405160405180910390a2565b80601e611ca4601383613991565b611caf601484613991565b611cb991906148a8565b10611cd7576040516306ceeb8360e21b815260040160405180910390fd5b5f611ce061391f565b9050611ceb816139c2565b611cf760138483613b34565b611d145760405163dd40dad960e01b815260040160405180910390fd5b505050565b5f610bd8601183613b40565b60606113e96011613a8f565b611d3961391f565b6002546001600160a01b03908116911614611d6757604051634b98449160e11b815260040160405180910390fd5b6001600160a01b038116611d8e5760405163fb7566d760e01b815260040160405180910390fd5b611d99601982613b61565b611db657604051631e577fa560e31b815260040160405180910390fd5b6040516001600160a01b038216907f5579b1eead2d904c2b05255a92f5a4a4f3e234ae0a4efe538adef3c1794e1cea905f90a250565b6003545f90600160a01b900460ff16806113e95750600c5f9054906101000a90046001600160a01b03166001600160a01b0316635c975abb6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611e51573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906113e9919061480c565b611e7d613b75565b6001600160a01b038316611e9557611d148282613bab565b611d146001600160a01b0384168383613cc5565b611eb161391f565b6002546001600160a01b03908116911614611edf57604051634b98449160e11b815260040160405180910390fd5b6001600160a01b038116611f065760405163fb7566d760e01b815260040160405180910390fd5b611f11601982613d17565b611f2e576040516362c4c75f60e01b815260040160405180910390fd5b6040516001600160a01b03821681527f5412e32b52c11e4b232ab59f3660d55b48eb20735ccb2c67a0a1ebea0d6fe0199060200160405180910390a150565b611f7561391f565b6002546001600160a01b03908116911614611fa357604051634b98449160e11b815260040160405180910390fd5b6001600160a01b038116611fca5760405163fb7566d760e01b815260040160405180910390fd5b5f816001600160a01b0316638230ecd66040518163ffffffff1660e01b8152600401602060405180830381865afa158015612007573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061202b9190614869565b90506001600160a01b0381166120545760405163013a1b4360e51b815260040160405180910390fd5b6001600160a01b038181165f90815260166020526040902054161561208c5760405163fa9b809960e01b815260040160405180910390fd5b612097601183613b61565b6120b457604051631f477b5760e11b815260040160405180910390fd5b6001600160a01b038181165f9081526016602052604080822080546001600160a01b0319169386169384179055517fad48bee6bbb1b8ece321157ad29afc3c6baa177f8dc043132d65038cc601cdd69190a25050565b5f805f61211561358a565b6001600160a01b031663b646638487866001600160a01b0316636f307dc36040518163ffffffff1660e01b8152600401602060405180830381865afa158015612160573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906121849190614869565b886040518463ffffffff1660e01b81526004016121a393929190614884565b602060405180830381865afa1580156121be573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906121e2919061482b565b6018546040805163cfc0c69f60e01b815281519395505f9384936001600160a01b03169263cfc0c69f92600480820193918290030181865afa15801561222a573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061224e91906148e8565b90925090506001600160801b0381161561227857612275846001600160801b03831661395b565b92505b6001600160801b038216156122a75761229a846001600160801b03841661395b565b6122a490856148a8565b93505b6122b184846148a8565b9450505093509350939050565b5f6122c761391f565b90506122d281613d2b565b6122de601483836139eb565b61105d576040516359c937f160e01b815260040160405180910390fd5b80601e612309601383613991565b612314601484613991565b61231e91906148a8565b1061233c576040516306ceeb8360e21b815260040160405180910390fd5b5f61234561391f565b905061235081613d2b565b61235c60148483613b34565b611d1457604051631f477b5760e11b815260040160405180910390fd5b61238161391f565b6002546001600160a01b039081169116146123af57604051634b98449160e11b815260040160405180910390fd5b6001600160a01b0381166123d65760405163fb7566d760e01b815260040160405180910390fd5b306001600160a01b0316816001600160a01b03166316f0115b6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561241c573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906124409190614869565b6001600160a01b0316146124665760405162de080760e01b815260040160405180910390fd5b5f816001600160a01b0316636f307dc36040518163ffffffff1660e01b8152600401602060405180830381865afa1580156124a3573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906124c79190614869565b6001600160a01b038082165f9081526010602052604090205491925016156125025760405163374f601360e11b815260040160405180910390fd5b6018546ebcbdbafe6df795443082480000000090612528906001600160a01b03166139f7565b61253a90670de0b6b3a76400006148a8565b836001600160a01b031663df011c416040518163ffffffff1660e01b8152600401602060405180830381865afa158015612576573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061259a919061482b565b6125a491906148bb565b106125c257604051639479a57160e01b815260040160405180910390fd5b601e6125ce600e613a7b565b106125ec5760405163225b605b60e21b815260040160405180910390fd5b6125f7600e83613b61565b6126145760405163dd40dad960e01b815260040160405180910390fd5b6001600160a01b038181165f9081526010602052604080822080546001600160a01b0319169386169384179055517fdc705e658c7b6c6c01f5802457bf4ffb99f204bf1603e7b1ae3d4c7536611bc29190a25050565b6060610bd8601383613d51565b61267f61391f565b6002546001600160a01b039081169116146126ad57604051634b98449160e11b815260040160405180910390fd5b6001600160a01b0381166126d45760405163fb7566d760e01b815260040160405180910390fd5b600d546001600160a01b0390811690821681900361270557604051630333a68160e41b815260040160405180910390fd5b6001600160a01b0381161561276b576040516326ed7c7960e11b81526001600160a01b038381166004830152821690634ddaf8f2906024015f604051808303815f87803b158015612754575f80fd5b505af1158015612766573d5f803e3d5ffd5b505050505b816001600160a01b0316816001600160a01b03167f4ab5be82436d353e61ca18726e984e561f5c1cc7c6d38b29d2553c790434705a60405160405180910390a350600d80546001600160a01b0319166001600160a01b0392909216919091179055565b6127d6611dec565b156127f457604051631309a56360e01b815260040160405180910390fd5b6127fc61391f565b6002546001600160a01b0390811691161461282a57604051634b98449160e11b815260040160405180910390fd5b6003805460ff60a01b1916600160a01b17905561284561391f565b6001600160a01b03167f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25860405160405180910390a2565b61288461391f565b6002546001600160a01b039081169116146128b257604051634b98449160e11b815260040160405180910390fd5b6001600160a01b0381166128d95760405163fb7566d760e01b815260040160405180910390fd5b601b546001600160a01b0390811690821681900361290a57604051630333a68160e41b815260040160405180910390fd5b604080516001600160a01b038084168252841660208201527f01b723df71593f812e405dc433f7dcf4134ff941def9d2e189a31f3cb1b1963b910160405180910390a150601b80546001600160a01b0319166001600160a01b0392909216919091179055565b5f8061297b846131c5565b5050505090508015612990575f915050612aa4565b6040516370a0823160e01b81526001600160a01b0385811660048301525f91612a07918891908716906370a0823190602401602060405180830381865afa1580156129dd573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612a01919061482b565b866113ee565b5050600b546001600160a01b038881165f90815260166020526040908190205490516370a0823160e01b81528983166004820152939450612a93939116906370a0823190602401602060405180830381865afa158015612a69573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612a8d919061482b565b9061395b565b925082811015612aa1578092505b50505b9392505050565b612ab361391f565b6002546001600160a01b03908116911614612ae157604051634b98449160e11b815260040160405180910390fd5b600c54604051600160a01b90910460ff1615808252907fc8011ac148e14ab1e8f93a022ebc29088beedc705027c8eb9514d6d69c5b23639060200160405180910390a1600c8054911515600160a01b0260ff60a01b19909216919091179055565b612b4a61391f565b6002546001600160a01b03908116911614612b7857604051634b98449160e11b815260040160405180910390fd5b6001600160a01b038116612b9f57604051634c267bfb60e01b815260040160405180910390fd5b600380546001600160a01b0319166001600160a01b0392909216919091179055565b600c54604080516331056e5760e21b815290515f926001600160a01b03169163c415b95c9160048083019260209291908290030181865afa158015612c08573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906113e99190614869565b5f612c376001613d5e565b90508015612c4e575f805461ff0019166101001790555b6001600160a01b038216612c7557604051637cb62f2b60e11b815260040160405180910390fd5b612c7d613de7565b600c80546001600160a81b0319166001600160a01b03841617600160a01b1790556706f05b59d3b20000600b55801561105d575f805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050565b612cfa61391f565b6002546001600160a01b03908116911614612d2857604051634b98449160e11b815260040160405180910390fd5b5f816001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612d65573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612d89919061482b565b1115612da85760405163066097f160e31b815260040160405180910390fd5b612db3601182613d17565b612dd0576040516359c937f160e01b815260040160405180910390fd5b60165f826001600160a01b0316638230ecd66040518163ffffffff1660e01b8152600401602060405180830381865afa158015612e0f573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612e339190614869565b6001600160a01b039081168252602082019290925260409081015f90812080546001600160a01b03191690559051918316917f81e9205ee5a9e1289fad5baa5e74bd49d4613652eb4626bb15925bf9fdbc0feb9190a250565b6060610bd8601483613d51565b5f80612ea361358a565b90505f612eb1601485613991565b90505f5b81811015613023575f612eca601487846139ae565b9050836001600160a01b0316638d0dba00826001600160a01b0316638230ecd66040518163ffffffff1660e01b8152600401602060405180830381865afa158015612f17573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612f3b9190614869565b6040516370a0823160e01b81526001600160a01b038a811660048301528516906370a0823190602401602060405180830381865afa158015612f7f573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612fa3919061482b565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401602060405180830381865afa158015612fea573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061300e919061482b565b61301890866148a8565b945050600101612eb5565b505050919050565b61303361391f565b6002546001600160a01b0390811691161461306157604051634b98449160e11b815260040160405180910390fd5b5f816001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561309e573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906130c2919061482b565b11156130e15760405163066097f160e31b815260040160405180910390fd5b6130ec600e82613d17565b6131095760405163a67d528360e01b815260040160405180910390fd5b60105f826001600160a01b0316636f307dc36040518163ffffffff1660e01b8152600401602060405180830381865afa158015613148573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061316c9190614869565b6001600160a01b039081168252602082019290925260409081015f90812080546001600160a01b03191690559051918316917fe5a19a76470297a1f85f9a38f3ff148b4c8cdc1209e074dbe59db5e22eb31a3a9190a250565b5f805f805f6131d386612e99565b92506131de86610e10565b80851115965090945091508183106131f6575f613200565b6132008383614856565b905091939590929450565b5f806132156135d1565b1561323357604051631b0e923f60e11b815260040160405180910390fd5b61323b613a9b565b6001600160a01b038086165f908152601660205260409020548691166132745760405163a596698b60e01b815260040160405180910390fd5b6001600160a01b038086165f908152601660205260409020548691166132ad5760405163a596698b60e01b815260040160405180910390fd5b5f6132b661391f565b600c54909150600160a01b900460ff166132e357604051633840404b60e21b815260040160405180910390fd5b85158061335657506040516370a0823160e01b81526001600160a01b0382811660048301528916906370a0823190602401602060405180830381865afa15801561332f573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613353919061482b565b86115b156133745760405163ca99073960e01b815260040160405180910390fd5b604051631dd319cb60e01b81526001600160a01b03828116600483015260248201889052891690631dd319cb906044015f604051808303815f87803b1580156133bb575f80fd5b505af11580156133cd573d5f803e3d5ffd5b505050506133dc888888611061565b909550935083156134c657866001600160a01b03166340c10f19600c5f9054906101000a90046001600160a01b03166001600160a01b031663c415b95c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613446573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061346a9190614869565b6040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602481018790526044015f604051808303815f87803b1580156134af575f80fd5b505af11580156134c1573d5f803e3d5ffd5b505050505b6040516340c10f1960e01b81526001600160a01b038281166004830152602482018790528816906340c10f19906044015f604051808303815f87803b15801561350d575f80fd5b505af115801561351f573d5f803e3d5ffd5b505060408051898152602081018990529081018790526001600160a01b03808b1693508b811692508416907fafd74f009c0ff7627726f24b568ee5529cd297f6a7a1e43ec363443a13a584209060600160405180910390a4505050613582613b0a565b935093915050565b600c5460408051637556d1c160e11b815290515f926001600160a01b03169163eaada3829160048083019260209291908290030181865afa158015612c08573d5f803e3d5ffd5b6003545f90600160a81b900460ff16806113e95750600c5f9054906101000a90046001600160a01b03166001600160a01b031663ecf3a3f96040518163ffffffff1660e01b8152600401602060405180830381865afa158015611e51573d5f803e3d5ffd5b61363e61391f565b6002546001600160a01b0390811691161461366c57604051634b98449160e11b815260040160405180910390fd5b670de0b6b3a764000081111561369557604051633c2c00b560e21b815260040160405180910390fd5b600b548082036136b857604051630333a68160e41b815260040160405180910390fd5b60408051828152602081018490527f6d8ed4ad9ba67058e16e32fc3c8da2e3358da6cd1599e0e0fb2630d0a19fd49c910160405180910390a150600b55565b6003546001600160a01b03168061370c61391f565b6001600160a01b0316146137335760405163038cdbad60e31b815260040160405180910390fd5b6002546040516001600160a01b038084169216907fd4459d5b8b913cab0244230fd9b1c08b6ceace7fe9230e60d0f74cbffdf849d0905f90a3600280546001600160a01b039092166001600160a01b0319928316179055600380549091169055565b5f610bd8600e83613b40565b60606113e9600e613a8f565b6137b56135d1565b156137d357604051631b0e923f60e11b815260040160405180910390fd5b6002546001600160a01b03166137e761391f565b6001600160a01b031614158015613806575061380461042761391f565b155b1561382457604051632cdbf8e160e21b815260040160405180910390fd5b6003805461ffff60a01b191661010160a01b17905561384161391f565b6001600160a01b03167f28b4c24cb1012c094cd2f59f98e89d791973295f8fda6eaa118022d6d318960a60405160405180910390a2565b6138806135d1565b61389d57604051636e2cff4560e01b815260040160405180910390fd5b6138a561391f565b6002546001600160a01b039081169116146138d357604051634b98449160e11b815260040160405180910390fd5b6003805460ff60a81b191690556138e861391f565b6001600160a01b03167fece7583a70a505ef0e36d4dec768f5ae597713e09c26011022599ee01abdabfc60405160405180910390a2565b5f6113e9613e15565b5f81613935600282614939565b613947670de0b6b3a7640000866148bb565b61395191906148a8565b612aa49190614939565b5f821580613967575081155b1561397357505f610bd8565b670de0b6b3a7640000613987600282614939565b61394784866148bb565b6001600160a01b0381165f90815260208390526040812054612aa4565b5f6139ba848484613f1d565b949350505050565b6139cb81613795565b6139e8576040516326688ebb60e11b815260040160405180910390fd5b50565b5f6139ba848484613f62565b5f805f836001600160a01b031663cfc0c69f6040518163ffffffff1660e01b81526004016040805180830381865afa158015613a35573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613a5991906148e8565b91509150806001600160801b0316826001600160801b03166139ba91906148a8565b5f610bd8825490565b5f612aa48383614105565b60605f612aa48361412b565b7f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f005c15613adb57604051633ee5aeb560e01b815260040160405180910390fd5b613b0860017f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f005b90614184565b565b613b085f7f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f00613b02565b5f6139ba84848461418b565b6001600160a01b0381165f9081526001830160205260408120541515612aa4565b5f612aa4836001600160a01b038416614216565b613b7d61391f565b6002546001600160a01b03908116911614613b0857604051634b98449160e11b815260040160405180910390fd5b80471015613c005760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e636500000060448201526064015b60405180910390fd5b5f826001600160a01b0316826040515f6040518083038185875af1925050503d805f8114613c49576040519150601f19603f3d011682016040523d82523d5f602084013e613c4e565b606091505b5050905080611d145760405162461bcd60e51b815260206004820152603a60248201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260448201527f6563697069656e74206d617920686176652072657665727465640000000000006064820152608401613bf7565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b179052611d14908490614262565b5f612aa4836001600160a01b038416614333565b613d3481611d19565b6139e8576040516304f8b91760e51b815260040160405180910390fd5b60605f6139ba848461441d565b5f8054610100900460ff1615613da3578160ff166001148015613d805750303b155b613d9c5760405162461bcd60e51b8152600401613bf790614958565b505f919050565b5f5460ff808416911610613dc95760405162461bcd60e51b8152600401613bf790614958565b505f805460ff191660ff92909216919091179055600190565b919050565b5f54610100900460ff16613e0d5760405162461bcd60e51b8152600401613bf7906149a6565b613b0861448f565b5f80613e29600c546001600160a01b031690565b90506001600160a01b03811615613f16575f816001600160a01b031663570ca7356040518163ffffffff1660e01b8152600401602060405180830381865afa158015613e77573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613e9b9190614869565b90506001600160a01b0381163303613f1457806001600160a01b031663d2c869a46040518163ffffffff1660e01b8152600401602060405180830381865afa158015613ee9573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613f0d9190614869565b9250505090565b505b3391505090565b6001600160a01b0382165f908152602084905260408120805483908110613f4657613f466149f1565b5f918252602090912001546001600160a01b0316949350505050565b6001600160a01b038083165f908152602085815260408083209385168352600190930190529081205480156140fc575f613f9d600183614856565b6001600160a01b0386165f9081526020889052604081205491925090613fc590600190614856565b905081811461407e576001600160a01b0386165f908152602088905260408120805483908110613ff757613ff76149f1565b5f9182526020808320909101546001600160a01b038a81168452918b90526040909220805491909216925082919085908110614035576140356149f1565b5f91825260208083209190910180546001600160a01b0319166001600160a01b0394851617905589831682528a8152604080832094909316825260019390930190925290208390555b6001600160a01b0386165f9081526020889052604090208054806140a4576140a4614a05565b5f828152602080822083015f1990810180546001600160a01b03191690559092019092556001600160a01b038881168352898252604080842091891684526001918201909252908220919091559350612aa492505050565b5f915050612aa4565b5f825f01828154811061411a5761411a6149f1565b905f5260205f200154905092915050565b6060815f0180548060200260200160405190810160405280929190818152602001828054801561417857602002820191905f5260205f20905b815481526020019060010190808311614164575b50505050509050919050565b80825d5050565b6001600160a01b038083165f908152602085815260408083209385168352600190930190529081205461420f57506001600160a01b038281165f9081526020858152604080832080546001808201835582865284862090910180546001600160a01b0319169688169687179055815495855290810190925290912091909155612aa4565b505f612aa4565b5f81815260018301602052604081205461425b57508154600181810184555f848152602080822090930184905584548482528286019093526040902091909155610bd8565b505f610bd8565b5f6142b6826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b031661450d9092919063ffffffff16565b805190915015611d1457808060200190518101906142d4919061480c565b611d145760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401613bf7565b5f818152600183016020526040812054801561440d575f614355600183614856565b85549091505f9061436890600190614856565b90508181146143c7575f865f018281548110614386576143866149f1565b905f5260205f200154905080875f0184815481106143a6576143a66149f1565b5f918252602080832090910192909255918252600188019052604090208390555b85548690806143d8576143d8614a05565b600190038181905f5260205f20015f90559055856001015f8681526020019081526020015f205f905560019350505050610bd8565b5f915050610bd8565b5092915050565b6001600160a01b0381165f908152602083815260409182902080548351818402810184019094528084526060939283018282801561448257602002820191905f5260205f20905b81546001600160a01b03168152600190910190602001808311614464575b5050505050905092915050565b5f54610100900460ff166144b55760405162461bcd60e51b8152600401613bf7906149a6565b5f6144be61391f565b600280546001600160a01b0319166001600160a01b038316908117909155604051919250905f907fd4459d5b8b913cab0244230fd9b1c08b6ceace7fe9230e60d0f74cbffdf849d0908290a350565b60606139ba84845f85856001600160a01b0385163b61456e5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401613bf7565b5f80866001600160a01b031685876040516145899190614a19565b5f6040518083038185875af1925050503d805f81146145c3576040519150601f19603f3d011682016040523d82523d5f602084013e6145c8565b606091505b50915091506145d88282866145e3565b979650505050505050565b606083156145f2575081612aa4565b8251156146025782518084602001fd5b8160405162461bcd60e51b8152600401613bf791906147da565b6001600160a01b03811681146139e8575f80fd5b5f60208284031215614640575f80fd5b8135612aa48161461c565b5f6020828403121561465b575f80fd5b5035919050565b5f805f60608486031215614674575f80fd5b833561467f8161461c565b9250602084013561468f8161461c565b929592945050506040919091013590565b602080825282518282018190525f9190848201906040850190845b818110156146e05783516001600160a01b0316835292840192918401916001016146bb565b50909695505050505050565b5f805f606084860312156146fe575f80fd5b83356147098161461c565b92506020840135915060408401356147208161461c565b809150509250925092565b5f805f806080858703121561473e575f80fd5b84356147498161461c565b935060208501356147598161461c565b92506040850135915060608501356147708161461c565b939692955090935050565b5f805f6060848603121561478d575f80fd5b83356147988161461c565b925060208401356147a88161461c565b915060408401356147208161461c565b5f5b838110156147d25781810151838201526020016147ba565b50505f910152565b602081525f82518060208401526147f88160408501602087016147b8565b601f01601f19169190910160400192915050565b5f6020828403121561481c575f80fd5b81518015158114612aa4575f80fd5b5f6020828403121561483b575f80fd5b5051919050565b634e487b7160e01b5f52601160045260245ffd5b81810381811115610bd857610bd8614842565b5f60208284031215614879575f80fd5b8151612aa48161461c565b6001600160a01b039384168152919092166020820152604081019190915260600190565b80820180821115610bd857610bd8614842565b8082028115828204841417610bd857610bd8614842565b80516001600160801b0381168114613de2575f80fd5b5f80604083850312156148f9575f80fd5b614902836148d2565b9150614910602084016148d2565b90509250929050565b6001600160801b0381811683821601908082111561441657614416614842565b5f8261495357634e487b7160e01b5f52601260045260245ffd5b500490565b6020808252602e908201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160408201526d191e481a5b9a5d1a585b1a5e995960921b606082015260800190565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b634e487b7160e01b5f52603260045260245ffd5b634e487b7160e01b5f52603160045260245ffd5b5f8251614a2a8184602087016147b8565b919091019291505056fea2646970667358221220f1caeab8c60a6bbe38e7a5629daf57bbe7bafc68fc812b9c9e8a41b81ec2791664736f6c63430008180033","optimization_enabled":true,"verified_twin_address_hash":null,"is_verified":true,"compiler_settings":{"evmVersion":"cancun","libraries":{},"metadata":{"useLiteralContent":true},"optimizer":{"enabled":true,"runs":200},"outputSelection":{"*":{"":["*"],"*":["*"]}}},"optimization_runs":200,"sourcify_repo_url":null,"decoded_constructor_args":null,"compiler_version":"v0.8.24+commit.e11b9ed9","is_verified_via_verifier_alliance":false,"verified_at":"2026-10-01T18:26:55.478630Z","implementations":[],"proxy_type":null,"external_libraries":[],"creation_bytecode":"0x608060405234801562000010575f80fd5b505f6200001c62000079565b600280546001600160a01b0319166001600160a01b038316908117909155604051919250905f907fd4459d5b8b913cab0244230fd9b1c08b6ceace7fe9230e60d0f74cbffdf849d0908290a3506200007362000089565b620002db565b5f6200008462000098565b905090565b6200009560ff620001a9565b50565b5f80620000ad600c546001600160a01b031690565b90506001600160a01b03811615620001a2575f816001600160a01b031663570ca7356040518163ffffffff1660e01b8152600401602060405180830381865afa158015620000fd573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190620001239190620002b6565b90506001600160a01b0381163303620001a057806001600160a01b031663d2c869a46040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000173573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190620001999190620002b6565b9250505090565b505b3391505090565b5f8054610100900460ff16156200022b578160ff166001148015620001cd5750303b155b620002245760405162461bcd60e51b815260206004820152602e60248201525f8051602062004d5383398151915260448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b505f919050565b5f5460ff808416911610620002885760405162461bcd60e51b815260206004820152602e60248201525f8051602062004d5383398151915260448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084016200021b565b505f805460ff191660ff92909216919091179055600190565b6001600160a01b038116811462000095575f80fd5b5f60208284031215620002c7575f80fd5b8151620002d481620002a1565b9392505050565b614a6a80620002e95f395ff3fe60806040526004361061039a575f3560e01c80637f51bb1f116101db578063d283e75f11610101578063f0c80d3b1161009f578063fb01600d1161006e578063fb01600d14610af3578063fc0e74d114610b07578063fcfff16f14610b1b578063ffa1ad7414610b2f576103b8565b8063f0c80d3b14610a8c578063f3b27bc314610aab578063f609280914610abf578063f8977b8414610ad4576103b8565b8063df791e50116100db578063df791e5014610a25578063e35bff9614610a44578063eaada38214610a64578063ecf3a3f914610a78576103b8565b8063d283e75f1461099e578063dbe466b1146109bd578063dde3ab95146109dc576103b8565b80639ab620dd11610179578063c415b95c11610148578063c415b95c1461092d578063c4d66de814610941578063c4d68a1a14610960578063d176e05f1461097f576103b8565b80639ab620dd146108a95780639f8f0fa8146108bd578063afcff50f146108f1578063b6aa515b1461090e576103b8565b8063892d522a116101b5578063892d522a1461082d5780638a11a3701461084c57806396aaccfe1461086b578063984a68b51461088a576103b8565b80637f51bb1f146107c65780638456cb59146107e557806387cddc86146107f9576103b8565b80634066fdea116102c057806363c56d421161025e57806375c6f8ec1161022d57806375c6f8ec1461074a578063770b69b41461076957806379e40cba146107885780637d355163146107a7576103b8565b806363c56d42146106d957806369c5dfd8146106f85780636b4f41af1461070c5780636c3393671461072b576103b8565b806356aaee2d1161029a57806356aaee2d146106685780635c975abb1461068757806361d027b31461069b57806362c06767146106ba576103b8565b80634066fdea14610616578063450058f8146106355780634ff9b74a14610654576103b8565b80632adcb0c6116103385780633c2dc254116103075780633c2dc2541461058a5780633de2f6b2146105c45780633f4ba83a146105e35780633f5fc131146105f7576103b8565b80632adcb0c6146105085780632bcb849c146105275780632dd6adb5146105465780633605b51b14610569576103b8565b80631a4660ce116103745780631a4660ce146104755780631ccfbc4f1461049657806323e3fbd5146104ca578063275038d0146104e9576103b8565b80630c340a24146103d15780630c68ba211461040d5780631a0dd00b1461043c576103b8565b366103b857604051636436c22d60e11b815260040160405180910390fd5b60405163a0152e6360e01b815260040160405180910390fd5b3480156103dc575f80fd5b506002546103f0906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b348015610418575f80fd5b5061042c610427366004614630565b610b6c565b6040519015158152602001610404565b348015610447575f80fd5b5061042c610456366004614630565b6001600160a01b039081165f9081526016602052604090205416151590565b348015610480575f80fd5b5061049461048f36600461464b565b610bde565b005b3480156104a1575f80fd5b506104b56104b0366004614662565b610c76565b60408051928352602083019190915201610404565b3480156104d5575f80fd5b506104b56104e4366004614630565b610e10565b3480156104f4575f80fd5b50610494610503366004614630565b611020565b348015610513575f80fd5b506104b5610522366004614662565b611061565b348015610532575f80fd5b50610494610541366004614630565b6111e5565b348015610551575f80fd5b5061055b600b5481565b604051908152602001610404565b348015610574575f80fd5b5061057d6113dd565b60405161040491906146a0565b348015610595575f80fd5b506105a96105a43660046146ec565b6113ee565b60408051938452602084019290925290820152606001610404565b3480156105cf575f80fd5b506105a96105de36600461472b565b6115de565b3480156105ee575f80fd5b50610494611bc9565b348015610602575f80fd5b50610494610611366004614630565b611c96565b348015610621575f80fd5b506018546103f0906001600160a01b031681565b348015610640575f80fd5b5061042c61064f366004614630565b611d19565b34801561065f575f80fd5b5061057d611d25565b348015610673575f80fd5b50610494610682366004614630565b611d31565b348015610692575f80fd5b5061042c611dec565b3480156106a6575f80fd5b50600d546103f0906001600160a01b031681565b3480156106c5575f80fd5b506104946106d4366004614662565b611e75565b3480156106e4575f80fd5b506104946106f3366004614630565b611ea9565b348015610703575f80fd5b5061055b601e81565b348015610717575f80fd5b50610494610726366004614630565b611f6d565b348015610736575f80fd5b506105a96107453660046146ec565b61210a565b348015610755575f80fd5b50610494610764366004614630565b6122be565b348015610774575f80fd5b50610494610783366004614630565b6122fb565b348015610793575f80fd5b506104946107a2366004614630565b612379565b3480156107b2575f80fd5b5061057d6107c1366004614630565b61266a565b3480156107d1575f80fd5b506104946107e0366004614630565b612677565b3480156107f0575f80fd5b506104946127ce565b348015610804575f80fd5b506103f0610813366004614630565b60106020525f90815260409020546001600160a01b031681565b348015610838575f80fd5b50610494610847366004614630565b61287c565b348015610857575f80fd5b506003546103f0906001600160a01b031681565b348015610876575f80fd5b50601b546103f0906001600160a01b031681565b348015610895575f80fd5b5061055b6108a436600461477b565b612970565b3480156108b4575f80fd5b50610494612aab565b3480156108c8575f80fd5b506103f06108d7366004614630565b60166020525f90815260409020546001600160a01b031681565b3480156108fc575f80fd5b50600c546001600160a01b03166103f0565b348015610919575f80fd5b50610494610928366004614630565b612b42565b348015610938575f80fd5b506103f0612bc1565b34801561094c575f80fd5b5061049461095b366004614630565b612c2c565b34801561096b575f80fd5b5061049461097a366004614630565b612cf2565b34801561098a575f80fd5b5061057d610999366004614630565b612e8c565b3480156109a9575f80fd5b5061055b6109b8366004614630565b612e99565b3480156109c8575f80fd5b506104946109d7366004614630565b61302b565b3480156109e7575f80fd5b506109fb6109f6366004614630565b6131c5565b6040805195151586526020860194909452928401919091526060830152608082015260a001610404565b348015610a30575f80fd5b506104b5610a3f366004614662565b61320b565b348015610a4f575f80fd5b50600c5461042c90600160a01b900460ff1681565b348015610a6f575f80fd5b506103f061358a565b348015610a83575f80fd5b5061042c6135d1565b348015610a97575f80fd5b50610494610aa636600461464b565b613636565b348015610ab6575f80fd5b506104946136f7565b348015610aca575f80fd5b5061055b60045481565b348015610adf575f80fd5b5061042c610aee366004614630565b613795565b348015610afe575f80fd5b5061057d6137a1565b348015610b12575f80fd5b506104946137ad565b348015610b26575f80fd5b50610494613878565b348015610b3a575f80fd5b50610b5f60405180604001604052806005815260200164312e342e3160d81b81525081565b60405161040491906147da565b600c54604051630c68ba2160e01b81526001600160a01b0383811660048301525f921690630c68ba2190602401602060405180830381865afa158015610bb4573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610bd8919061480c565b92915050565b610be661391f565b6002546001600160a01b03908116911614610c1457604051634b98449160e11b815260040160405180910390fd5b600454808203610c3757604051630333a68160e41b815260040160405180910390fd5b60408051828152602081018490527f0662703672e57800b9439de3a419c9155283ad25ea7776c139c876bd8b93bb98910160405180910390a150600455565b601854604051634c6bf1d360e11b81526001600160a01b03858116600483015284811660248301525f9283928392909116906398d7e3a690604401602060405180830381865afa158015610ccc573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610cf0919061482b565b90508015610d2357610d14610d0d82670de0b6b3a7640000614856565b8590613928565b9350610d20848261395b565b91505b600c5f9054906101000a90046001600160a01b03166001600160a01b031663eaada3826040518163ffffffff1660e01b8152600401602060405180830381865afa158015610d73573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610d979190614869565b6001600160a01b031663b64663848688876040518463ffffffff1660e01b8152600401610dc693929190614884565b602060405180830381865afa158015610de1573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610e05919061482b565b925050935093915050565b5f805f610e1b61358a565b90505f610e29601386613991565b90505f5b81811015611018575f610e42601388846139ae565b90505f846001600160a01b0316638d0dba00836001600160a01b0316636f307dc36040518163ffffffff1660e01b8152600401602060405180830381865afa158015610e90573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610eb49190614869565b6040516370a0823160e01b81526001600160a01b038c811660048301528616906370a0823190602401602060405180830381865afa158015610ef8573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610f1c919061482b565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401602060405180830381865afa158015610f63573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610f87919061482b565b9050610f9381886148a8565b9650610fff826001600160a01b031663df011c416040518163ffffffff1660e01b8152600401602060405180830381865afa158015610fd4573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610ff8919061482b565b829061395b565b61100990876148a8565b95505050806001019050610e2d565b505050915091565b5f61102961391f565b9050611034816139c2565b611040601383836139eb565b61105d5760405163a67d528360e01b815260040160405180910390fd5b5050565b5f80600c5f9054906101000a90046001600160a01b03166001600160a01b031663eaada3826040518163ffffffff1660e01b8152600401602060405180830381865afa1580156110b3573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906110d79190614869565b6001600160a01b031663b64663848686866040518463ffffffff1660e01b815260040161110693929190614884565b602060405180830381865afa158015611121573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611145919061482b565b601854604051634c6bf1d360e11b81526001600160a01b03888116600483015287811660248301529294505f92909116906398d7e3a690604401602060405180830381865afa15801561119a573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111be919061482b565b905080156111dc576111d0838261395b565b9150610e058284614856565b50935093915050565b6111ed61391f565b6002546001600160a01b0390811691161461121b57604051634b98449160e11b815260040160405180910390fd5b6001600160a01b0381166112425760405163fb7566d760e01b815260040160405180910390fd5b6018546001600160a01b0390811690821681900361127357604051630333a68160e41b815260040160405180910390fd5b5f61127d836139f7565b90506001600160a01b0382161580159061129e575061129b826139f7565b81115b15611379575f6112ae600e613a7b565b90505f5b81811015611376576ebcbdbafe6df79544308248000000006112dc84670de0b6b3a76400006148a8565b6112e7600e84613a84565b6001600160a01b031663df011c416040518163ffffffff1660e01b8152600401602060405180830381865afa158015611322573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611346919061482b565b61135091906148bb565b1061136e57604051639479a57160e01b815260040160405180910390fd5b6001016112b2565b50505b826001600160a01b0316826001600160a01b03167f66fa9df7ccacf7a0c110fd7dd4591f59c76a798409b4aeaf850002679baca45560405160405180910390a35050601880546001600160a01b0319166001600160a01b0392909216919091179055565b60606113e96019613a8f565b905090565b6018546040805163cfc0c69f60e01b815281515f9384938493849384936001600160a01b03169263cfc0c69f92600480820193918290030181865afa158015611439573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061145d91906148e8565b90925090505f61146d8383614919565b6001600160801b0316905087811561149e5761149b61149483670de0b6b3a76400006148a8565b8290613928565b90505b6114a661358a565b6001600160a01b031663b6466384896001600160a01b0316636f307dc36040518163ffffffff1660e01b8152600401602060405180830381865afa1580156114f0573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906115149190614869565b8c846040518463ffffffff1660e01b815260040161153493929190614884565b602060405180830381865afa15801561154f573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611573919061482b565b96506001600160801b0383161561159a57611597816001600160801b03851661395b565b94505b6001600160801b038416156115d1576115ce6115be85670de0b6b3a7640000614919565b82906001600160801b031661395b565b95505b5050505093509350939050565b5f805f6115e96135d1565b1561160757604051631b0e923f60e11b815260040160405180910390fd5b61160f613a9b565b6001600160a01b038088165f908152601660205260409020548891166116485760405163a596698b60e01b815260040160405180910390fd5b8461165281613795565b61166f5760405163a67d528360e01b815260040160405180910390fd5b5f61167861391f565b9050875f0361169a576040516310eb483f60e21b815260040160405180910390fd5b886001600160a01b0316816001600160a01b0316036116cc57604051630ecda8a760e01b815260040160405180910390fd5b6001600160a01b03808b165f9081526016602052604080822054815163a6afed9560e01b81529151931692839263a6afed95926004808201939182900301818387803b15801561171a575f80fd5b505af115801561172c573d5f803e3d5ffd5b505050505f61173a8b6131c5565b505050509050801561175f5760405163202881bd60e11b815260040160405180910390fd5b6040516370a0823160e01b81526001600160a01b038c811660048301525f91908416906370a0823190602401602060405180830381865afa1580156117a6573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906117ca919061482b565b600b549091506117da8c83613928565b11156117f95760405163e292f24f60e01b815260040160405180910390fd5b600454156118c0575f61180a61358a565b6001600160a01b0316638d0dba008f6118238f86614856565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401602060405180830381865afa15801561186a573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061188e919061482b565b90505f811180156118a0575060045481105b156118be576040516332b9d47360e01b815260040160405180910390fd5b505b6118cb8d8c8c61210a565b6040516370a0823160e01b8152929b5090995097506001600160a01b038b16906370a082319061190e908f906004016001600160a01b0391909116815260200190565b602060405180830381865afa158015611929573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061194d919061482b565b89111561196d57604051635de1e54160e01b815260040160405180910390fd5b604051631dd319cb60e01b81526001600160a01b038581166004830152602482018d90528e1690631dd319cb906044015f604051808303815f87803b1580156119b4575f80fd5b505af11580156119c6573d5f803e3d5ffd5b5050604051631dd319cb60e01b81526001600160a01b038f81166004830152602482018f905286169250631dd319cb91506044015f604051808303815f87803b158015611a11575f80fd5b505af1158015611a23573d5f803e3d5ffd5b505060405163b2a02ff160e01b81526001600160a01b038d16925063b2a02ff19150611a57908f9088908d90600401614884565b5f604051808303815f87803b158015611a6e575f80fd5b505af1158015611a80573d5f803e3d5ffd5b505050505f871115611b5d57896001600160a01b031663b2a02ff18d600c5f9054906101000a90046001600160a01b03166001600160a01b031663c415b95c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611aec573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611b109190614869565b8a6040518463ffffffff1660e01b8152600401611b2f93929190614884565b5f604051808303815f87803b158015611b46575f80fd5b505af1158015611b58573d5f803e3d5ffd5b505050505b604080518c8152602081018b90529081018890526001600160a01b03808f16918e8216918716907fe1c3870e3d7d5199a16d200133088e6e3f7012d28571e442a110b4c83b5e3b949060600160405180910390a4505050505050611bbf613b0a565b9450945094915050565b611bd1611dec565b611bee5760405163bc871ce560e01b815260040160405180910390fd5b611bf66135d1565b15611c1457604051631b0e923f60e11b815260040160405180910390fd5b611c1c61391f565b6002546001600160a01b03908116911614611c4a57604051634b98449160e11b815260040160405180910390fd5b6003805460ff60a01b19169055611c5f61391f565b6001600160a01b03167f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa60405160405180910390a2565b80601e611ca4601383613991565b611caf601484613991565b611cb991906148a8565b10611cd7576040516306ceeb8360e21b815260040160405180910390fd5b5f611ce061391f565b9050611ceb816139c2565b611cf760138483613b34565b611d145760405163dd40dad960e01b815260040160405180910390fd5b505050565b5f610bd8601183613b40565b60606113e96011613a8f565b611d3961391f565b6002546001600160a01b03908116911614611d6757604051634b98449160e11b815260040160405180910390fd5b6001600160a01b038116611d8e5760405163fb7566d760e01b815260040160405180910390fd5b611d99601982613b61565b611db657604051631e577fa560e31b815260040160405180910390fd5b6040516001600160a01b038216907f5579b1eead2d904c2b05255a92f5a4a4f3e234ae0a4efe538adef3c1794e1cea905f90a250565b6003545f90600160a01b900460ff16806113e95750600c5f9054906101000a90046001600160a01b03166001600160a01b0316635c975abb6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611e51573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906113e9919061480c565b611e7d613b75565b6001600160a01b038316611e9557611d148282613bab565b611d146001600160a01b0384168383613cc5565b611eb161391f565b6002546001600160a01b03908116911614611edf57604051634b98449160e11b815260040160405180910390fd5b6001600160a01b038116611f065760405163fb7566d760e01b815260040160405180910390fd5b611f11601982613d17565b611f2e576040516362c4c75f60e01b815260040160405180910390fd5b6040516001600160a01b03821681527f5412e32b52c11e4b232ab59f3660d55b48eb20735ccb2c67a0a1ebea0d6fe0199060200160405180910390a150565b611f7561391f565b6002546001600160a01b03908116911614611fa357604051634b98449160e11b815260040160405180910390fd5b6001600160a01b038116611fca5760405163fb7566d760e01b815260040160405180910390fd5b5f816001600160a01b0316638230ecd66040518163ffffffff1660e01b8152600401602060405180830381865afa158015612007573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061202b9190614869565b90506001600160a01b0381166120545760405163013a1b4360e51b815260040160405180910390fd5b6001600160a01b038181165f90815260166020526040902054161561208c5760405163fa9b809960e01b815260040160405180910390fd5b612097601183613b61565b6120b457604051631f477b5760e11b815260040160405180910390fd5b6001600160a01b038181165f9081526016602052604080822080546001600160a01b0319169386169384179055517fad48bee6bbb1b8ece321157ad29afc3c6baa177f8dc043132d65038cc601cdd69190a25050565b5f805f61211561358a565b6001600160a01b031663b646638487866001600160a01b0316636f307dc36040518163ffffffff1660e01b8152600401602060405180830381865afa158015612160573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906121849190614869565b886040518463ffffffff1660e01b81526004016121a393929190614884565b602060405180830381865afa1580156121be573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906121e2919061482b565b6018546040805163cfc0c69f60e01b815281519395505f9384936001600160a01b03169263cfc0c69f92600480820193918290030181865afa15801561222a573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061224e91906148e8565b90925090506001600160801b0381161561227857612275846001600160801b03831661395b565b92505b6001600160801b038216156122a75761229a846001600160801b03841661395b565b6122a490856148a8565b93505b6122b184846148a8565b9450505093509350939050565b5f6122c761391f565b90506122d281613d2b565b6122de601483836139eb565b61105d576040516359c937f160e01b815260040160405180910390fd5b80601e612309601383613991565b612314601484613991565b61231e91906148a8565b1061233c576040516306ceeb8360e21b815260040160405180910390fd5b5f61234561391f565b905061235081613d2b565b61235c60148483613b34565b611d1457604051631f477b5760e11b815260040160405180910390fd5b61238161391f565b6002546001600160a01b039081169116146123af57604051634b98449160e11b815260040160405180910390fd5b6001600160a01b0381166123d65760405163fb7566d760e01b815260040160405180910390fd5b306001600160a01b0316816001600160a01b03166316f0115b6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561241c573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906124409190614869565b6001600160a01b0316146124665760405162de080760e01b815260040160405180910390fd5b5f816001600160a01b0316636f307dc36040518163ffffffff1660e01b8152600401602060405180830381865afa1580156124a3573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906124c79190614869565b6001600160a01b038082165f9081526010602052604090205491925016156125025760405163374f601360e11b815260040160405180910390fd5b6018546ebcbdbafe6df795443082480000000090612528906001600160a01b03166139f7565b61253a90670de0b6b3a76400006148a8565b836001600160a01b031663df011c416040518163ffffffff1660e01b8152600401602060405180830381865afa158015612576573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061259a919061482b565b6125a491906148bb565b106125c257604051639479a57160e01b815260040160405180910390fd5b601e6125ce600e613a7b565b106125ec5760405163225b605b60e21b815260040160405180910390fd5b6125f7600e83613b61565b6126145760405163dd40dad960e01b815260040160405180910390fd5b6001600160a01b038181165f9081526010602052604080822080546001600160a01b0319169386169384179055517fdc705e658c7b6c6c01f5802457bf4ffb99f204bf1603e7b1ae3d4c7536611bc29190a25050565b6060610bd8601383613d51565b61267f61391f565b6002546001600160a01b039081169116146126ad57604051634b98449160e11b815260040160405180910390fd5b6001600160a01b0381166126d45760405163fb7566d760e01b815260040160405180910390fd5b600d546001600160a01b0390811690821681900361270557604051630333a68160e41b815260040160405180910390fd5b6001600160a01b0381161561276b576040516326ed7c7960e11b81526001600160a01b038381166004830152821690634ddaf8f2906024015f604051808303815f87803b158015612754575f80fd5b505af1158015612766573d5f803e3d5ffd5b505050505b816001600160a01b0316816001600160a01b03167f4ab5be82436d353e61ca18726e984e561f5c1cc7c6d38b29d2553c790434705a60405160405180910390a350600d80546001600160a01b0319166001600160a01b0392909216919091179055565b6127d6611dec565b156127f457604051631309a56360e01b815260040160405180910390fd5b6127fc61391f565b6002546001600160a01b0390811691161461282a57604051634b98449160e11b815260040160405180910390fd5b6003805460ff60a01b1916600160a01b17905561284561391f565b6001600160a01b03167f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25860405160405180910390a2565b61288461391f565b6002546001600160a01b039081169116146128b257604051634b98449160e11b815260040160405180910390fd5b6001600160a01b0381166128d95760405163fb7566d760e01b815260040160405180910390fd5b601b546001600160a01b0390811690821681900361290a57604051630333a68160e41b815260040160405180910390fd5b604080516001600160a01b038084168252841660208201527f01b723df71593f812e405dc433f7dcf4134ff941def9d2e189a31f3cb1b1963b910160405180910390a150601b80546001600160a01b0319166001600160a01b0392909216919091179055565b5f8061297b846131c5565b5050505090508015612990575f915050612aa4565b6040516370a0823160e01b81526001600160a01b0385811660048301525f91612a07918891908716906370a0823190602401602060405180830381865afa1580156129dd573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612a01919061482b565b866113ee565b5050600b546001600160a01b038881165f90815260166020526040908190205490516370a0823160e01b81528983166004820152939450612a93939116906370a0823190602401602060405180830381865afa158015612a69573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612a8d919061482b565b9061395b565b925082811015612aa1578092505b50505b9392505050565b612ab361391f565b6002546001600160a01b03908116911614612ae157604051634b98449160e11b815260040160405180910390fd5b600c54604051600160a01b90910460ff1615808252907fc8011ac148e14ab1e8f93a022ebc29088beedc705027c8eb9514d6d69c5b23639060200160405180910390a1600c8054911515600160a01b0260ff60a01b19909216919091179055565b612b4a61391f565b6002546001600160a01b03908116911614612b7857604051634b98449160e11b815260040160405180910390fd5b6001600160a01b038116612b9f57604051634c267bfb60e01b815260040160405180910390fd5b600380546001600160a01b0319166001600160a01b0392909216919091179055565b600c54604080516331056e5760e21b815290515f926001600160a01b03169163c415b95c9160048083019260209291908290030181865afa158015612c08573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906113e99190614869565b5f612c376001613d5e565b90508015612c4e575f805461ff0019166101001790555b6001600160a01b038216612c7557604051637cb62f2b60e11b815260040160405180910390fd5b612c7d613de7565b600c80546001600160a81b0319166001600160a01b03841617600160a01b1790556706f05b59d3b20000600b55801561105d575f805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050565b612cfa61391f565b6002546001600160a01b03908116911614612d2857604051634b98449160e11b815260040160405180910390fd5b5f816001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612d65573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612d89919061482b565b1115612da85760405163066097f160e31b815260040160405180910390fd5b612db3601182613d17565b612dd0576040516359c937f160e01b815260040160405180910390fd5b60165f826001600160a01b0316638230ecd66040518163ffffffff1660e01b8152600401602060405180830381865afa158015612e0f573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612e339190614869565b6001600160a01b039081168252602082019290925260409081015f90812080546001600160a01b03191690559051918316917f81e9205ee5a9e1289fad5baa5e74bd49d4613652eb4626bb15925bf9fdbc0feb9190a250565b6060610bd8601483613d51565b5f80612ea361358a565b90505f612eb1601485613991565b90505f5b81811015613023575f612eca601487846139ae565b9050836001600160a01b0316638d0dba00826001600160a01b0316638230ecd66040518163ffffffff1660e01b8152600401602060405180830381865afa158015612f17573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612f3b9190614869565b6040516370a0823160e01b81526001600160a01b038a811660048301528516906370a0823190602401602060405180830381865afa158015612f7f573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612fa3919061482b565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401602060405180830381865afa158015612fea573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061300e919061482b565b61301890866148a8565b945050600101612eb5565b505050919050565b61303361391f565b6002546001600160a01b0390811691161461306157604051634b98449160e11b815260040160405180910390fd5b5f816001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561309e573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906130c2919061482b565b11156130e15760405163066097f160e31b815260040160405180910390fd5b6130ec600e82613d17565b6131095760405163a67d528360e01b815260040160405180910390fd5b60105f826001600160a01b0316636f307dc36040518163ffffffff1660e01b8152600401602060405180830381865afa158015613148573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061316c9190614869565b6001600160a01b039081168252602082019290925260409081015f90812080546001600160a01b03191690559051918316917fe5a19a76470297a1f85f9a38f3ff148b4c8cdc1209e074dbe59db5e22eb31a3a9190a250565b5f805f805f6131d386612e99565b92506131de86610e10565b80851115965090945091508183106131f6575f613200565b6132008383614856565b905091939590929450565b5f806132156135d1565b1561323357604051631b0e923f60e11b815260040160405180910390fd5b61323b613a9b565b6001600160a01b038086165f908152601660205260409020548691166132745760405163a596698b60e01b815260040160405180910390fd5b6001600160a01b038086165f908152601660205260409020548691166132ad5760405163a596698b60e01b815260040160405180910390fd5b5f6132b661391f565b600c54909150600160a01b900460ff166132e357604051633840404b60e21b815260040160405180910390fd5b85158061335657506040516370a0823160e01b81526001600160a01b0382811660048301528916906370a0823190602401602060405180830381865afa15801561332f573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613353919061482b565b86115b156133745760405163ca99073960e01b815260040160405180910390fd5b604051631dd319cb60e01b81526001600160a01b03828116600483015260248201889052891690631dd319cb906044015f604051808303815f87803b1580156133bb575f80fd5b505af11580156133cd573d5f803e3d5ffd5b505050506133dc888888611061565b909550935083156134c657866001600160a01b03166340c10f19600c5f9054906101000a90046001600160a01b03166001600160a01b031663c415b95c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613446573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061346a9190614869565b6040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602481018790526044015f604051808303815f87803b1580156134af575f80fd5b505af11580156134c1573d5f803e3d5ffd5b505050505b6040516340c10f1960e01b81526001600160a01b038281166004830152602482018790528816906340c10f19906044015f604051808303815f87803b15801561350d575f80fd5b505af115801561351f573d5f803e3d5ffd5b505060408051898152602081018990529081018790526001600160a01b03808b1693508b811692508416907fafd74f009c0ff7627726f24b568ee5529cd297f6a7a1e43ec363443a13a584209060600160405180910390a4505050613582613b0a565b935093915050565b600c5460408051637556d1c160e11b815290515f926001600160a01b03169163eaada3829160048083019260209291908290030181865afa158015612c08573d5f803e3d5ffd5b6003545f90600160a81b900460ff16806113e95750600c5f9054906101000a90046001600160a01b03166001600160a01b031663ecf3a3f96040518163ffffffff1660e01b8152600401602060405180830381865afa158015611e51573d5f803e3d5ffd5b61363e61391f565b6002546001600160a01b0390811691161461366c57604051634b98449160e11b815260040160405180910390fd5b670de0b6b3a764000081111561369557604051633c2c00b560e21b815260040160405180910390fd5b600b548082036136b857604051630333a68160e41b815260040160405180910390fd5b60408051828152602081018490527f6d8ed4ad9ba67058e16e32fc3c8da2e3358da6cd1599e0e0fb2630d0a19fd49c910160405180910390a150600b55565b6003546001600160a01b03168061370c61391f565b6001600160a01b0316146137335760405163038cdbad60e31b815260040160405180910390fd5b6002546040516001600160a01b038084169216907fd4459d5b8b913cab0244230fd9b1c08b6ceace7fe9230e60d0f74cbffdf849d0905f90a3600280546001600160a01b039092166001600160a01b0319928316179055600380549091169055565b5f610bd8600e83613b40565b60606113e9600e613a8f565b6137b56135d1565b156137d357604051631b0e923f60e11b815260040160405180910390fd5b6002546001600160a01b03166137e761391f565b6001600160a01b031614158015613806575061380461042761391f565b155b1561382457604051632cdbf8e160e21b815260040160405180910390fd5b6003805461ffff60a01b191661010160a01b17905561384161391f565b6001600160a01b03167f28b4c24cb1012c094cd2f59f98e89d791973295f8fda6eaa118022d6d318960a60405160405180910390a2565b6138806135d1565b61389d57604051636e2cff4560e01b815260040160405180910390fd5b6138a561391f565b6002546001600160a01b039081169116146138d357604051634b98449160e11b815260040160405180910390fd5b6003805460ff60a81b191690556138e861391f565b6001600160a01b03167fece7583a70a505ef0e36d4dec768f5ae597713e09c26011022599ee01abdabfc60405160405180910390a2565b5f6113e9613e15565b5f81613935600282614939565b613947670de0b6b3a7640000866148bb565b61395191906148a8565b612aa49190614939565b5f821580613967575081155b1561397357505f610bd8565b670de0b6b3a7640000613987600282614939565b61394784866148bb565b6001600160a01b0381165f90815260208390526040812054612aa4565b5f6139ba848484613f1d565b949350505050565b6139cb81613795565b6139e8576040516326688ebb60e11b815260040160405180910390fd5b50565b5f6139ba848484613f62565b5f805f836001600160a01b031663cfc0c69f6040518163ffffffff1660e01b81526004016040805180830381865afa158015613a35573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613a5991906148e8565b91509150806001600160801b0316826001600160801b03166139ba91906148a8565b5f610bd8825490565b5f612aa48383614105565b60605f612aa48361412b565b7f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f005c15613adb57604051633ee5aeb560e01b815260040160405180910390fd5b613b0860017f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f005b90614184565b565b613b085f7f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f00613b02565b5f6139ba84848461418b565b6001600160a01b0381165f9081526001830160205260408120541515612aa4565b5f612aa4836001600160a01b038416614216565b613b7d61391f565b6002546001600160a01b03908116911614613b0857604051634b98449160e11b815260040160405180910390fd5b80471015613c005760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e636500000060448201526064015b60405180910390fd5b5f826001600160a01b0316826040515f6040518083038185875af1925050503d805f8114613c49576040519150601f19603f3d011682016040523d82523d5f602084013e613c4e565b606091505b5050905080611d145760405162461bcd60e51b815260206004820152603a60248201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260448201527f6563697069656e74206d617920686176652072657665727465640000000000006064820152608401613bf7565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b179052611d14908490614262565b5f612aa4836001600160a01b038416614333565b613d3481611d19565b6139e8576040516304f8b91760e51b815260040160405180910390fd5b60605f6139ba848461441d565b5f8054610100900460ff1615613da3578160ff166001148015613d805750303b155b613d9c5760405162461bcd60e51b8152600401613bf790614958565b505f919050565b5f5460ff808416911610613dc95760405162461bcd60e51b8152600401613bf790614958565b505f805460ff191660ff92909216919091179055600190565b919050565b5f54610100900460ff16613e0d5760405162461bcd60e51b8152600401613bf7906149a6565b613b0861448f565b5f80613e29600c546001600160a01b031690565b90506001600160a01b03811615613f16575f816001600160a01b031663570ca7356040518163ffffffff1660e01b8152600401602060405180830381865afa158015613e77573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613e9b9190614869565b90506001600160a01b0381163303613f1457806001600160a01b031663d2c869a46040518163ffffffff1660e01b8152600401602060405180830381865afa158015613ee9573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613f0d9190614869565b9250505090565b505b3391505090565b6001600160a01b0382165f908152602084905260408120805483908110613f4657613f466149f1565b5f918252602090912001546001600160a01b0316949350505050565b6001600160a01b038083165f908152602085815260408083209385168352600190930190529081205480156140fc575f613f9d600183614856565b6001600160a01b0386165f9081526020889052604081205491925090613fc590600190614856565b905081811461407e576001600160a01b0386165f908152602088905260408120805483908110613ff757613ff76149f1565b5f9182526020808320909101546001600160a01b038a81168452918b90526040909220805491909216925082919085908110614035576140356149f1565b5f91825260208083209190910180546001600160a01b0319166001600160a01b0394851617905589831682528a8152604080832094909316825260019390930190925290208390555b6001600160a01b0386165f9081526020889052604090208054806140a4576140a4614a05565b5f828152602080822083015f1990810180546001600160a01b03191690559092019092556001600160a01b038881168352898252604080842091891684526001918201909252908220919091559350612aa492505050565b5f915050612aa4565b5f825f01828154811061411a5761411a6149f1565b905f5260205f200154905092915050565b6060815f0180548060200260200160405190810160405280929190818152602001828054801561417857602002820191905f5260205f20905b815481526020019060010190808311614164575b50505050509050919050565b80825d5050565b6001600160a01b038083165f908152602085815260408083209385168352600190930190529081205461420f57506001600160a01b038281165f9081526020858152604080832080546001808201835582865284862090910180546001600160a01b0319169688169687179055815495855290810190925290912091909155612aa4565b505f612aa4565b5f81815260018301602052604081205461425b57508154600181810184555f848152602080822090930184905584548482528286019093526040902091909155610bd8565b505f610bd8565b5f6142b6826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b031661450d9092919063ffffffff16565b805190915015611d1457808060200190518101906142d4919061480c565b611d145760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401613bf7565b5f818152600183016020526040812054801561440d575f614355600183614856565b85549091505f9061436890600190614856565b90508181146143c7575f865f018281548110614386576143866149f1565b905f5260205f200154905080875f0184815481106143a6576143a66149f1565b5f918252602080832090910192909255918252600188019052604090208390555b85548690806143d8576143d8614a05565b600190038181905f5260205f20015f90559055856001015f8681526020019081526020015f205f905560019350505050610bd8565b5f915050610bd8565b5092915050565b6001600160a01b0381165f908152602083815260409182902080548351818402810184019094528084526060939283018282801561448257602002820191905f5260205f20905b81546001600160a01b03168152600190910190602001808311614464575b5050505050905092915050565b5f54610100900460ff166144b55760405162461bcd60e51b8152600401613bf7906149a6565b5f6144be61391f565b600280546001600160a01b0319166001600160a01b038316908117909155604051919250905f907fd4459d5b8b913cab0244230fd9b1c08b6ceace7fe9230e60d0f74cbffdf849d0908290a350565b60606139ba84845f85856001600160a01b0385163b61456e5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401613bf7565b5f80866001600160a01b031685876040516145899190614a19565b5f6040518083038185875af1925050503d805f81146145c3576040519150601f19603f3d011682016040523d82523d5f602084013e6145c8565b606091505b50915091506145d88282866145e3565b979650505050505050565b606083156145f2575081612aa4565b8251156146025782518084602001fd5b8160405162461bcd60e51b8152600401613bf791906147da565b6001600160a01b03811681146139e8575f80fd5b5f60208284031215614640575f80fd5b8135612aa48161461c565b5f6020828403121561465b575f80fd5b5035919050565b5f805f60608486031215614674575f80fd5b833561467f8161461c565b9250602084013561468f8161461c565b929592945050506040919091013590565b602080825282518282018190525f9190848201906040850190845b818110156146e05783516001600160a01b0316835292840192918401916001016146bb565b50909695505050505050565b5f805f606084860312156146fe575f80fd5b83356147098161461c565b92506020840135915060408401356147208161461c565b809150509250925092565b5f805f806080858703121561473e575f80fd5b84356147498161461c565b935060208501356147598161461c565b92506040850135915060608501356147708161461c565b939692955090935050565b5f805f6060848603121561478d575f80fd5b83356147988161461c565b925060208401356147a88161461c565b915060408401356147208161461c565b5f5b838110156147d25781810151838201526020016147ba565b50505f910152565b602081525f82518060208401526147f88160408501602087016147b8565b601f01601f19169190910160400192915050565b5f6020828403121561481c575f80fd5b81518015158114612aa4575f80fd5b5f6020828403121561483b575f80fd5b5051919050565b634e487b7160e01b5f52601160045260245ffd5b81810381811115610bd857610bd8614842565b5f60208284031215614879575f80fd5b8151612aa48161461c565b6001600160a01b039384168152919092166020820152604081019190915260600190565b80820180821115610bd857610bd8614842565b8082028115828204841417610bd857610bd8614842565b80516001600160801b0381168114613de2575f80fd5b5f80604083850312156148f9575f80fd5b614902836148d2565b9150614910602084016148d2565b90509250929050565b6001600160801b0381811683821601908082111561441657614416614842565b5f8261495357634e487b7160e01b5f52601260045260245ffd5b500490565b6020808252602e908201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160408201526d191e481a5b9a5d1a585b1a5e995960921b606082015260800190565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b634e487b7160e01b5f52603260045260245ffd5b634e487b7160e01b5f52603160045260245ffd5b5f8251614a2a8184602087016147b8565b919091019291505056fea2646970667358221220f1caeab8c60a6bbe38e7a5629daf57bbe7bafc68fc812b9c9e8a41b81ec2791664736f6c63430008180033496e697469616c697a61626c653a20636f6e747261637420697320616c726561","name":"Pool","is_blueprint":false,"license_type":"none","is_fully_verified":true,"is_verified_via_eth_bytecode_db":true,"language":"solidity","evm_version":"cancun","can_be_visualized_via_sol2uml":true,"is_verified_via_sourcify":false,"additional_sources":[{"file_path":"contracts/dependencies/@layerzerolabs/solidity-examples/token/oft/composable/IOFTReceiver.sol","source_code":"// SPDX-License-Identifier: BUSL-1.1\n\npragma solidity >=0.5.0;\n\ninterface IOFTReceiver {\n    /**\n     * @dev Called by the OFT contract when tokens are received from source chain.\n     * @param _srcChainId The chain id of the source chain.\n     * @param _srcAddress The address of the OFT token contract on the source chain.\n     * @param _nonce The nonce of the transaction on the source chain.\n     * @param _from The address of the account who calls the sendAndCall() on the source chain.\n     * @param _amount The amount of tokens to transfer.\n     * @param _payload Additional data with no specified format.\n     */\n    function onOFTReceived(\n        uint16 _srcChainId,\n        bytes calldata _srcAddress,\n        uint64 _nonce,\n        bytes calldata _from,\n        uint _amount,\n        bytes calldata _payload\n    ) external;\n}\n"},{"file_path":"contracts/interfaces/external/IWETH.sol","source_code":"// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.24;\n\nimport {IERC20} from \"../../dependencies/openzeppelin/token/ERC20/IERC20.sol\";\n\ninterface IWETH is IERC20 {\n    function deposit() external payable;\n\n    function withdraw(uint256) external;\n}\n"},{"file_path":"contracts/interfaces/IFeeProvider.sol","source_code":"// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.24;\n\n/**\n * @notice FeeProvider interface\n */\ninterface IFeeProvider {\n    struct LiquidationFees {\n        uint128 liquidatorIncentive;\n        uint128 protocolFee;\n    }\n\n    function swapFees(address synthIn, address synthOut) external view returns (uint256);\n\n    function depositFee() external view returns (uint256);\n\n    function issueFee() external view returns (uint256);\n\n    function liquidationFees() external view returns (uint128 liquidatorIncentive, uint128 protocolFee);\n\n    function repayFee() external view returns (uint256);\n\n    function withdrawFee() external view returns (uint256);\n}\n"},{"file_path":"contracts/interfaces/external/IStargateBridge.sol","source_code":"// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.24;\n\nimport {ILayerZeroEndpoint} from \"../../dependencies/@layerzerolabs/solidity-examples/interfaces/ILayerZeroEndpoint.sol\";\n\ninterface IStargateBridge {\n    function layerZeroEndpoint() external view returns (ILayerZeroEndpoint _lzEndpoint);\n}\n"},{"file_path":"contracts/storage/AMOStorage.sol","source_code":"// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.24;\n\nimport {EnumerableSet} from \"../dependencies/openzeppelin/utils/structs/EnumerableSet.sol\";\nimport {IPoolRegistry} from \"../interfaces/IPoolRegistry.sol\";\n\ncontract AMOStorage {\n    /**\n     * @notice The Pool Registry\n     */\n    IPoolRegistry internal _poolRegistry;\n\n    /**\n     * @dev Direct deposit keepers\n     */\n    EnumerableSet.AddressSet internal keepers;\n\n    /**\n     * @dev Authorized Vesper Pools\n     */\n    mapping(address => address) public vPools;\n}\n"},{"file_path":"contracts/storage/DebtTokenStorage.sol","source_code":"// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.24;\n\nimport {IDebtToken} from \"../interfaces/IDebtToken.sol\";\nimport {ISyntheticToken} from \"../interfaces/ISyntheticToken.sol\";\n\nabstract contract DebtTokenStorageV1 is IDebtToken {\n    /**\n     * @notice The name of the token\n     */\n    string public override name;\n\n    /**\n     * @notice The symbol of the token\n     */\n    string public override symbol;\n\n    /**\n     * @notice The mapping of the users' minted tokens\n     * @dev This value changes within the mint and burn operations\n     */\n    mapping(address => uint256) internal principalOf;\n\n    /**\n     * @notice The `debtIndex` \"snapshot\" of the account's latest `principalOf` update (i.e. mint/burn)\n     */\n    mapping(address => uint256) internal debtIndexOf;\n\n    /**\n     * @notice The supply cap\n     */\n    uint256 public override maxTotalSupply;\n\n    /**\n     * @notice The total amount of minted tokens\n     */\n    uint256 internal totalSupply_;\n\n    /**\n     * @notice The timestamp when interest accrual was calculated for the last time\n     */\n    uint256 public override lastTimestampAccrued;\n\n    /**\n     * @notice Accumulator of the total earned interest rate since the beginning\n     */\n    uint256 public override debtIndex;\n\n    /**\n     * @notice Interest rate\n     * @dev Use 0.1e18 for 10% APR\n     */\n    uint256 public override interestRate;\n\n    /**\n     * @notice The Synthetic token\n     */\n    ISyntheticToken public override syntheticToken;\n\n    /**\n     * @notice If true, disables msAsset minting on this pool\n     */\n    bool public override isActive;\n\n    /**\n     * @notice The decimals of the token\n     */\n    uint8 public override decimals;\n}\n\nabstract contract DebtTokenStorageV2 is DebtTokenStorageV1 {\n    /**\n     * @notice Pending interest fee to collect\n     */\n    uint256 internal pendingInterestFee;\n}\n"},{"file_path":"contracts/interfaces/IRewardsDistributor.sol","source_code":"// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.24;\n\nimport {IERC20} from \"../dependencies/openzeppelin/token/ERC20/IERC20.sol\";\n\n/**\n * @notice Reward Distributor interface\n */\ninterface IRewardsDistributor {\n    function rewardToken() external view returns (IERC20);\n\n    function tokenSpeeds(IERC20 token_) external view returns (uint256);\n\n    function tokensAccruedOf(address account_) external view returns (uint256);\n\n    function updateBeforeMintOrBurn(IERC20 token_, address account_) external;\n\n    function updateBeforeTransfer(IERC20 token_, address from_, address to_) external;\n\n    function claimable(address account_) external view returns (uint256 _claimable);\n\n    function claimable(address account_, IERC20 token_) external view returns (uint256 _claimable);\n\n    function claimRewards(address account_) external;\n\n    function claimRewards(address account_, IERC20[] memory tokens_) external;\n\n    function claimRewards(address[] memory accounts_, IERC20[] memory tokens_) external;\n\n    function updateTokenSpeed(IERC20 token_, uint256 newSpeed_) external;\n\n    function updateTokenSpeeds(IERC20[] calldata tokens_, uint256[] calldata speeds_) external;\n\n    function tokens(uint256) external view returns (IERC20);\n\n    function tokenStates(IERC20) external view returns (uint224 index, uint32 timestamp);\n\n    function accountIndexOf(IERC20, address) external view returns (uint256);\n}\n"},{"file_path":"contracts/mock/TokenOracleMock.sol","source_code":"// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.24;\n\ncontract TokenOracleMock {\n    mapping(address => uint256) public prices;\n\n    function updatePrice(address token_, uint256 price_) external {\n        prices[token_] = price_;\n    }\n\n    function getPriceInUsd(address token_) external view returns (uint256 _priceInUsd) {\n        return prices[token_];\n    }\n}\n"},{"file_path":"contracts/interfaces/external/IPoolRewards.sol","source_code":"// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.24;\n\ninterface IPoolRewards {\n    function claimReward(address) external;\n\n    function updateReward(address) external;\n\n    function getRewardTokens() external view returns (address[] memory);\n}\n"},{"file_path":"contracts/dependencies/openzeppelin/utils/math/SafeCast.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/math/SafeCast.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\n * checks.\n *\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\n * easily result in undesired exploitation or bugs, since developers usually\n * assume that overflows raise errors. `SafeCast` restores this intuition by\n * reverting the transaction when such an operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n *\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\n * all math on `uint256` and `int256` and then downcasting.\n */\nlibrary SafeCast {\n    /**\n     * @dev Returns the downcasted 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        require(value <= type(uint224).max, \"SafeCast: value doesn't fit in 224 bits\");\n        return uint224(value);\n    }\n\n    /**\n     * @dev Returns the downcasted 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        require(value <= type(uint128).max, \"SafeCast: value doesn't fit in 128 bits\");\n        return uint128(value);\n    }\n\n    /**\n     * @dev Returns the downcasted 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        require(value <= type(uint96).max, \"SafeCast: value doesn't fit in 96 bits\");\n        return uint96(value);\n    }\n\n    /**\n     * @dev Returns the downcasted 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        require(value <= type(uint64).max, \"SafeCast: value doesn't fit in 64 bits\");\n        return uint64(value);\n    }\n\n    /**\n     * @dev Returns the downcasted 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        require(value <= type(uint32).max, \"SafeCast: value doesn't fit in 32 bits\");\n        return uint32(value);\n    }\n\n    /**\n     * @dev Returns the downcasted 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        require(value <= type(uint16).max, \"SafeCast: value doesn't fit in 16 bits\");\n        return uint16(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint8 from uint256, reverting on\n     * overflow (when the input is greater than largest uint8).\n     *\n     * Counterpart to Solidity's `uint8` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 8 bits.\n     */\n    function toUint8(uint256 value) internal pure returns (uint8) {\n        require(value <= type(uint8).max, \"SafeCast: value doesn't fit in 8 bits\");\n        return uint8(value);\n    }\n\n    /**\n     * @dev Converts a signed int256 into an unsigned uint256.\n     *\n     * Requirements:\n     *\n     * - input must be greater than or equal to 0.\n     */\n    function toUint256(int256 value) internal pure returns (uint256) {\n        require(value >= 0, \"SafeCast: value must be positive\");\n        return uint256(value);\n    }\n\n    /**\n     * @dev Returns the downcasted int128 from int256, reverting on\n     * overflow (when the input is less than smallest int128 or\n     * greater than largest int128).\n     *\n     * Counterpart to Solidity's `int128` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 128 bits\n     *\n     * _Available since v3.1._\n     */\n    function toInt128(int256 value) internal pure returns (int128) {\n        require(value >= type(int128).min && value <= type(int128).max, \"SafeCast: value doesn't fit in 128 bits\");\n        return int128(value);\n    }\n\n    /**\n     * @dev Returns the downcasted int64 from int256, reverting on\n     * overflow (when the input is less than smallest int64 or\n     * greater than largest int64).\n     *\n     * Counterpart to Solidity's `int64` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 64 bits\n     *\n     * _Available since v3.1._\n     */\n    function toInt64(int256 value) internal pure returns (int64) {\n        require(value >= type(int64).min && value <= type(int64).max, \"SafeCast: value doesn't fit in 64 bits\");\n        return int64(value);\n    }\n\n    /**\n     * @dev Returns the downcasted int32 from int256, reverting on\n     * overflow (when the input is less than smallest int32 or\n     * greater than largest int32).\n     *\n     * Counterpart to Solidity's `int32` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 32 bits\n     *\n     * _Available since v3.1._\n     */\n    function toInt32(int256 value) internal pure returns (int32) {\n        require(value >= type(int32).min && value <= type(int32).max, \"SafeCast: value doesn't fit in 32 bits\");\n        return int32(value);\n    }\n\n    /**\n     * @dev Returns the downcasted int16 from int256, reverting on\n     * overflow (when the input is less than smallest int16 or\n     * greater than largest int16).\n     *\n     * Counterpart to Solidity's `int16` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 16 bits\n     *\n     * _Available since v3.1._\n     */\n    function toInt16(int256 value) internal pure returns (int16) {\n        require(value >= type(int16).min && value <= type(int16).max, \"SafeCast: value doesn't fit in 16 bits\");\n        return int16(value);\n    }\n\n    /**\n     * @dev Returns the downcasted int8 from int256, reverting on\n     * overflow (when the input is less than smallest int8 or\n     * greater than largest int8).\n     *\n     * Counterpart to Solidity's `int8` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 8 bits.\n     *\n     * _Available since v3.1._\n     */\n    function toInt8(int256 value) internal pure returns (int8) {\n        require(value >= type(int8).min && value <= type(int8).max, \"SafeCast: value doesn't fit in 8 bits\");\n        return int8(value);\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        require(value <= uint256(type(int256).max), \"SafeCast: value doesn't fit in an int256\");\n        return int256(value);\n    }\n}\n"},{"file_path":"contracts/dependencies/@layerzerolabs/solidity-examples/interfaces/ILayerZeroReceiver.sol","source_code":"// SPDX-License-Identifier: MIT\n\npragma solidity >=0.5.0;\n\ninterface ILayerZeroReceiver {\n    // @notice LayerZero endpoint will invoke this function to deliver the message on the destination\n    // @param _srcChainId - the source endpoint identifier\n    // @param _srcAddress - the source sending contract address from the source chain\n    // @param _nonce - the ordered message nonce\n    // @param _payload - the signed payload is the UA bytes has encoded to be sent\n    function lzReceive(uint16 _srcChainId, bytes calldata _srcAddress, uint64 _nonce, bytes calldata _payload) external;\n}\n"},{"file_path":"contracts/mock/PoolRewardsMock.sol","source_code":"// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.24;\n\nimport {IERC20} from \"../dependencies/openzeppelin/token/ERC20/IERC20.sol\";\n\ncontract PoolRewardsMock {\n    address[] public rewardTokens;\n\n    function updateReward(address) external {}\n\n    function getRewardTokens() external view returns (address[] memory) {\n        return rewardTokens;\n    }\n\n    function claimReward(address) external {\n        for (uint256 i; i < rewardTokens.length; ++i) {\n            uint256 _balance = IERC20(rewardTokens[i]).balanceOf(address(this));\n            if (_balance > 0) {\n                IERC20(rewardTokens[i]).transfer(msg.sender, _balance);\n            }\n        }\n    }\n\n    function setRewardTokens(address[] memory rewardTokens_) external {\n        rewardTokens = rewardTokens_;\n    }\n}\n"},{"file_path":"contracts/mock/SwapperMock.sol","source_code":"// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.24;\n\nimport {IERC20} from \"../dependencies/openzeppelin/token/ERC20/IERC20.sol\";\nimport {IMasterOracle} from \"../interfaces/external/IMasterOracle.sol\";\nimport {ISwapper} from \"../interfaces/external/ISwapper.sol\";\n\ncontract SwapperMock is ISwapper {\n    uint256 public rate = 1e18;\n    IMasterOracle masterOracle;\n\n    constructor(IMasterOracle masterOracle_) {\n        masterOracle = masterOracle_;\n    }\n\n    function swapExactInput(\n        address tokenIn_,\n        address tokenOut_,\n        uint256 amountIn_,\n        uint256 amountOutMin_,\n        address receiver_\n    ) external returns (uint256 _amountOut) {\n        IERC20(tokenIn_).transferFrom(msg.sender, address(this), amountIn_);\n        _amountOut = (masterOracle.quote(tokenIn_, tokenOut_, amountIn_) * rate) / 1e18;\n        require(_amountOut >= amountOutMin_, \"swapper-mock-slippage\");\n        require(_amountOut > 100, \"amount-out-zero\");\n        IERC20(tokenOut_).transfer(receiver_, _amountOut);\n    }\n\n    function updateRate(uint256 rate_) external {\n        rate = rate_;\n    }\n}\n"},{"file_path":"contracts/storage/PoolRegistryStorage.sol","source_code":"// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.24;\n\nimport {EnumerableSet} from \"../dependencies/openzeppelin/utils/structs/EnumerableSet.sol\";\nimport {IMasterOracle} from \"../interfaces/external/IMasterOracle.sol\";\nimport {ISwapper} from \"../interfaces/external/ISwapper.sol\";\nimport {IPoolRegistry} from \"../interfaces/IPoolRegistry.sol\";\nimport {IOperator} from \"../interfaces/IOperator.sol\";\n\nabstract contract PoolRegistryStorageV1 is IPoolRegistry {\n    /**\n     * @notice Pools collection\n     */\n    EnumerableSet.AddressSet internal pools;\n\n    /**\n     * @notice Prices' oracle\n     */\n    IMasterOracle public override masterOracle;\n\n    /**\n     * @notice Fee collector address\n     */\n    address public override feeCollector;\n\n    /**\n     * @notice Native token gateway address\n     */\n    address public override nativeTokenGateway;\n\n    /**\n     * @notice Map of the ids of the pools\n     */\n    mapping(address => uint256) public override idOfPool;\n\n    /**\n     * @notice Counter of ids of the pools\n     */\n    uint256 public override nextPoolId;\n\n    /**\n     * @notice Swapper contract\n     */\n    ISwapper public swapper;\n}\n\nabstract contract PoolRegistryStorageV2 is PoolRegistryStorageV1 {\n    /**\n     * @notice The Quoter contract\n     */\n    address private quoter_DEPRECATED;\n\n    /**\n     * @notice The Cross-chain dispatcher contract\n     */\n    address private crossChainDispatcher_DEPRECATED;\n}\n\nabstract contract PoolRegistryStorageV3 is PoolRegistryStorageV2 {\n    /**\n     * @notice Flag that pause/unpause all cross-chain flash repay operations\n     */\n    bool private isCrossChainFlashRepayActive_DEPRECATED;\n}\n\nabstract contract PoolRegistryStorageV4 is PoolRegistryStorageV3 {\n    /**\n     * @notice Pools collection\n     */\n    EnumerableSet.AddressSet internal guardians;\n\n    /**\n     * @notice Flag that pause/unpause all cross-chain flash repay operations\n     */\n    IOperator public operator;\n}\n\nabstract contract PoolRegistryStorageV5 is PoolRegistryStorageV4 {\n    /**\n     * @notice The base gas to pay for cross-chain calls\n     * @dev This limit covers basic token transfer LZ cost\n     */\n    uint256 public lzBaseGasLimit;\n\n    /**\n     * @notice Flag that pause/unpause all cross-chain activities\n     */\n    bool public isBridgingActive;\n\n    /**\n     * @notice Maps supported cross-chain routes (i.e. which chains are allowed to be used as source of liquidity)\n     */\n    mapping(uint16 => bool) public isDestinationChainSupported;\n}\n"},{"file_path":"contracts/utils/SynthContext.sol","source_code":"// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.24;\n\nimport {Context} from \"../dependencies/openzeppelin/utils/Context.sol\";\nimport {IOperator} from \"../interfaces/IOperator.sol\";\nimport {IPoolRegistry} from \"../interfaces/IPoolRegistry.sol\";\n\nabstract contract SynthContext is Context {\n    /// @notice Get pool registry contract\n    function poolRegistry() public view virtual returns (IPoolRegistry);\n\n    /// @inheritdoc Context\n    function _msgSender() internal view virtual override returns (address) {\n        IPoolRegistry _poolRegistry = poolRegistry();\n        if (address(_poolRegistry) != address(0)) {\n            IOperator _operator = _poolRegistry.operator();\n            if (msg.sender == address(_operator)) {\n                return _operator.getActualMsgSender();\n            }\n        }\n\n        return msg.sender;\n    }\n}\n"},{"file_path":"contracts/dependencies/openzeppelin/proxy/transparent/ProxyAdmin.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (proxy/transparent/ProxyAdmin.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./TransparentUpgradeableProxy.sol\";\nimport \"../../access/Ownable.sol\";\n\n/**\n * @dev This is an auxiliary contract meant to be assigned as the admin of a {TransparentUpgradeableProxy}. For an\n * explanation of why you would want to use this see the documentation for {TransparentUpgradeableProxy}.\n */\ncontract ProxyAdmin is Ownable {\n    /**\n     * @dev Returns the current implementation of `proxy`.\n     *\n     * Requirements:\n     *\n     * - This contract must be the admin of `proxy`.\n     */\n    function getProxyImplementation(TransparentUpgradeableProxy proxy) public view virtual returns (address) {\n        // We need to manually run the static call since the getter cannot be flagged as view\n        // bytes4(keccak256(\"implementation()\")) == 0x5c60da1b\n        (bool success, bytes memory returndata) = address(proxy).staticcall(hex\"5c60da1b\");\n        require(success);\n        return abi.decode(returndata, (address));\n    }\n\n    /**\n     * @dev Returns the current admin of `proxy`.\n     *\n     * Requirements:\n     *\n     * - This contract must be the admin of `proxy`.\n     */\n    function getProxyAdmin(TransparentUpgradeableProxy proxy) public view virtual returns (address) {\n        // We need to manually run the static call since the getter cannot be flagged as view\n        // bytes4(keccak256(\"admin()\")) == 0xf851a440\n        (bool success, bytes memory returndata) = address(proxy).staticcall(hex\"f851a440\");\n        require(success);\n        return abi.decode(returndata, (address));\n    }\n\n    /**\n     * @dev Changes the admin of `proxy` to `newAdmin`.\n     *\n     * Requirements:\n     *\n     * - This contract must be the current admin of `proxy`.\n     */\n    function changeProxyAdmin(TransparentUpgradeableProxy proxy, address newAdmin) public virtual onlyOwner {\n        proxy.changeAdmin(newAdmin);\n    }\n\n    /**\n     * @dev Upgrades `proxy` to `implementation`. See {TransparentUpgradeableProxy-upgradeTo}.\n     *\n     * Requirements:\n     *\n     * - This contract must be the admin of `proxy`.\n     */\n    function upgrade(TransparentUpgradeableProxy proxy, address implementation) public virtual onlyOwner {\n        proxy.upgradeTo(implementation);\n    }\n\n    /**\n     * @dev Upgrades `proxy` to `implementation` and calls a function on the new implementation. See\n     * {TransparentUpgradeableProxy-upgradeToAndCall}.\n     *\n     * Requirements:\n     *\n     * - This contract must be the admin of `proxy`.\n     */\n    function upgradeAndCall(\n        TransparentUpgradeableProxy proxy,\n        address implementation,\n        bytes memory data\n    ) public payable virtual onlyOwner {\n        proxy.upgradeToAndCall{value: msg.value}(implementation, data);\n    }\n}\n"},{"file_path":"contracts/dependencies/@layerzerolabs/solidity-examples/contracts-upgradeable/token/oft/OFTCoreUpgradeable.sol","source_code":"// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.2;\n\nimport \"./IOFTCoreUpgradeable.sol\";\nimport \"../../../../../openzeppelin-upgradeable/utils/introspection/ERC165Upgradeable.sol\";\nimport \"../../lzApp/NonblockingLzAppUpgradeable.sol\";\n\nabstract contract OFTCoreUpgradeable is\n    Initializable,\n    NonblockingLzAppUpgradeable,\n    ERC165Upgradeable,\n    IOFTCoreUpgradeable\n{\n    using BytesLib for bytes;\n\n    uint public constant NO_EXTRA_GAS = 0;\n\n    // packet type\n    uint16 public constant PT_SEND = 0;\n\n    bool public useCustomAdapterParams;\n\n    function __OFTCoreUpgradeable_init(address _lzEndpoint) internal onlyInitializing {\n        __Ownable_init_unchained();\n        __LzAppUpgradeable_init_unchained(_lzEndpoint);\n    }\n\n    function __OFTCoreUpgradeable_init_unchained() internal onlyInitializing {}\n\n    function supportsInterface(\n        bytes4 interfaceId\n    ) public view virtual override(ERC165Upgradeable, IERC165Upgradeable) returns (bool) {\n        return interfaceId == type(IOFTCoreUpgradeable).interfaceId || super.supportsInterface(interfaceId);\n    }\n\n    function estimateSendFee(\n        uint16 _dstChainId,\n        bytes calldata _toAddress,\n        uint _amount,\n        bool _useZro,\n        bytes calldata _adapterParams\n    ) public view virtual override returns (uint nativeFee, uint zroFee) {\n        // mock the payload for sendFrom()\n        bytes memory payload = abi.encode(PT_SEND, _toAddress, _amount);\n        return lzEndpoint.estimateFees(_dstChainId, address(this), payload, _useZro, _adapterParams);\n    }\n\n    function sendFrom(\n        address _from,\n        uint16 _dstChainId,\n        bytes calldata _toAddress,\n        uint _amount,\n        address payable _refundAddress,\n        address _zroPaymentAddress,\n        bytes calldata _adapterParams\n    ) public payable virtual override {\n        _send(_from, _dstChainId, _toAddress, _amount, _refundAddress, _zroPaymentAddress, _adapterParams);\n    }\n\n    function setUseCustomAdapterParams(bool _useCustomAdapterParams) public virtual onlyOwner {\n        useCustomAdapterParams = _useCustomAdapterParams;\n        emit SetUseCustomAdapterParams(_useCustomAdapterParams);\n    }\n\n    function _nonblockingLzReceive(\n        uint16 _srcChainId,\n        bytes memory _srcAddress,\n        uint64 _nonce,\n        bytes memory _payload\n    ) internal virtual override {\n        uint16 packetType;\n        assembly {\n            packetType := mload(add(_payload, 32))\n        }\n\n        if (packetType == PT_SEND) {\n            _sendAck(_srcChainId, _srcAddress, _nonce, _payload);\n        } else {\n            revert(\"OFTCore: unknown packet type\");\n        }\n    }\n\n    function _send(\n        address _from,\n        uint16 _dstChainId,\n        bytes memory _toAddress,\n        uint _amount,\n        address payable _refundAddress,\n        address _zroPaymentAddress,\n        bytes memory _adapterParams\n    ) internal virtual {\n        _checkAdapterParams(_dstChainId, PT_SEND, _adapterParams, NO_EXTRA_GAS);\n\n        uint amount = _debitFrom(_from, _dstChainId, _toAddress, _amount);\n\n        bytes memory lzPayload = abi.encode(PT_SEND, _toAddress, amount);\n        _lzSend(_dstChainId, lzPayload, _refundAddress, _zroPaymentAddress, _adapterParams, msg.value);\n\n        emit SendToChain(_dstChainId, _from, _toAddress, amount);\n    }\n\n    function _sendAck(uint16 _srcChainId, bytes memory, uint64, bytes memory _payload) internal virtual {\n        (, bytes memory toAddressBytes, uint amount) = abi.decode(_payload, (uint16, bytes, uint));\n\n        address to = toAddressBytes.toAddress(0);\n\n        amount = _creditTo(_srcChainId, to, amount);\n        emit ReceiveFromChain(_srcChainId, to, amount);\n    }\n\n    function _checkAdapterParams(\n        uint16 _dstChainId,\n        uint16 _pkType,\n        bytes memory _adapterParams,\n        uint _extraGas\n    ) internal virtual {\n        if (useCustomAdapterParams) {\n            _checkGasLimit(_dstChainId, _pkType, _adapterParams, _extraGas);\n        } else {\n            require(_adapterParams.length == 0, \"OFTCore: _adapterParams must be empty.\");\n        }\n    }\n\n    function _debitFrom(\n        address _from,\n        uint16 _dstChainId,\n        bytes memory _toAddress,\n        uint _amount\n    ) internal virtual returns (uint);\n\n    function _creditTo(uint16 _srcChainId, address _toAddress, uint _amount) internal virtual returns (uint);\n\n    /**\n     * @dev This empty reserved space is put in place to allow future versions to add new\n     * variables without shifting down storage in the inheritance chain.\n     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n     */\n    uint[49] private __gap;\n}\n"},{"file_path":"contracts/mock/VPoolMock.sol","source_code":"// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.24;\n\nimport {IERC20, IERC20Metadata, ERC20} from \"../dependencies/openzeppelin/token/ERC20/ERC20.sol\";\nimport {IVPool} from \"../interfaces/external/IVPool.sol\";\n\ncontract VPoolMock is IVPool, ERC20 {\n    address public token;\n\n    constructor(string memory name_, string memory symbol_, address token_) ERC20(name_, symbol_) {\n        token = token_;\n    }\n\n    function deposit(uint256 amount_) external {\n        IERC20(token).transferFrom(msg.sender, address(this), amount_);\n        _mint(msg.sender, amount_ * (10 ** (decimals() - IERC20Metadata(token).decimals())));\n    }\n\n    function withdraw(uint256 shares_) external {\n        _burn(msg.sender, shares_);\n        IERC20(token).transfer(msg.sender, shares_ / (10 ** (decimals() - IERC20Metadata(token).decimals())));\n    }\n\n    function mint(address to_, uint256 amount_) external {\n        _mint(to_, amount_);\n    }\n\n    function poolRewards() external pure returns (address) {\n        revert(\"mock-does-not-implement\");\n    }\n\n    function pricePerShare() external pure returns (uint256) {\n        revert(\"mock-does-not-implement\");\n    }\n}\n"},{"file_path":"contracts/dependencies/@layerzerolabs/solidity-examples/token/oft/composable/IComposableOFT.sol","source_code":"// SPDX-License-Identifier: MIT\n\npragma solidity >=0.5.0;\n\nimport \"./IComposableOFTCore.sol\";\nimport \"../IOFT.sol\";\n\n/**\n * @dev Interface of the OFT standard\n */\ninterface IComposableOFT is IOFT, IComposableOFTCore {\n\n}\n"},{"file_path":"contracts/utils/ReentrancyGuardTransient.sol","source_code":"// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.24;\n\nimport {TransientSlot} from \"../dependencies/openzeppelin/utils/TransientSlot.sol\";\n\n/**\n * @dev Variant of {ReentrancyGuard} that uses transient storage.\n *\n * NOTE: This variant only works on networks where EIP-1153 is available.\n *\n * _Available since v5.1._\n */\nabstract contract ReentrancyGuardTransient {\n    using TransientSlot for *;\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    /**\n     * @dev Unauthorized reentrant call.\n     */\n    error ReentrancyGuardReentrantCall();\n\n    /**\n     * @dev Prevents a contract from calling itself, directly or indirectly.\n     * Calling a `nonReentrant` function from another `nonReentrant`\n     * function is not supported. It is possible to prevent this from happening\n     * by making the `nonReentrant` function external, and making it call a\n     * `private` function that does the actual work.\n     */\n    modifier nonReentrant() {\n        _nonReentrantBefore();\n        _;\n        _nonReentrantAfter();\n    }\n\n    function _nonReentrantBefore() private {\n        // On the first call to nonReentrant, _status will be NOT_ENTERED\n        if (_reentrancyGuardEntered()) {\n            revert ReentrancyGuardReentrantCall();\n        }\n\n        // Any calls to nonReentrant after this point will fail\n        REENTRANCY_GUARD_STORAGE.asBoolean().tstore(true);\n    }\n\n    function _nonReentrantAfter() private {\n        REENTRANCY_GUARD_STORAGE.asBoolean().tstore(false);\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 REENTRANCY_GUARD_STORAGE.asBoolean().tload();\n    }\n}\n"},{"file_path":"contracts/dependencies/@layerzerolabs/solidity-examples/contracts-upgradeable/lzApp/LzAppUpgradeable.sol","source_code":"// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.2;\n\nimport \"../../../../openzeppelin-upgradeable/access/OwnableUpgradeable.sol\";\nimport \"../interfaces/ILayerZeroReceiverUpgradeable.sol\";\nimport \"../interfaces/ILayerZeroUserApplicationConfigUpgradeable.sol\";\nimport \"../interfaces/ILayerZeroEndpointUpgradeable.sol\";\nimport \"../../util/BytesLib.sol\";\n\n/*\n * a generic LzReceiver implementation\n */\nabstract contract LzAppUpgradeable is\n    Initializable,\n    OwnableUpgradeable,\n    ILayerZeroReceiverUpgradeable,\n    ILayerZeroUserApplicationConfigUpgradeable\n{\n    using BytesLib for bytes;\n\n    // ua can not send payload larger than this by default, but it can be changed by the ua owner\n    uint public constant DEFAULT_PAYLOAD_SIZE_LIMIT = 10000;\n\n    ILayerZeroEndpointUpgradeable public lzEndpoint;\n    mapping(uint16 => bytes) public trustedRemoteLookup;\n    mapping(uint16 => mapping(uint16 => uint)) public minDstGasLookup;\n    mapping(uint16 => uint) public payloadSizeLimitLookup;\n    address public precrime;\n\n    event SetPrecrime(address precrime);\n    event SetTrustedRemote(uint16 _remoteChainId, bytes _path);\n    event SetTrustedRemoteAddress(uint16 _remoteChainId, bytes _remoteAddress);\n    event SetMinDstGas(uint16 _dstChainId, uint16 _type, uint _minDstGas);\n\n    function __LzAppUpgradeable_init(address _endpoint) internal onlyInitializing {\n        __Ownable_init_unchained();\n        __LzAppUpgradeable_init_unchained(_endpoint);\n    }\n\n    function __LzAppUpgradeable_init_unchained(address _endpoint) internal onlyInitializing {\n        lzEndpoint = ILayerZeroEndpointUpgradeable(_endpoint);\n    }\n\n    function lzReceive(\n        uint16 _srcChainId,\n        bytes calldata _srcAddress,\n        uint64 _nonce,\n        bytes calldata _payload\n    ) public virtual override {\n        // lzReceive must be called by the endpoint for security\n        require(_msgSender() == address(lzEndpoint), \"LzApp: invalid endpoint caller\");\n\n        bytes memory trustedRemote = trustedRemoteLookup[_srcChainId];\n        // if will still block the message pathway from (srcChainId, srcAddress). should not receive message from untrusted remote.\n        require(\n            _srcAddress.length == trustedRemote.length &&\n                trustedRemote.length > 0 &&\n                keccak256(_srcAddress) == keccak256(trustedRemote),\n            \"LzApp: invalid source sending contract\"\n        );\n\n        _blockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload);\n    }\n\n    // abstract function - the default behaviour of LayerZero is blocking. See: NonblockingLzApp if you dont need to enforce ordered messaging\n    function _blockingLzReceive(\n        uint16 _srcChainId,\n        bytes memory _srcAddress,\n        uint64 _nonce,\n        bytes memory _payload\n    ) internal virtual;\n\n    function _lzSend(\n        uint16 _dstChainId,\n        bytes memory _payload,\n        address payable _refundAddress,\n        address _zroPaymentAddress,\n        bytes memory _adapterParams,\n        uint _nativeFee\n    ) internal virtual {\n        bytes memory trustedRemote = trustedRemoteLookup[_dstChainId];\n        require(trustedRemote.length != 0, \"LzApp: destination chain is not a trusted source\");\n        _checkPayloadSize(_dstChainId, _payload.length);\n        lzEndpoint.send{value: _nativeFee}(\n            _dstChainId,\n            trustedRemote,\n            _payload,\n            _refundAddress,\n            _zroPaymentAddress,\n            _adapterParams\n        );\n    }\n\n    function _checkGasLimit(\n        uint16 _dstChainId,\n        uint16 _type,\n        bytes memory _adapterParams,\n        uint _extraGas\n    ) internal view virtual {\n        uint providedGasLimit = _getGasLimit(_adapterParams);\n        uint minGasLimit = minDstGasLookup[_dstChainId][_type] + _extraGas;\n        require(minGasLimit > 0, \"LzApp: minGasLimit not set\");\n        require(providedGasLimit >= minGasLimit, \"LzApp: gas limit is too low\");\n    }\n\n    function _getGasLimit(bytes memory _adapterParams) internal pure virtual returns (uint gasLimit) {\n        require(_adapterParams.length >= 34, \"LzApp: invalid adapterParams\");\n        assembly {\n            gasLimit := mload(add(_adapterParams, 34))\n        }\n    }\n\n    function _checkPayloadSize(uint16 _dstChainId, uint _payloadSize) internal view virtual {\n        uint payloadSizeLimit = payloadSizeLimitLookup[_dstChainId];\n        if (payloadSizeLimit == 0) {\n            // use default if not set\n            payloadSizeLimit = DEFAULT_PAYLOAD_SIZE_LIMIT;\n        }\n        require(_payloadSize <= payloadSizeLimit, \"LzApp: payload size is too large\");\n    }\n\n    //---------------------------UserApplication config----------------------------------------\n    function getConfig(\n        uint16 _version,\n        uint16 _chainId,\n        address,\n        uint _configType\n    ) external view returns (bytes memory) {\n        return lzEndpoint.getConfig(_version, _chainId, address(this), _configType);\n    }\n\n    // generic config for LayerZero user Application\n    function setConfig(\n        uint16 _version,\n        uint16 _chainId,\n        uint _configType,\n        bytes calldata _config\n    ) external override onlyOwner {\n        lzEndpoint.setConfig(_version, _chainId, _configType, _config);\n    }\n\n    function setSendVersion(uint16 _version) external override onlyOwner {\n        lzEndpoint.setSendVersion(_version);\n    }\n\n    function setReceiveVersion(uint16 _version) external override onlyOwner {\n        lzEndpoint.setReceiveVersion(_version);\n    }\n\n    function forceResumeReceive(uint16 _srcChainId, bytes calldata _srcAddress) external override onlyOwner {\n        lzEndpoint.forceResumeReceive(_srcChainId, _srcAddress);\n    }\n\n    // _path = abi.encodePacked(remoteAddress, localAddress)\n    // this function set the trusted path for the cross-chain communication\n    function setTrustedRemote(uint16 _srcChainId, bytes calldata _path) external onlyOwner {\n        trustedRemoteLookup[_srcChainId] = _path;\n        emit SetTrustedRemote(_srcChainId, _path);\n    }\n\n    function setTrustedRemoteAddress(uint16 _remoteChainId, bytes calldata _remoteAddress) external onlyOwner {\n        trustedRemoteLookup[_remoteChainId] = abi.encodePacked(_remoteAddress, address(this));\n        emit SetTrustedRemoteAddress(_remoteChainId, _remoteAddress);\n    }\n\n    function getTrustedRemoteAddress(uint16 _remoteChainId) external view returns (bytes memory) {\n        bytes memory path = trustedRemoteLookup[_remoteChainId];\n        require(path.length != 0, \"LzApp: no trusted path record\");\n        return path.slice(0, path.length - 20); // the last 20 bytes should be address(this)\n    }\n\n    function setPrecrime(address _precrime) external onlyOwner {\n        precrime = _precrime;\n        emit SetPrecrime(_precrime);\n    }\n\n    function setMinDstGas(uint16 _dstChainId, uint16 _packetType, uint _minGas) external onlyOwner {\n        require(_minGas > 0, \"LzApp: invalid minGas\");\n        minDstGasLookup[_dstChainId][_packetType] = _minGas;\n        emit SetMinDstGas(_dstChainId, _packetType, _minGas);\n    }\n\n    // if the size is 0, it means default size limit\n    function setPayloadSizeLimit(uint16 _dstChainId, uint _size) external onlyOwner {\n        payloadSizeLimitLookup[_dstChainId] = _size;\n    }\n\n    //--------------------------- VIEW FUNCTION ----------------------------------------\n    function isTrustedRemote(uint16 _srcChainId, bytes calldata _srcAddress) external view returns (bool) {\n        bytes memory trustedSource = trustedRemoteLookup[_srcChainId];\n        return keccak256(trustedSource) == keccak256(_srcAddress);\n    }\n\n    /**\n     * @dev This empty reserved space is put in place to allow future versions to add new\n     * variables without shifting down storage in the inheritance chain.\n     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n     */\n    uint[45] private __gap;\n}\n"},{"file_path":"contracts/dependencies/openzeppelin/token/ERC20/ERC20.sol","source_code":"// SPDX-License-Identifier: MIT\n\n// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20.sol\";\nimport \"./extensions/IERC20Metadata.sol\";\nimport \"../../utils/Context.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * The default value of {decimals} is 18. To change this, you should override\n * this function so it returns a different value.\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20 is Context, IERC20, IERC20Metadata {\n    mapping(address => uint256) private _balances;\n\n    mapping(address => mapping(address => uint256)) private _allowances;\n\n    uint256 private _totalSupply;\n\n    string private _name;\n    string private _symbol;\n\n    /**\n     * @dev Sets the values for {name} and {symbol}.\n     *\n     * All two of these values are immutable: they can only be set once during\n     * construction.\n     */\n    constructor(string memory name_, string memory symbol_) {\n        _name = name_;\n        _symbol = symbol_;\n    }\n\n    /**\n     * @dev Returns the name of the token.\n     */\n    function name() public view virtual override returns (string memory) {\n        return _name;\n    }\n\n    /**\n     * @dev Returns the symbol of the token, usually a shorter version of the\n     * name.\n     */\n    function symbol() public view virtual override returns (string memory) {\n        return _symbol;\n    }\n\n    /**\n     * @dev Returns the number of decimals used to get its user representation.\n     * For example, if `decimals` equals `2`, a balance of `505` tokens should\n     * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n     *\n     * Tokens usually opt for a value of 18, imitating the relationship between\n     * Ether and Wei. This is the default value returned by this function, unless\n     * it's overridden.\n     *\n     * NOTE: This information is only used for _display_ purposes: it in\n     * no way affects any of the arithmetic of the contract, including\n     * {IERC20-balanceOf} and {IERC20-transfer}.\n     */\n    function decimals() public view virtual override returns (uint8) {\n        return 18;\n    }\n\n    /**\n     * @dev See {IERC20-totalSupply}.\n     */\n    function totalSupply() public view virtual override returns (uint256) {\n        return _totalSupply;\n    }\n\n    /**\n     * @dev See {IERC20-balanceOf}.\n     */\n    function balanceOf(address account) public view virtual override returns (uint256) {\n        return _balances[account];\n    }\n\n    /**\n     * @dev See {IERC20-transfer}.\n     *\n     * Requirements:\n     *\n     * - `to` cannot be the zero address.\n     * - the caller must have a balance of at least `amount`.\n     */\n    function transfer(address to, uint256 amount) public virtual override returns (bool) {\n        address owner = _msgSender();\n        _transfer(owner, to, amount);\n        return true;\n    }\n\n    /**\n     * @dev See {IERC20-allowance}.\n     */\n    function allowance(address owner, address spender) public view virtual override returns (uint256) {\n        return _allowances[owner][spender];\n    }\n\n    /**\n     * @dev See {IERC20-approve}.\n     *\n     * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\n     * `transferFrom`. This is semantically equivalent to an infinite approval.\n     *\n     * Requirements:\n     *\n     * - `spender` cannot be the zero address.\n     */\n    function approve(address spender, uint256 amount) public virtual override returns (bool) {\n        address owner = _msgSender();\n        _approve(owner, spender, amount);\n        return true;\n    }\n\n    /**\n     * @dev See {IERC20-transferFrom}.\n     *\n     * Emits an {Approval} event indicating the updated allowance. This is not\n     * required by the EIP. See the note at the beginning of {ERC20}.\n     *\n     * NOTE: Does not update the allowance if the current allowance\n     * is the maximum `uint256`.\n     *\n     * Requirements:\n     *\n     * - `from` and `to` cannot be the zero address.\n     * - `from` must have a balance of at least `amount`.\n     * - the caller must have allowance for ``from``'s tokens of at least\n     * `amount`.\n     */\n    function transferFrom(address from, address to, uint256 amount) public virtual override returns (bool) {\n        address spender = _msgSender();\n        _spendAllowance(from, spender, amount);\n        _transfer(from, to, amount);\n        return true;\n    }\n\n    /**\n     * @dev Atomically increases the allowance granted to `spender` by the caller.\n     *\n     * This is an alternative to {approve} that can be used as a mitigation for\n     * problems described in {IERC20-approve}.\n     *\n     * Emits an {Approval} event indicating the updated allowance.\n     *\n     * Requirements:\n     *\n     * - `spender` cannot be the zero address.\n     */\n    function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n        address owner = _msgSender();\n        _approve(owner, spender, allowance(owner, spender) + addedValue);\n        return true;\n    }\n\n    /**\n     * @dev Atomically decreases the allowance granted to `spender` by the caller.\n     *\n     * This is an alternative to {approve} that can be used as a mitigation for\n     * problems described in {IERC20-approve}.\n     *\n     * Emits an {Approval} event indicating the updated allowance.\n     *\n     * Requirements:\n     *\n     * - `spender` cannot be the zero address.\n     * - `spender` must have allowance for the caller of at least\n     * `subtractedValue`.\n     */\n    function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n        address owner = _msgSender();\n        uint256 currentAllowance = allowance(owner, spender);\n        require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n        unchecked {\n            _approve(owner, spender, currentAllowance - subtractedValue);\n        }\n\n        return true;\n    }\n\n    /**\n     * @dev Moves `amount` of tokens from `from` to `to`.\n     *\n     * This internal function is equivalent to {transfer}, and can be used to\n     * e.g. implement automatic token fees, slashing mechanisms, etc.\n     *\n     * Emits a {Transfer} event.\n     *\n     * Requirements:\n     *\n     * - `from` cannot be the zero address.\n     * - `to` cannot be the zero address.\n     * - `from` must have a balance of at least `amount`.\n     */\n    function _transfer(address from, address to, uint256 amount) internal virtual {\n        require(from != address(0), \"ERC20: transfer from the zero address\");\n        require(to != address(0), \"ERC20: transfer to the zero address\");\n\n        _beforeTokenTransfer(from, to, amount);\n\n        uint256 fromBalance = _balances[from];\n        require(fromBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n        unchecked {\n            _balances[from] = fromBalance - amount;\n            // Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by\n            // decrementing then incrementing.\n            _balances[to] += amount;\n        }\n\n        emit Transfer(from, to, amount);\n\n        _afterTokenTransfer(from, to, amount);\n    }\n\n    /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n     * the total supply.\n     *\n     * Emits a {Transfer} event with `from` set to the zero address.\n     *\n     * Requirements:\n     *\n     * - `account` cannot be the zero address.\n     */\n    function _mint(address account, uint256 amount) internal virtual {\n        require(account != address(0), \"ERC20: mint to the zero address\");\n\n        _beforeTokenTransfer(address(0), account, amount);\n\n        _totalSupply += amount;\n        unchecked {\n            // Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above.\n            _balances[account] += amount;\n        }\n        emit Transfer(address(0), account, amount);\n\n        _afterTokenTransfer(address(0), account, amount);\n    }\n\n    /**\n     * @dev Destroys `amount` tokens from `account`, reducing the\n     * total supply.\n     *\n     * Emits a {Transfer} event with `to` set to the zero address.\n     *\n     * Requirements:\n     *\n     * - `account` cannot be the zero address.\n     * - `account` must have at least `amount` tokens.\n     */\n    function _burn(address account, uint256 amount) internal virtual {\n        require(account != address(0), \"ERC20: burn from the zero address\");\n\n        _beforeTokenTransfer(account, address(0), amount);\n\n        uint256 accountBalance = _balances[account];\n        require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n        unchecked {\n            _balances[account] = accountBalance - amount;\n            // Overflow not possible: amount <= accountBalance <= totalSupply.\n            _totalSupply -= amount;\n        }\n\n        emit Transfer(account, address(0), amount);\n\n        _afterTokenTransfer(account, address(0), amount);\n    }\n\n    /**\n     * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n     *\n     * This internal function is equivalent to `approve`, and can be used to\n     * e.g. set automatic allowances for certain subsystems, etc.\n     *\n     * Emits an {Approval} event.\n     *\n     * Requirements:\n     *\n     * - `owner` cannot be the zero address.\n     * - `spender` cannot be the zero address.\n     */\n    function _approve(address owner, address spender, uint256 amount) internal virtual {\n        require(owner != address(0), \"ERC20: approve from the zero address\");\n        require(spender != address(0), \"ERC20: approve to the zero address\");\n\n        _allowances[owner][spender] = amount;\n        emit Approval(owner, spender, amount);\n    }\n\n    /**\n     * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n     *\n     * Does not update the allowance amount in case of infinite allowance.\n     * Revert if not enough allowance is available.\n     *\n     * Might emit an {Approval} event.\n     */\n    function _spendAllowance(address owner, address spender, uint256 amount) internal virtual {\n        uint256 currentAllowance = allowance(owner, spender);\n        if (currentAllowance != type(uint256).max) {\n            require(currentAllowance >= amount, \"ERC20: insufficient allowance\");\n            unchecked {\n                _approve(owner, spender, currentAllowance - amount);\n            }\n        }\n    }\n\n    /**\n     * @dev Hook that is called before any transfer of tokens. This includes\n     * minting and burning.\n     *\n     * Calling conditions:\n     *\n     * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n     * will be transferred to `to`.\n     * - when `from` is zero, `amount` tokens will be minted for `to`.\n     * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n     * - `from` and `to` are never both zero.\n     *\n     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n     */\n    function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n\n    /**\n     * @dev Hook that is called after any transfer of tokens. This includes\n     * minting and burning.\n     *\n     * Calling conditions:\n     *\n     * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n     * has been transferred to `to`.\n     * - when `from` is zero, `amount` tokens have been minted for `to`.\n     * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n     * - `from` and `to` are never both zero.\n     *\n     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n     */\n    function _afterTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n}\n"},{"file_path":"contracts/storage/ProxyOFTStorage.sol","source_code":"// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.24;\n\nimport {ISyntheticToken} from \"../interfaces/ISyntheticToken.sol\";\nimport {IProxyOFT} from \"../interfaces/IProxyOFT.sol\";\n\nabstract contract ProxyOFTStorageV1 is IProxyOFT {\n    /**\n     * @notice The synthetic token contract\n     */\n    ISyntheticToken internal syntheticToken;\n}\n\nabstract contract ProxyOFTStorageV2 is ProxyOFTStorageV1 {\n    /**\n     * @notice The fee charged on the source chain when bridging synthetic tokens\n     * @dev Use 18 decimals (e.g. 1e16 = 1%)\n     */\n    uint256 public override oftFee;\n}\n"},{"file_path":"contracts/dependencies/openzeppelin/token/ERC20/utils/SafeERC20.sol","source_code":"// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\nimport \"../../../utils/Address.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n    using Address for address;\n\n    function safeTransfer(\n        IERC20 token,\n        address to,\n        uint256 value\n    ) internal {\n        _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n    }\n\n    function safeTransferFrom(\n        IERC20 token,\n        address from,\n        address to,\n        uint256 value\n    ) internal {\n        _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n    }\n\n    /**\n     * @dev Deprecated. This function has issues similar to the ones found in\n     * {IERC20-approve}, and its usage is discouraged.\n     *\n     * Whenever possible, use {safeIncreaseAllowance} and\n     * {safeDecreaseAllowance} instead.\n     */\n    function safeApprove(\n        IERC20 token,\n        address spender,\n        uint256 value\n    ) internal {\n        // safeApprove should only be called when setting an initial allowance,\n        // or when resetting it to zero. To increase and decrease it, use\n        // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\n        require(\n            (value == 0) || (token.allowance(address(this), spender) == 0),\n            \"SafeERC20: approve from non-zero to non-zero allowance\"\n        );\n        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n    }\n\n    function safeIncreaseAllowance(\n        IERC20 token,\n        address spender,\n        uint256 value\n    ) internal {\n        uint256 newAllowance = token.allowance(address(this), spender) + value;\n        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n    }\n\n    function safeDecreaseAllowance(\n        IERC20 token,\n        address spender,\n        uint256 value\n    ) internal {\n        unchecked {\n            uint256 oldAllowance = token.allowance(address(this), spender);\n            require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n            uint256 newAllowance = oldAllowance - value;\n            _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n        }\n    }\n\n    /**\n     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n     * on the return value: the return value is optional (but if data is returned, it must not be false).\n     * @param token The token targeted by the call.\n     * @param data The call data (encoded using abi.encode or one of its variants).\n     */\n    function _callOptionalReturn(IERC20 token, bytes memory data) private {\n        // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n        // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\n        // the target address contains contract code and also asserts for success in the low-level call.\n\n        bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n        if (returndata.length > 0) {\n            // Return data is optional\n            require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n        }\n    }\n}\n"},{"file_path":"contracts/dependencies/@layerzerolabs/solidity-examples/contracts-upgradeable/interfaces/ILayerZeroUserApplicationConfigUpgradeable.sol","source_code":"// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.2;\n\ninterface ILayerZeroUserApplicationConfigUpgradeable {\n    // @notice set the configuration of the LayerZero messaging library of the specified version\n    // @param _version - messaging library version\n    // @param _chainId - the chainId for the pending config change\n    // @param _configType - type of configuration. every messaging library has its own convention.\n    // @param _config - configuration in the bytes. can encode arbitrary content.\n    function setConfig(uint16 _version, uint16 _chainId, uint _configType, bytes calldata _config) external;\n\n    // @notice set the send() LayerZero messaging library version to _version\n    // @param _version - new messaging library version\n    function setSendVersion(uint16 _version) external;\n\n    // @notice set the lzReceive() LayerZero messaging library version to _version\n    // @param _version - new messaging library version\n    function setReceiveVersion(uint16 _version) external;\n\n    // @notice Only when the UA needs to resume the message flow in blocking mode and clear the stored payload\n    // @param _srcChainId - the chainId of the source chain\n    // @param _srcAddress - the contract address of the source contract at the source chain\n    function forceResumeReceive(uint16 _srcChainId, bytes calldata _srcAddress) external;\n}\n"},{"file_path":"contracts/dependencies/@layerzerolabs/solidity-examples/contracts-upgradeable/token/oft/composable/IComposableOFTCoreUpgradeable.sol","source_code":"// SPDX-License-Identifier: MIT\n\npragma solidity >=0.5.0;\n\nimport \"../IOFTCoreUpgradeable.sol\";\n\n/**\n * @dev Interface of the composable OFT core standard\n */\ninterface IComposableOFTCoreUpgradeable is IOFTCoreUpgradeable {\n    function estimateSendAndCallFee(\n        uint16 _dstChainId,\n        bytes calldata _toAddress,\n        uint _amount,\n        bytes calldata _payload,\n        uint64 _dstGasForCall,\n        bool _useZro,\n        bytes calldata _adapterParams\n    ) external view returns (uint nativeFee, uint zroFee);\n\n    function sendAndCall(\n        address _from,\n        uint16 _dstChainId,\n        bytes calldata _toAddress,\n        uint _amount,\n        bytes calldata _payload,\n        uint64 _dstGasForCall,\n        address payable _refundAddress,\n        address _zroPaymentAddress,\n        bytes calldata _adapterParams\n    ) external payable;\n\n    function retryOFTReceived(\n        uint16 _srcChainId,\n        bytes calldata _srcAddress,\n        uint64 _nonce,\n        bytes calldata _from,\n        address _to,\n        uint _amount,\n        bytes calldata _payload\n    ) external;\n\n    event CallOFTReceivedFailure(\n        uint16 indexed _srcChainId,\n        bytes _srcAddress,\n        uint64 _nonce,\n        bytes _from,\n        address indexed _to,\n        uint _amount,\n        bytes _payload,\n        bytes _reason\n    );\n\n    event CallOFTReceivedSuccess(uint16 indexed _srcChainId, bytes _srcAddress, uint64 _nonce, bytes32 _hash);\n\n    event RetryOFTReceivedSuccess(bytes32 _messageHash);\n\n    event NonContractAddress(address _address);\n}\n"},{"file_path":"contracts/interfaces/external/IVPool.sol","source_code":"// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.24;\n\nimport {IERC20} from \"../../dependencies/openzeppelin/token/ERC20/IERC20.sol\";\n\ninterface IVPool is IERC20 {\n    function token() external view returns (address _token);\n\n    function deposit(uint256 _amount) external;\n\n    function withdraw(uint256 _shares) external;\n\n    function poolRewards() external view returns (address);\n\n    function pricePerShare() external view returns (uint256);\n}\n"},{"file_path":"contracts/NativeTokenGateway.sol","source_code":"// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.24;\n\nimport {Address} from \"./dependencies/openzeppelin/utils/Address.sol\";\nimport {SafeERC20} from \"./dependencies/openzeppelin/token/ERC20/utils/SafeERC20.sol\";\nimport {IERC20} from \"./dependencies/openzeppelin/token/ERC20/IERC20.sol\";\nimport {SynthContext} from \"./utils/SynthContext.sol\";\nimport {ReentrancyGuardTransient} from \"./utils/ReentrancyGuardTransient.sol\";\nimport {TokenHolder} from \"./utils/TokenHolder.sol\";\nimport {IWETH} from \"./interfaces/external/IWETH.sol\";\nimport {INativeTokenGateway} from \"./interfaces/INativeTokenGateway.sol\";\nimport {IDepositToken} from \"./interfaces/IDepositToken.sol\";\nimport {IPoolRegistry} from \"./interfaces/IPoolRegistry.sol\";\nimport {IPool} from \"./interfaces/IPool.sol\";\n\nerror SenderIsNotGovernor();\nerror SenderIsNotNativeToken();\nerror UnregisteredPool();\n\n/**\n * @title Helper contract to easily support native tokens (e.g. ETH/AVAX) as collateral\n */\ncontract NativeTokenGateway is SynthContext, ReentrancyGuardTransient, TokenHolder, INativeTokenGateway {\n    using SafeERC20 for IERC20;\n    using SafeERC20 for IWETH;\n    using SafeERC20 for IDepositToken;\n\n    IPoolRegistry internal immutable _poolRegistry;\n    IWETH public immutable nativeToken;\n\n    modifier onlyGovernor() {\n        if (_poolRegistry.governor() != _msgSender()) revert SenderIsNotGovernor();\n        _;\n    }\n\n    constructor(IPoolRegistry poolRegistry_, IWETH nativeToken_) {\n        _poolRegistry = poolRegistry_;\n        nativeToken = nativeToken_;\n    }\n\n    /**\n     * @notice deposits NATIVE_TOKEN as collateral using native. A corresponding amount of the deposit token is minted.\n     * @param pool_ The Pool contract\n     */\n    function deposit(IPool pool_) external payable override {\n        if (!_poolRegistry.isPoolRegistered(address(pool_))) revert UnregisteredPool();\n\n        nativeToken.deposit{value: msg.value}();\n        IDepositToken _depositToken = pool_.depositTokenOf(nativeToken);\n        nativeToken.safeApprove(address(_depositToken), 0);\n        nativeToken.safeApprove(address(_depositToken), msg.value);\n        _depositToken.deposit(msg.value, _msgSender());\n    }\n\n    /**\n     * @notice withdraws the NATIVE_TOKEN deposit of _msgSender().\n     * @param pool_ The Pool contract\n     * @param amount_ The amount of deposit tokens to withdraw and receive native ETH\n     */\n    function withdraw(IPool pool_, uint256 amount_) external override nonReentrant {\n        if (!_poolRegistry.isPoolRegistered(address(pool_))) revert UnregisteredPool();\n\n        address _msgSender = _msgSender();\n        IDepositToken _depositToken = pool_.depositTokenOf(nativeToken);\n        _depositToken.safeTransferFrom(_msgSender, address(this), amount_);\n        (uint256 _withdrawn, ) = _depositToken.withdraw(amount_, address(this));\n        nativeToken.withdraw(_withdrawn);\n        Address.sendValue(payable(_msgSender), _withdrawn);\n    }\n\n    /// @inheritdoc SynthContext\n    function poolRegistry() public view override returns (IPoolRegistry) {\n        return _poolRegistry;\n    }\n\n    /// @inheritdoc TokenHolder\n    // solhint-disable-next-line no-empty-blocks\n    function _requireCanSweep() internal view override onlyGovernor {}\n\n    /**\n     * @dev Only `nativeToken` contract is allowed to transfer to here. Prevent other addresses to send coins to this contract.\n     */\n    receive() external payable override {\n        if (_msgSender() != address(nativeToken)) revert SenderIsNotNativeToken();\n    }\n}\n"},{"file_path":"contracts/dependencies/openzeppelin/proxy/beacon/IBeacon.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\n */\ninterface IBeacon {\n    /**\n     * @dev Must return an address that can be used as a delegate call target.\n     *\n     * {BeaconProxy} will check that this address is a contract.\n     */\n    function implementation() external view returns (address);\n}\n"},{"file_path":"contracts/interfaces/IPauseable.sol","source_code":"// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.24;\n\ninterface IPauseable {\n    function paused() external view returns (bool);\n\n    function everythingStopped() external view returns (bool);\n}\n"},{"file_path":"contracts/dependencies/@layerzerolabs/solidity-examples/interfaces/ILayerZeroEndpoint.sol","source_code":"// SPDX-License-Identifier: MIT\n\npragma solidity >=0.5.0;\n\nimport \"./ILayerZeroUserApplicationConfig.sol\";\n\ninterface ILayerZeroEndpoint is ILayerZeroUserApplicationConfig {\n    // @notice send a LayerZero message to the specified address at a LayerZero endpoint.\n    // @param _dstChainId - the destination chain identifier\n    // @param _destination - the address on destination chain (in bytes). address length/format may vary by chains\n    // @param _payload - a custom bytes payload to send to the destination contract\n    // @param _refundAddress - if the source transaction is cheaper than the amount of value passed, refund the additional amount to this address\n    // @param _zroPaymentAddress - the address of the ZRO token holder who would pay for the transaction\n    // @param _adapterParams - parameters for custom functionality. e.g. receive airdropped native gas from the relayer on destination\n    function send(\n        uint16 _dstChainId,\n        bytes calldata _destination,\n        bytes calldata _payload,\n        address payable _refundAddress,\n        address _zroPaymentAddress,\n        bytes calldata _adapterParams\n    ) external payable;\n\n    // @notice used by the messaging library to publish verified payload\n    // @param _srcChainId - the source chain identifier\n    // @param _srcAddress - the source contract (as bytes) at the source chain\n    // @param _dstAddress - the address on destination chain\n    // @param _nonce - the unbound message ordering nonce\n    // @param _gasLimit - the gas limit for external contract execution\n    // @param _payload - verified payload to send to the destination contract\n    function receivePayload(\n        uint16 _srcChainId,\n        bytes calldata _srcAddress,\n        address _dstAddress,\n        uint64 _nonce,\n        uint _gasLimit,\n        bytes calldata _payload\n    ) external;\n\n    // @notice get the inboundNonce of a lzApp from a source chain which could be EVM or non-EVM chain\n    // @param _srcChainId - the source chain identifier\n    // @param _srcAddress - the source chain contract address\n    function getInboundNonce(uint16 _srcChainId, bytes calldata _srcAddress) external view returns (uint64);\n\n    // @notice get the outboundNonce from this source chain which, consequently, is always an EVM\n    // @param _srcAddress - the source chain contract address\n    function getOutboundNonce(uint16 _dstChainId, address _srcAddress) external view returns (uint64);\n\n    // @notice gets a quote in source native gas, for the amount that send() requires to pay for message delivery\n    // @param _dstChainId - the destination chain identifier\n    // @param _userApplication - the user app address on this EVM chain\n    // @param _payload - the custom message to send over LayerZero\n    // @param _payInZRO - if false, user app pays the protocol fee in native token\n    // @param _adapterParam - parameters for the adapter service, e.g. send some dust native token to dstChain\n    function estimateFees(\n        uint16 _dstChainId,\n        address _userApplication,\n        bytes calldata _payload,\n        bool _payInZRO,\n        bytes calldata _adapterParam\n    ) external view returns (uint nativeFee, uint zroFee);\n\n    // @notice get this Endpoint's immutable source identifier\n    function getChainId() external view returns (uint16);\n\n    // @notice the interface to retry failed message on this Endpoint destination\n    // @param _srcChainId - the source chain identifier\n    // @param _srcAddress - the source chain contract address\n    // @param _payload - the payload to be retried\n    function retryPayload(uint16 _srcChainId, bytes calldata _srcAddress, bytes calldata _payload) external;\n\n    // @notice query if any STORED payload (message blocking) at the endpoint.\n    // @param _srcChainId - the source chain identifier\n    // @param _srcAddress - the source chain contract address\n    function hasStoredPayload(uint16 _srcChainId, bytes calldata _srcAddress) external view returns (bool);\n\n    // @notice query if the _libraryAddress is valid for sending msgs.\n    // @param _userApplication - the user app address on this EVM chain\n    function getSendLibraryAddress(address _userApplication) external view returns (address);\n\n    // @notice query if the _libraryAddress is valid for receiving msgs.\n    // @param _userApplication - the user app address on this EVM chain\n    function getReceiveLibraryAddress(address _userApplication) external view returns (address);\n\n    // @notice query if the non-reentrancy guard for send() is on\n    // @return true if the guard is on. false otherwise\n    function isSendingPayload() external view returns (bool);\n\n    // @notice query if the non-reentrancy guard for receive() is on\n    // @return true if the guard is on. false otherwise\n    function isReceivingPayload() external view returns (bool);\n\n    // @notice get the configuration of the LayerZero messaging library of the specified version\n    // @param _version - messaging library version\n    // @param _chainId - the chainId for the pending config change\n    // @param _userApplication - the contract address of the user application\n    // @param _configType - type of configuration. every messaging library has its own convention.\n    function getConfig(\n        uint16 _version,\n        uint16 _chainId,\n        address _userApplication,\n        uint _configType\n    ) external view returns (bytes memory);\n\n    // @notice get the send() LayerZero messaging library version\n    // @param _userApplication - the contract address of the user application\n    function getSendVersion(address _userApplication) external view returns (uint16);\n\n    // @notice get the lzReceive() LayerZero messaging library version\n    // @param _userApplication - the contract address of the user application\n    function getReceiveVersion(address _userApplication) external view returns (uint16);\n}\n"},{"file_path":"contracts/dependencies/stargate-protocol/Pool.sol","source_code":"// SPDX-License-Identifier: BUSL-1.1\n\npragma solidity ^0.8.9;\npragma abicoder v2;\n\n// imports\nimport \"../openzeppelin/access/Ownable.sol\";\nimport \"../openzeppelin/security/ReentrancyGuard.sol\";\nimport \"./LPTokenERC20.sol\";\nimport \"./interfaces/IStargateFeeLibrary.sol\";\n\n// libraries\nimport \"../openzeppelin/utils/math/SafeMath.sol\";\n\n/// Pool contracts on other chains and managed by the Stargate protocol.\ncontract Pool is LPTokenERC20, ReentrancyGuard {\n    using SafeMath for uint256;\n\n    //---------------------------------------------------------------------------\n    // CONSTANTS\n    bytes4 private constant SELECTOR = bytes4(keccak256(bytes(\"transfer(address,uint256)\")));\n    uint256 public constant BP_DENOMINATOR = 10000;\n\n    //---------------------------------------------------------------------------\n    // STRUCTS\n    struct ChainPath {\n        bool ready; // indicate if the counter chainPath has been created.\n        uint16 dstChainId;\n        uint256 dstPoolId;\n        uint256 weight;\n        uint256 balance;\n        uint256 lkb;\n        uint256 credits;\n        uint256 idealBalance;\n    }\n\n    struct SwapObj {\n        uint256 amount;\n        uint256 eqFee;\n        uint256 eqReward;\n        uint256 lpFee;\n        uint256 protocolFee;\n        uint256 lkbRemove;\n    }\n\n    struct CreditObj {\n        uint256 credits;\n        uint256 idealBalance;\n    }\n\n    //---------------------------------------------------------------------------\n    // VARIABLES\n\n    // chainPath\n    ChainPath[] public chainPaths; // list of connected chains with shared pools\n    mapping(uint16 => mapping(uint256 => uint256)) public chainPathIndexLookup; // lookup for chainPath by chainId => poolId =>index\n\n    // metadata\n    uint256 public immutable poolId; // shared id between chains to represent same pool\n    uint256 public sharedDecimals; // the shared decimals (lowest common decimals between chains)\n    uint256 public localDecimals; // the decimals for the token\n    uint256 public immutable convertRate; // the decimals for the token\n    address public immutable token; // the token for the pool\n    address public immutable router; // the token for the pool\n\n    bool public stopSwap; // flag to stop swapping in extreme cases\n\n    // Fee and Liquidity\n    uint256 public totalLiquidity; // the total amount of tokens added on this side of the chain (fees + deposits - withdrawals)\n    uint256 public totalWeight; // total weight for pool percentages\n    uint256 public mintFeeBP; // fee basis points for the mint/deposit\n    uint256 public protocolFeeBalance; // fee balance created from dao fee\n    uint256 public mintFeeBalance; // fee balance created from mint fee\n    uint256 public eqFeePool; // pool rewards in Shared Decimal format. indicate the total budget for reverse swap incentive\n    address public feeLibrary; // address for retrieving fee params for swaps\n\n    // Delta related\n    uint256 public deltaCredit; // credits accumulated from txn\n    bool public batched; // flag to indicate if we want batch processing.\n    bool public defaultSwapMode; // flag for the default mode for swap\n    bool public defaultLPMode; // flag for the default mode for lp\n    uint256 public swapDeltaBP; // basis points of poolCredits to activate Delta in swap\n    uint256 public lpDeltaBP; // basis points of poolCredits to activate Delta in liquidity events\n\n    //---------------------------------------------------------------------------\n    // EVENTS\n    event Mint(address to, uint256 amountLP, uint256 amountSD, uint256 mintFeeAmountSD);\n    event Burn(address from, uint256 amountLP, uint256 amountSD);\n    event RedeemLocalCallback(address _to, uint256 _amountSD, uint256 _amountToMintSD);\n    event Swap(\n        uint16 chainId,\n        uint256 dstPoolId,\n        address from,\n        uint256 amountSD,\n        uint256 eqReward,\n        uint256 eqFee,\n        uint256 protocolFee,\n        uint256 lpFee\n    );\n    event SendCredits(uint16 dstChainId, uint256 dstPoolId, uint256 credits, uint256 idealBalance);\n    event RedeemRemote(uint16 chainId, uint256 dstPoolId, address from, uint256 amountLP, uint256 amountSD);\n    event RedeemLocal(address from, uint256 amountLP, uint256 amountSD, uint16 chainId, uint256 dstPoolId, bytes to);\n    event InstantRedeemLocal(address from, uint256 amountLP, uint256 amountSD, address to);\n    event CreditChainPath(uint16 chainId, uint256 srcPoolId, uint256 amountSD, uint256 idealBalance);\n    event SwapRemote(address to, uint256 amountSD, uint256 protocolFee, uint256 dstFee);\n    event WithdrawRemote(uint16 srcChainId, uint256 srcPoolId, uint256 swapAmount, uint256 mintAmount);\n    event ChainPathUpdate(uint16 dstChainId, uint256 dstPoolId, uint256 weight);\n    event FeesUpdated(uint256 mintFeeBP);\n    event FeeLibraryUpdated(address feeLibraryAddr);\n    event StopSwapUpdated(bool swapStop);\n    event WithdrawProtocolFeeBalance(address to, uint256 amountSD);\n    event WithdrawMintFeeBalance(address to, uint256 amountSD);\n    event DeltaParamUpdated(\n        bool batched,\n        uint256 swapDeltaBP,\n        uint256 lpDeltaBP,\n        bool defaultSwapMode,\n        bool defaultLPMode\n    );\n\n    //---------------------------------------------------------------------------\n    // MODIFIERS\n    modifier onlyRouter() {\n        require(msg.sender == router, \"Stargate: only the router can call this method\");\n        _;\n    }\n\n    constructor(\n        uint256 _poolId,\n        address _router,\n        address _token,\n        uint256 _sharedDecimals,\n        uint256 _localDecimals,\n        address _feeLibrary,\n        string memory _name,\n        string memory _symbol\n    ) LPTokenERC20(_name, _symbol) {\n        require(_token != address(0x0), \"Stargate: _token cannot be 0x0\");\n        require(_router != address(0x0), \"Stargate: _router cannot be 0x0\");\n        poolId = _poolId;\n        router = _router;\n        token = _token;\n        sharedDecimals = _sharedDecimals;\n        decimals = uint8(_sharedDecimals);\n        localDecimals = _localDecimals;\n        convertRate = 10 ** (uint256(localDecimals).sub(sharedDecimals));\n        totalWeight = 0;\n        feeLibrary = _feeLibrary;\n\n        //delta algo related\n        batched = false;\n        defaultSwapMode = true;\n        defaultLPMode = true;\n    }\n\n    function getChainPathsLength() public view returns (uint256) {\n        return chainPaths.length;\n    }\n\n    //---------------------------------------------------------------------------\n    // LOCAL CHAIN FUNCTIONS\n\n    function mint(address _to, uint256 _amountLD) external nonReentrant onlyRouter returns (uint256) {\n        return _mintLocal(_to, _amountLD, true, true);\n    }\n\n    // Local                                    Remote\n    // -------                                  ---------\n    // swap             ->                      swapRemote\n    function swap(\n        uint16 _dstChainId,\n        uint256 _dstPoolId,\n        address _from,\n        uint256 _amountLD,\n        uint256 _minAmountLD,\n        bool newLiquidity\n    ) external nonReentrant onlyRouter returns (SwapObj memory) {\n        require(!stopSwap, \"Stargate: swap func stopped\");\n        ChainPath storage cp = getAndCheckCP(_dstChainId, _dstPoolId);\n        require(cp.ready == true, \"Stargate: counter chainPath is not ready\");\n\n        uint256 amountSD = amountLDtoSD(_amountLD);\n        uint256 minAmountSD = amountLDtoSD(_minAmountLD);\n\n        // request fee params from library\n        SwapObj memory s = IStargateFeeLibrary(feeLibrary).getFees(poolId, _dstPoolId, _dstChainId, _from, amountSD);\n\n        // equilibrium fee and reward. note eqFee/eqReward are separated from swap liquidity\n        eqFeePool = eqFeePool.sub(s.eqReward);\n        // update the new amount the user gets minus the fees\n        s.amount = amountSD.sub(s.eqFee).sub(s.protocolFee).sub(s.lpFee);\n        // users will also get the eqReward\n        require(s.amount.add(s.eqReward) >= minAmountSD, \"Stargate: slippage too high\");\n\n        // behaviours\n        //     - protocolFee: booked, stayed and withdrawn at remote.\n        //     - eqFee: booked, stayed and withdrawn at remote.\n        //     - lpFee: booked and stayed at remote, can be withdrawn anywhere\n\n        s.lkbRemove = amountSD.sub(s.lpFee).add(s.eqReward);\n        // check for transfer solvency.\n        require(cp.balance >= s.lkbRemove, \"Stargate: dst balance too low\");\n        cp.balance = cp.balance.sub(s.lkbRemove);\n\n        if (newLiquidity) {\n            deltaCredit = deltaCredit.add(amountSD).add(s.eqReward);\n        } else if (s.eqReward > 0) {\n            deltaCredit = deltaCredit.add(s.eqReward);\n        }\n\n        // distribute credits on condition.\n        if (!batched || deltaCredit >= totalLiquidity.mul(swapDeltaBP).div(BP_DENOMINATOR)) {\n            _delta(defaultSwapMode);\n        }\n\n        emit Swap(_dstChainId, _dstPoolId, _from, s.amount, s.eqReward, s.eqFee, s.protocolFee, s.lpFee);\n        return s;\n    }\n\n    // Local                                    Remote\n    // -------                                  ---------\n    // sendCredits      ->                      creditChainPath\n    function sendCredits(\n        uint16 _dstChainId,\n        uint256 _dstPoolId\n    ) external nonReentrant onlyRouter returns (CreditObj memory c) {\n        ChainPath storage cp = getAndCheckCP(_dstChainId, _dstPoolId);\n        require(cp.ready == true, \"Stargate: counter chainPath is not ready\");\n        cp.lkb = cp.lkb.add(cp.credits);\n        c.idealBalance = totalLiquidity.mul(cp.weight).div(totalWeight);\n        c.credits = cp.credits;\n        cp.credits = 0;\n        emit SendCredits(_dstChainId, _dstPoolId, c.credits, c.idealBalance);\n    }\n\n    // Local                                    Remote\n    // -------                                  ---------\n    // redeemRemote   ->                        swapRemote\n    function redeemRemote(\n        uint16 _dstChainId,\n        uint256 _dstPoolId,\n        address _from,\n        uint256 _amountLP\n    ) external nonReentrant onlyRouter {\n        require(_from != address(0x0), \"Stargate: _from cannot be 0x0\");\n        uint256 amountSD = _burnLocal(_from, _amountLP);\n        //run Delta\n        if (!batched || deltaCredit > totalLiquidity.mul(lpDeltaBP).div(BP_DENOMINATOR)) {\n            _delta(defaultLPMode);\n        }\n        uint256 amountLD = amountSDtoLD(amountSD);\n        emit RedeemRemote(_dstChainId, _dstPoolId, _from, _amountLP, amountLD);\n    }\n\n    function instantRedeemLocal(\n        address _from,\n        uint256 _amountLP,\n        address _to\n    ) external nonReentrant onlyRouter returns (uint256 amountSD) {\n        require(_from != address(0x0), \"Stargate: _from cannot be 0x0\");\n        uint256 _deltaCredit = deltaCredit; // sload optimization.\n        uint256 _capAmountLP = _amountSDtoLP(_deltaCredit);\n\n        if (_amountLP > _capAmountLP) _amountLP = _capAmountLP;\n\n        amountSD = _burnLocal(_from, _amountLP);\n        deltaCredit = _deltaCredit.sub(amountSD);\n        uint256 amountLD = amountSDtoLD(amountSD);\n        _safeTransfer(token, _to, amountLD);\n        emit InstantRedeemLocal(_from, _amountLP, amountSD, _to);\n    }\n\n    // Local                                    Remote\n    // -------                                  ---------\n    // redeemLocal   ->                         redeemLocalCheckOnRemote\n    // redeemLocalCallback             <-\n    function redeemLocal(\n        address _from,\n        uint256 _amountLP,\n        uint16 _dstChainId,\n        uint256 _dstPoolId,\n        bytes calldata _to\n    ) external nonReentrant onlyRouter returns (uint256 amountSD) {\n        require(_from != address(0x0), \"Stargate: _from cannot be 0x0\");\n\n        // safeguard.\n        require(\n            chainPaths[chainPathIndexLookup[_dstChainId][_dstPoolId]].ready == true,\n            \"Stargate: counter chainPath is not ready\"\n        );\n        amountSD = _burnLocal(_from, _amountLP);\n\n        // run Delta\n        if (!batched || deltaCredit > totalLiquidity.mul(lpDeltaBP).div(BP_DENOMINATOR)) {\n            _delta(false);\n        }\n        emit RedeemLocal(_from, _amountLP, amountSD, _dstChainId, _dstPoolId, _to);\n    }\n\n    //---------------------------------------------------------------------------\n    // REMOTE CHAIN FUNCTIONS\n\n    // Local                                    Remote\n    // -------                                  ---------\n    // sendCredits      ->                      creditChainPath\n    function creditChainPath(\n        uint16 _dstChainId,\n        uint256 _dstPoolId,\n        CreditObj memory _c\n    ) external nonReentrant onlyRouter {\n        ChainPath storage cp = chainPaths[chainPathIndexLookup[_dstChainId][_dstPoolId]];\n        cp.balance = cp.balance.add(_c.credits);\n        if (cp.idealBalance != _c.idealBalance) {\n            cp.idealBalance = _c.idealBalance;\n        }\n        emit CreditChainPath(_dstChainId, _dstPoolId, _c.credits, _c.idealBalance);\n    }\n\n    // Local                                    Remote\n    // -------                                  ---------\n    // swap             ->                      swapRemote\n    function swapRemote(\n        uint16 _srcChainId,\n        uint256 _srcPoolId,\n        address _to,\n        SwapObj memory _s\n    ) external nonReentrant onlyRouter returns (uint256 amountLD) {\n        // booking lpFee\n        totalLiquidity = totalLiquidity.add(_s.lpFee);\n        // booking eqFee\n        eqFeePool = eqFeePool.add(_s.eqFee);\n        // booking stargateFee\n        protocolFeeBalance = protocolFeeBalance.add(_s.protocolFee);\n\n        // update LKB\n        uint256 chainPathIndex = chainPathIndexLookup[_srcChainId][_srcPoolId];\n        chainPaths[chainPathIndex].lkb = chainPaths[chainPathIndex].lkb.sub(_s.lkbRemove);\n\n        // user receives the amount + the srcReward\n        amountLD = amountSDtoLD(_s.amount.add(_s.eqReward));\n        _safeTransfer(token, _to, amountLD);\n        emit SwapRemote(_to, _s.amount.add(_s.eqReward), _s.protocolFee, _s.eqFee);\n    }\n\n    // Local                                    Remote\n    // -------                                  ---------\n    // redeemLocal   ->                         redeemLocalCheckOnRemote\n    // redeemLocalCallback             <-\n    function redeemLocalCallback(\n        uint16 _srcChainId,\n        uint256 _srcPoolId,\n        address _to,\n        uint256 _amountSD,\n        uint256 _amountToMintSD\n    ) external nonReentrant onlyRouter {\n        if (_amountToMintSD > 0) {\n            _mintLocal(_to, amountSDtoLD(_amountToMintSD), false, false);\n        }\n\n        ChainPath storage cp = getAndCheckCP(_srcChainId, _srcPoolId);\n        cp.lkb = cp.lkb.sub(_amountSD);\n\n        uint256 amountLD = amountSDtoLD(_amountSD);\n        _safeTransfer(token, _to, amountLD);\n        emit RedeemLocalCallback(_to, _amountSD, _amountToMintSD);\n    }\n\n    // Local                                    Remote\n    // -------                                  ---------\n    // redeemLocal(amount)   ->               redeemLocalCheckOnRemote\n    // redeemLocalCallback             <-\n    function redeemLocalCheckOnRemote(\n        uint16 _srcChainId,\n        uint256 _srcPoolId,\n        uint256 _amountSD\n    ) external nonReentrant onlyRouter returns (uint256 swapAmount, uint256 mintAmount) {\n        ChainPath storage cp = getAndCheckCP(_srcChainId, _srcPoolId);\n        if (_amountSD > cp.balance) {\n            mintAmount = _amountSD - cp.balance;\n            swapAmount = cp.balance;\n            cp.balance = 0;\n        } else {\n            cp.balance = cp.balance.sub(_amountSD);\n            swapAmount = _amountSD;\n            mintAmount = 0;\n        }\n        emit WithdrawRemote(_srcChainId, _srcPoolId, swapAmount, mintAmount);\n    }\n\n    //---------------------------------------------------------------------------\n    // DAO Calls\n    function createChainPath(uint16 _dstChainId, uint256 _dstPoolId, uint256 _weight) external onlyRouter {\n        for (uint256 i = 0; i < chainPaths.length; ++i) {\n            ChainPath memory cp = chainPaths[i];\n            bool exists = cp.dstChainId == _dstChainId && cp.dstPoolId == _dstPoolId;\n            require(!exists, \"Stargate: cant createChainPath of existing dstChainId and _dstPoolId\");\n        }\n        totalWeight = totalWeight.add(_weight);\n        chainPathIndexLookup[_dstChainId][_dstPoolId] = chainPaths.length;\n        chainPaths.push(ChainPath(false, _dstChainId, _dstPoolId, _weight, 0, 0, 0, 0));\n        emit ChainPathUpdate(_dstChainId, _dstPoolId, _weight);\n    }\n\n    function setWeightForChainPath(uint16 _dstChainId, uint256 _dstPoolId, uint16 _weight) external onlyRouter {\n        ChainPath storage cp = getAndCheckCP(_dstChainId, _dstPoolId);\n        totalWeight = totalWeight.sub(cp.weight).add(_weight);\n        cp.weight = _weight;\n        emit ChainPathUpdate(_dstChainId, _dstPoolId, _weight);\n    }\n\n    function setFee(uint256 _mintFeeBP) external onlyRouter {\n        require(_mintFeeBP <= BP_DENOMINATOR, \"Bridge: cum fees > 100%\");\n        mintFeeBP = _mintFeeBP;\n        emit FeesUpdated(mintFeeBP);\n    }\n\n    function setFeeLibrary(address _feeLibraryAddr) external onlyRouter {\n        require(_feeLibraryAddr != address(0x0), \"Stargate: fee library cant be 0x0\");\n        feeLibrary = _feeLibraryAddr;\n        emit FeeLibraryUpdated(_feeLibraryAddr);\n    }\n\n    function setSwapStop(bool _swapStop) external onlyRouter {\n        stopSwap = _swapStop;\n        emit StopSwapUpdated(_swapStop);\n    }\n\n    function setDeltaParam(\n        bool _batched,\n        uint256 _swapDeltaBP,\n        uint256 _lpDeltaBP,\n        bool _defaultSwapMode,\n        bool _defaultLPMode\n    ) external onlyRouter {\n        require(_swapDeltaBP <= BP_DENOMINATOR && _lpDeltaBP <= BP_DENOMINATOR, \"Stargate: wrong Delta param\");\n        batched = _batched;\n        swapDeltaBP = _swapDeltaBP;\n        lpDeltaBP = _lpDeltaBP;\n        defaultSwapMode = _defaultSwapMode;\n        defaultLPMode = _defaultLPMode;\n        emit DeltaParamUpdated(_batched, _swapDeltaBP, _lpDeltaBP, _defaultSwapMode, _defaultLPMode);\n    }\n\n    function callDelta(bool _fullMode) external onlyRouter {\n        _delta(_fullMode);\n    }\n\n    function activateChainPath(uint16 _dstChainId, uint256 _dstPoolId) external onlyRouter {\n        ChainPath storage cp = getAndCheckCP(_dstChainId, _dstPoolId);\n        require(cp.ready == false, \"Stargate: chainPath is already active\");\n        // this func will only be called once\n        cp.ready = true;\n    }\n\n    function withdrawProtocolFeeBalance(address _to) external onlyRouter {\n        if (protocolFeeBalance > 0) {\n            uint256 amountOfLD = amountSDtoLD(protocolFeeBalance);\n            protocolFeeBalance = 0;\n            _safeTransfer(token, _to, amountOfLD);\n            emit WithdrawProtocolFeeBalance(_to, amountOfLD);\n        }\n    }\n\n    function withdrawMintFeeBalance(address _to) external onlyRouter {\n        if (mintFeeBalance > 0) {\n            uint256 amountOfLD = amountSDtoLD(mintFeeBalance);\n            mintFeeBalance = 0;\n            _safeTransfer(token, _to, amountOfLD);\n            emit WithdrawMintFeeBalance(_to, amountOfLD);\n        }\n    }\n\n    //---------------------------------------------------------------------------\n    // INTERNAL\n    // Conversion Helpers\n    //---------------------------------------------------------------------------\n    function amountLPtoLD(uint256 _amountLP) external view returns (uint256) {\n        return amountSDtoLD(_amountLPtoSD(_amountLP));\n    }\n\n    function _amountLPtoSD(uint256 _amountLP) internal view returns (uint256) {\n        require(totalSupply > 0, \"Stargate: cant convert LPtoSD when totalSupply == 0\");\n        return _amountLP.mul(totalLiquidity).div(totalSupply);\n    }\n\n    function _amountSDtoLP(uint256 _amountSD) internal view returns (uint256) {\n        require(totalLiquidity > 0, \"Stargate: cant convert SDtoLP when totalLiq == 0\");\n        return _amountSD.mul(totalSupply).div(totalLiquidity);\n    }\n\n    function amountSDtoLD(uint256 _amount) internal view returns (uint256) {\n        return _amount.mul(convertRate);\n    }\n\n    function amountLDtoSD(uint256 _amount) internal view returns (uint256) {\n        return _amount.div(convertRate);\n    }\n\n    function getAndCheckCP(uint16 _dstChainId, uint256 _dstPoolId) internal view returns (ChainPath storage) {\n        require(chainPaths.length > 0, \"Stargate: no chainpaths exist\");\n        ChainPath storage cp = chainPaths[chainPathIndexLookup[_dstChainId][_dstPoolId]];\n        require(cp.dstChainId == _dstChainId && cp.dstPoolId == _dstPoolId, \"Stargate: local chainPath does not exist\");\n        return cp;\n    }\n\n    function getChainPath(uint16 _dstChainId, uint256 _dstPoolId) external view returns (ChainPath memory) {\n        ChainPath memory cp = chainPaths[chainPathIndexLookup[_dstChainId][_dstPoolId]];\n        require(cp.dstChainId == _dstChainId && cp.dstPoolId == _dstPoolId, \"Stargate: local chainPath does not exist\");\n        return cp;\n    }\n\n    function _burnLocal(address _from, uint256 _amountLP) internal returns (uint256) {\n        require(totalSupply > 0, \"Stargate: cant burn when totalSupply == 0\");\n        uint256 amountOfLPTokens = balanceOf[_from];\n        require(amountOfLPTokens >= _amountLP, \"Stargate: not enough LP tokens to burn\");\n\n        uint256 amountSD = _amountLP.mul(totalLiquidity).div(totalSupply);\n        //subtract totalLiquidity accordingly\n        totalLiquidity = totalLiquidity.sub(amountSD);\n\n        _burn(_from, _amountLP);\n        emit Burn(_from, _amountLP, amountSD);\n        return amountSD;\n    }\n\n    function _delta(bool fullMode) internal {\n        if (deltaCredit > 0 && totalWeight > 0) {\n            uint256 cpLength = chainPaths.length;\n            uint256[] memory deficit = new uint256[](cpLength);\n            uint256 totalDeficit = 0;\n\n            // algorithm steps 6-9: calculate the total and the amounts required to get to balance state\n            for (uint256 i = 0; i < cpLength; ++i) {\n                ChainPath storage cp = chainPaths[i];\n                // (liquidity * (weight/totalWeight)) - (lkb+credits)\n                uint256 balLiq = totalLiquidity.mul(cp.weight).div(totalWeight);\n                uint256 currLiq = cp.lkb.add(cp.credits);\n                if (balLiq > currLiq) {\n                    // save gas since we know balLiq > currLiq and we know deficit[i] > 0\n                    deficit[i] = balLiq - currLiq;\n                    totalDeficit = totalDeficit.add(deficit[i]);\n                }\n            }\n\n            // indicates how much delta credit is distributed\n            uint256 spent;\n\n            // handle credits with 2 tranches. the [ < totalDeficit] [excessCredit]\n            // run full Delta, allocate all credits\n            if (totalDeficit == 0) {\n                // only fullMode delta will allocate excess credits\n                if (fullMode && deltaCredit > 0) {\n                    // credit ChainPath by weights\n                    for (uint256 i = 0; i < cpLength; ++i) {\n                        ChainPath storage cp = chainPaths[i];\n                        // credits = credits + toBalanceChange + remaining allocation based on weight\n                        uint256 amtToCredit = deltaCredit.mul(cp.weight).div(totalWeight);\n                        spent = spent.add(amtToCredit);\n                        cp.credits = cp.credits.add(amtToCredit);\n                    }\n                } // else do nth\n            } else if (totalDeficit <= deltaCredit) {\n                if (fullMode) {\n                    // algorithm step 13: calculate amount to disperse to bring to balance state or as close as possible\n                    uint256 excessCredit = deltaCredit - totalDeficit;\n                    // algorithm steps 14-16: calculate credits\n                    for (uint256 i = 0; i < cpLength; ++i) {\n                        if (deficit[i] > 0) {\n                            ChainPath storage cp = chainPaths[i];\n                            // credits = credits + deficit + remaining allocation based on weight\n                            uint256 amtToCredit = deficit[i].add(excessCredit.mul(cp.weight).div(totalWeight));\n                            spent = spent.add(amtToCredit);\n                            cp.credits = cp.credits.add(amtToCredit);\n                        }\n                    }\n                } else {\n                    // totalDeficit <= deltaCredit but not running fullMode\n                    // credit chainPaths as is if any deficit, not using all deltaCredit\n                    for (uint256 i = 0; i < cpLength; ++i) {\n                        if (deficit[i] > 0) {\n                            ChainPath storage cp = chainPaths[i];\n                            uint256 amtToCredit = deficit[i];\n                            spent = spent.add(amtToCredit);\n                            cp.credits = cp.credits.add(amtToCredit);\n                        }\n                    }\n                }\n            } else {\n                // totalDeficit > deltaCredit, fullMode or not, normalize the deficit by deltaCredit\n                for (uint256 i = 0; i < cpLength; ++i) {\n                    if (deficit[i] > 0) {\n                        ChainPath storage cp = chainPaths[i];\n                        uint256 proportionalDeficit = deficit[i].mul(deltaCredit).div(totalDeficit);\n                        spent = spent.add(proportionalDeficit);\n                        cp.credits = cp.credits.add(proportionalDeficit);\n                    }\n                }\n            }\n\n            // deduct the amount of credit sent\n            deltaCredit = deltaCredit.sub(spent);\n        }\n    }\n\n    function _mintLocal(\n        address _to,\n        uint256 _amountLD,\n        bool _feesEnabled,\n        bool _creditDelta\n    ) internal returns (uint256 amountSD) {\n        require(totalWeight > 0, \"Stargate: No ChainPaths exist\");\n        amountSD = amountLDtoSD(_amountLD);\n\n        uint256 mintFeeSD = 0;\n        if (_feesEnabled) {\n            mintFeeSD = amountSD.mul(mintFeeBP).div(BP_DENOMINATOR);\n            amountSD = amountSD.sub(mintFeeSD);\n            mintFeeBalance = mintFeeBalance.add(mintFeeSD);\n        }\n\n        if (_creditDelta) {\n            deltaCredit = deltaCredit.add(amountSD);\n        }\n\n        uint256 amountLPTokens = amountSD;\n        if (totalSupply != 0) {\n            amountLPTokens = amountSD.mul(totalSupply).div(totalLiquidity);\n        }\n        totalLiquidity = totalLiquidity.add(amountSD);\n\n        _mint(_to, amountLPTokens);\n        emit Mint(_to, amountLPTokens, amountSD, mintFeeSD);\n\n        // add to credits and call delta. short circuit to save gas\n        if (!batched || deltaCredit > totalLiquidity.mul(lpDeltaBP).div(BP_DENOMINATOR)) {\n            _delta(defaultLPMode);\n        }\n    }\n\n    function _safeTransfer(address _token, address _to, uint256 _value) private {\n        (bool success, bytes memory data) = _token.call(abi.encodeWithSelector(SELECTOR, _to, _value));\n        require(success && (data.length == 0 || abi.decode(data, (bool))), \"Stargate: TRANSFER_FAILED\");\n    }\n}\n"},{"file_path":"contracts/interfaces/ITreasury.sol","source_code":"// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.24;\n\ninterface ITreasury {\n    function pull(address to_, uint256 amount_) external;\n\n    function migrateTo(address newTreasury_) external;\n}\n"},{"file_path":"contracts/storage/FeeProviderStorage.sol","source_code":"// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.24;\n\nimport {IFeeProvider} from \"../interfaces/IFeeProvider.sol\";\nimport {IPoolRegistry} from \"../interfaces/IPoolRegistry.sol\";\nimport {IESMET} from \"../interfaces/external/IESMET.sol\";\n\nabstract contract FeeProviderStorageV1 is IFeeProvider {\n    struct Tier {\n        uint128 min; // esMET min balance needed to be eligible for `discount`\n        uint128 discount; // discount in percentage to apply. Use 18 decimals (e.g. 1e16 = 1%)\n    }\n\n    /**\n     * @notice The fee discount tiers\n     */\n    Tier[] private tiers__DEPRECATED;\n\n    /**\n     * @notice The default fee charged when swapping synthetic tokens\n     * @dev Use 18 decimals (e.g. 1e16 = 1%)\n     */\n    uint256 private defaultSwapFee__DEPRECATED;\n\n    /**\n     * @notice The fee charged when depositing collateral\n     * @dev Use 18 decimals (e.g. 1e16 = 1%)\n     */\n    uint256 public override depositFee;\n\n    /**\n     * @notice The fee charged when minting a synthetic token\n     * @dev Use 18 decimals (e.g. 1e16 = 1%)\n     */\n    uint256 public override issueFee;\n\n    /**\n     * @notice The fee charged when withdrawing collateral\n     * @dev Use 18 decimals (e.g. 1e16 = 1%)\n     */\n    uint256 public override withdrawFee;\n\n    /**\n     * @notice The fee charged when repaying debt\n     * @dev Use 18 decimals (e.g. 1e16 = 1%)\n     */\n    uint256 public override repayFee;\n\n    /**\n     * @notice The fees charged when liquidating a position\n     * @dev Use 18 decimals (e.g. 1e16 = 1%)\n     */\n    LiquidationFees public override liquidationFees;\n\n    /**\n     * @dev The Pool Registry\n     */\n    IPoolRegistry internal _poolRegistry;\n\n    /**\n     * @notice The esMET contract\n     */\n    IESMET public esMET;\n}\n\nabstract contract FeeProviderStorageV2 is FeeProviderStorageV1 {\n    /**\n     * @notice The fees charged when swapping synthetic tokens (by synthIn => synthOut directions)\n     * @dev Use 18 decimals (e.g. 1e16 = 1%)\n     */\n    mapping(address => mapping(address => uint256)) public override swapFees;\n}\n"},{"file_path":"contracts/Operator.sol","source_code":"// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.24;\n\nimport {TransientSlot} from \"./dependencies/openzeppelin/utils/TransientSlot.sol\";\nimport {Address} from \"./dependencies/openzeppelin/utils/Address.sol\";\nimport {ReentrancyGuardTransient} from \"./utils/ReentrancyGuardTransient.sol\";\nimport {IOperator} from \"./interfaces/IOperator.sol\";\n\n/// @title Operator contract\n/// @dev Allows Synth's users to perform calls from their EOAs\ncontract Operator is IOperator, ReentrancyGuardTransient {\n    using TransientSlot for *;\n    using Address for address;\n\n    // keccak256(abi.encode(uint256(keccak256(\"io.metronome.storage.Operator\")) - 1)) & ~bytes32(uint256(0xff))\n    bytes32 private constant MSG_SENDER_STORAGE = 0x7981994d60f65f1a18561bb9cc3329c34123a74c00a075d350036a66d0ed9a00;\n\n    /// @notice The sender which the operator is executing on behalf of\n    modifier setMsgSender() {\n        MSG_SENDER_STORAGE.asAddress().tstore(msg.sender);\n        _;\n        MSG_SENDER_STORAGE.asAddress().tstore(address(0));\n    }\n\n    /// @notice Get actual `msg.sender` that is executing the call\n    /// @dev It reverts if read outside of a call context\n    function getActualMsgSender() external view returns (address _actualMsgSender) {\n        _actualMsgSender = MSG_SENDER_STORAGE.asAddress().tload();\n        require(_actualMsgSender != address(0), \"not-authenticated\");\n    }\n\n    /// @notice Execute calls on sender's behalf\n    function execute(\n        Call[] calldata calls_\n    ) external payable override nonReentrant setMsgSender returns (bytes[] memory _returnData) {\n        uint256 _length = calls_.length;\n        _returnData = new bytes[](_length);\n\n        uint256 _sumOfValues;\n        Call calldata _call;\n        for (uint256 i; i < _length; ) {\n            _call = calls_[i];\n            uint256 _value = _call.value;\n            unchecked {\n                _sumOfValues += _value;\n            }\n            _returnData[i] = _call.target.functionCallWithValue(_call.callData, _value);\n            unchecked {\n                ++i;\n            }\n        }\n\n        require(msg.value == _sumOfValues, \"value-mismatch\");\n    }\n}\n"},{"file_path":"contracts/ProxyOFT.sol","source_code":"// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.24;\n\nimport {ContextUpgradeable} from \"./dependencies/openzeppelin-upgradeable/utils/ContextUpgradeable.sol\";\nimport {OwnableUpgradeable} from \"./dependencies/openzeppelin-upgradeable/access/OwnableUpgradeable.sol\";\nimport {IOFTCoreUpgradeable, IComposableOFTCoreUpgradeable, OFTCoreUpgradeable, ComposableOFTCoreUpgradeable} from \"./dependencies/@layerzerolabs/solidity-examples/contracts-upgradeable/token/oft/composable/ComposableOFTCoreUpgradeable.sol\";\nimport {BytesLib} from \"./dependencies/@layerzerolabs/solidity-examples/util/BytesLib.sol\";\nimport {Context, SynthContext} from \"./utils/SynthContext.sol\";\nimport {ProxyOFTStorageV2} from \"./storage/ProxyOFTStorage.sol\";\nimport {IPoolRegistry} from \"./interfaces/IPoolRegistry.sol\";\nimport {ISyntheticToken} from \"./interfaces/ISyntheticToken.sol\";\nimport {WadRayMath} from \"./lib/WadRayMath.sol\";\n\nerror AddressIsNull();\nerror SenderIsNotTheOwner();\nerror BridgingIsPaused();\nerror SendAndCallNotAllowed();\nerror DestinationChainNotAllowed();\nerror InvalidToAddress();\nerror FeeIsGreaterThanTheMax();\nerror NewValueIsSameAsCurrent();\n\n/**\n * @title The ProxyOFT contract\n */\ncontract ProxyOFT is SynthContext, ComposableOFTCoreUpgradeable, ProxyOFTStorageV2 {\n    using BytesLib for bytes;\n    using WadRayMath for uint256;\n\n    string public constant VERSION = \"1.4.1\";\n\n    uint256 internal constant MAX_OFT_FEE = 0.25e18; // 25%\n\n    /// @notice Emitted when OFT fee is updated\n    event OftFeeUpdated(uint256 oldOftFee, uint256 newOftFee);\n\n    constructor() {\n        _disableInitializers();\n    }\n\n    /// @inheritdoc Context\n    function _msgSender() internal view virtual override(ContextUpgradeable, SynthContext) returns (address) {\n        return SynthContext._msgSender();\n    }\n\n    /// @inheritdoc Context\n    function _msgData() internal view virtual override(ContextUpgradeable, Context) returns (bytes calldata) {\n        return Context._msgData();\n    }\n\n    function initialize(address lzEndpoint_, ISyntheticToken syntheticToken_) external initializer {\n        if (address(syntheticToken_) == address(0)) revert AddressIsNull();\n        if (address(lzEndpoint_) == address(0)) revert AddressIsNull();\n\n        syntheticToken = syntheticToken_;\n\n        __ComposableOFTCoreUpgradeable_init(lzEndpoint_);\n    }\n\n    /// @inheritdoc IOFTCoreUpgradeable\n    function circulatingSupply() public view override returns (uint) {\n        return syntheticToken.totalSupply();\n    }\n\n    /**\n     * @notice Get other chains Proxy OFT contracts\n     * @param chainId_ the chain to get contract from\n     */\n    function getProxyOFTOf(uint16 chainId_) public view returns (address _proxyOFT) {\n        return trustedRemoteLookup[chainId_].toAddress(0);\n    }\n\n    /// @inheritdoc IOFTCoreUpgradeable\n    function token() public view override returns (address) {\n        return address(syntheticToken);\n    }\n\n    /// @notice Indicates whether the OFT contract requires approval of the `token()` to send.\n    function approvalRequired() external pure virtual returns (bool) {\n        return false;\n    }\n\n    /// @inheritdoc OFTCoreUpgradeable\n    function _debitFrom(\n        address from_,\n        uint16 dstChainId_,\n        bytes memory toAddress_,\n        uint amount_\n    ) internal override returns (uint256 _sent) {\n        IPoolRegistry _poolRegistry = syntheticToken.poolRegistry();\n        if (_msgSender() != from_) revert SenderIsNotTheOwner();\n        if (!_poolRegistry.isBridgingActive()) revert BridgingIsPaused();\n        if (!_poolRegistry.isDestinationChainSupported(dstChainId_)) revert DestinationChainNotAllowed();\n        // Note: All supported destinations are EVM chains, hence the 20-byte address\n        if (toAddress_.length != 20 || toAddress_.toAddress(0) == address(0)) revert InvalidToAddress();\n\n        uint256 _fee;\n        (_sent, _fee) = quoteSendFromOut(amount_);\n        if (_fee > 0) {\n            syntheticToken.seize(from_, _poolRegistry.feeCollector(), _fee);\n        }\n        syntheticToken.burnFor(from_, _sent);\n    }\n\n    /// @inheritdoc OFTCoreUpgradeable\n    function _creditTo(\n        uint16 /*srcChainId_*/,\n        address toAddress_,\n        uint amount_\n    ) internal override returns (uint256 _received) {\n        syntheticToken.mint(toAddress_, amount_);\n        return amount_;\n    }\n\n    /// @inheritdoc ComposableOFTCoreUpgradeable\n    function sendAndCall(\n        address /*from_*/,\n        uint16 /*dstChainId_*/,\n        bytes calldata /*toAddress_*/,\n        uint /*amount_*/,\n        bytes calldata /*payload_*/,\n        uint64 /*dstGasForCall_*/,\n        address payable /*refundAddress_*/,\n        address /*zroPaymentAddress_*/,\n        bytes calldata /*adapterParams_*/\n    ) public payable override(ComposableOFTCoreUpgradeable, IComposableOFTCoreUpgradeable) {\n        // Note: We do not allow sendAndCall functionality in the ProxyOFT\n        // Replace the revert with `_sendAndCall` call to enable.\n        revert SendAndCallNotAllowed();\n    }\n\n    /**\n     * @notice User friendly `sendFrom()` function\n     */\n    function sendFrom(address from_, uint16 dstChainId_, address to_, uint256 amount_) external payable {\n        _send({\n            _from: from_,\n            _dstChainId: dstChainId_,\n            _toAddress: abi.encodePacked(to_),\n            _amount: amount_,\n            _refundAddress: payable(from_),\n            _zroPaymentAddress: address(0),\n            _adapterParams: abi.encodePacked(\n                uint16(1), // LZ_ADAPTER_PARAMS_VERSION\n                syntheticToken.poolRegistry().lzBaseGasLimit()\n            )\n        });\n    }\n\n    /**\n     * @notice User friendly `sendFrom()` function\n     */\n    function estimateSendFee(\n        uint16 dstChainId_,\n        address to_,\n        uint256 amount_\n    ) external view returns (uint256 _nativeFee) {\n        (_nativeFee, ) = this.estimateSendFee({\n            _dstChainId: dstChainId_,\n            _toAddress: abi.encodePacked(to_),\n            _amount: amount_,\n            _useZro: false,\n            _adapterParams: abi.encodePacked(\n                uint16(1), // LZ_ADAPTER_PARAMS_VERSION\n                syntheticToken.poolRegistry().lzBaseGasLimit()\n            )\n        });\n    }\n\n    /**\n     * @notice Quote `amountIn_` needed to receive `amountOut_` on the destination chain\n     * @param amountOut_ Amount to receive on the destination chain\n     * @return _amountIn Amount to send from the source chain\n     * @return _fee Fee to charge on the source chain\n     */\n    function quoteSendFromIn(uint256 amountOut_) external view override returns (uint256 _amountIn, uint256 _fee) {\n        uint256 _oftFee = oftFee;\n        if (_oftFee == 0) return (amountOut_, 0);\n\n        // Note: Round up to ensure that `quoteSendFromOut(_amountIn) >= amountOut_`\n        uint256 _denominator = 1e18 - _oftFee;\n        _amountIn = (amountOut_ * 1e18 + _denominator - 1) / _denominator;\n        _fee = _amountIn.wadMul(_oftFee);\n    }\n\n    /**\n     * @notice Quote `amountOut_` received on the destination chain when sending `amountIn_`\n     * @param amountIn_ Amount to send from the source chain\n     * @return _amountOut Amount to receive on the destination chain\n     * @return _fee Fee to charge on the source chain\n     */\n    function quoteSendFromOut(uint256 amountIn_) public view override returns (uint256 _amountOut, uint256 _fee) {\n        _fee = amountIn_.wadMul(oftFee);\n        _amountOut = amountIn_ - _fee;\n    }\n\n    /// @notice Get pool registry contract\n    function poolRegistry() public view override returns (IPoolRegistry) {\n        return syntheticToken.poolRegistry();\n    }\n\n    /// @inheritdoc OwnableUpgradeable\n    function owner() public view override returns (address) {\n        return syntheticToken.poolRegistry().governor();\n    }\n\n    /// @inheritdoc OwnableUpgradeable\n    function renounceOwnership() public override {\n        revert(\"disabled\");\n    }\n\n    /// @inheritdoc OwnableUpgradeable\n    function transferOwnership(address) public override {\n        revert(\"disabled\");\n    }\n\n    /**\n     * @notice Update OFT fee\n     * @param newOftFee_ The new fee\n     */\n    function updateOftFee(uint256 newOftFee_) external override onlyOwner {\n        if (newOftFee_ > MAX_OFT_FEE) revert FeeIsGreaterThanTheMax();\n        uint256 _current = oftFee;\n        if (newOftFee_ == _current) revert NewValueIsSameAsCurrent();\n        emit OftFeeUpdated(_current, newOftFee_);\n        oftFee = newOftFee_;\n    }\n}\n"},{"file_path":"contracts/utils/Pauseable.sol","source_code":"// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.24;\n\nimport {IPauseable} from \"../interfaces/IPauseable.sol\";\nimport {Governable} from \"../access/Governable.sol\";\n\nerror IsPaused();\nerror IsShutdown();\nerror IsNotPaused();\nerror IsNotShutdown();\nerror SenderIsNotAuthorized();\n\n/**\n * @dev Contract module which allows children to implement an emergency stop\n * mechanism that can be triggered by an authorized account.\n */\nabstract contract Pauseable is IPauseable, Governable {\n    /// @notice Emitted when contract is turned on\n    event Open(address indexed caller);\n\n    /// @notice Emitted when contract is paused\n    event Paused(address indexed caller);\n\n    /// @notice Emitted when contract is shuted down\n    event Shutdown(address indexed caller);\n\n    /// @notice Emitted when contract is unpaused\n    event Unpaused(address indexed caller);\n\n    bool private _paused;\n    bool private _everythingStopped;\n\n    modifier canShutdown() {\n        if (_msgSender() != governor && !isGuardian(_msgSender())) revert SenderIsNotAuthorized();\n        _;\n    }\n\n    /**\n     * @dev Throws if contract is paused\n     */\n    modifier whenNotPaused() {\n        if (paused()) revert IsPaused();\n        _;\n    }\n\n    /**\n     * @dev Throws if contract is shutdown\n     */\n    modifier whenNotShutdown() {\n        if (everythingStopped()) revert IsShutdown();\n        _;\n    }\n\n    /**\n     * @dev Throws if contract is not paused\n     */\n    modifier whenPaused() {\n        if (!paused()) revert IsNotPaused();\n        _;\n    }\n\n    /**\n     * @dev Throws if contract is not shutdown\n     */\n    modifier whenShutdown() {\n        if (!everythingStopped()) revert IsNotShutdown();\n        _;\n    }\n\n    /**\n     * @dev If inheriting child is using proxy then child contract can use\n     * __Pauseable_init() function to initialization this contract\n     */\n    // solhint-disable-next-line func-name-mixedcase\n    function __Pauseable_init() internal onlyInitializing {\n        __Governable_init();\n    }\n\n    /**\n     * @notice Return `true` if contract is shutdown\n     */\n    function everythingStopped() public view virtual returns (bool) {\n        return _everythingStopped;\n    }\n\n    /**\n     * @notice Return `true` if contract is paused\n     */\n    function paused() public view virtual returns (bool) {\n        return _paused;\n    }\n\n    /**\n     * @dev Open contract operations, if contract is in shutdown state\n     */\n    function open() external virtual whenShutdown onlyGovernor {\n        _everythingStopped = false;\n        emit Open(_msgSender());\n    }\n\n    /**\n     * @dev Suspend deposit feature, if contract is not paused.\n     */\n    function pause() external virtual whenNotPaused onlyGovernor {\n        _paused = true;\n        emit Paused(_msgSender());\n    }\n\n    /**\n     * @dev Suspend all features (issue, repay, deposit, withdraw, liquidate and swap), if not already shutdown.\n     */\n    function shutdown() external virtual whenNotShutdown canShutdown {\n        _everythingStopped = true;\n        _paused = true;\n        emit Shutdown(_msgSender());\n    }\n\n    /**\n     * @dev Unpause contract operations, allow only if contract is paused and not shutdown.\n     */\n    function unpause() external virtual whenPaused whenNotShutdown onlyGovernor {\n        _paused = false;\n        emit Unpaused(_msgSender());\n    }\n\n    /**\n     * @dev Check if the sender is an authorized guardian\n     */\n    function isGuardian(address) public view virtual returns (bool);\n}\n"},{"file_path":"contracts/interfaces/external/IStargatePool.sol","source_code":"// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.24;\n\ninterface IStargatePool {\n    function token() external view returns (address _token);\n}\n"},{"file_path":"contracts/interfaces/external/ISwapper.sol","source_code":"// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.24;\n\ninterface ISwapper {\n    function swapExactInput(\n        address tokenIn_,\n        address tokenOut_,\n        uint256 amountIn_,\n        uint256 amountOutMin_,\n        address receiver_\n    ) external returns (uint256 _amountOut);\n}\n"},{"file_path":"contracts/AMO.sol","source_code":"// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.24;\n\nimport {Address} from \"./dependencies/openzeppelin/utils/Address.sol\";\nimport {Initializable} from \"./dependencies/openzeppelin-upgradeable/proxy/utils/Initializable.sol\";\nimport {SafeERC20} from \"./dependencies/openzeppelin/token/ERC20/utils/SafeERC20.sol\";\nimport {IERC20} from \"./dependencies/openzeppelin/token/ERC20/IERC20.sol\";\nimport {EnumerableSet} from \"./dependencies/openzeppelin/utils/structs/EnumerableSet.sol\";\nimport {SynthContext} from \"./utils/SynthContext.sol\";\nimport {IPoolRegistry} from \"./interfaces/IPoolRegistry.sol\";\nimport {ISyntheticToken} from \"./interfaces/ISyntheticToken.sol\";\nimport {IVPool} from \"./interfaces/external/IVPool.sol\";\nimport {AMOStorage} from \"./storage/AMOStorage.sol\";\nimport {Math} from \"./dependencies/openzeppelin/utils/math/Math.sol\";\n\n/**\n * @title Automated Market Operator\n * @notice Operator will mint/burn SyntheticToken liquidity and deposit/withdraw to/from Vesper pool as needed.\n */\ncontract AMO is SynthContext, Initializable, AMOStorage {\n    using SafeERC20 for IERC20;\n    using SafeERC20 for ISyntheticToken;\n    using EnumerableSet for EnumerableSet.AddressSet;\n\n    string public constant VERSION = \"1.4.1\";\n\n    event MintAndDeposit(ISyntheticToken indexed syntheticToken, IVPool indexed vPool, uint256 amountDeposited);\n    event WithdrawAndBurn(ISyntheticToken indexed syntheticToken, IVPool indexed vPool, uint256 amountBurnt);\n    event Harvest(ISyntheticToken indexed syntheticToken, IVPool indexed vPool, uint256 profit);\n    event KeeperUpdated(address indexed keeper, string indexed ops);\n    event VesperPoolUpdated(ISyntheticToken indexed syntheticToken, IVPool indexed vPool);\n\n    error AddressIsNull();\n    error CallerIsNotAuthorized();\n    error SyntheticTokenDoesNotMatch();\n    error AmountIsZero();\n    error CallerIsNotGovernor();\n    error VesperPoolIsNotAllowed();\n    error AmountToBurnGreaterThanAmoSupply();\n\n    modifier onlyAuthorized() {\n        address _msgSender = _msgSender();\n        if (!isKeeper(_msgSender) && _msgSender != governor()) revert CallerIsNotAuthorized();\n        _;\n    }\n\n    modifier onlyGovernor() {\n        if (_msgSender() != governor()) revert CallerIsNotGovernor();\n        _;\n    }\n\n    constructor() {\n        _disableInitializers();\n    }\n\n    function initialize(IPoolRegistry poolRegistry_) public initializer {\n        if (address(poolRegistry_) == address(0)) revert AddressIsNull();\n\n        _poolRegistry = poolRegistry_;\n    }\n\n    /**\n     * @notice Only 'authorized' role can call this function.\n     * It will mint `amount_` from `syntheticToken_` token and deposit those into `vPool_`.\n     * @param syntheticToken_ Synthetic Token Address\n     * @param vPool_ Vesper pool address where Synthetic token is defined as collateral.\n     * @param amount_ Amount in Synthetic token\n     */\n    function mintAndDeposit(ISyntheticToken syntheticToken_, IVPool vPool_, uint256 amount_) external onlyAuthorized {\n        if (amount_ == 0) revert AmountIsZero();\n        if (vPools[address(syntheticToken_)] != address(vPool_)) revert VesperPoolIsNotAllowed();\n\n        // 1. Mint Synth here\n        syntheticToken_.mint(address(this), amount_);\n\n        // 2. Deposit minted Synth in Vesper pool\n        syntheticToken_.safeApprove(address(vPool_), 0);\n        syntheticToken_.safeApprove(address(vPool_), amount_);\n        vPool_.deposit(amount_);\n\n        emit MintAndDeposit(syntheticToken_, vPool_, amount_);\n    }\n\n    /**\n     * @notice Only 'authorized' role can call this function.\n     * It will calculate `_shares` from `amount_` and withdraw `_shares` from `vPool_` and\n     * burn amount of Synthetic token withdrawn from Vesper.\n     * @param syntheticToken_ Synthetic Token Address\n     * @param vPool_ Vesper pool address where Synthetic token is defined as collateral.\n     * @param amount_ Amount in Synthetic token\n     */\n    function withdrawAndBurn(ISyntheticToken syntheticToken_, IVPool vPool_, uint256 amount_) external onlyAuthorized {\n        if (amount_ == 0) revert AmountIsZero();\n        if (vPools[address(syntheticToken_)] != address(vPool_)) revert VesperPoolIsNotAllowed();\n\n        // 1. Calculate shares to withdraw\n        uint256 _shares = Math.min((amount_ * 1e18) / vPool_.pricePerShare(), vPool_.balanceOf(address(this)));\n\n        // 2. Withdraw synth from Vesper pool\n        uint256 _amountToBurn = _withdrawFromVesper(syntheticToken_, vPool_, _shares);\n        if (_amountToBurn > syntheticToken_.amoSupply()) revert AmountToBurnGreaterThanAmoSupply();\n\n        // 3. Burn synth withdrawn from Vesper pool\n        syntheticToken_.burn(_amountToBurn);\n\n        emit WithdrawAndBurn(syntheticToken_, vPool_, _amountToBurn);\n    }\n\n    /**\n     * @notice Only 'authorized' role can call this function.\n     * It will calculate profit, withdraw profit from Vesper pool and transfer profit to governor.\n     * @param syntheticToken_ Synthetic token address\n     * @param vPool_ Vesper pool address where Synthetic token is defined as collateral.\n     */\n    function harvest(ISyntheticToken syntheticToken_, IVPool vPool_) external onlyAuthorized {\n        if (vPools[address(syntheticToken_)] != address(vPool_)) revert VesperPoolIsNotAllowed();\n\n        // 1. Calculate profit in Synth\n        uint256 _synthInPool = (vPool_.balanceOf(address(this)) * vPool_.pricePerShare()) / 1e18;\n        uint256 _synthDeposited = syntheticToken_.amoSupply();\n        uint256 _profit = _synthInPool > _synthDeposited ? _synthInPool - _synthDeposited : 0;\n\n        if (_profit > 0) {\n            // 2. Calculate profit in Vesper pool shares\n            uint256 _profitInShare = (_profit * 1e18) / vPool_.pricePerShare();\n\n            // 3. Withdraw profit from Vesper pool\n            uint256 _actualProfit = _withdrawFromVesper(syntheticToken_, vPool_, _profitInShare);\n\n            // 4. Transfer profit to governor\n            syntheticToken_.transfer(governor(), _actualProfit);\n            emit Harvest(syntheticToken_, vPool_, _actualProfit);\n        }\n    }\n\n    function _withdrawFromVesper(\n        ISyntheticToken syntheticToken_,\n        IVPool vPool_,\n        uint256 shares_\n    ) private returns (uint256) {\n        // Vesper pool may withdraw less, of course burn less shares too, than requested.\n        // Hence the difference of Synth balance after withdraw and before withdraw is actual Synth withdrawn.\n        uint256 _before = syntheticToken_.balanceOf(address(this));\n        vPool_.withdraw(shares_);\n        return syntheticToken_.balanceOf(address(this)) - _before;\n    }\n\n    /// @inheritdoc SynthContext\n    function poolRegistry() public view override returns (IPoolRegistry) {\n        return _poolRegistry;\n    }\n\n    /**\n     * @notice Governor of this contract is same as PoolRegistry governor.\n     * Governor can perform all authorized actions.\n     */\n    function governor() public view returns (address) {\n        return _poolRegistry.governor();\n    }\n\n    /**\n     * @notice List of keepers. Keeper can perform all authorized actions.\n     */\n    function getKeepers() external view returns (address[] memory) {\n        return keepers.values();\n    }\n\n    /**\n     * @notice Returns whether given address is keeper or not.\n     * @param user_ User address to check\n     */\n    function isKeeper(address user_) public view returns (bool) {\n        return keepers.contains(user_);\n    }\n\n    /**\n     * @notice ERC20 recovery in case of stuck tokens due direct transfers to the contract address.\n     * @param token_ The token to transfer\n     * @param amount_ The amount to send\n     */\n    function sweep(IERC20 token_, uint256 amount_) external onlyGovernor {\n        if (amount_ == 0) revert AmountIsZero();\n\n        if (address(token_) == address(0)) {\n            Address.sendValue(payable(governor()), amount_);\n        } else {\n            token_.safeTransfer(governor(), amount_);\n        }\n    }\n\n    /**\n     * @notice Only 'governor' role can call this function.\n     * This function will remove keeper_ if already exist in list else add in list.\n     * @param keeper_ Keeper address to add/remove.\n     */\n    function updateKeeper(address keeper_) external onlyGovernor {\n        if (keepers.contains(keeper_)) {\n            keepers.remove(keeper_);\n            emit KeeperUpdated(keeper_, \"remove\");\n        } else {\n            keepers.add(keeper_);\n            emit KeeperUpdated(keeper_, \"add\");\n        }\n    }\n\n    /**\n     * @notice Only 'governor' role can call this function.\n     * This function will set a `vPool_` allowed to receive funds for a given synthetic asset\n     * @param syntheticToken_ The Synthetic token\n     * @param vPool_ The Vesper Pool allowed\n     */\n    function updateVesperPool(ISyntheticToken syntheticToken_, IVPool vPool_) external onlyGovernor {\n        if (address(vPool_) != address(0) && vPool_.token() != address(syntheticToken_))\n            revert SyntheticTokenDoesNotMatch();\n\n        vPools[address(syntheticToken_)] = address(vPool_);\n\n        emit VesperPoolUpdated(syntheticToken_, vPool_);\n    }\n}\n"},{"file_path":"contracts/dependencies/openzeppelin/utils/StorageSlot.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/StorageSlot.sol)\n\npragma solidity ^0.8.0;\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 ERC1967 implementation slot:\n * ```\n * contract ERC1967 {\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(Address.isContract(newImplementation), \"ERC1967: new implementation is not a contract\");\n *         StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\n *     }\n * }\n * ```\n *\n * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._\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    /**\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 {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\n     */\n    function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\n        assembly {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\n     */\n    function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\n        assembly {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\n     */\n    function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\n        assembly {\n            r.slot := slot\n        }\n    }\n}\n"},{"file_path":"contracts/dependencies/openzeppelin/utils/Context.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n    function _msgSender() internal view virtual returns (address) {\n        return msg.sender;\n    }\n\n    function _msgData() internal view virtual returns (bytes calldata) {\n        return msg.data;\n    }\n}\n"},{"file_path":"contracts/dependencies/openzeppelin/interfaces/draft-IERC1822.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\n * proxy whose upgrades are fully controlled by the current implementation.\n */\ninterface IERC1822Proxiable {\n    /**\n     * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\n     * address.\n     *\n     * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\n     * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\n     * function revert if invoked through a proxy.\n     */\n    function proxiableUUID() external view returns (bytes32);\n}\n"},{"file_path":"contracts/access/Governable.sol","source_code":"// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.24;\n\nimport {Initializable} from \"../dependencies/openzeppelin-upgradeable/proxy/utils/Initializable.sol\";\nimport {Context} from \"../dependencies/openzeppelin/utils/Context.sol\";\nimport {TokenHolder} from \"../utils/TokenHolder.sol\";\nimport {IGovernable} from \"../interfaces/IGovernable.sol\";\n\nerror SenderIsNotGovernor();\nerror ProposedGovernorIsNull();\nerror SenderIsNotTheProposedGovernor();\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (governor) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the governor account will be the one that deploys the contract. This\n * can later be changed with {transferGovernorship}.\n *\n */\nabstract contract Governable is IGovernable, Context, TokenHolder, Initializable {\n    /**\n     * @notice The governor\n     * @dev By default the contract deployer is the initial governor\n     */\n    address public governor;\n\n    /**\n     * @notice The proposed governor\n     * @dev It will be empty (address(0)) if there isn't a proposed governor\n     */\n    address public proposedGovernor;\n\n    event UpdatedGovernor(address indexed previousGovernor, address indexed proposedGovernor);\n\n    constructor() {\n        address _msgSender = _msgSender();\n        governor = _msgSender;\n        emit UpdatedGovernor(address(0), _msgSender);\n    }\n\n    /**\n     * @dev If inheriting child is using proxy then child contract can use\n     * __Governable_init() function to initialization this contract\n     */\n    // solhint-disable-next-line func-name-mixedcase\n    function __Governable_init() internal onlyInitializing {\n        address _msgSender = _msgSender();\n        governor = _msgSender;\n        emit UpdatedGovernor(address(0), _msgSender);\n    }\n\n    /**\n     * @dev Throws if called by any account other than the governor.\n     */\n    modifier onlyGovernor() {\n        if (governor != _msgSender()) revert SenderIsNotGovernor();\n        _;\n    }\n\n    /// @inheritdoc TokenHolder\n    // solhint-disable-next-line no-empty-blocks\n    function _requireCanSweep() internal view override onlyGovernor {}\n\n    /**\n     * @notice Transfers governorship of the contract to a new account (`proposedGovernor`).\n     * @dev Can only be called by the current owner.\n     * @param proposedGovernor_ The new proposed governor\n     */\n    function transferGovernorship(address proposedGovernor_) external onlyGovernor {\n        if (proposedGovernor_ == address(0)) revert ProposedGovernorIsNull();\n        proposedGovernor = proposedGovernor_;\n    }\n\n    /**\n     * @notice Allows new governor to accept governorship of the contract.\n     */\n    function acceptGovernorship() external {\n        address _proposedGovernor = proposedGovernor;\n        if (_msgSender() != _proposedGovernor) revert SenderIsNotTheProposedGovernor();\n        emit UpdatedGovernor(governor, _proposedGovernor);\n        governor = _proposedGovernor;\n        proposedGovernor = address(0);\n    }\n}\n"},{"file_path":"contracts/interfaces/ISyntheticToken.sol","source_code":"// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.24;\n\nimport {IERC20Metadata} from \"../dependencies/openzeppelin/token/ERC20/extensions/IERC20Metadata.sol\";\nimport {IPoolRegistry} from \"./IPoolRegistry.sol\";\nimport {IProxyOFT} from \"../interfaces/IProxyOFT.sol\";\n\ninterface ISyntheticToken is IERC20Metadata {\n    function isActive() external view returns (bool);\n\n    function mint(address to_, uint256 amount_) external;\n\n    function burnFor(address from_, uint256 amount) external;\n\n    function burn(uint256 amount_) external;\n\n    function burnFrom(address from_, uint256 amount_) external;\n\n    function poolRegistry() external view returns (IPoolRegistry);\n\n    function toggleIsActive() external;\n\n    function seize(address from_, address to_, uint256 amount_) external;\n\n    function updateMaxTotalSupply(uint256 newMaxTotalSupply_) external;\n\n    function updateProxyOFT(IProxyOFT newProxyOFT_) external;\n\n    function maxTotalSupply() external view returns (uint256);\n\n    function proxyOFT() external view returns (IProxyOFT);\n\n    function amoSupply() external view returns (uint256);\n}\n"},{"file_path":"contracts/VesperGateway.sol","source_code":"// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.24;\n\nimport {SafeERC20} from \"./dependencies/openzeppelin/token/ERC20/utils/SafeERC20.sol\";\nimport {IERC20} from \"./dependencies/openzeppelin/token/ERC20/IERC20.sol\";\nimport {SynthContext} from \"./utils/SynthContext.sol\";\nimport {ReentrancyGuardTransient} from \"./utils/ReentrancyGuardTransient.sol\";\nimport {TokenHolder} from \"./utils/TokenHolder.sol\";\nimport {IVPool} from \"./interfaces/external/IVPool.sol\";\nimport {IPoolRegistry} from \"./interfaces/IPoolRegistry.sol\";\nimport {IVesperGateway} from \"./interfaces/IVesperGateway.sol\";\nimport {IDepositToken} from \"./interfaces/IDepositToken.sol\";\nimport {IPool} from \"./interfaces/IPool.sol\";\n\nerror SenderIsNotGovernor();\nerror UnregisteredPool();\n\n/**\n * @title Helper contract to easily support vTokens as collateral\n */\ncontract VesperGateway is SynthContext, ReentrancyGuardTransient, TokenHolder, IVesperGateway {\n    using SafeERC20 for IERC20;\n    using SafeERC20 for IDepositToken;\n    using SafeERC20 for IVPool;\n\n    IPoolRegistry internal immutable _poolRegistry;\n\n    modifier onlyGovernor() {\n        if (_poolRegistry.governor() != _msgSender()) revert SenderIsNotGovernor();\n        _;\n    }\n\n    constructor(IPoolRegistry poolRegistry_) {\n        _poolRegistry = poolRegistry_;\n    }\n\n    /**\n     * @notice Deposit `vToken` as collateral using underlying asset.\n     * @param pool_ The Pool contract\n     * @param vToken_ The vToken to deposit\n     * @param amount_ The amount of `underlying` asset to deposit\n     */\n    function deposit(IPool pool_, IVPool vToken_, uint256 amount_) external override {\n        if (!_poolRegistry.isPoolRegistered(address(pool_))) revert UnregisteredPool();\n\n        address _msgSender = _msgSender();\n\n        // 1. Get `underlying` asset\n        IERC20 _underlying = IERC20(vToken_.token());\n        _underlying.safeTransferFrom(_msgSender, address(this), amount_);\n\n        // 2. Deposit `underlying` to `VPool`\n        _underlying.safeApprove(address(vToken_), 0);\n        _underlying.safeApprove(address(vToken_), amount_);\n        uint256 _balanceBefore = vToken_.balanceOf(address(this));\n        vToken_.deposit(amount_);\n        uint256 _vTokenAmount = vToken_.balanceOf(address(this)) - _balanceBefore;\n\n        // 3. Deposit `VPool` to `Synth` and send `msdTokens` to the `_msgSender()`\n        IDepositToken _depositToken = pool_.depositTokenOf(vToken_);\n        vToken_.safeApprove(address(_depositToken), 0);\n        vToken_.safeApprove(address(_depositToken), _vTokenAmount);\n        _depositToken.deposit(_vTokenAmount, _msgSender);\n    }\n\n    /**\n     * @notice Withdraws the `vToken` deposit of _msgSender().\n     * @param pool_ The Pool contract\n     * @param vToken_ The vToken to withdraw\n     * @param amount_ The amount of deposit tokens to withdraw and receive underlying\n     */\n    function withdraw(IPool pool_, IVPool vToken_, uint256 amount_) external override nonReentrant {\n        if (!_poolRegistry.isPoolRegistered(address(pool_))) revert UnregisteredPool();\n\n        address _msgSender = _msgSender();\n\n        // 1. Get `msdTokens`\n        IDepositToken _depositToken = pool_.depositTokenOf(vToken_);\n        _depositToken.safeTransferFrom(_msgSender, address(this), amount_);\n\n        // 2. Withdraw `vTokens` from `Synth`\n        (uint256 _vTokenAmount, ) = _depositToken.withdraw(amount_, address(this));\n\n        // 3. Withdraw `underlying` from `VPool`\n        IERC20 _underlying = IERC20(vToken_.token());\n        uint256 _balanceBefore = _underlying.balanceOf(address(this));\n        vToken_.withdraw(_vTokenAmount);\n        uint256 _underlyingAmount = _underlying.balanceOf(address(this)) - _balanceBefore;\n\n        // 4. Transfer `underlying` to the `_msgSender()`\n        _underlying.safeTransfer(_msgSender, _underlyingAmount);\n    }\n\n    /// @inheritdoc SynthContext\n    function poolRegistry() public view override returns (IPoolRegistry) {\n        return _poolRegistry;\n    }\n\n    /// @inheritdoc TokenHolder\n    // solhint-disable-next-line no-empty-blocks\n    function _requireCanSweep() internal view override onlyGovernor {}\n}\n"},{"file_path":"contracts/dependencies/@layerzerolabs/solidity-examples/token/oft/composable/ComposableOFT.sol","source_code":"// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../../../../../openzeppelin/token/ERC20/ERC20.sol\";\nimport \"./IComposableOFT.sol\";\nimport \"./ComposableOFTCore.sol\";\n\ncontract ComposableOFT is ComposableOFTCore, ERC20, IComposableOFT {\n    constructor(\n        string memory _name,\n        string memory _symbol,\n        address _lzEndpoint\n    ) ERC20(_name, _symbol) ComposableOFTCore(_lzEndpoint) {}\n\n    function supportsInterface(\n        bytes4 interfaceId\n    ) public view virtual override(ComposableOFTCore, IERC165) returns (bool) {\n        return\n            interfaceId == type(IComposableOFT).interfaceId ||\n            interfaceId == type(IOFT).interfaceId ||\n            interfaceId == type(IERC20).interfaceId ||\n            super.supportsInterface(interfaceId);\n    }\n\n    function circulatingSupply() public view virtual override returns (uint) {\n        return totalSupply();\n    }\n\n    function token() public view virtual override returns (address) {\n        return address(this);\n    }\n\n    function _debitFrom(address _from, uint16, bytes memory, uint _amount) internal virtual override returns (uint) {\n        address spender = _msgSender();\n        if (_from != spender) _spendAllowance(_from, spender, _amount);\n        _burn(_from, _amount);\n        return _amount;\n    }\n\n    function _creditTo(uint16, address _toAddress, uint _amount) internal virtual override returns (uint) {\n        _mint(_toAddress, _amount);\n        return _amount;\n    }\n}\n"},{"file_path":"contracts/PoolRegistry.sol","source_code":"// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.24;\n\nimport {Initializable} from \"./dependencies/openzeppelin-upgradeable/proxy/utils/Initializable.sol\";\nimport {ReentrancyGuardDeprecated} from \"./utils/ReentrancyGuardDeprecated.sol\";\nimport {ReentrancyGuardTransient} from \"./utils/ReentrancyGuardTransient.sol\";\nimport {WadRayMath} from \"./lib/WadRayMath.sol\";\nimport {PoolRegistryStorageV5} from \"./storage/PoolRegistryStorage.sol\";\nimport {IPool} from \"./interfaces/IPool.sol\";\nimport {Pauseable} from \"./utils/Pauseable.sol\";\nimport {EnumerableSet} from \"./dependencies/openzeppelin/utils/structs/EnumerableSet.sol\";\nimport {IMasterOracle} from \"./interfaces/external/IMasterOracle.sol\";\nimport {ISwapper} from \"./interfaces/external/ISwapper.sol\";\nimport {IPoolRegistry} from \"./interfaces/IPoolRegistry.sol\";\nimport {IOperator} from \"./interfaces/IOperator.sol\";\nimport {ISyntheticToken} from \"./interfaces/ISyntheticToken.sol\";\n\nerror AddressIsNull();\nerror OracleIsNull();\nerror FeeCollectorIsNull();\nerror NativeTokenGatewayIsNull();\nerror AlreadyRegistered();\nerror UnregisteredPool();\nerror NewValueIsSameAsCurrent();\nerror UnregisteredGuardian();\n\n/**\n * @title PoolRegistry contract\n */\ncontract PoolRegistry is\n    Initializable,\n    ReentrancyGuardDeprecated,\n    ReentrancyGuardTransient,\n    Pauseable,\n    PoolRegistryStorageV5\n{\n    using WadRayMath for uint256;\n    using EnumerableSet for EnumerableSet.AddressSet;\n\n    string public constant VERSION = \"1.4.1\";\n\n    /// @notice Emitted when fee collector is updated\n    event FeeCollectorUpdated(address indexed oldFeeCollector, address indexed newFeeCollector);\n\n    /// @notice Emitted when master oracle contract is updated\n    event MasterOracleUpdated(IMasterOracle indexed oldOracle, IMasterOracle indexed newOracle);\n\n    /// @notice Emitted when native token gateway is updated\n    event NativeTokenGatewayUpdated(address indexed oldGateway, address indexed newGateway);\n\n    /// @notice Emitted when a pool is registered\n    event PoolRegistered(uint256 indexed id, address indexed pool);\n\n    /// @notice Emitted when a pool is unregistered\n    event PoolUnregistered(uint256 indexed id, address indexed pool);\n\n    /// @notice Emitted when Swapper contract is updated\n    event SwapperUpdated(ISwapper oldSwapFee, ISwapper newSwapFee);\n\n    /// @notice Emitted when a guardian is added\n    event GuardianAdded(address indexed guardian);\n\n    /// @notice Emitted when a guardian is removed\n    event GuardianRemoved(address indexed guardian);\n\n    /// @notice Emitted when Operator contract is updated\n    event OperatorUpdated(IOperator oldOperator, IOperator newOperator);\n\n    /// @notice Emitted when Lz base gas limit updated\n    event LzBaseGasLimitUpdated(uint256 oldLzBaseGasLimit, uint256 newLzBaseGasLimit);\n\n    /// @notice Emitted when flag for pause bridge transfer is toggled\n    event BridgingIsActiveUpdated(bool newIsActive);\n\n    /// @notice Emitted when flag for support chain is toggled\n    event DestinationChainIsActiveUpdated(uint16 chainId, bool newIsSupported);\n\n    constructor() {\n        _disableInitializers();\n    }\n\n    function initialize(IMasterOracle masterOracle_, address feeCollector_) external initializer {\n        if (address(masterOracle_) == address(0)) revert OracleIsNull();\n        if (feeCollector_ == address(0)) revert FeeCollectorIsNull();\n\n        __Pauseable_init();\n\n        masterOracle = masterOracle_;\n        feeCollector = feeCollector_;\n\n        nextPoolId = 1;\n    }\n\n    /**\n     * @notice Check if any pool has the token as part of its offerings\n     * @param syntheticToken_ Asset to check\n     * @return _exists Return true if exists\n     */\n    function doesSyntheticTokenExist(ISyntheticToken syntheticToken_) external view returns (bool _exists) {\n        uint256 _length = pools.length();\n        for (uint256 i; i < _length; ++i) {\n            if (IPool(pools.at(i)).doesSyntheticTokenExist(syntheticToken_)) {\n                return true;\n            }\n        }\n    }\n\n    /**\n     * @notice Get all pools\n     * @dev 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.\n     */\n    function getPools() external view override returns (address[] memory) {\n        return pools.values();\n    }\n\n    /**\n     * @notice Check if pool is registered\n     * @param pool_ Pool to check\n     * @return true if exists\n     */\n    function isPoolRegistered(address pool_) external view override returns (bool) {\n        return pools.contains(pool_);\n    }\n\n    /**\n     * @inheritdoc Pauseable\n     */\n    function isGuardian(address sender_) public view override(IPoolRegistry, Pauseable) returns (bool) {\n        return guardians.contains(sender_);\n    }\n\n    /**\n     * @notice Register pool\n     */\n    function registerPool(address pool_) external override onlyGovernor {\n        if (pool_ == address(0)) revert AddressIsNull();\n        if (!pools.add(pool_)) revert AlreadyRegistered();\n        uint256 _id = idOfPool[pool_];\n        if (_id == 0) {\n            _id = nextPoolId++;\n            idOfPool[pool_] = _id;\n        }\n        emit PoolRegistered(_id, pool_);\n    }\n\n    /**\n     * @notice Unregister pool\n     */\n    function unregisterPool(address pool_) external override onlyGovernor {\n        if (!pools.remove(pool_)) revert UnregisteredPool();\n        emit PoolUnregistered(idOfPool[pool_], pool_);\n    }\n\n    /**\n     * @notice Add guardian\n     */\n    function addGuardian(address guardian_) external onlyGovernor {\n        if (guardian_ == address(0)) revert AddressIsNull();\n        if (!guardians.add(guardian_)) revert AlreadyRegistered();\n        emit GuardianAdded(guardian_);\n    }\n\n    /**\n     * @notice Remove guardian\n     */\n    function removeGuardian(address guardian_) external onlyGovernor {\n        if (!guardians.remove(guardian_)) revert UnregisteredGuardian();\n        emit GuardianRemoved(guardian_);\n    }\n\n    /**\n     * @notice Get all guardians\n     * @dev 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.\n     */\n    function getGuardians() external view returns (address[] memory) {\n        return guardians.values();\n    }\n\n    /**\n     * @notice Update fee collector\n     */\n    function updateFeeCollector(address newFeeCollector_) external override onlyGovernor {\n        if (newFeeCollector_ == address(0)) revert FeeCollectorIsNull();\n        address _currentFeeCollector = feeCollector;\n        if (newFeeCollector_ == _currentFeeCollector) revert NewValueIsSameAsCurrent();\n        emit FeeCollectorUpdated(_currentFeeCollector, newFeeCollector_);\n        feeCollector = newFeeCollector_;\n    }\n\n    /**\n     * @notice Update master oracle contract\n     */\n    function updateMasterOracle(IMasterOracle newMasterOracle_) external onlyGovernor {\n        if (address(newMasterOracle_) == address(0)) revert OracleIsNull();\n        IMasterOracle _currentMasterOracle = masterOracle;\n        if (newMasterOracle_ == _currentMasterOracle) revert NewValueIsSameAsCurrent();\n        emit MasterOracleUpdated(_currentMasterOracle, newMasterOracle_);\n        masterOracle = newMasterOracle_;\n    }\n\n    /**\n     * @notice Update native token gateway\n     */\n    function updateNativeTokenGateway(address newGateway_) external onlyGovernor {\n        if (address(newGateway_) == address(0)) revert NativeTokenGatewayIsNull();\n        address _currentGateway = nativeTokenGateway;\n        if (newGateway_ == _currentGateway) revert NewValueIsSameAsCurrent();\n        emit NativeTokenGatewayUpdated(_currentGateway, newGateway_);\n        nativeTokenGateway = newGateway_;\n    }\n\n    /**\n     * @notice Update Swapper contract\n     */\n    function updateSwapper(ISwapper newSwapper_) external onlyGovernor {\n        if (address(newSwapper_) == address(0)) revert AddressIsNull();\n        ISwapper _currentSwapper = swapper;\n        if (newSwapper_ == _currentSwapper) revert NewValueIsSameAsCurrent();\n\n        emit SwapperUpdated(_currentSwapper, newSwapper_);\n        swapper = newSwapper_;\n    }\n\n    /**\n     * @notice Update Operator contract\n     */\n    function updateOperator(IOperator newOperator_) external onlyGovernor {\n        IOperator _currentOperator = operator;\n        if (newOperator_ == _currentOperator) revert NewValueIsSameAsCurrent();\n\n        emit OperatorUpdated(_currentOperator, newOperator_);\n        operator = newOperator_;\n    }\n\n    /**\n     * @notice Update Lz base gas limit\n     */\n    function updateLzBaseGasLimit(uint256 newLzBaseGasLimit_) external onlyGovernor {\n        uint256 _currentBaseGasLimit = lzBaseGasLimit;\n        if (newLzBaseGasLimit_ == _currentBaseGasLimit) revert NewValueIsSameAsCurrent();\n        emit LzBaseGasLimitUpdated(_currentBaseGasLimit, newLzBaseGasLimit_);\n        lzBaseGasLimit = newLzBaseGasLimit_;\n    }\n\n    /**\n     * @notice Pause/Unpause bridge transfers\n     */\n    function toggleBridgingIsActive() external onlyGovernor {\n        bool _newIsBridgingActive = !isBridgingActive;\n        emit BridgingIsActiveUpdated(_newIsBridgingActive);\n        isBridgingActive = _newIsBridgingActive;\n    }\n\n    /**\n     * @notice Allow/Disallow destination chain\n     * @dev Use LZ chain id\n     */\n    function toggleDestinationChainIsActive(uint16 chainId_) external onlyGovernor {\n        bool _isDestinationChainSupported = !isDestinationChainSupported[chainId_];\n        emit DestinationChainIsActiveUpdated(chainId_, _isDestinationChainSupported);\n        isDestinationChainSupported[chainId_] = _isDestinationChainSupported;\n    }\n}\n"},{"file_path":"contracts/storage/SyntheticTokenStorage.sol","source_code":"// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.24;\n\nimport {IPoolRegistry} from \"../interfaces/IPoolRegistry.sol\";\nimport {IProxyOFT} from \"../interfaces/IProxyOFT.sol\";\nimport {ISyntheticToken} from \"../interfaces/ISyntheticToken.sol\";\n\nabstract contract SyntheticTokenStorageV1 is ISyntheticToken {\n    /**\n     * @notice The name of the token\n     */\n    string public override name;\n\n    /**\n     * @notice The symbol of the token\n     */\n    string public override symbol;\n\n    /**\n     * @dev The amount of tokens owned by `account`\n     */\n    mapping(address => uint256) public override balanceOf;\n\n    /**\n     * @dev The remaining number of tokens that `spender` will be\n     * allowed to spend on behalf of `owner` through {transferFrom}\n     */\n    mapping(address => mapping(address => uint256)) public override allowance;\n\n    /**\n     * @dev Amount of tokens in existence\n     */\n    uint256 public override totalSupply;\n\n    /**\n     * @notice The supply cap\n     */\n    uint256 public override maxTotalSupply;\n\n    /**\n     * @dev The Pool Registry\n     */\n    IPoolRegistry internal _poolRegistry;\n\n    /**\n     * @notice If true, disables msAsset minting globally\n     */\n    bool public override isActive;\n\n    /**\n     * @notice The decimals of the token\n     */\n    uint8 public override decimals;\n\n    /**\n     * @notice The ProxyOFT contract\n     */\n    IProxyOFT public override proxyOFT;\n\n    /**\n     * @notice Track amount received cross-chain\n     */\n    uint256 public totalBridgedIn;\n\n    /**\n     * @notice Track amount sent cross-chain\n     */\n    uint256 public totalBridgedOut;\n\n    /**\n     * @notice Maximum allowed bridged-in (mint-related) supply\n     */\n    uint256 public maxBridgedInSupply;\n\n    /**\n     * @notice Maximum allowed bridged-out (burn-related) supply\n     */\n    uint256 public maxBridgedOutSupply;\n}\n\nabstract contract SyntheticTokenStorageV2 is SyntheticTokenStorageV1 {\n    /**\n     * @notice Automated Market Operator, it can be a contract, safe or EOA\n     */\n    address public amo;\n\n    /**\n     * @notice Maximum Synth AMO can mint. It can be updated by admin/governor.\n     */\n    uint256 public maxAmoSupply;\n\n    /**\n     * @notice Synth minted by AMO so far. It will be reduced when Synths are burnt by AMO.\n     */\n    uint256 public amoSupply;\n}\n"},{"file_path":"contracts/dependencies/stargate-protocol/interfaces/IStargateRouter.sol","source_code":"// SPDX-License-Identifier: BUSL-1.1\n\npragma solidity ^0.8.9;\n\ninterface IStargateRouter {\n    struct lzTxObj {\n        uint256 dstGasForCall;\n        uint256 dstNativeAmount;\n        bytes dstNativeAddr;\n    }\n\n    function addLiquidity(uint256 _poolId, uint256 _amountLD, address _to) external;\n\n    function swap(\n        uint16 _dstChainId,\n        uint256 _srcPoolId,\n        uint256 _dstPoolId,\n        address payable _refundAddress,\n        uint256 _amountLD,\n        uint256 _minAmountLD,\n        lzTxObj memory _lzTxParams,\n        bytes calldata _to,\n        bytes calldata _payload\n    ) external payable;\n\n    function redeemRemote(\n        uint16 _dstChainId,\n        uint256 _srcPoolId,\n        uint256 _dstPoolId,\n        address payable _refundAddress,\n        uint256 _amountLP,\n        uint256 _minAmountLD,\n        bytes calldata _to,\n        lzTxObj memory _lzTxParams\n    ) external payable;\n\n    function instantRedeemLocal(uint16 _srcPoolId, uint256 _amountLP, address _to) external returns (uint256);\n\n    function redeemLocal(\n        uint16 _dstChainId,\n        uint256 _srcPoolId,\n        uint256 _dstPoolId,\n        address payable _refundAddress,\n        uint256 _amountLP,\n        bytes calldata _to,\n        lzTxObj memory _lzTxParams\n    ) external payable;\n\n    function sendCredits(\n        uint16 _dstChainId,\n        uint256 _srcPoolId,\n        uint256 _dstPoolId,\n        address payable _refundAddress\n    ) external payable;\n\n    function quoteLayerZeroFee(\n        uint16 _dstChainId,\n        uint8 _functionType,\n        bytes calldata _toAddress,\n        bytes calldata _transferAndCallPayload,\n        lzTxObj memory _lzTxParams\n    ) external view returns (uint256, uint256);\n\n    function clearCachedSwap(uint16 _srcChainId, bytes calldata _srcAddress, uint256 _nonce) external;\n\n    function factory() external view returns (address);\n\n    function bridge() external view returns (address);\n\n    function cachedSwapLookup(\n        uint16 _chainId_,\n        bytes calldata _srcAddress,\n        uint256 _nonce\n    ) external view returns (address token, uint256 amountLD, address to, bytes memory payload);\n}\n"},{"file_path":"contracts/interfaces/external/IESMET.sol","source_code":"// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.24;\n\nimport {IERC20} from \"../../dependencies/openzeppelin/token/ERC20/IERC20.sol\";\n\ninterface IESMET is IERC20 {\n    struct LockPosition {\n        uint256 lockedAmount; // MET locked\n        uint256 boostedAmount; // based on the `lockPeriod`\n        uint256 unlockTime; // now + `lockPeriod`\n    }\n\n    function positions(uint256) external view returns (LockPosition memory);\n\n    function MINIMUM_LOCK_PERIOD() external view returns (uint256);\n\n    function MAXIMUM_LOCK_PERIOD() external view returns (uint256);\n\n    function balanceOf(address account_) external view returns (uint256);\n\n    function lock(uint256 amount_, uint256 lockPeriod_) external;\n\n    function lockFor(address to_, uint256 amount_, uint256 lockPeriod_) external;\n}\n"},{"file_path":"contracts/dependencies/openzeppelin/utils/introspection/IERC165.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165 {\n    /**\n     * @dev Returns true if this contract implements the interface defined by\n     * `interfaceId`. See the corresponding\n     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n     * to learn more about how these ids are created.\n     *\n     * This function call must use less than 30 000 gas.\n     */\n    function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n"},{"file_path":"contracts/storage/DepositTokenStorage.sol","source_code":"// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.24;\n\nimport {IERC20} from \"../dependencies/openzeppelin/token/ERC20/IERC20.sol\";\nimport {IDepositToken} from \"../interfaces/IDepositToken.sol\";\n\nabstract contract DepositTokenStorageV1 is IDepositToken {\n    /**\n     * @dev The amount of tokens owned by `account`\n     */\n    mapping(address => uint256) public override balanceOf;\n\n    /**\n     * @dev The remaining number of tokens that `spender` will be\n     * allowed to spend on behalf of `owner` through {transferFrom}\n     */\n    mapping(address => mapping(address => uint256)) public override allowance;\n\n    /**\n     * @notice The name of the token\n     */\n    string public override name;\n\n    /**\n     * @notice The symbol of the token\n     */\n    string public override symbol;\n\n    /**\n     * @dev Amount of tokens in existence\n     */\n    uint256 public override totalSupply;\n\n    /**\n     * @notice The supply cap (in USD)\n     */\n    uint256 public override maxTotalSupply;\n\n    /**\n     * @notice Collateral factor for the deposit token\n     * @dev Use 18 decimals (e.g. 0.66e18 = 66%)\n     */\n    uint256 public override collateralFactor;\n\n    /**\n     * @notice Deposit underlying asset (e.g. MET)\n     */\n    IERC20 public override underlying;\n\n    /**\n     * @notice If a collateral isn't active, it disables minting new tokens\n     */\n    bool public override isActive;\n\n    /**\n     * @notice The decimals of the token\n     */\n    uint8 public override decimals;\n}\n"},{"file_path":"contracts/dependencies/@layerzerolabs/solidity-examples/contracts-upgradeable/interfaces/ILayerZeroEndpointUpgradeable.sol","source_code":"// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.2;\n\nimport \"./ILayerZeroUserApplicationConfigUpgradeable.sol\";\n\ninterface ILayerZeroEndpointUpgradeable is ILayerZeroUserApplicationConfigUpgradeable {\n    // @notice send a LayerZero message to the specified address at a LayerZero endpoint.\n    // @param _dstChainId - the destination chain identifier\n    // @param _destination - the address on destination chain (in bytes). address length/format may vary by chains\n    // @param _payload - a custom bytes payload to send to the destination contract\n    // @param _refundAddress - if the source transaction is cheaper than the amount of value passed, refund the additional amount to this address\n    // @param _zroPaymentAddress - the address of the ZRO token holder who would pay for the transaction\n    // @param _adapterParams - parameters for custom functionality. e.g. receive airdropped native gas from the relayer on destination\n    function send(uint16 _dstChainId, bytes calldata _destination, bytes calldata _payload, address payable _refundAddress, address _zroPaymentAddress, bytes calldata _adapterParams) external payable;\n\n    // @notice used by the messaging library to publish verified payload\n    // @param _srcChainId - the source chain identifier\n    // @param _srcAddress - the source contract (as bytes) at the source chain\n    // @param _dstAddress - the address on destination chain\n    // @param _nonce - the unbound message ordering nonce\n    // @param _gasLimit - the gas limit for external contract execution\n    // @param _payload - verified payload to send to the destination contract\n    function receivePayload(uint16 _srcChainId, bytes calldata _srcAddress, address _dstAddress, uint64 _nonce, uint _gasLimit, bytes calldata _payload) external;\n\n    // @notice get the inboundNonce of a lzApp from a source chain which could be EVM or non-EVM chain\n    // @param _srcChainId - the source chain identifier\n    // @param _srcAddress - the source chain contract address\n    function getInboundNonce(uint16 _srcChainId, bytes calldata _srcAddress) external view returns (uint64);\n\n    // @notice get the outboundNonce from this source chain which, consequently, is always an EVM\n    // @param _srcAddress - the source chain contract address\n    function getOutboundNonce(uint16 _dstChainId, address _srcAddress) external view returns (uint64);\n\n    // @notice gets a quote in source native gas, for the amount that send() requires to pay for message delivery\n    // @param _dstChainId - the destination chain identifier\n    // @param _userApplication - the user app address on this EVM chain\n    // @param _payload - the custom message to send over LayerZero\n    // @param _payInZRO - if false, user app pays the protocol fee in native token\n    // @param _adapterParam - parameters for the adapter service, e.g. send some dust native token to dstChain\n    function estimateFees(uint16 _dstChainId, address _userApplication, bytes calldata _payload, bool _payInZRO, bytes calldata _adapterParam) external view returns (uint nativeFee, uint zroFee);\n\n    // @notice get this Endpoint's immutable source identifier\n    function getChainId() external view returns (uint16);\n\n    // @notice the interface to retry failed message on this Endpoint destination\n    // @param _srcChainId - the source chain identifier\n    // @param _srcAddress - the source chain contract address\n    // @param _payload - the payload to be retried\n    function retryPayload(uint16 _srcChainId, bytes calldata _srcAddress, bytes calldata _payload) external;\n\n    // @notice query if any STORED payload (message blocking) at the endpoint.\n    // @param _srcChainId - the source chain identifier\n    // @param _srcAddress - the source chain contract address\n    function hasStoredPayload(uint16 _srcChainId, bytes calldata _srcAddress) external view returns (bool);\n\n    // @notice query if the _libraryAddress is valid for sending msgs.\n    // @param _userApplication - the user app address on this EVM chain\n    function getSendLibraryAddress(address _userApplication) external view returns (address);\n\n    // @notice query if the _libraryAddress is valid for receiving msgs.\n    // @param _userApplication - the user app address on this EVM chain\n    function getReceiveLibraryAddress(address _userApplication) external view returns (address);\n\n    // @notice query if the non-reentrancy guard for send() is on\n    // @return true if the guard is on. false otherwise\n    function isSendingPayload() external view returns (bool);\n\n    // @notice query if the non-reentrancy guard for receive() is on\n    // @return true if the guard is on. false otherwise\n    function isReceivingPayload() external view returns (bool);\n\n    // @notice get the configuration of the LayerZero messaging library of the specified version\n    // @param _version - messaging library version\n    // @param _chainId - the chainId for the pending config change\n    // @param _userApplication - the contract address of the user application\n    // @param _configType - type of configuration. every messaging library has its own convention.\n    function getConfig(uint16 _version, uint16 _chainId, address _userApplication, uint _configType) external view returns (bytes memory);\n\n    // @notice get the send() LayerZero messaging library version\n    // @param _userApplication - the contract address of the user application\n    function getSendVersion(address _userApplication) external view returns (uint16);\n\n    // @notice get the lzReceive() LayerZero messaging library version\n    // @param _userApplication - the contract address of the user application\n    function getReceiveVersion(address _userApplication) external view returns (uint16);\n}\n"},{"file_path":"contracts/DepositToken.sol","source_code":"// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.24;\n\nimport {IERC20} from \"./dependencies/openzeppelin/token/ERC20/IERC20.sol\";\nimport {SafeERC20} from \"./dependencies/openzeppelin/token/ERC20/utils/SafeERC20.sol\";\nimport {Initializable} from \"./dependencies/openzeppelin-upgradeable/proxy/utils/Initializable.sol\";\nimport {Math} from \"./dependencies/openzeppelin/utils/math/Math.sol\";\nimport {Manageable, SenderIsNotPool} from \"./access/Manageable.sol\";\nimport {ReentrancyGuardDeprecated} from \"./utils/ReentrancyGuardDeprecated.sol\";\nimport {ReentrancyGuardTransient} from \"./utils/ReentrancyGuardTransient.sol\";\nimport {TokenHolder} from \"./utils/TokenHolder.sol\";\nimport {WadRayMath} from \"./lib/WadRayMath.sol\";\nimport {IRewardsDistributor} from \"./interfaces/IRewardsDistributor.sol\";\nimport {IPool} from \"./interfaces/IPool.sol\";\nimport {DepositTokenStorageV1} from \"./storage/DepositTokenStorage.sol\";\n\nerror CollateralIsInexistent();\nerror DepositTokenIsInactive();\nerror NotEnoughFreeBalance();\nerror UnderlyingAssetIsNull();\nerror PoolIsNull();\nerror SymbolIsNull();\nerror DecimalsIsNull();\nerror CollateralFactorTooHigh();\nerror CollateralFactorTooLow();\nerror DecreasedAllowanceBelowZero();\nerror AmountIsZero();\nerror BeneficiaryIsNull();\nerror AmountExceedsAllowance();\nerror RecipientIsNull();\nerror ApproveFromTheZeroAddress();\nerror ApproveToTheZeroAddress();\nerror BurnFromTheZeroAddress();\nerror BurnAmountExceedsBalance();\nerror MintToTheZeroAddress();\nerror SurpassMaxDepositSupply();\nerror TransferFromTheZeroAddress();\nerror TransferToTheZeroAddress();\nerror TransferAmountExceedsBalance();\nerror NewValueIsSameAsCurrent();\nerror SenderIsNotSmartFarmingManager();\nerror TreasuryCanNotDeposit();\n\n/**\n * @title Represents the users' deposits\n */\ncontract DepositToken is\n    Initializable,\n    ReentrancyGuardDeprecated,\n    ReentrancyGuardTransient,\n    TokenHolder,\n    Manageable,\n    DepositTokenStorageV1\n{\n    using SafeERC20 for IERC20;\n    using WadRayMath for uint256;\n\n    string public constant VERSION = \"1.4.1\";\n\n    // Note: Upper bound on `collateralFactor * (1 + liquidationFees)`. The `< 1e36` form only\n    // guarantees liquidation *eventually* helps; at exactly 1e36 it closes 0 wei of the health\n    // gap. This leaves a margin so every liquidation closes >= 2% of the amount repaid.\n    uint256 internal constant MAX_CF_TIMES_LIQUIDATION_FEES = 0.98e36;\n\n    /// @notice Emitted when collateral is deposited\n    event CollateralDeposited(\n        address indexed from,\n        address indexed account,\n        uint256 amount,\n        uint256 deposited,\n        uint256 fee\n    );\n\n    /// @notice Emitted when CF is updated\n    event CollateralFactorUpdated(uint256 oldCollateralFactor, uint256 newCollateralFactor);\n\n    /// @notice Emitted when collateral is withdrawn\n    event CollateralWithdrawn(\n        address indexed account,\n        address indexed to,\n        uint256 amount,\n        uint256 withdrawn,\n        uint256 fee\n    );\n\n    /// @notice Emitted when active flag is updated\n    event DepositTokenActiveUpdated(bool newActive);\n\n    /// @notice Emitted when max total supply is updated\n    event MaxTotalSupplyUpdated(uint256 oldMaxTotalSupply, uint256 newMaxTotalSupply);\n\n    /**\n     * @dev Throws if sender is SmartFarmingManager\n     */\n    modifier onlyIfSmartFarmingManager() {\n        if (_msgSender() != address(pool.smartFarmingManager())) revert SenderIsNotSmartFarmingManager();\n        _;\n    }\n\n    /**\n     * @dev Throws if sender can't seize\n     */\n    modifier onlyIfCanSeize() {\n        if (_msgSender() != address(pool)) revert SenderIsNotPool();\n        _;\n    }\n\n    /**\n     * @dev Throws if deposit token doesn't exist\n     */\n    modifier onlyIfDepositTokenExists() {\n        if (!pool.doesDepositTokenExist(this)) revert CollateralIsInexistent();\n        _;\n    }\n\n    /**\n     * @dev Throws if deposit token isn't enabled\n     */\n    modifier onlyIfDepositTokenIsActive() {\n        if (!isActive) revert DepositTokenIsInactive();\n        _;\n    }\n\n    /**\n     * @notice Update reward contracts' states\n     * @dev Should be called before balance changes (i.e. mint/burn)\n     */\n    modifier updateRewardsBeforeMintOrBurn(address account_) {\n        address[] memory _rewardsDistributors = pool.getRewardsDistributors();\n        uint256 _length = _rewardsDistributors.length;\n        for (uint256 i; i < _length; ++i) {\n            IRewardsDistributor(_rewardsDistributors[i]).updateBeforeMintOrBurn(this, account_);\n        }\n        _;\n    }\n\n    /**\n     * @notice Update reward contracts' states\n     * @dev Should be called before balance changes (i.e. transfer)\n     */\n    modifier updateRewardsBeforeTransfer(address sender_, address recipient_) {\n        address[] memory _rewardsDistributors = pool.getRewardsDistributors();\n        uint256 _length = _rewardsDistributors.length;\n        for (uint256 i; i < _length; ++i) {\n            IRewardsDistributor(_rewardsDistributors[i]).updateBeforeTransfer(this, sender_, recipient_);\n        }\n        _;\n    }\n\n    constructor() {\n        _disableInitializers();\n    }\n\n    function initialize(\n        IERC20 underlying_,\n        IPool pool_,\n        string calldata name_,\n        string calldata symbol_,\n        uint8 decimals_,\n        uint128 collateralFactor_,\n        uint256 maxTotalSupply_\n    ) external initializer {\n        if (address(underlying_) == address(0)) revert UnderlyingAssetIsNull();\n        if (address(pool_) == address(0)) revert PoolIsNull();\n        if (bytes(symbol_).length == 0) revert SymbolIsNull();\n        if (decimals_ == 0) revert DecimalsIsNull();\n        if (collateralFactor_ == 0) revert CollateralFactorTooLow();\n        if (collateralFactor_ >= 1e18) revert CollateralFactorTooHigh();\n\n        __Manageable_init(pool_);\n\n        name = name_;\n        symbol = symbol_;\n        underlying = underlying_;\n        isActive = true;\n        decimals = decimals_;\n        collateralFactor = collateralFactor_;\n        maxTotalSupply = maxTotalSupply_;\n    }\n\n    /**\n     * @notice Requires that amount is lower than the account's unlocked balance\n     */\n    function _revertIfLocked(address account_, uint256 amount_) private view {\n        if (unlockedBalanceOf(account_) < amount_) revert NotEnoughFreeBalance();\n    }\n\n    /**\n     * @notice Set `amount` as the allowance of `spender` over the caller's tokens\n     */\n    function approve(address spender_, uint256 amount_) external override returns (bool) {\n        _approve(_msgSender(), spender_, amount_);\n        return true;\n    }\n\n    /**\n     * @notice Atomically decrease the allowance granted to `spender` by the caller\n     */\n    function decreaseAllowance(address spender_, uint256 subtractedValue_) external returns (bool) {\n        address _msgSender = _msgSender();\n        uint256 _currentAllowance = allowance[_msgSender][spender_];\n        if (_currentAllowance < subtractedValue_) revert DecreasedAllowanceBelowZero();\n        unchecked {\n            _approve(_msgSender, spender_, _currentAllowance - subtractedValue_);\n        }\n        return true;\n    }\n\n    /**\n     * @notice Deposit collateral and mint msdTOKEN (tokenized deposit position)\n     * @param amount_ The amount of collateral tokens to deposit\n     * @param onBehalfOf_ The account to deposit to\n     * @return _deposited The amount deposited after fees\n     */\n    function deposit(\n        uint256 amount_,\n        address onBehalfOf_\n    ) external override whenNotPaused nonReentrant onlyIfDepositTokenExists returns (uint256 _deposited, uint256 _fee) {\n        if (amount_ == 0) revert AmountIsZero();\n        if (onBehalfOf_ == address(0)) revert BeneficiaryIsNull();\n\n        IPool _pool = pool;\n        IERC20 _underlying = underlying;\n        address _msgSender = _msgSender();\n        address _treasury = address(_pool.treasury());\n\n        if (_msgSender == _treasury) revert TreasuryCanNotDeposit();\n\n        uint256 _balanceBefore = _underlying.balanceOf(_treasury);\n        _underlying.safeTransferFrom(_msgSender, _treasury, amount_);\n        amount_ = _underlying.balanceOf(_treasury) - _balanceBefore;\n\n        (_deposited, _fee) = quoteDepositOut(amount_);\n        if (_fee > 0) {\n            _mint(_pool.feeCollector(), _fee);\n        }\n\n        _mint(onBehalfOf_, _deposited);\n\n        emit CollateralDeposited(_msgSender, onBehalfOf_, amount_, _deposited, _fee);\n    }\n\n    /**\n     * @notice Burn msdTOKEN, withdraw collateral and transfer to `_msgSender()` (i.e. SmartFarmingManager)\n     * @param account_ The account where deposit token will be burnt from\n     * @param amount_ The amount of collateral to withdraw\n     * @return _withdrawn The amount withdrawn after fees\n     */\n    function flashWithdraw(\n        address account_,\n        uint256 amount_\n    ) external override onlyIfSmartFarmingManager returns (uint256 _withdrawn, uint256 _fee) {\n        return _withdraw({account_: account_, amount_: amount_, to_: _msgSender()});\n    }\n\n    /**\n     * @notice Atomically increase the allowance granted to `spender` by the caller\n     */\n    function increaseAllowance(address spender_, uint256 addedValue_) external returns (bool) {\n        address _msgSender = _msgSender();\n        _approve(_msgSender, spender_, allowance[_msgSender][spender_] + addedValue_);\n        return true;\n    }\n\n    /**\n     * @notice Get the locked balance\n     * @param account_ The account to check\n     * @return _lockedBalance The locked amount\n     */\n    function lockedBalanceOf(address account_) external view override returns (uint256 _lockedBalance) {\n        unchecked {\n            return balanceOf[account_] - unlockedBalanceOf(account_);\n        }\n    }\n\n    /**\n     * @notice Quote gross `_amount` to deposit `amountToDeposit_` collateral\n     * @param amountToDeposit_ Collateral to deposit\n     * @return _amount Gross amount\n     * @return _fee Fee amount to collect\n     */\n    function quoteDepositIn(uint256 amountToDeposit_) external view override returns (uint256 _amount, uint256 _fee) {\n        uint256 _depositFee = pool.feeProvider().depositFee();\n        if (_depositFee == 0) {\n            return (amountToDeposit_, _fee);\n        }\n\n        _amount = amountToDeposit_.wadDiv(1e18 - _depositFee);\n        _fee = _amount - amountToDeposit_;\n    }\n\n    /**\n     * @notice Quote collateral `_amountToDeposit` by using gross `amount_`\n     * @param amount_ Gross amount\n     * @return _amountToDeposit Collateral to deposit\n     * @return _fee Fee amount to collect\n     */\n    function quoteDepositOut(uint256 amount_) public view override returns (uint256 _amountToDeposit, uint256 _fee) {\n        uint256 _depositFee = pool.feeProvider().depositFee();\n        if (_depositFee == 0) {\n            return (amount_, _fee);\n        }\n\n        _fee = amount_.wadMul(_depositFee);\n        _amountToDeposit = amount_ - _fee;\n    }\n\n    /**\n     * @notice Quote gross `_amount` to withdraw `amountToWithdraw_` collateral\n     * @param amountToWithdraw_ Collateral to withdraw\n     * @return _amount Gross amount\n     * @return _fee Fee amount to collect\n     */\n    function quoteWithdrawIn(uint256 amountToWithdraw_) external view override returns (uint256 _amount, uint256 _fee) {\n        uint256 _withdrawFee = pool.feeProvider().withdrawFee();\n        if (_withdrawFee == 0) {\n            return (amountToWithdraw_, _fee);\n        }\n\n        _amount = amountToWithdraw_.wadDiv(1e18 - _withdrawFee);\n        _fee = _amount - amountToWithdraw_;\n    }\n\n    /**\n     * @notice Quote collateral `_amountToWithdraw` by using gross `_amount`\n     * @param amount_ Gross amount\n     * @return _amountToWithdraw Collateral to withdraw\n     * @return _fee Fee amount to collect\n     */\n    function quoteWithdrawOut(uint256 amount_) public view override returns (uint256 _amountToWithdraw, uint256 _fee) {\n        uint256 _withdrawFee = pool.feeProvider().withdrawFee();\n        if (_withdrawFee == 0) {\n            return (amount_, _fee);\n        }\n\n        _fee = amount_.wadMul(_withdrawFee);\n        _amountToWithdraw = amount_ - _fee;\n    }\n\n    /**\n     * @notice Seize tokens\n     * @dev Same as _transfer\n     * @param from_ The account to seize from\n     * @param to_ The beneficiary account\n     * @param amount_ The amount to seize\n     */\n    function seize(address from_, address to_, uint256 amount_) external override onlyIfCanSeize {\n        _transfer(from_, to_, amount_);\n    }\n\n    /// @inheritdoc IERC20\n    function transfer(address to_, uint256 amount_) external override returns (bool) {\n        address _msgSender = _msgSender();\n        _revertIfLocked(_msgSender, amount_);\n\n        _transfer(_msgSender, to_, amount_);\n        return true;\n    }\n\n    /// @inheritdoc IERC20\n    function transferFrom(\n        address sender_,\n        address recipient_,\n        uint256 amount_\n    ) external override nonReentrant returns (bool) {\n        _revertIfLocked(sender_, amount_);\n\n        address _msgSender = _msgSender();\n        uint256 _currentAllowance = allowance[sender_][_msgSender];\n        if (_currentAllowance != type(uint256).max) {\n            if (_currentAllowance < amount_) revert AmountExceedsAllowance();\n            unchecked {\n                _approve(sender_, _msgSender, _currentAllowance - amount_);\n            }\n        }\n\n        _transfer(sender_, recipient_, amount_);\n\n        return true;\n    }\n\n    /**\n     * @notice Get the unlocked balance (i.e. transferable, withdrawable)\n     * @param account_ The account to check\n     * @return _unlockedBalance The amount that user can transfer or withdraw\n     */\n    function unlockedBalanceOf(address account_) public view override returns (uint256 _unlockedBalance) {\n        IPool _pool = pool;\n\n        (, , uint256 _debtInUsd, , uint256 _issuableInUsd) = _pool.debtPositionOf(account_);\n\n        if (_debtInUsd == 0) {\n            return balanceOf[account_];\n        }\n\n        if (_issuableInUsd > 0) {\n            _unlockedBalance = Math.min(\n                balanceOf[account_],\n                _pool.masterOracle().quoteUsdToToken(address(underlying), _issuableInUsd.wadDiv(collateralFactor))\n            );\n        }\n    }\n\n    /**\n     * @notice Burn msdTOKEN and withdraw collateral\n     * @param amount_ The amount of collateral to withdraw\n     * @param to_ The account that will receive withdrawn collateral\n     * @return _withdrawn The amount withdrawn after fees\n     */\n    function withdraw(uint256 amount_, address to_) external override returns (uint256 _withdrawn, uint256 _fee) {\n        if (to_ == address(0)) revert RecipientIsNull();\n        address _msgSender = _msgSender();\n        _revertIfLocked(_msgSender, amount_);\n\n        return _withdraw({account_: _msgSender, amount_: amount_, to_: to_});\n    }\n\n    /**\n     * @notice Burn msdTOKEN and withdraw collateral from a given account\n     * @param from_ The account to withdraw from\n     * @param amount_ The amount of collateral to withdraw\n     * @return _withdrawn The amount withdrawn after fees\n     */\n    function withdrawFrom(\n        address from_,\n        uint256 amount_\n    ) external override onlyIfSmartFarmingManager returns (uint256 _withdrawn, uint256 _fee) {\n        _revertIfLocked(from_, amount_);\n\n        return _withdraw({account_: from_, amount_: amount_, to_: _msgSender()});\n    }\n\n    /**\n     * @notice Set `amount` as the allowance of `spender` over the caller's tokens\n     */\n    function _approve(address owner_, address spender_, uint256 amount_) private {\n        if (owner_ == address(0)) revert ApproveFromTheZeroAddress();\n        if (spender_ == address(0)) revert ApproveToTheZeroAddress();\n\n        allowance[owner_][spender_] = amount_;\n        emit Approval(owner_, spender_, amount_);\n    }\n\n    /**\n     * @notice Destroy `amount` tokens from `account`, reducing the\n     * total supply\n     */\n    function _burn(address _account, uint256 _amount) private updateRewardsBeforeMintOrBurn(_account) {\n        if (_account == address(0)) revert BurnFromTheZeroAddress();\n\n        uint256 _balanceBefore = balanceOf[_account];\n        if (_balanceBefore < _amount) revert BurnAmountExceedsBalance();\n        uint256 _balanceAfter;\n        unchecked {\n            _balanceAfter = _balanceBefore - _amount;\n            totalSupply -= _amount;\n        }\n\n        balanceOf[_account] = _balanceAfter;\n\n        emit Transfer(_account, address(0), _amount);\n\n        // Remove this token from the deposit tokens list if the sender's balance goes to zero\n        if (_amount > 0 && _balanceAfter == 0) {\n            pool.removeFromDepositTokensOfAccount(_account);\n        }\n    }\n\n    /**\n     * @notice Create `amount` tokens and assigns them to `account`, increasing\n     * the total supply\n     */\n    function _mint(\n        address account_,\n        uint256 amount_\n    ) private onlyIfDepositTokenIsActive updateRewardsBeforeMintOrBurn(account_) {\n        if (account_ == address(0)) revert MintToTheZeroAddress();\n\n        totalSupply += amount_;\n        if (totalSupply > maxTotalSupply) revert SurpassMaxDepositSupply();\n\n        uint256 _balanceBefore = balanceOf[account_];\n        unchecked {\n            balanceOf[account_] = _balanceBefore + amount_;\n        }\n\n        emit Transfer(address(0), account_, amount_);\n\n        // Add this token to the deposit tokens list if the recipient is receiving it for the 1st time\n        if (_balanceBefore == 0 && amount_ > 0) {\n            pool.addToDepositTokensOfAccount(account_);\n        }\n    }\n\n    /// @inheritdoc TokenHolder\n    // solhint-disable-next-line no-empty-blocks\n    function _requireCanSweep() internal view override onlyGovernor {}\n\n    /**\n     * @notice Move `amount` of tokens from `sender` to `recipient`\n     */\n    function _transfer(\n        address sender_,\n        address recipient_,\n        uint256 amount_\n    ) private updateRewardsBeforeTransfer(sender_, recipient_) {\n        if (sender_ == address(0)) revert TransferFromTheZeroAddress();\n        if (recipient_ == address(0)) revert TransferToTheZeroAddress();\n\n        uint256 _senderBalanceBefore = balanceOf[sender_];\n        if (_senderBalanceBefore < amount_) revert TransferAmountExceedsBalance();\n        uint256 _recipientBalanceBefore = balanceOf[recipient_];\n\n        unchecked {\n            balanceOf[sender_] = _senderBalanceBefore - amount_;\n            balanceOf[recipient_] += amount_;\n        }\n\n        emit Transfer(sender_, recipient_, amount_);\n\n        // Add this token to the deposit tokens list if the recipient is receiving it for the 1st time\n        if (_recipientBalanceBefore == 0 && amount_ > 0) {\n            pool.addToDepositTokensOfAccount(recipient_);\n        }\n\n        // Remove this token from the deposit tokens list if the sender's balance goes to zero\n        if (amount_ > 0 && balanceOf[sender_] == 0) {\n            pool.removeFromDepositTokensOfAccount(sender_);\n        }\n    }\n\n    /**\n     * @notice Burn msdTOKEN, withdraw collateral and transfer to `_msgSender()` (i.e. Pool)\n     * @dev This function doesn't check if the amount is unlocked!\n     * @param account_ The account where deposit token will be burnt from\n     * @param amount_ The amount of collateral to withdraw\n     * @param to_ The account that will receive withdrawn collateral\n     * @return _withdrawn The amount withdrawn after fees\n     */\n    function _withdraw(\n        address account_,\n        uint256 amount_,\n        address to_\n    ) private whenNotShutdown nonReentrant onlyIfDepositTokenExists returns (uint256 _withdrawn, uint256 _fee) {\n        if (amount_ == 0) revert AmountIsZero();\n\n        IPool _pool = pool;\n\n        (_withdrawn, _fee) = quoteWithdrawOut(amount_);\n        if (_fee > 0) {\n            _transfer(account_, _pool.feeCollector(), _fee);\n        }\n\n        _burn(account_, _withdrawn);\n        _pool.treasury().pull(to_, _withdrawn);\n\n        emit CollateralWithdrawn(account_, to_, amount_, _withdrawn, _fee);\n    }\n\n    /**\n     * @notice Enable/Disable the Deposit Token\n     */\n    function toggleIsActive() external override onlyGovernor {\n        bool _newIsActive = !isActive;\n        emit DepositTokenActiveUpdated(_newIsActive);\n        isActive = _newIsActive;\n    }\n\n    /**\n     * @notice Update collateral factor\n     * @param newCollateralFactor_ The new CF value\n     */\n    function updateCollateralFactor(uint128 newCollateralFactor_) external override onlyGovernor {\n        if (newCollateralFactor_ == 0) revert CollateralFactorTooLow();\n        if (newCollateralFactor_ >= 1e18) revert CollateralFactorTooHigh();\n        // Note: The `CF * (1 + liquidationFees) < 1` invariant must hold, with a margin (see the constant)\n        (uint256 _liquidatorIncentive, uint256 _protocolFee) = pool.feeProvider().liquidationFees();\n        if (newCollateralFactor_ * (1e18 + _liquidatorIncentive + _protocolFee) >= MAX_CF_TIMES_LIQUIDATION_FEES) {\n            revert CollateralFactorTooHigh();\n        }\n        uint256 _currentCollateralFactor = collateralFactor;\n        if (newCollateralFactor_ == _currentCollateralFactor) revert NewValueIsSameAsCurrent();\n        emit CollateralFactorUpdated(_currentCollateralFactor, newCollateralFactor_);\n        collateralFactor = newCollateralFactor_;\n    }\n\n    /**\n     * @notice Update max total supply\n     * @param newMaxTotalSupply_ The new max total supply\n     */\n    function updateMaxTotalSupply(uint256 newMaxTotalSupply_) external override onlyGovernor {\n        uint256 _currentMaxTotalSupply = maxTotalSupply;\n        if (newMaxTotalSupply_ == _currentMaxTotalSupply) revert NewValueIsSameAsCurrent();\n        emit MaxTotalSupplyUpdated(_currentMaxTotalSupply, newMaxTotalSupply_);\n        maxTotalSupply = newMaxTotalSupply_;\n    }\n}\n"},{"file_path":"contracts/dependencies/openzeppelin/token/ERC20/extensions/IERC20Metadata.sol","source_code":"// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\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":"contracts/dependencies/openzeppelin/utils/cryptography/MerkleProof.sol","source_code":"// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @dev These functions deal with verification of Merkle Trees proofs.\n *\n * The proofs can be generated using the JavaScript library\n * https://github.com/miguelmota/merkletreejs[merkletreejs].\n * Note: the hashing algorithm should be keccak256 and pair sorting should be enabled.\n *\n * See `test/utils/cryptography/MerkleProof.test.js` for some examples.\n */\nlibrary MerkleProof {\n    /**\n     * @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree\n     * defined by `root`. For this, a `proof` must be provided, containing\n     * sibling hashes on the branch from the leaf to the root of the tree. Each\n     * pair of leaves and each pair of pre-images are assumed to be sorted.\n     */\n    function verify(bytes32[] memory proof, bytes32 root, bytes32 leaf) internal pure returns (bool) {\n        bytes32 computedHash = leaf;\n\n        for (uint256 i = 0; i < proof.length; i++) {\n            bytes32 proofElement = proof[i];\n\n            if (computedHash <= proofElement) {\n                // Hash(current computed hash + current element of the proof)\n                computedHash = keccak256(abi.encodePacked(computedHash, proofElement));\n            } else {\n                // Hash(current element of the proof + current computed hash)\n                computedHash = keccak256(abi.encodePacked(proofElement, computedHash));\n            }\n        }\n\n        // Check if the computed hash (root) is equal to the provided root\n        return computedHash == root;\n    }\n}\n"},{"file_path":"contracts/dependencies/@layerzerolabs/solidity-examples/token/oft/IOFT.sol","source_code":"// SPDX-License-Identifier: MIT\n\npragma solidity >=0.5.0;\n\nimport \"./IOFTCore.sol\";\nimport \"../../../../openzeppelin/token/ERC20/IERC20.sol\";\n\n/**\n * @dev Interface of the OFT standard\n */\ninterface IOFT is IOFTCore, IERC20 {\n\n}\n"},{"file_path":"contracts/storage/PoolStorage.sol","source_code":"// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.24;\n\nimport {IERC20} from \"../dependencies/openzeppelin/token/ERC20/IERC20.sol\";\nimport {EnumerableSet} from \"../dependencies/openzeppelin/utils/structs/EnumerableSet.sol\";\nimport {MappedEnumerableSet} from \"../lib/MappedEnumerableSet.sol\";\nimport {ISwapper} from \"../interfaces/external/ISwapper.sol\";\nimport {IPool} from \"../interfaces/IPool.sol\";\nimport {ISmartFarmingManager} from \"../interfaces/ISmartFarmingManager.sol\";\nimport {IPoolRegistry} from \"../interfaces/IPoolRegistry.sol\";\nimport {ITreasury} from \"../interfaces/ITreasury.sol\";\nimport {IDepositToken} from \"../interfaces/IDepositToken.sol\";\nimport {IRewardsDistributor} from \"../interfaces/IRewardsDistributor.sol\";\nimport {ISyntheticToken} from \"../interfaces/ISyntheticToken.sol\";\nimport {IDebtToken} from \"../interfaces/IDebtToken.sol\";\nimport {IFeeProvider} from \"../interfaces/IFeeProvider.sol\";\n\n// solhint-disable var-name-mixedcase, max-states-count\nabstract contract PoolStorageV1 is IPool {\n    /**\n     * @notice The debt floor (in USD) for each synthetic token\n     * This parameters is used to keep incentive for liquidators (i.e. cover gas and provide enough profit)\n     */\n    uint256 public override debtFloorInUsd;\n\n    uint256 private depositFee__DEPRECATED;\n\n    uint256 private issueFee__DEPRECATED;\n\n    uint256 private withdrawFee__DEPRECATED;\n\n    uint256 private repayFee__DEPRECATED;\n\n    uint256 private swapFee__DEPRECATED;\n\n    uint256 private liquidationFees__DEPRECATED;\n\n    /**\n     * @notice The max percent of the debt allowed to liquidate\n     * @dev Use 18 decimals (e.g. 1e16 = 1%)\n     */\n    uint256 public override maxLiquidable;\n\n    /**\n     * @notice PoolRegistry\n     */\n    IPoolRegistry internal _poolRegistry;\n\n    /**\n     * @notice Swap feature on/off flag\n     */\n    bool public override isSwapActive;\n\n    /**\n     * @notice Treasury contract\n     */\n    ITreasury public override treasury;\n\n    /**\n     * @notice Represents collateral's deposits\n     */\n    EnumerableSet.AddressSet internal depositTokens;\n\n    /**\n     * @notice Get the deposit token's address from given underlying asset\n     */\n    mapping(IERC20 => IDepositToken) public override depositTokenOf;\n\n    /**\n     * @notice Available debt tokens\n     */\n    EnumerableSet.AddressSet internal debtTokens;\n\n    /**\n     * @notice Per-account deposit tokens (i.e. tokens that user has balance > 0)\n     */\n    MappedEnumerableSet.AddressSet internal depositTokensOfAccount;\n\n    /**\n     * @notice Per-account debt tokens (i.e. tokens that user has balance > 0)\n     */\n    MappedEnumerableSet.AddressSet internal debtTokensOfAccount;\n\n    /**\n     * @notice RewardsDistributor contracts\n     */\n    IRewardsDistributor[] internal rewardsDistributors__DEPRECATED;\n\n    /**\n     * @notice Get the debt token's address from given synthetic asset\n     */\n    mapping(ISyntheticToken => IDebtToken) public override debtTokenOf;\n}\n\nabstract contract PoolStorageV2 is PoolStorageV1 {\n    ISwapper private swapper__DEPRECATED;\n\n    /**\n     * @notice FeeProvider contract\n     */\n    IFeeProvider public override feeProvider;\n\n    /**\n     * @notice RewardsDistributor contracts\n     */\n    EnumerableSet.AddressSet internal rewardsDistributors;\n}\n\nabstract contract PoolStorageV3 is PoolStorageV2 {\n    /**\n     * @notice SmartFarmingManager contract\n     */\n    ISmartFarmingManager public smartFarmingManager;\n}\n\nabstract contract PoolStorageV4 is PoolStorageV3 {\n    /**\n     * @notice Flag that pause/unpause pool's cross-chain activities\n     */\n    bool private isBridgingActive_DEPRECATED;\n}\n"},{"file_path":"contracts/mock/PoolMock.sol","source_code":"// SPDX-License-Identifier: MIT\n\n// solhint-disable no-unused-vars\n// solhint-disable avoid-low-level-calls\n// solhint-disable use-forbidden-name\n// solhint-disable no-empty-blocks\n\npragma solidity 0.8.24;\n\nimport {IERC20} from \"../dependencies/openzeppelin/token/ERC20/IERC20.sol\";\nimport {WadRayMath} from \"../lib/WadRayMath.sol\";\nimport {Pauseable} from \"../utils/Pauseable.sol\";\nimport {IPool} from \"../interfaces/IPool.sol\";\nimport {ITreasury} from \"../interfaces/ITreasury.sol\";\nimport {ISyntheticToken} from \"../interfaces/ISyntheticToken.sol\";\nimport {IDebtToken} from \"../interfaces/IDebtToken.sol\";\nimport {IDepositToken} from \"../interfaces/IDepositToken.sol\";\nimport {IPoolRegistry} from \"../interfaces/IPoolRegistry.sol\";\nimport {ISmartFarmingManager} from \"../interfaces/ISmartFarmingManager.sol\";\nimport {IMasterOracle} from \"../interfaces/external/IMasterOracle.sol\";\nimport {IFeeProvider} from \"../interfaces/IFeeProvider.sol\";\nimport {Governable} from \"../access/Governable.sol\";\n\ncontract PoolMock is IPool, Governable, Pauseable {\n    using WadRayMath for uint256;\n\n    ITreasury public treasury;\n    ISyntheticToken public syntheticToken;\n    IDebtToken public debtToken;\n    IDepositToken public depositToken;\n    IMasterOracle public masterOracle;\n    IPoolRegistry public poolRegistry;\n    IFeeProvider public feeProvider;\n    ISmartFarmingManager public smartFarmingManager;\n    uint256 public debtFloorInUsd;\n    uint256 public maxLiquidable;\n    bool public isSwapActive;\n\n    constructor(\n        IDepositToken _depositToken,\n        IMasterOracle _masterOracle,\n        ISyntheticToken _syntheticToken,\n        IDebtToken _debtToken,\n        IPoolRegistry _poolRegistry,\n        IFeeProvider _feeProvider\n    ) {\n        depositToken = _depositToken;\n        masterOracle = _masterOracle;\n        syntheticToken = _syntheticToken;\n        debtToken = _debtToken;\n        poolRegistry = _poolRegistry;\n        feeProvider = _feeProvider;\n    }\n\n    function feeCollector() external view returns (address) {\n        return poolRegistry.feeCollector();\n    }\n\n    function getDepositTokens() external pure override returns (address[] memory) {\n        revert(\"mock-does-not-implement\");\n    }\n\n    function getDebtTokens() external pure override returns (address[] memory) {\n        revert(\"mock-does-not-implement\");\n    }\n\n    function debtOf(address _account) public view override returns (uint256 _debtInUsd) {\n        if (address(syntheticToken) != address(0)) {\n            uint256 _debtBalance = debtToken.balanceOf(_account);\n            return masterOracle.quoteTokenToUsd(address(syntheticToken), _debtBalance);\n        }\n    }\n\n    function depositOf(address) external pure override returns (uint256, uint256) {\n        revert(\"mock-does-not-implement\");\n    }\n\n    function debtPositionOf(\n        address _account\n    )\n        public\n        view\n        override\n        returns (\n            bool _isHealthy,\n            uint256 _depositInUsd,\n            uint256 _debtInUsd,\n            uint256 _issuableLimitInUsd,\n            uint256 _issuableInUsd\n        )\n    {\n        _isHealthy = true;\n        uint256 _deposit = depositToken.balanceOf(_account);\n        _depositInUsd = masterOracle.quoteTokenToUsd(address(depositToken.underlying()), _deposit);\n        _debtInUsd = debtOf(_account);\n        _issuableLimitInUsd = _depositInUsd.wadMul(depositToken.collateralFactor());\n        _issuableInUsd = _debtInUsd < _issuableLimitInUsd ? _issuableLimitInUsd - _debtInUsd : 0;\n    }\n\n    function liquidate(\n        ISyntheticToken,\n        address,\n        uint256,\n        IDepositToken\n    ) external pure override returns (uint256, uint256, uint256) {\n        revert(\"mock-does-not-implement\");\n    }\n\n    function quoteLiquidateIn(\n        ISyntheticToken,\n        uint256,\n        IDepositToken\n    ) external pure returns (uint256, uint256, uint256) {\n        revert(\"mock-does-not-implement\");\n    }\n\n    function quoteLiquidateMax(ISyntheticToken, address, IDepositToken) external pure returns (uint256) {\n        revert(\"mock-does-not-implement\");\n    }\n\n    function quoteLiquidateOut(\n        ISyntheticToken,\n        uint256,\n        IDepositToken\n    ) external pure returns (uint256, uint256, uint256) {\n        revert(\"mock-does-not-implement\");\n    }\n\n    function quoteSwapIn(ISyntheticToken, ISyntheticToken, uint256) external pure override returns (uint256, uint256) {\n        revert(\"mock-does-not-implement\");\n    }\n\n    function quoteSwapOut(ISyntheticToken, ISyntheticToken, uint256) public pure override returns (uint256, uint256) {\n        revert(\"mock-does-not-implement\");\n    }\n\n    function swap(ISyntheticToken, ISyntheticToken, uint256) external pure override returns (uint256, uint256) {\n        revert(\"mock-does-not-implement\");\n    }\n\n    function updateDebtFloor(uint256 _newDebtFloorInUsd) external {\n        debtFloorInUsd = _newDebtFloorInUsd;\n    }\n\n    function doesSyntheticTokenExist(ISyntheticToken _syntheticToken) external view override returns (bool) {\n        return address(_syntheticToken) == address(syntheticToken);\n    }\n\n    function doesDebtTokenExist(IDebtToken) external pure returns (bool) {\n        return true;\n    }\n\n    function doesDepositTokenExist(IDepositToken) external pure override returns (bool) {\n        return true;\n    }\n\n    function updateTreasury(ITreasury _treasury) external {\n        treasury = _treasury;\n    }\n\n    function debtTokenOf(ISyntheticToken) external view override returns (IDebtToken) {\n        return debtToken;\n    }\n\n    function depositTokenOf(IERC20) external view override returns (IDepositToken) {\n        return depositToken;\n    }\n\n    function addToDepositTokensOfAccount(address) external pure override {}\n\n    function removeFromDepositTokensOfAccount(address) external pure override {}\n\n    function addToDebtTokensOfAccount(address) external pure override {}\n\n    function removeFromDebtTokensOfAccount(address) external pure override {}\n\n    function getDepositTokensOfAccount(address) external pure override returns (address[] memory) {\n        revert(\"mock-does-not-implement\");\n    }\n\n    function getDebtTokensOfAccount(address) external pure override returns (address[] memory) {\n        revert(\"mock-does-not-implement\");\n    }\n\n    function getRewardsDistributors() external pure override returns (address[] memory _rewardsDistributors) {}\n\n    function isGuardian(address /*sender_*/) public view override returns (bool) {\n        revert(\"mock-does-not-implement\");\n    }\n\n    function isBridgingActive() external view returns (bool) {\n        revert(\"mock-does-not-implement\");\n    }\n}\n"},{"file_path":"contracts/lib/MappedEnumerableSet.sol","source_code":"// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.24;\n\n/**\n * @dev EnumerableSet fork to support `address => address[]` mapping\n * @dev Forked from OZ 4.3.2\n */\nlibrary MappedEnumerableSet {\n    struct Set {\n        // Storage of set values\n        address[] _values;\n        // Position of the value in the `values` array, plus 1 because index 0\n        // means a value is not in the set.\n        mapping(address => uint256) _indexes;\n    }\n\n    struct AddressSet {\n        mapping(address => Set) _ofAddress;\n    }\n\n    function _add(AddressSet storage set, address _key, address value) private returns (bool) {\n        if (!_contains(set, _key, value)) {\n            set._ofAddress[_key]._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._ofAddress[_key]._indexes[value] = set._ofAddress[_key]._values.length;\n            return true;\n        } else {\n            return false;\n        }\n    }\n\n    function _remove(AddressSet storage set, address _key, address value) private returns (bool) {\n        // We read and store the value's index to prevent multiple reads from the same storage slot\n        uint256 valueIndex = set._ofAddress[_key]._indexes[value];\n\n        if (valueIndex != 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 toDeleteIndex = valueIndex - 1;\n            uint256 lastIndex = set._ofAddress[_key]._values.length - 1;\n\n            if (lastIndex != toDeleteIndex) {\n                address lastvalue = set._ofAddress[_key]._values[lastIndex];\n\n                // Move the last value to the index where the value to delete is\n                set._ofAddress[_key]._values[toDeleteIndex] = lastvalue;\n                // Update the index for the moved value\n                set._ofAddress[_key]._indexes[lastvalue] = valueIndex; // Replace lastvalue's index to valueIndex\n            }\n\n            // Delete the slot where the moved value was stored\n            set._ofAddress[_key]._values.pop();\n\n            // Delete the index for the deleted slot\n            delete set._ofAddress[_key]._indexes[value];\n\n            return true;\n        } else {\n            return false;\n        }\n    }\n\n    function _contains(AddressSet storage set, address _key, address value) private view returns (bool) {\n        return set._ofAddress[_key]._indexes[value] != 0;\n    }\n\n    function _length(AddressSet storage set, address _key) private view returns (uint256) {\n        return set._ofAddress[_key]._values.length;\n    }\n\n    function _at(AddressSet storage set, address _key, uint256 index) private view returns (address) {\n        return set._ofAddress[_key]._values[index];\n    }\n\n    function _values(AddressSet storage set, address _key) private view returns (address[] memory) {\n        return set._ofAddress[_key]._values;\n    }\n\n    function add(AddressSet storage set, address key, address value) internal returns (bool) {\n        return _add(set, key, value);\n    }\n\n    function remove(AddressSet storage set, address key, address value) internal returns (bool) {\n        return _remove(set, key, value);\n    }\n\n    function contains(AddressSet storage set, address key, address value) internal view returns (bool) {\n        return _contains(set, key, value);\n    }\n\n    function length(AddressSet storage set, address key) internal view returns (uint256) {\n        return _length(set, key);\n    }\n\n    function at(AddressSet storage set, address key, uint256 index) internal view returns (address) {\n        return _at(set, key, index);\n    }\n\n    function values(AddressSet storage set, address key) internal view returns (address[] memory) {\n        address[] memory store = _values(set, key);\n        address[] memory result;\n\n        assembly {\n            result := store\n        }\n\n        return result;\n    }\n}\n"},{"file_path":"contracts/dependencies/openzeppelin-upgradeable/utils/introspection/ERC165Upgradeable.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n *     return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n *\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\n */\nabstract contract ERC165Upgradeable is Initializable, IERC165Upgradeable {\n    function __ERC165_init() internal onlyInitializing {\n    }\n\n    function __ERC165_init_unchained() internal onlyInitializing {\n    }\n    /**\n     * @dev See {IERC165-supportsInterface}.\n     */\n    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n        return interfaceId == type(IERC165Upgradeable).interfaceId;\n    }\n\n    /**\n     * @dev This empty reserved space is put in place to allow future versions to add new\n     * variables without shifting down storage in the inheritance chain.\n     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n     */\n    uint256[50] private __gap;\n}\n"},{"file_path":"contracts/dependencies/stargate-protocol/interfaces/IStargateComposer.sol","source_code":"// SPDX-License-Identifier: BUSL-1.1\n\npragma solidity ^0.8.9;\n\nimport \"./IStargateRouter.sol\";\n\ninterface IStargateComposer {\n    function swap(\n        uint16 _dstChainId,\n        uint256 _srcPoolId,\n        uint256 _dstPoolId,\n        address payable _refundAddress,\n        uint256 _amountLD,\n        uint256 _minAmountLD,\n        IStargateRouter.lzTxObj memory _lzTxParams,\n        bytes calldata _to,\n        bytes calldata _payload\n    ) external payable;\n\n    function factory() external view returns (address);\n\n    function stargateBridge() external view returns (address);\n\n    function stargateRouter() external view returns (IStargateRouter);\n\n    function quoteLayerZeroFee(\n        uint16 _dstChainId,\n        uint8 _functionType,\n        bytes calldata _toAddress,\n        bytes calldata _transferAndCallPayload,\n        IStargateRouter.lzTxObj memory _lzTxParams\n    ) external view returns (uint256, uint256);\n\n    function peers(uint16 _chainId) external view returns (address);\n\n    function payloadHashes(\n        uint16 _srcChainId,\n        bytes calldata _srcAddress,\n        uint256 _nonce\n    ) external view returns (bytes32);\n\n    function clearCachedSwap(\n        uint16 _srcChainId,\n        bytes calldata _srcAddress,\n        uint64 _nonce,\n        address _receiver,\n        bytes calldata _sgReceiveCallData\n    ) external;\n}\n"},{"file_path":"contracts/DebtToken.sol","source_code":"// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.24;\n\nimport {Initializable} from \"./dependencies/openzeppelin-upgradeable/proxy/utils/Initializable.sol\";\nimport {IERC20} from \"./dependencies/openzeppelin/token/ERC20/IERC20.sol\";\nimport {Manageable} from \"./access/Manageable.sol\";\nimport {ReentrancyGuardDeprecated} from \"./utils/ReentrancyGuardDeprecated.sol\";\nimport {ReentrancyGuardTransient} from \"./utils/ReentrancyGuardTransient.sol\";\nimport {TokenHolder} from \"./utils/TokenHolder.sol\";\nimport {WadRayMath} from \"./lib/WadRayMath.sol\";\nimport {IMasterOracle} from \"./interfaces/external/IMasterOracle.sol\";\nimport {IPool} from \"./interfaces/IPool.sol\";\nimport {ISyntheticToken} from \"./interfaces/ISyntheticToken.sol\";\nimport {IRewardsDistributor} from \"./interfaces/IRewardsDistributor.sol\";\nimport {DebtTokenStorageV2} from \"./storage/DebtTokenStorage.sol\";\n\nerror SyntheticDoesNotExist();\nerror SyntheticIsInactive();\nerror DebtTokenInactive();\nerror NameIsNull();\nerror SymbolIsNull();\nerror PoolIsNull();\nerror SyntheticIsNull();\nerror AllowanceNotSupported();\nerror ApprovalNotSupported();\nerror AmountIsZero();\nerror NotEnoughCollateral();\nerror DebtLowerThanTheFloor();\nerror RemainingDebtIsLowerThanTheFloor();\nerror TransferNotSupported();\nerror BurnFromNullAddress();\nerror BurnAmountExceedsBalance();\nerror MintToNullAddress();\nerror SurpassMaxDebtSupply();\nerror NewValueIsSameAsCurrent();\nerror SenderIsNotSmartFarmingManager();\n\n/**\n * @title Non-transferable token that represents users' debts\n */\ncontract DebtToken is\n    Initializable,\n    ReentrancyGuardDeprecated,\n    ReentrancyGuardTransient,\n    TokenHolder,\n    Manageable,\n    DebtTokenStorageV2\n{\n    using WadRayMath for uint256;\n\n    string public constant VERSION = \"1.4.1\";\n\n    uint256 public constant SECONDS_PER_YEAR = 365.25 days;\n    uint256 private constant HUNDRED_PERCENT = 1e18;\n\n    /// @notice Emitted when synthetic's debt is repaid\n    event DebtRepaid(address indexed payer, address indexed account, uint256 amount, uint256 repaid, uint256 fee);\n\n    /// @notice Emitted when active flag is updated\n    event DebtTokenActiveUpdated(bool newActive);\n\n    /// @notice Emitted when interest rate is updated\n    event InterestRateUpdated(uint256 oldInterestRate, uint256 newInterestRate);\n\n    /// @notice Emitted when max total supply is updated\n    event MaxTotalSupplyUpdated(uint256 oldMaxTotalSupply, uint256 newMaxTotalSupply);\n\n    /// @notice Emitted when synthetic token is issued\n    event SyntheticTokenIssued(\n        address indexed account,\n        address indexed to,\n        uint256 amount,\n        uint256 issued,\n        uint256 fee\n    );\n\n    /**\n     * @dev Throws if sender is not SmartFarmingManager\n     */\n    modifier onlyIfSmartFarmingManager() {\n        if (_msgSender() != address(pool.smartFarmingManager())) revert SenderIsNotSmartFarmingManager();\n        _;\n    }\n\n    /**\n     * @dev Throws if synthetic token doesn't exist\n     */\n    modifier onlyIfSyntheticTokenExists() {\n        if (!pool.doesSyntheticTokenExist(syntheticToken)) revert SyntheticDoesNotExist();\n        _;\n    }\n\n    /**\n     * @dev Throws if debt token isn't enabled\n     */\n    modifier onlyIfDebtTokenIsActive() {\n        if (!isActive) revert DebtTokenInactive();\n        _;\n    }\n\n    /**\n     * @dev Throws if synthetic token isn't enabled\n     */\n    modifier onlyIfSyntheticTokenIsActive() {\n        if (!syntheticToken.isActive()) revert SyntheticIsInactive();\n        _;\n    }\n\n    /**\n     * @notice Update reward contracts' states\n     * @dev Should be called before balance changes (i.e. mint/burn)\n     */\n    modifier updateRewardsBeforeMintOrBurn(address account_) {\n        address[] memory _rewardsDistributors = pool.getRewardsDistributors();\n        uint256 _length = _rewardsDistributors.length;\n        for (uint256 i; i < _length; ++i) {\n            IRewardsDistributor(_rewardsDistributors[i]).updateBeforeMintOrBurn(this, account_);\n        }\n        _;\n    }\n\n    constructor() {\n        _disableInitializers();\n    }\n\n    function initialize(\n        string calldata name_,\n        string calldata symbol_,\n        IPool pool_,\n        ISyntheticToken syntheticToken_,\n        uint256 interestRate_,\n        uint256 maxTotalSupply_\n    ) external initializer {\n        if (bytes(name_).length == 0) revert NameIsNull();\n        if (bytes(symbol_).length == 0) revert SymbolIsNull();\n        if (address(pool_) == address(0)) revert PoolIsNull();\n        if (address(syntheticToken_) == address(0)) revert SyntheticIsNull();\n\n        __Manageable_init(pool_);\n\n        name = name_;\n        symbol = symbol_;\n        decimals = syntheticToken_.decimals();\n        syntheticToken = syntheticToken_;\n        lastTimestampAccrued = block.timestamp;\n        debtIndex = 1e18;\n        interestRate = interestRate_;\n        maxTotalSupply = maxTotalSupply_;\n        isActive = true;\n    }\n\n    /**\n     * @notice Accrue interest over debt supply\n     */\n    function accrueInterest() public override {\n        (\n            uint256 _interestAmountAccrued,\n            uint256 _debtIndex,\n            uint256 _lastTimestampAccrued\n        ) = _calculateInterestAccrual();\n\n        if (block.timestamp == _lastTimestampAccrued) {\n            return;\n        }\n\n        lastTimestampAccrued = block.timestamp;\n\n        if (_interestAmountAccrued > 0) {\n            totalSupply_ += _interestAmountAccrued;\n            debtIndex = _debtIndex;\n\n            // Note: Address states where minting will fail (e.g. the token is inactive, it reached max supply, etc)\n            try syntheticToken.mint(pool.feeCollector(), _interestAmountAccrued + pendingInterestFee) {\n                pendingInterestFee = 0;\n            } catch {\n                pendingInterestFee += _interestAmountAccrued;\n            }\n        }\n    }\n\n    /// @inheritdoc IERC20\n    function allowance(address /*owner_*/, address /*spender_*/) external pure override returns (uint256) {\n        revert AllowanceNotSupported();\n    }\n\n    /// @inheritdoc IERC20\n    // solhint-disable-next-line\n    function approve(address /*spender_*/, uint256 /*amount_*/) external override returns (bool) {\n        revert ApprovalNotSupported();\n    }\n\n    /**\n     * @notice Get the updated (principal + interest) user's debt\n     */\n    function balanceOf(address account_) public view override returns (uint256) {\n        uint256 _principal = principalOf[account_];\n        if (_principal == 0) {\n            return 0;\n        }\n\n        (, uint256 _debtIndex, ) = _calculateInterestAccrual();\n\n        // Note: The `debtIndex / debtIndexOf` gives the interest to apply to the principal amount\n        return (_principal * _debtIndex) / debtIndexOf[account_];\n    }\n\n    /**\n     * @notice Burn debt token\n     * @param from_ The account to burn from\n     * @param amount_ The amount to burn\n     */\n    function burnFor(address from_, uint256 amount_) external override onlyPool {\n        _burn(from_, amount_);\n    }\n\n    /**\n     * @notice Collect pending interest fee if any\n     */\n    function collectPendingInterestFee() external {\n        uint256 _pendingInterestFee = pendingInterestFee;\n        if (_pendingInterestFee > 0) {\n            syntheticToken.mint(pool.feeCollector(), _pendingInterestFee);\n            pendingInterestFee = 0;\n        }\n    }\n\n    /**\n     * @notice Lock collateral and mint synthetic token\n     * @param amount_ The amount to mint\n     * @param to_ The beneficiary account\n     * @return _issued The amount issued after fees\n     * @return _fee The fee amount collected\n     */\n    function issue(\n        uint256 amount_,\n        address to_\n    )\n        external\n        override\n        whenNotShutdown\n        nonReentrant\n        onlyIfSyntheticTokenExists\n        returns (uint256 _issued, uint256 _fee)\n    {\n        if (amount_ == 0) revert AmountIsZero();\n\n        accrueInterest();\n\n        address _msgSender = _msgSender();\n        IPool _pool = pool;\n        ISyntheticToken _syntheticToken = syntheticToken;\n\n        (, , , , uint256 _issuableInUsd) = _pool.debtPositionOf(_msgSender);\n\n        IMasterOracle _masterOracle = _pool.masterOracle();\n\n        if (amount_ > _masterOracle.quoteUsdToToken(address(_syntheticToken), _issuableInUsd)) {\n            revert NotEnoughCollateral();\n        }\n\n        _mint(_pool, _masterOracle, _msgSender, amount_);\n\n        (_issued, _fee) = quoteIssueOut(amount_);\n        if (_fee > 0) {\n            _syntheticToken.mint(_pool.feeCollector(), _fee);\n        }\n        _syntheticToken.mint(to_, _issued);\n\n        emit SyntheticTokenIssued(_msgSender, to_, amount_, _issued, _fee);\n    }\n\n    /**\n     * @notice Issue synth without checking collateral and without minting debt tokens\n     * @dev The healthy of outcome position must be done afterhand\n     * @param to_ The beneficiary account\n     * @param amount_ The amount to mint\n     * @return _issued The amount issued after fees\n     * @return _fee The fee amount collected\n     */\n    function flashIssue(\n        address to_,\n        uint256 amount_\n    )\n        external\n        override\n        onlyIfSmartFarmingManager\n        whenNotShutdown\n        nonReentrant\n        onlyIfSyntheticTokenExists\n        onlyIfDebtTokenIsActive\n        returns (uint256 _issued, uint256 _fee)\n    {\n        if (amount_ == 0) revert AmountIsZero();\n\n        accrueInterest();\n\n        ISyntheticToken _syntheticToken = syntheticToken;\n\n        (_issued, _fee) = quoteIssueOut(amount_);\n        if (_fee > 0) {\n            _syntheticToken.mint(pool.feeCollector(), _fee);\n        }\n        _syntheticToken.mint(to_, _issued);\n    }\n\n    /**\n     * @notice Get updated pending interest fee\n     */\n    function getPendingInterestFee() external view returns (uint256 _stored, uint256 _current) {\n        (uint256 _interestAmountAccrued, , ) = _calculateInterestAccrual();\n        uint256 _pendingInterestFee = pendingInterestFee;\n        return (_pendingInterestFee, _pendingInterestFee + _interestAmountAccrued);\n    }\n\n    /**\n     * @notice Return interest rate (in percent) per second\n     */\n    function interestRatePerSecond() public view override returns (uint256) {\n        return interestRate / SECONDS_PER_YEAR;\n    }\n\n    /**\n     * @notice onlySmartFarmingManager:: Mint `amount_` of debtToken at `to_`.\n     * @param to_ Receiver address\n     * @param amount_ Token amount to mint\n     */\n    function mint(\n        address to_,\n        uint256 amount_\n    )\n        external\n        override\n        onlyIfSmartFarmingManager\n        whenNotShutdown\n        nonReentrant\n        onlyIfSyntheticTokenExists\n        onlyIfSyntheticTokenIsActive\n    {\n        accrueInterest();\n\n        IPool _pool = pool;\n\n        _mint(_pool, _pool.masterOracle(), to_, amount_);\n    }\n\n    /**\n     * @notice Quote gross `_amount` to issue `amountToIssue_` synthetic tokens\n     * @param amountToIssue_ Synth to issue\n     * @return _amount Gross amount\n     * @return _fee The fee amount to collect\n     */\n    function quoteIssueIn(uint256 amountToIssue_) external view override returns (uint256 _amount, uint256 _fee) {\n        uint256 _issueFee = pool.feeProvider().issueFee();\n        if (_issueFee == 0) {\n            return (amountToIssue_, _fee);\n        }\n\n        _amount = amountToIssue_.wadDiv(HUNDRED_PERCENT - _issueFee);\n        _fee = _amount - amountToIssue_;\n    }\n\n    /**\n     * @notice Quote synthetic tokens `_amountToIssue` by using gross `_amount`\n     * @param amount_ Gross amount\n     * @return _amountToIssue Synth to issue\n     * @return _fee The fee amount to collect\n     */\n    function quoteIssueOut(uint256 amount_) public view override returns (uint256 _amountToIssue, uint256 _fee) {\n        uint256 _issueFee = pool.feeProvider().issueFee();\n        if (_issueFee == 0) {\n            return (amount_, _fee);\n        }\n\n        _fee = amount_.wadMul(_issueFee);\n        _amountToIssue = amount_ - _fee;\n    }\n\n    /**\n     * @notice Quote synthetic token `_amount` need to repay `amountToRepay_` debt\n     * @param amountToRepay_ Debt amount to repay\n     * @return _amount Gross amount\n     * @return _fee The fee amount to collect\n     */\n    function quoteRepayIn(uint256 amountToRepay_) public view override returns (uint256 _amount, uint256 _fee) {\n        uint256 _repayFee = pool.feeProvider().repayFee();\n        if (_repayFee == 0) {\n            return (amountToRepay_, _fee);\n        }\n\n        _fee = amountToRepay_.wadMul(_repayFee);\n        _amount = amountToRepay_ + _fee;\n    }\n\n    /**\n     * @notice Quote debt `_amountToRepay` by burning `_amount` synthetic tokens\n     * @param amount_ Gross amount\n     * @return _amountToRepay Debt amount to repay\n     * @return _fee The fee amount to collect\n     */\n    function quoteRepayOut(uint256 amount_) public view override returns (uint256 _amountToRepay, uint256 _fee) {\n        uint256 _repayFee = pool.feeProvider().repayFee();\n        if (_repayFee == 0) {\n            return (amount_, _fee);\n        }\n\n        _amountToRepay = amount_.wadDiv(HUNDRED_PERCENT + _repayFee);\n        _fee = amount_ - _amountToRepay;\n    }\n\n    /**\n     * @notice Send synthetic token to decrease debt\n     * @dev The _msgSender() is the payer and the account beneficed\n     * @param onBehalfOf_ The account that will have debt decreased\n     * @param amount_ The amount of synthetic token to burn (this is the gross amount, the repay fee will be subtracted from it)\n     * @return _repaid The amount repaid after fees\n     */\n    function repay(\n        address onBehalfOf_,\n        uint256 amount_\n    )\n        external\n        override\n        whenNotShutdown\n        nonReentrant\n        onlyIfSyntheticTokenExists\n        returns (uint256 _repaid, uint256 _fee)\n    {\n        if (amount_ == 0) revert AmountIsZero();\n\n        accrueInterest();\n\n        address _msgSender = _msgSender();\n        IPool _pool = pool;\n        ISyntheticToken _syntheticToken = syntheticToken;\n\n        (_repaid, _fee) = quoteRepayOut(amount_);\n        if (_fee > 0) {\n            _syntheticToken.seize(_msgSender, _pool.feeCollector(), _fee);\n        }\n\n        uint256 _debtFloorInUsd = _pool.debtFloorInUsd();\n        if (_debtFloorInUsd > 0) {\n            uint256 _newDebtInUsd = _pool.masterOracle().quoteTokenToUsd(\n                address(_syntheticToken),\n                balanceOf(onBehalfOf_) - _repaid\n            );\n            if (_newDebtInUsd > 0 && _newDebtInUsd < _debtFloorInUsd) {\n                revert RemainingDebtIsLowerThanTheFloor();\n            }\n        }\n\n        _syntheticToken.burnFor(_msgSender, _repaid);\n        _burn(onBehalfOf_, _repaid);\n\n        emit DebtRepaid(_msgSender, onBehalfOf_, amount_, _repaid, _fee);\n    }\n\n    /**\n     * @notice Send synthetic token to decrease debt\n     * @dev This function helps users to no leave debt dust behind\n     * @param onBehalfOf_ The account that will have debt decreased\n     * @return _repaid The amount repaid after fees\n     * @return _fee The fee amount collected\n     */\n    function repayAll(\n        address onBehalfOf_\n    )\n        external\n        override\n        whenNotShutdown\n        nonReentrant\n        onlyIfSyntheticTokenExists\n        returns (uint256 _repaid, uint256 _fee)\n    {\n        accrueInterest();\n\n        _repaid = balanceOf(onBehalfOf_);\n        if (_repaid == 0) revert AmountIsZero();\n\n        address _msgSender = _msgSender();\n        ISyntheticToken _syntheticToken = syntheticToken;\n\n        uint256 _amount;\n        (_amount, _fee) = quoteRepayIn(_repaid);\n\n        if (_fee > 0) {\n            _syntheticToken.seize(_msgSender, pool.feeCollector(), _fee);\n        }\n\n        _syntheticToken.burnFor(_msgSender, _repaid);\n        _burn(onBehalfOf_, _repaid);\n\n        emit DebtRepaid(_msgSender, onBehalfOf_, _amount, _repaid, _fee);\n    }\n\n    /**\n     * @notice Return the total supply\n     */\n    function totalSupply() external view override returns (uint256) {\n        (uint256 _interestAmountAccrued, , ) = _calculateInterestAccrual();\n        return totalSupply_ + _interestAmountAccrued;\n    }\n\n    /// @inheritdoc IERC20\n    // solhint-disable-next-line\n    function transfer(address /*recipient_*/, uint256 /*amount_*/) external override returns (bool) {\n        revert TransferNotSupported();\n    }\n\n    /// @inheritdoc IERC20\n    // solhint-disable-next-line\n    function transferFrom(\n        address /*sender_*/,\n        address /*recipient_*/,\n        uint256 /*amount_*/\n    ) external override returns (bool) {\n        revert TransferNotSupported();\n    }\n\n    /**\n     * @notice Destroy `amount` tokens from `account`, reducing the\n     * total supply\n     */\n    function _burn(address account_, uint256 amount_) private updateRewardsBeforeMintOrBurn(account_) {\n        if (account_ == address(0)) revert BurnFromNullAddress();\n\n        uint256 _accountBalance = balanceOf(account_);\n        if (_accountBalance < amount_) revert BurnAmountExceedsBalance();\n\n        uint256 _totalSupply = totalSupply_;\n        unchecked {\n            principalOf[account_] = _accountBalance - amount_;\n            debtIndexOf[account_] = debtIndex;\n            totalSupply_ = amount_ < _totalSupply ? _totalSupply - amount_ : 0;\n        }\n\n        emit Transfer(account_, address(0), amount_);\n\n        // Remove this token from the debt tokens list if the sender's balance goes to zero\n        if (amount_ > 0 && balanceOf(account_) == 0) {\n            pool.removeFromDebtTokensOfAccount(account_);\n        }\n    }\n\n    /**\n     * @notice Calculate interest to accrue\n     * @dev This util function avoids code duplication across `balanceOf` and `accrueInterest`\n     * @return _interestAmountAccrued The total amount of debt tokens accrued\n     * @return _debtIndex The new `debtIndex` value\n     */\n    function _calculateInterestAccrual()\n        private\n        view\n        returns (uint256 _interestAmountAccrued, uint256 _debtIndex, uint256 _lastTimestampAccrued)\n    {\n        _lastTimestampAccrued = lastTimestampAccrued;\n        _debtIndex = debtIndex;\n\n        if (block.timestamp > _lastTimestampAccrued) {\n            uint256 _interestRateToAccrue = interestRatePerSecond() * (block.timestamp - _lastTimestampAccrued);\n            if (_interestRateToAccrue > 0) {\n                _interestAmountAccrued = _interestRateToAccrue.wadMul(totalSupply_);\n                _debtIndex += _interestRateToAccrue.wadMul(_debtIndex);\n            }\n        }\n    }\n\n    /**\n     * @dev Create `amount` tokens and assigns them to `account`, increasing\n     * the total supply\n     */\n    function _mint(\n        IPool pool_,\n        IMasterOracle masterOracle_,\n        address account_,\n        uint256 amount_\n    ) private onlyIfDebtTokenIsActive updateRewardsBeforeMintOrBurn(account_) {\n        if (account_ == address(0)) revert MintToNullAddress();\n\n        uint256 _debtFloorInUsd = pool_.debtFloorInUsd();\n        uint256 _balanceBefore = balanceOf(account_);\n\n        if (\n            _debtFloorInUsd > 0 &&\n            masterOracle_.quoteTokenToUsd(address(syntheticToken), _balanceBefore + amount_) < _debtFloorInUsd\n        ) {\n            revert DebtLowerThanTheFloor();\n        }\n\n        totalSupply_ += amount_;\n        if (totalSupply_ > maxTotalSupply) revert SurpassMaxDebtSupply();\n\n        principalOf[account_] = _balanceBefore + amount_;\n        debtIndexOf[account_] = debtIndex;\n        emit Transfer(address(0), account_, amount_);\n\n        //  Add this token to the debt tokens list if the recipient is receiving it for the 1st time\n        if (_balanceBefore == 0 && amount_ > 0) {\n            pool.addToDebtTokensOfAccount(account_);\n        }\n    }\n\n    /// @inheritdoc TokenHolder\n    // solhint-disable-next-line no-empty-blocks\n    function _requireCanSweep() internal view override onlyGovernor {}\n\n    /**\n     * @notice Update max total supply\n     */\n    function updateMaxTotalSupply(uint256 newMaxTotalSupply_) external override onlyGovernor {\n        uint256 _currentMaxTotalSupply = maxTotalSupply;\n        if (newMaxTotalSupply_ == _currentMaxTotalSupply) revert NewValueIsSameAsCurrent();\n        emit MaxTotalSupplyUpdated(_currentMaxTotalSupply, newMaxTotalSupply_);\n        maxTotalSupply = newMaxTotalSupply_;\n    }\n\n    /**\n     * @notice Update interest rate (APR)\n     */\n    function updateInterestRate(uint256 newInterestRate_) external override onlyGovernor {\n        accrueInterest();\n        uint256 _currentInterestRate = interestRate;\n        if (newInterestRate_ == _currentInterestRate) revert NewValueIsSameAsCurrent();\n        emit InterestRateUpdated(_currentInterestRate, newInterestRate_);\n        interestRate = newInterestRate_;\n    }\n\n    /**\n     * @notice Enable/Disable the Debt Token\n     */\n    function toggleIsActive() external override onlyGovernor {\n        bool _newIsActive = !isActive;\n        emit DebtTokenActiveUpdated(_newIsActive);\n        isActive = _newIsActive;\n    }\n}\n"},{"file_path":"contracts/dependencies/@layerzerolabs/solidity-examples/contracts-upgradeable/token/oft/composable/IOFTReceiverUpgradeable.sol","source_code":"// SPDX-License-Identifier: MIT\n\npragma solidity >=0.5.0;\n\ninterface IOFTReceiverUpgradeable {\n    /**\n     * @dev Called by the OFT contract when tokens are received from source chain.\n     * @param _srcChainId The chain id of the source chain.\n     * @param _srcAddress The address of the OFT token contract on the source chain.\n     * @param _nonce The nonce of the transaction on the source chain.\n     * @param _from The address of the account who calls the sendAndCall() on the source chain.\n     * @param _amount The amount of tokens to transfer.\n     * @param _payload Additional data with no specified format.\n     */\n    function onOFTReceived(\n        uint16 _srcChainId,\n        bytes calldata _srcAddress,\n        uint64 _nonce,\n        bytes calldata _from,\n        uint _amount,\n        bytes calldata _payload\n    ) external;\n}\n"},{"file_path":"contracts/dependencies/@layerzerolabs/solidity-examples/util/ExcessivelySafeCall.sol","source_code":"// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.7.6;\n\nlibrary ExcessivelySafeCall {\n    uint256 constant LOW_28_MASK = 0x00000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff;\n\n    /// @notice Use when you _really_ really _really_ don't trust the called\n    /// contract. This prevents the called contract from causing reversion of\n    /// the caller in as many ways as we can.\n    /// @dev The main difference between this and a solidity low-level call is\n    /// that we limit the number of bytes that the callee can cause to be\n    /// copied to caller memory. This prevents stupid things like malicious\n    /// contracts returning 10,000,000 bytes causing a local OOG when copying\n    /// to memory.\n    /// @param _target The address to call\n    /// @param _gas The amount of gas to forward to the remote contract\n    /// @param _maxCopy The maximum number of bytes of returndata to copy\n    /// to memory.\n    /// @param _calldata The data to send to the remote contract\n    /// @return success and returndata, as `.call()`. Returndata is capped to\n    /// `_maxCopy` bytes.\n    function excessivelySafeCall(\n        address _target,\n        uint256 _gas,\n        uint16 _maxCopy,\n        bytes memory _calldata\n    ) internal returns (bool, bytes memory) {\n        // set up for assembly call\n        uint256 _toCopy;\n        bool _success;\n        bytes memory _returnData = new bytes(_maxCopy);\n        // dispatch message to recipient\n        // by assembly calling \"handle\" function\n        // we call via assembly to avoid memcopying a very large returndata\n        // returned by a malicious contract\n        assembly {\n            _success := call(\n                _gas, // gas\n                _target, // recipient\n                0, // ether value\n                add(_calldata, 0x20), // inloc\n                mload(_calldata), // inlen\n                0, // outloc\n                0 // outlen\n            )\n            // limit our copy to 256 bytes\n            _toCopy := returndatasize()\n            if gt(_toCopy, _maxCopy) {\n                _toCopy := _maxCopy\n            }\n            // Store the length of the copied bytes\n            mstore(_returnData, _toCopy)\n            // copy the bytes from returndata[0:_toCopy]\n            returndatacopy(add(_returnData, 0x20), 0, _toCopy)\n        }\n        return (_success, _returnData);\n    }\n\n    /// @notice Use when you _really_ really _really_ don't trust the called\n    /// contract. This prevents the called contract from causing reversion of\n    /// the caller in as many ways as we can.\n    /// @dev The main difference between this and a solidity low-level call is\n    /// that we limit the number of bytes that the callee can cause to be\n    /// copied to caller memory. This prevents stupid things like malicious\n    /// contracts returning 10,000,000 bytes causing a local OOG when copying\n    /// to memory.\n    /// @param _target The address to call\n    /// @param _gas The amount of gas to forward to the remote contract\n    /// @param _maxCopy The maximum number of bytes of returndata to copy\n    /// to memory.\n    /// @param _calldata The data to send to the remote contract\n    /// @return success and returndata, as `.call()`. Returndata is capped to\n    /// `_maxCopy` bytes.\n    function excessivelySafeStaticCall(\n        address _target,\n        uint256 _gas,\n        uint16 _maxCopy,\n        bytes memory _calldata\n    ) internal view returns (bool, bytes memory) {\n        // set up for assembly call\n        uint256 _toCopy;\n        bool _success;\n        bytes memory _returnData = new bytes(_maxCopy);\n        // dispatch message to recipient\n        // by assembly calling \"handle\" function\n        // we call via assembly to avoid memcopying a very large returndata\n        // returned by a malicious contract\n        assembly {\n            _success := staticcall(\n                _gas, // gas\n                _target, // recipient\n                add(_calldata, 0x20), // inloc\n                mload(_calldata), // inlen\n                0, // outloc\n                0 // outlen\n            )\n            // limit our copy to 256 bytes\n            _toCopy := returndatasize()\n            if gt(_toCopy, _maxCopy) {\n                _toCopy := _maxCopy\n            }\n            // Store the length of the copied bytes\n            mstore(_returnData, _toCopy)\n            // copy the bytes from returndata[0:_toCopy]\n            returndatacopy(add(_returnData, 0x20), 0, _toCopy)\n        }\n        return (_success, _returnData);\n    }\n\n    /**\n     * @notice Swaps function selectors in encoded contract calls\n     * @dev Allows reuse of encoded calldata for functions with identical\n     * argument types but different names. It simply swaps out the first 4 bytes\n     * for the new selector. This function modifies memory in place, and should\n     * only be used with caution.\n     * @param _newSelector The new 4-byte selector\n     * @param _buf The encoded contract args\n     */\n    function swapSelector(bytes4 _newSelector, bytes memory _buf) internal pure {\n        require(_buf.length >= 4);\n        uint256 _mask = LOW_28_MASK;\n        assembly {\n            // load the first word of\n            let _word := mload(add(_buf, 0x20))\n            // mask out the top 4 bytes\n            // /x\n            _word := and(_word, _mask)\n            _word := or(_newSelector, _word)\n            mstore(add(_buf, 0x20), _word)\n        }\n    }\n}\n"},{"file_path":"contracts/interfaces/IDebtToken.sol","source_code":"// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.24;\n\nimport {IERC20Metadata} from \"../dependencies/openzeppelin/token/ERC20/extensions/IERC20Metadata.sol\";\nimport {ISyntheticToken} from \"./ISyntheticToken.sol\";\n\ninterface IDebtToken is IERC20Metadata {\n    function lastTimestampAccrued() external view returns (uint256);\n\n    function isActive() external view returns (bool);\n\n    function syntheticToken() external view returns (ISyntheticToken);\n\n    function accrueInterest() external;\n\n    function debtIndex() external returns (uint256 debtIndex_);\n\n    function burnFor(address from_, uint256 amount_) external;\n\n    function issue(uint256 amount_, address to_) external returns (uint256 _issued, uint256 _fee);\n\n    function flashIssue(address to_, uint256 amount_) external returns (uint256 _issued, uint256 _fee);\n\n    function mint(address to_, uint256 amount_) external;\n\n    function repay(address onBehalfOf_, uint256 amount_) external returns (uint256 _repaid, uint256 _fee);\n\n    function repayAll(address onBehalfOf_) external returns (uint256 _repaid, uint256 _fee);\n\n    function quoteIssueIn(uint256 amountToIssue_) external view returns (uint256 _amount, uint256 _fee);\n\n    function quoteIssueOut(uint256 amount_) external view returns (uint256 _amountToIssue, uint256 _fee);\n\n    function quoteRepayIn(uint256 amountToRepay_) external view returns (uint256 _amount, uint256 _fee);\n\n    function quoteRepayOut(uint256 amount_) external view returns (uint256 _amountToRepay, uint256 _fee);\n\n    function updateMaxTotalSupply(uint256 newMaxTotalSupply_) external;\n\n    function updateInterestRate(uint256 newInterestRate_) external;\n\n    function maxTotalSupply() external view returns (uint256);\n\n    function interestRate() external view returns (uint256);\n\n    function interestRatePerSecond() external view returns (uint256);\n\n    function toggleIsActive() external;\n}\n"},{"file_path":"contracts/dependencies/openzeppelin/proxy/utils/Initializable.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../../utils/Address.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n *     function initialize() initializer public {\n *         __ERC20_init(\"MyToken\", \"MTK\");\n *     }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n *     function initializeV2() reinitializer(2) public {\n *         __ERC20Permit_init(\"MyToken\");\n *     }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n *     _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n    /**\n     * @dev Indicates that the contract has been initialized.\n     * @custom:oz-retyped-from bool\n     */\n    uint8 private _initialized;\n\n    /**\n     * @dev Indicates that the contract is in the process of being initialized.\n     */\n    bool private _initializing;\n\n    /**\n     * @dev Triggered when the contract has been initialized or reinitialized.\n     */\n    event Initialized(uint8 version);\n\n    /**\n     * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n     * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n     */\n    modifier initializer() {\n        bool isTopLevelCall = _setInitializedVersion(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     * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n     * initialization step. This is essential to configure modules that are added through upgrades and that require\n     * initialization.\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    modifier reinitializer(uint8 version) {\n        bool isTopLevelCall = _setInitializedVersion(version);\n        if (isTopLevelCall) {\n            _initializing = true;\n        }\n        _;\n        if (isTopLevelCall) {\n            _initializing = false;\n            emit Initialized(version);\n        }\n    }\n\n    /**\n     * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n     * {initializer} and {reinitializer} modifiers, directly or indirectly.\n     */\n    modifier onlyInitializing() {\n        require(_initializing, \"Initializable: contract is not initializing\");\n        _;\n    }\n\n    /**\n     * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n     * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n     * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n     * through proxies.\n     */\n    function _disableInitializers() internal virtual {\n        _setInitializedVersion(type(uint8).max);\n    }\n\n    function _setInitializedVersion(uint8 version) private returns (bool) {\n        // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n        // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n        // of initializers, because in other contexts the contract may have been reentered.\n        if (_initializing) {\n            require(\n                version == 1 && !Address.isContract(address(this)),\n                \"Initializable: contract is already initialized\"\n            );\n            return false;\n        } else {\n            require(_initialized < version, \"Initializable: contract is already initialized\");\n            _initialized = version;\n            return true;\n        }\n    }\n}\n"},{"file_path":"contracts/interfaces/INativeTokenGateway.sol","source_code":"// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.24;\n\nimport {IPool} from \"./IPool.sol\";\n\ninterface INativeTokenGateway {\n    function deposit(IPool pool_) external payable;\n\n    function withdraw(IPool pool_, uint256 amount_) external;\n}\n"},{"file_path":"contracts/interfaces/IOperator.sol","source_code":"// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.24;\n\ninterface IOperator {\n    struct Call {\n        address target;\n        uint256 value;\n        bytes callData;\n    }\n\n    function getActualMsgSender() external view returns (address);\n\n    function execute(Call[] calldata calls_) external payable returns (bytes[] memory _returnData);\n}\n"},{"file_path":"contracts/dependencies/@layerzerolabs/solidity-examples/contracts-upgradeable/token/oft/IOFTCoreUpgradeable.sol","source_code":"// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.2;\n\nimport \"../../../../../openzeppelin-upgradeable/utils/introspection/IERC165Upgradeable.sol\";\n\n/**\n * @dev Interface of the IOFT core standard\n */\ninterface IOFTCoreUpgradeable is IERC165Upgradeable {\n    /**\n     * @dev estimate send token `_tokenId` to (`_dstChainId`, `_toAddress`)\n     * _dstChainId - L0 defined chain id to send tokens too\n     * _toAddress - dynamic bytes array which contains the address to whom you are sending tokens to on the dstChain\n     * _amount - amount of the tokens to transfer\n     * _useZro - indicates to use zro to pay L0 fees\n     * _adapterParam - flexible bytes array to indicate messaging adapter services in L0\n     */\n    function estimateSendFee(\n        uint16 _dstChainId,\n        bytes calldata _toAddress,\n        uint _amount,\n        bool _useZro,\n        bytes calldata _adapterParams\n    ) external view returns (uint nativeFee, uint zroFee);\n\n    /**\n     * @dev send `_amount` amount of token to (`_dstChainId`, `_toAddress`) from `_from`\n     * `_from` the owner of token\n     * `_dstChainId` the destination chain identifier\n     * `_toAddress` can be any size depending on the `dstChainId`.\n     * `_amount` the quantity of tokens in wei\n     * `_refundAddress` the address LayerZero refunds if too much message fee is sent\n     * `_zroPaymentAddress` set to address(0x0) if not paying in ZRO (LayerZero Token)\n     * `_adapterParams` is a flexible bytes array to indicate messaging adapter services\n     */\n    function sendFrom(\n        address _from,\n        uint16 _dstChainId,\n        bytes calldata _toAddress,\n        uint _amount,\n        address payable _refundAddress,\n        address _zroPaymentAddress,\n        bytes calldata _adapterParams\n    ) external payable;\n\n    /**\n     * @dev returns the circulating amount of tokens on current chain\n     */\n    function circulatingSupply() external view returns (uint);\n\n    /**\n     * @dev returns the address of the ERC20 token\n     */\n    function token() external view returns (address);\n\n    /**\n     * @dev Emitted when `_amount` tokens are moved from the `_sender` to (`_dstChainId`, `_toAddress`)\n     * `_nonce` is the outbound nonce\n     */\n    event SendToChain(uint16 indexed _dstChainId, address indexed _from, bytes _toAddress, uint _amount);\n\n    /**\n     * @dev Emitted when `_amount` tokens are received from `_srcChainId` into the `_toAddress` on the local chain.\n     * `_nonce` is the inbound nonce.\n     */\n    event ReceiveFromChain(uint16 indexed _srcChainId, address indexed _to, uint _amount);\n\n    event SetUseCustomAdapterParams(bool _useCustomAdapterParams);\n}\n"},{"file_path":"contracts/dependencies/openzeppelin/access/Ownable.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n    address private _owner;\n\n    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n    /**\n     * @dev Initializes the contract setting the deployer as the initial owner.\n     */\n    constructor() {\n        _transferOwnership(_msgSender());\n    }\n\n    /**\n     * @dev Returns the address of the current owner.\n     */\n    function owner() public view virtual returns (address) {\n        return _owner;\n    }\n\n    /**\n     * @dev Throws if called by any account other than the owner.\n     */\n    modifier onlyOwner() {\n        require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n        _;\n    }\n\n    /**\n     * @dev Leaves the contract without owner. It will not be possible to call\n     * `onlyOwner` functions anymore. Can only be called by the current owner.\n     *\n     * NOTE: Renouncing ownership will leave the contract without an owner,\n     * thereby removing any functionality that is only available to the owner.\n     */\n    function renounceOwnership() public virtual onlyOwner {\n        _transferOwnership(address(0));\n    }\n\n    /**\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\n     * Can only be called by the current owner.\n     */\n    function transferOwnership(address newOwner) public virtual onlyOwner {\n        require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n        _transferOwnership(newOwner);\n    }\n\n    /**\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\n     * Internal function without access restriction.\n     */\n    function _transferOwnership(address newOwner) internal virtual {\n        address oldOwner = _owner;\n        _owner = newOwner;\n        emit OwnershipTransferred(oldOwner, newOwner);\n    }\n}\n"},{"file_path":"contracts/dependencies/@layerzerolabs/solidity-examples/token/oft/composable/ComposableProxyOFT.sol","source_code":"// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"./ComposableOFTCore.sol\";\nimport \"../../../../../openzeppelin/token/ERC20/utils/SafeERC20.sol\";\n\ncontract ComposableProxyOFT is ComposableOFTCore {\n    using SafeERC20 for IERC20;\n\n    IERC20 internal immutable innerToken;\n\n    constructor(address _lzEndpoint, address _proxyToken) ComposableOFTCore(_lzEndpoint) {\n        innerToken = IERC20(_proxyToken);\n    }\n\n    function circulatingSupply() public view virtual override returns (uint) {\n        unchecked {\n            return innerToken.totalSupply() - innerToken.balanceOf(address(this));\n        }\n    }\n\n    function token() public view virtual override returns (address) {\n        return address(innerToken);\n    }\n\n    function _debitFrom(address _from, uint16, bytes memory, uint _amount) internal virtual override returns (uint) {\n        require(_from == _msgSender(), \"ComposableProxyOFT: owner is not send caller\");\n        uint before = innerToken.balanceOf(address(this));\n        innerToken.safeTransferFrom(_from, address(this), _amount);\n        return innerToken.balanceOf(address(this)) - before;\n    }\n\n    function _creditTo(uint16, address _toAddress, uint _amount) internal virtual override returns (uint) {\n        uint before = innerToken.balanceOf(_toAddress);\n        innerToken.safeTransfer(_toAddress, _amount);\n        return innerToken.balanceOf(_toAddress) - before;\n    }\n}\n"},{"file_path":"contracts/Treasury.sol","source_code":"// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.24;\n\nimport {Initializable} from \"./dependencies/openzeppelin-upgradeable/proxy/utils/Initializable.sol\";\nimport {IERC20} from \"./dependencies/openzeppelin/token/ERC20/IERC20.sol\";\nimport {ReentrancyGuardDeprecated} from \"./utils/ReentrancyGuardDeprecated.sol\";\nimport {ReentrancyGuardTransient} from \"./utils/ReentrancyGuardTransient.sol\";\nimport {SafeERC20} from \"./dependencies/openzeppelin/token/ERC20/utils/SafeERC20.sol\";\nimport {Manageable} from \"./access/Manageable.sol\";\nimport {IVPool} from \"./interfaces/external/IVPool.sol\";\nimport {IPoolRewards} from \"./interfaces/external/IPoolRewards.sol\";\nimport {IDepositToken} from \"./interfaces/IDepositToken.sol\";\nimport {IPool} from \"./interfaces/IPool.sol\";\nimport {TreasuryStorageV1} from \"./storage/TreasuryStorage.sol\";\n\nerror SenderIsNotDepositToken();\nerror AddressIsNull();\nerror RecipientIsNull();\nerror AmountIsZero();\n\n/**\n * @title Treasury contract\n */\ncontract Treasury is Initializable, ReentrancyGuardDeprecated, ReentrancyGuardTransient, Manageable, TreasuryStorageV1 {\n    using SafeERC20 for IERC20;\n    using SafeERC20 for IDepositToken;\n\n    string public constant VERSION = \"1.4.1\";\n\n    constructor() {\n        _disableInitializers();\n    }\n\n    function initialize(IPool pool_) external initializer {\n        __Manageable_init(pool_);\n    }\n\n    /**\n     * @notice Transfer all funds to another contract\n     * @dev This function can become too expensive depending on the length of the arrays\n     * @param newTreasury_ The new treasury\n     */\n    function migrateTo(address newTreasury_) external override onlyPool {\n        if (newTreasury_ == address(0)) revert AddressIsNull();\n\n        address[] memory _depositTokens = pool.getDepositTokens();\n        uint256 _len = _depositTokens.length;\n\n        for (uint256 i; i < _len; ++i) {\n            IERC20 _underlying = IDepositToken(_depositTokens[i]).underlying();\n\n            uint256 _underlyingBalance = _underlying.balanceOf(address(this));\n\n            if (_underlyingBalance > 0) {\n                _underlying.safeTransfer(newTreasury_, _underlyingBalance);\n            }\n        }\n    }\n\n    /**\n     * @notice Pull token from the Treasury\n     * @param to_ The transfer recipient\n     * @param amount_ The transfer amount\n     */\n    function pull(address to_, uint256 amount_) external override nonReentrant {\n        address _msgSender = _msgSender();\n        if (!pool.doesDepositTokenExist(IDepositToken(_msgSender))) revert SenderIsNotDepositToken();\n        if (to_ == address(0)) revert RecipientIsNull();\n        if (amount_ == 0) revert AmountIsZero();\n        IDepositToken(_msgSender).underlying().safeTransfer(to_, amount_);\n    }\n\n    /**\n     * @notice Claim and withdraw rewards from Vesper\n     * @param vPool_ The Vesper pool to collect rewards from\n     * @param to_ The transfer recipient\n     */\n    function claimFromVesper(IVPool vPool_, address to_) external onlyGovernor {\n        IPoolRewards _rewards = IPoolRewards(vPool_.poolRewards());\n        _rewards.updateReward(address(this));\n        _rewards.claimReward(address(this));\n\n        IPool _pool = pool;\n        address[] memory _rewardTokens = _rewards.getRewardTokens();\n        uint256 _len = _rewardTokens.length;\n        for (uint256 i; i < _len; ++i) {\n            IERC20 _token = IERC20(_rewardTokens[i]);\n            uint256 _amount = _token.balanceOf(address(this));\n\n            // Note: If the reward token is a collateral, transfer the surpass balance only\n            IDepositToken _depositToken = _pool.depositTokenOf(_token);\n            if (address(_depositToken) != address(0)) {\n                _amount -= _depositToken.totalSupply();\n            }\n\n            if (_amount > 0) {\n                _token.safeTransfer(to_, _amount);\n            }\n        }\n    }\n}\n"},{"file_path":"contracts/dependencies/@layerzerolabs/solidity-examples/interfaces/ILayerZeroUserApplicationConfig.sol","source_code":"// SPDX-License-Identifier: MIT\n\npragma solidity >=0.5.0;\n\ninterface ILayerZeroUserApplicationConfig {\n    // @notice set the configuration of the LayerZero messaging library of the specified version\n    // @param _version - messaging library version\n    // @param _chainId - the chainId for the pending config change\n    // @param _configType - type of configuration. every messaging library has its own convention.\n    // @param _config - configuration in the bytes. can encode arbitrary content.\n    function setConfig(uint16 _version, uint16 _chainId, uint _configType, bytes calldata _config) external;\n\n    // @notice set the send() LayerZero messaging library version to _version\n    // @param _version - new messaging library version\n    function setSendVersion(uint16 _version) external;\n\n    // @notice set the lzReceive() LayerZero messaging library version to _version\n    // @param _version - new messaging library version\n    function setReceiveVersion(uint16 _version) external;\n\n    // @notice Only when the UA needs to resume the message flow in blocking mode and clear the stored payload\n    // @param _srcChainId - the chainId of the source chain\n    // @param _srcAddress - the contract address of the source contract at the source chain\n    function forceResumeReceive(uint16 _srcChainId, bytes calldata _srcAddress) external;\n}\n"},{"file_path":"contracts/dependencies/@layerzerolabs/solidity-examples/lzApp/LzApp.sol","source_code":"// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../../../openzeppelin/access/Ownable.sol\";\nimport \"../interfaces/ILayerZeroReceiver.sol\";\nimport \"../interfaces/ILayerZeroUserApplicationConfig.sol\";\nimport \"../interfaces/ILayerZeroEndpoint.sol\";\nimport \"../util/BytesLib.sol\";\n\n/*\n * a generic LzReceiver implementation\n */\nabstract contract LzApp is Ownable, ILayerZeroReceiver, ILayerZeroUserApplicationConfig {\n    using BytesLib for bytes;\n\n    // ua can not send payload larger than this by default, but it can be changed by the ua owner\n    uint public constant DEFAULT_PAYLOAD_SIZE_LIMIT = 10000;\n\n    ILayerZeroEndpoint public immutable lzEndpoint;\n    mapping(uint16 => bytes) public trustedRemoteLookup;\n    mapping(uint16 => mapping(uint16 => uint)) public minDstGasLookup;\n    mapping(uint16 => uint) public payloadSizeLimitLookup;\n    address public precrime;\n\n    event SetPrecrime(address precrime);\n    event SetTrustedRemote(uint16 _remoteChainId, bytes _path);\n    event SetTrustedRemoteAddress(uint16 _remoteChainId, bytes _remoteAddress);\n    event SetMinDstGas(uint16 _dstChainId, uint16 _type, uint _minDstGas);\n\n    constructor(address _endpoint) {\n        lzEndpoint = ILayerZeroEndpoint(_endpoint);\n    }\n\n    function lzReceive(\n        uint16 _srcChainId,\n        bytes calldata _srcAddress,\n        uint64 _nonce,\n        bytes calldata _payload\n    ) public virtual override {\n        // lzReceive must be called by the endpoint for security\n        require(_msgSender() == address(lzEndpoint), \"LzApp: invalid endpoint caller\");\n\n        bytes memory trustedRemote = trustedRemoteLookup[_srcChainId];\n        // if will still block the message pathway from (srcChainId, srcAddress). should not receive message from untrusted remote.\n        require(\n            _srcAddress.length == trustedRemote.length &&\n                trustedRemote.length > 0 &&\n                keccak256(_srcAddress) == keccak256(trustedRemote),\n            \"LzApp: invalid source sending contract\"\n        );\n\n        _blockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload);\n    }\n\n    // abstract function - the default behaviour of LayerZero is blocking. See: NonblockingLzApp if you dont need to enforce ordered messaging\n    function _blockingLzReceive(\n        uint16 _srcChainId,\n        bytes memory _srcAddress,\n        uint64 _nonce,\n        bytes memory _payload\n    ) internal virtual;\n\n    function _lzSend(\n        uint16 _dstChainId,\n        bytes memory _payload,\n        address payable _refundAddress,\n        address _zroPaymentAddress,\n        bytes memory _adapterParams,\n        uint _nativeFee\n    ) internal virtual {\n        bytes memory trustedRemote = trustedRemoteLookup[_dstChainId];\n        require(trustedRemote.length != 0, \"LzApp: destination chain is not a trusted source\");\n        _checkPayloadSize(_dstChainId, _payload.length);\n        lzEndpoint.send{value: _nativeFee}(\n            _dstChainId,\n            trustedRemote,\n            _payload,\n            _refundAddress,\n            _zroPaymentAddress,\n            _adapterParams\n        );\n    }\n\n    function _checkGasLimit(\n        uint16 _dstChainId,\n        uint16 _type,\n        bytes memory _adapterParams,\n        uint _extraGas\n    ) internal view virtual {\n        uint providedGasLimit = _getGasLimit(_adapterParams);\n        uint minGasLimit = minDstGasLookup[_dstChainId][_type] + _extraGas;\n        require(minGasLimit > 0, \"LzApp: minGasLimit not set\");\n        require(providedGasLimit >= minGasLimit, \"LzApp: gas limit is too low\");\n    }\n\n    function _getGasLimit(bytes memory _adapterParams) internal pure virtual returns (uint gasLimit) {\n        require(_adapterParams.length >= 34, \"LzApp: invalid adapterParams\");\n        assembly {\n            gasLimit := mload(add(_adapterParams, 34))\n        }\n    }\n\n    function _checkPayloadSize(uint16 _dstChainId, uint _payloadSize) internal view virtual {\n        uint payloadSizeLimit = payloadSizeLimitLookup[_dstChainId];\n        if (payloadSizeLimit == 0) {\n            // use default if not set\n            payloadSizeLimit = DEFAULT_PAYLOAD_SIZE_LIMIT;\n        }\n        require(_payloadSize <= payloadSizeLimit, \"LzApp: payload size is too large\");\n    }\n\n    //---------------------------UserApplication config----------------------------------------\n    function getConfig(\n        uint16 _version,\n        uint16 _chainId,\n        address,\n        uint _configType\n    ) external view returns (bytes memory) {\n        return lzEndpoint.getConfig(_version, _chainId, address(this), _configType);\n    }\n\n    // generic config for LayerZero user Application\n    function setConfig(\n        uint16 _version,\n        uint16 _chainId,\n        uint _configType,\n        bytes calldata _config\n    ) external override onlyOwner {\n        lzEndpoint.setConfig(_version, _chainId, _configType, _config);\n    }\n\n    function setSendVersion(uint16 _version) external override onlyOwner {\n        lzEndpoint.setSendVersion(_version);\n    }\n\n    function setReceiveVersion(uint16 _version) external override onlyOwner {\n        lzEndpoint.setReceiveVersion(_version);\n    }\n\n    function forceResumeReceive(uint16 _srcChainId, bytes calldata _srcAddress) external override onlyOwner {\n        lzEndpoint.forceResumeReceive(_srcChainId, _srcAddress);\n    }\n\n    // _path = abi.encodePacked(remoteAddress, localAddress)\n    // this function set the trusted path for the cross-chain communication\n    function setTrustedRemote(uint16 _remoteChainId, bytes calldata _path) external onlyOwner {\n        trustedRemoteLookup[_remoteChainId] = _path;\n        emit SetTrustedRemote(_remoteChainId, _path);\n    }\n\n    function setTrustedRemoteAddress(uint16 _remoteChainId, bytes calldata _remoteAddress) external onlyOwner {\n        trustedRemoteLookup[_remoteChainId] = abi.encodePacked(_remoteAddress, address(this));\n        emit SetTrustedRemoteAddress(_remoteChainId, _remoteAddress);\n    }\n\n    function getTrustedRemoteAddress(uint16 _remoteChainId) external view returns (bytes memory) {\n        bytes memory path = trustedRemoteLookup[_remoteChainId];\n        require(path.length != 0, \"LzApp: no trusted path record\");\n        return path.slice(0, path.length - 20); // the last 20 bytes should be address(this)\n    }\n\n    function setPrecrime(address _precrime) external onlyOwner {\n        precrime = _precrime;\n        emit SetPrecrime(_precrime);\n    }\n\n    function setMinDstGas(uint16 _dstChainId, uint16 _packetType, uint _minGas) external onlyOwner {\n        require(_minGas > 0, \"LzApp: invalid minGas\");\n        minDstGasLookup[_dstChainId][_packetType] = _minGas;\n        emit SetMinDstGas(_dstChainId, _packetType, _minGas);\n    }\n\n    // if the size is 0, it means default size limit\n    function setPayloadSizeLimit(uint16 _dstChainId, uint _size) external onlyOwner {\n        payloadSizeLimitLookup[_dstChainId] = _size;\n    }\n\n    //--------------------------- VIEW FUNCTION ----------------------------------------\n    function isTrustedRemote(uint16 _srcChainId, bytes calldata _srcAddress) external view returns (bool) {\n        bytes memory trustedSource = trustedRemoteLookup[_srcChainId];\n        return keccak256(trustedSource) == keccak256(_srcAddress);\n    }\n}\n"},{"file_path":"contracts/interfaces/external/IStargateFactory.sol","source_code":"// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.24;\n\ninterface IStargateFactory {\n    function getPool(uint256 _id) external view returns (address _pool);\n}\n"},{"file_path":"contracts/dependencies/openzeppelin/proxy/ERC1967/ERC1967Upgrade.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (proxy/ERC1967/ERC1967Upgrade.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../beacon/IBeacon.sol\";\nimport \"../../interfaces/draft-IERC1822.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/StorageSlot.sol\";\n\n/**\n * @dev This abstract contract provides getters and event emitting update functions for\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\n *\n * _Available since v4.1._\n *\n * @custom:oz-upgrades-unsafe-allow delegatecall\n */\nabstract contract ERC1967Upgrade {\n    // This is the keccak-256 hash of \"eip1967.proxy.rollback\" subtracted by 1\n    bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\n\n    /**\n     * @dev Storage slot with the address of the current implementation.\n     * This is the keccak-256 hash of \"eip1967.proxy.implementation\" subtracted by 1, and is\n     * validated in the constructor.\n     */\n    bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n\n    /**\n     * @dev Emitted when the implementation is upgraded.\n     */\n    event Upgraded(address indexed implementation);\n\n    /**\n     * @dev Returns the current implementation address.\n     */\n    function _getImplementation() internal view returns (address) {\n        return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\n    }\n\n    /**\n     * @dev Stores a new address in the EIP1967 implementation slot.\n     */\n    function _setImplementation(address newImplementation) private {\n        require(Address.isContract(newImplementation), \"ERC1967: new implementation is not a contract\");\n        StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\n    }\n\n    /**\n     * @dev Perform implementation upgrade\n     *\n     * Emits an {Upgraded} event.\n     */\n    function _upgradeTo(address newImplementation) internal {\n        _setImplementation(newImplementation);\n        emit Upgraded(newImplementation);\n    }\n\n    /**\n     * @dev Perform implementation upgrade with additional setup call.\n     *\n     * Emits an {Upgraded} event.\n     */\n    function _upgradeToAndCall(\n        address newImplementation,\n        bytes memory data,\n        bool forceCall\n    ) internal {\n        _upgradeTo(newImplementation);\n        if (data.length > 0 || forceCall) {\n            Address.functionDelegateCall(newImplementation, data);\n        }\n    }\n\n    /**\n     * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\n     *\n     * Emits an {Upgraded} event.\n     */\n    function _upgradeToAndCallUUPS(\n        address newImplementation,\n        bytes memory data,\n        bool forceCall\n    ) internal {\n        // Upgrades from old implementations will perform a rollback test. This test requires the new\n        // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\n        // this special case will break upgrade paths from old UUPS implementation to new ones.\n        if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) {\n            _setImplementation(newImplementation);\n        } else {\n            try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\n                require(slot == _IMPLEMENTATION_SLOT, \"ERC1967Upgrade: unsupported proxiableUUID\");\n            } catch {\n                revert(\"ERC1967Upgrade: new implementation is not UUPS\");\n            }\n            _upgradeToAndCall(newImplementation, data, forceCall);\n        }\n    }\n\n    /**\n     * @dev Storage slot with the admin of the contract.\n     * This is the keccak-256 hash of \"eip1967.proxy.admin\" subtracted by 1, and is\n     * validated in the constructor.\n     */\n    bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\n\n    /**\n     * @dev Emitted when the admin account has changed.\n     */\n    event AdminChanged(address previousAdmin, address newAdmin);\n\n    /**\n     * @dev Returns the current admin.\n     */\n    function _getAdmin() internal view returns (address) {\n        return StorageSlot.getAddressSlot(_ADMIN_SLOT).value;\n    }\n\n    /**\n     * @dev Stores a new address in the EIP1967 admin slot.\n     */\n    function _setAdmin(address newAdmin) private {\n        require(newAdmin != address(0), \"ERC1967: new admin is the zero address\");\n        StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\n    }\n\n    /**\n     * @dev Changes the admin of the proxy.\n     *\n     * Emits an {AdminChanged} event.\n     */\n    function _changeAdmin(address newAdmin) internal {\n        emit AdminChanged(_getAdmin(), newAdmin);\n        _setAdmin(newAdmin);\n    }\n\n    /**\n     * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\n     * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\n     */\n    bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\n\n    /**\n     * @dev Emitted when the beacon is upgraded.\n     */\n    event BeaconUpgraded(address indexed beacon);\n\n    /**\n     * @dev Returns the current beacon.\n     */\n    function _getBeacon() internal view returns (address) {\n        return StorageSlot.getAddressSlot(_BEACON_SLOT).value;\n    }\n\n    /**\n     * @dev Stores a new beacon in the EIP1967 beacon slot.\n     */\n    function _setBeacon(address newBeacon) private {\n        require(Address.isContract(newBeacon), \"ERC1967: new beacon is not a contract\");\n        require(\n            Address.isContract(IBeacon(newBeacon).implementation()),\n            \"ERC1967: beacon implementation is not a contract\"\n        );\n        StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon;\n    }\n\n    /**\n     * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\n     * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\n     *\n     * Emits a {BeaconUpgraded} event.\n     */\n    function _upgradeBeaconToAndCall(\n        address newBeacon,\n        bytes memory data,\n        bool forceCall\n    ) internal {\n        _setBeacon(newBeacon);\n        emit BeaconUpgraded(newBeacon);\n        if (data.length > 0 || forceCall) {\n            Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);\n        }\n    }\n}\n"},{"file_path":"contracts/FeeProvider.sol","source_code":"// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.24;\n\nimport {Initializable} from \"./dependencies/openzeppelin-upgradeable/proxy/utils/Initializable.sol\";\nimport {SynthContext} from \"./utils/SynthContext.sol\";\nimport {FeeProviderStorageV2} from \"./storage/FeeProviderStorage.sol\";\nimport {IPoolRegistry} from \"./interfaces/IPoolRegistry.sol\";\nimport {IPool} from \"./interfaces/IPool.sol\";\nimport {IDepositToken} from \"./interfaces/IDepositToken.sol\";\nimport {IESMET} from \"./interfaces/external/IESMET.sol\";\nimport {WadRayMath} from \"./lib/WadRayMath.sol\";\n\nerror SenderIsNotGovernor();\nerror PoolRegistryIsNull();\nerror NewValueIsSameAsCurrent();\nerror FeeIsGreaterThanTheMax();\nerror LiquidationFeesTooHigh();\n\n/**\n * @title FeeProvider contract\n */\ncontract FeeProvider is SynthContext, Initializable, FeeProviderStorageV2 {\n    using WadRayMath for uint256;\n\n    string public constant VERSION = \"1.4.1\";\n\n    uint256 internal constant MAX_FEE_VALUE = 0.25e18; // 25%\n\n    // Note: Upper bound on `collateralFactor * (1 + liquidationFees)`. The `< 1e36` form only\n    // guarantees liquidation *eventually* helps; at exactly 1e36 it closes 0 wei of the health\n    // gap. This leaves a margin so every liquidation closes >= 2% of the amount repaid.\n    uint256 internal constant MAX_CF_TIMES_LIQUIDATION_FEES = 0.98e36;\n\n    /// @notice Emitted when deposit fee is updated\n    event DepositFeeUpdated(uint256 oldDepositFee, uint256 newDepositFee);\n\n    /// @notice Emitted when issue fee is updated\n    event IssueFeeUpdated(uint256 oldIssueFee, uint256 newIssueFee);\n\n    /// @notice Emitted when liquidator incentive is updated\n    event LiquidatorIncentiveUpdated(uint256 oldLiquidatorIncentive, uint256 newLiquidatorIncentive);\n\n    /// @notice Emitted when protocol liquidation fee is updated\n    event ProtocolLiquidationFeeUpdated(uint256 oldProtocolLiquidationFee, uint256 newProtocolLiquidationFee);\n\n    /// @notice Emitted when repay fee is updated\n    event RepayFeeUpdated(uint256 oldRepayFee, uint256 newRepayFee);\n\n    /// @notice Emitted when swap fee is updated\n    event SwapFeeUpdated(address synthIn, address synthOut, uint256 oldSwapFee, uint256 newSwapFee);\n\n    /// @notice Emitted when withdraw fee is updated\n    event WithdrawFeeUpdated(uint256 oldWithdrawFee, uint256 newWithdrawFee);\n\n    /**\n     * @notice Throws if caller isn't the governor\n     */\n    modifier onlyGovernor() {\n        if (_msgSender() != _poolRegistry.governor()) revert SenderIsNotGovernor();\n        _;\n    }\n\n    constructor() {\n        _disableInitializers();\n    }\n\n    function initialize(IPoolRegistry poolRegistry_, IESMET esMET_) public initializer {\n        if (address(poolRegistry_) == address(0)) revert PoolRegistryIsNull();\n\n        _poolRegistry = poolRegistry_;\n        esMET = esMET_;\n\n        liquidationFees = LiquidationFees({\n            liquidatorIncentive: 1e17, // 10%\n            protocolFee: 5e16 // 5%\n        });\n    }\n\n    function _revertIfLiquidationFeesAreTooHigh(uint256 newLiquidationFees_) private view {\n        address[] memory _pools = _poolRegistry.getPools();\n        uint256 _poolsLength = _pools.length;\n        for (uint256 i; i < _poolsLength; ++i) {\n            IPool _pool = IPool(_pools[i]);\n            if (address(_pool.feeProvider()) != address(this)) continue;\n\n            address[] memory _depositTokens = _pool.getDepositTokens();\n            uint256 _depositTokensLength = _depositTokens.length;\n            for (uint256 j; j < _depositTokensLength; ++j) {\n                uint256 _collateralFactor = IDepositToken(_depositTokens[j]).collateralFactor();\n                // Note: The `CF * (1 + liquidationFees) < 1` invariant must hold, with a margin (see the constant)\n                if (_collateralFactor * (1e18 + newLiquidationFees_) >= MAX_CF_TIMES_LIQUIDATION_FEES) {\n                    revert LiquidationFeesTooHigh();\n                }\n            }\n        }\n    }\n\n    /// @inheritdoc SynthContext\n    function poolRegistry() public view override returns (IPoolRegistry) {\n        return _poolRegistry;\n    }\n\n    /**\n     * @notice Update deposit fee\n     */\n    function updateDepositFee(uint256 newDepositFee_) external onlyGovernor {\n        if (newDepositFee_ > MAX_FEE_VALUE) revert FeeIsGreaterThanTheMax();\n        uint256 _currentDepositFee = depositFee;\n        if (newDepositFee_ == _currentDepositFee) revert NewValueIsSameAsCurrent();\n        emit DepositFeeUpdated(_currentDepositFee, newDepositFee_);\n        depositFee = newDepositFee_;\n    }\n\n    /**\n     * @notice Update issue fee\n     */\n    function updateIssueFee(uint256 newIssueFee_) external onlyGovernor {\n        if (newIssueFee_ > MAX_FEE_VALUE) revert FeeIsGreaterThanTheMax();\n        uint256 _currentIssueFee = issueFee;\n        if (newIssueFee_ == _currentIssueFee) revert NewValueIsSameAsCurrent();\n        emit IssueFeeUpdated(_currentIssueFee, newIssueFee_);\n        issueFee = newIssueFee_;\n    }\n\n    /**\n     * @notice Update liquidator incentive\n     * @dev liquidatorIncentive + protocolFee can't surpass max\n     */\n    function updateLiquidatorIncentive(uint128 newLiquidatorIncentive_) external onlyGovernor {\n        LiquidationFees memory _current = liquidationFees;\n        if (newLiquidatorIncentive_ + _current.protocolFee > MAX_FEE_VALUE) revert FeeIsGreaterThanTheMax();\n        if (newLiquidatorIncentive_ == _current.liquidatorIncentive) revert NewValueIsSameAsCurrent();\n        if (newLiquidatorIncentive_ > _current.liquidatorIncentive) {\n            _revertIfLiquidationFeesAreTooHigh(newLiquidatorIncentive_ + _current.protocolFee);\n        }\n        emit LiquidatorIncentiveUpdated(_current.liquidatorIncentive, newLiquidatorIncentive_);\n        liquidationFees.liquidatorIncentive = newLiquidatorIncentive_;\n    }\n\n    /**\n     * @notice Update protocol liquidation fee\n     * @dev liquidatorIncentive + protocolFee can't surpass max\n     */\n    function updateProtocolLiquidationFee(uint128 newProtocolLiquidationFee_) external onlyGovernor {\n        LiquidationFees memory _current = liquidationFees;\n        if (newProtocolLiquidationFee_ + _current.liquidatorIncentive > MAX_FEE_VALUE) revert FeeIsGreaterThanTheMax();\n        if (newProtocolLiquidationFee_ == _current.protocolFee) revert NewValueIsSameAsCurrent();\n        if (newProtocolLiquidationFee_ > _current.protocolFee) {\n            _revertIfLiquidationFeesAreTooHigh(newProtocolLiquidationFee_ + _current.liquidatorIncentive);\n        }\n        emit ProtocolLiquidationFeeUpdated(_current.protocolFee, newProtocolLiquidationFee_);\n        liquidationFees.protocolFee = newProtocolLiquidationFee_;\n    }\n\n    /**\n     * @notice Update repay fee\n     */\n    function updateRepayFee(uint256 newRepayFee_) external onlyGovernor {\n        if (newRepayFee_ > MAX_FEE_VALUE) revert FeeIsGreaterThanTheMax();\n        uint256 _currentRepayFee = repayFee;\n        if (newRepayFee_ == _currentRepayFee) revert NewValueIsSameAsCurrent();\n        emit RepayFeeUpdated(_currentRepayFee, newRepayFee_);\n        repayFee = newRepayFee_;\n    }\n\n    /**\n     * @notice Update swap fee\n     */\n    function updateSwapFee(address synthIn_, address synthOut_, uint256 newSwapFee_) external onlyGovernor {\n        if (newSwapFee_ > MAX_FEE_VALUE) revert FeeIsGreaterThanTheMax();\n        uint256 _current = swapFees[synthIn_][synthOut_];\n        if (newSwapFee_ == _current) revert NewValueIsSameAsCurrent();\n        emit SwapFeeUpdated(synthIn_, synthOut_, _current, newSwapFee_);\n        swapFees[synthIn_][synthOut_] = newSwapFee_;\n    }\n\n    /**\n     * @notice Update withdraw fee\n     */\n    function updateWithdrawFee(uint256 newWithdrawFee_) external onlyGovernor {\n        if (newWithdrawFee_ > MAX_FEE_VALUE) revert FeeIsGreaterThanTheMax();\n        uint256 _currentWithdrawFee = withdrawFee;\n        if (newWithdrawFee_ == _currentWithdrawFee) revert NewValueIsSameAsCurrent();\n        emit WithdrawFeeUpdated(_currentWithdrawFee, newWithdrawFee_);\n        withdrawFee = newWithdrawFee_;\n    }\n}\n"},{"file_path":"contracts/dependencies/@layerzerolabs/solidity-examples/contracts-upgradeable/interfaces/ILayerZeroReceiverUpgradeable.sol","source_code":"// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.2;\n\ninterface ILayerZeroReceiverUpgradeable {\n    // @notice LayerZero endpoint will invoke this function to deliver the message on the destination\n    // @param _srcChainId - the source endpoint identifier\n    // @param _srcAddress - the source sending contract address from the source chain\n    // @param _nonce - the ordered message nonce\n    // @param _payload - the signed payload is the UA bytes has encoded to be sent\n    function lzReceive(uint16 _srcChainId, bytes calldata _srcAddress, uint64 _nonce, bytes calldata _payload) external;\n}\n"},{"file_path":"contracts/utils/TokenHolder.sol","source_code":"// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.24;\n\nimport {Address} from \"../dependencies/openzeppelin/utils/Address.sol\";\nimport {SafeERC20, IERC20} from \"../dependencies/openzeppelin/token/ERC20/utils/SafeERC20.sol\";\n\nerror FallbackIsNotAllowed();\nerror ReceiveIsNotAllowed();\n\n/**\n * @title Utils contract that handles tokens sent to it\n */\nabstract contract TokenHolder {\n    using SafeERC20 for IERC20;\n\n    /**\n     * @dev Revert fallback calls\n     */\n    fallback() external payable {\n        revert FallbackIsNotAllowed();\n    }\n\n    /**\n     * @dev Revert when receiving by default\n     */\n    receive() external payable virtual {\n        revert ReceiveIsNotAllowed();\n    }\n\n    /**\n     * @notice ERC20 recovery in case of stuck tokens due direct transfers to the contract address.\n     * @param token_ The token to transfer\n     * @param to_ The recipient of the transfer\n     * @param amount_ The amount to send\n     */\n    function sweep(IERC20 token_, address to_, uint256 amount_) external {\n        _requireCanSweep();\n\n        if (address(token_) == address(0)) {\n            Address.sendValue(payable(to_), amount_);\n        } else {\n            token_.safeTransfer(to_, amount_);\n        }\n    }\n\n    /**\n     * @notice Function that reverts if the caller isn't allowed to sweep tokens\n     * @dev Usually requires the owner or governor as the caller\n     */\n    function _requireCanSweep() internal view virtual;\n}\n"},{"file_path":"contracts/storage/RewardsDistributorStorage.sol","source_code":"// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.24;\n\nimport {IERC20} from \"../dependencies/openzeppelin/token/ERC20/IERC20.sol\";\nimport {IRewardsDistributor} from \"../interfaces/IRewardsDistributor.sol\";\n\nabstract contract RewardsDistributorStorageV1 is IRewardsDistributor {\n    struct TokenState {\n        uint224 index; // The last updated index\n        uint32 timestamp; // The timestamp of the latest index update\n    }\n\n    /**\n     * @notice The token to reward\n     */\n    IERC20 public override rewardToken;\n\n    /**\n     * @notice Track tokens for reward\n     */\n    IERC20[] public override tokens;\n\n    /**\n     * @notice The amount of token distributed for each token per second\n     */\n    mapping(IERC20 => uint256) public override tokenSpeeds;\n\n    /**\n     * @notice The reward state for each token\n     */\n    mapping(IERC20 => TokenState) public override tokenStates;\n\n    /**\n     * @notice The supply index for each token for each account as of the last time they accrued token\n     */\n    mapping(IERC20 => mapping(address => uint256)) public override accountIndexOf;\n\n    /**\n     * @notice The token accrued but not yet transferred to each user\n     */\n    mapping(address => uint256) public override tokensAccruedOf;\n}\n\nabstract contract RewardsDistributorStorageV2 is RewardsDistributorStorageV1 {\n    address public tokenSpeedKeeper;\n}\n"},{"file_path":"contracts/interfaces/IPool.sol","source_code":"// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.24;\n\nimport {IERC20} from \"../dependencies/openzeppelin/token/ERC20/IERC20.sol\";\nimport {IDepositToken} from \"./IDepositToken.sol\";\nimport {IDebtToken} from \"./IDebtToken.sol\";\nimport {ITreasury} from \"./ITreasury.sol\";\nimport {IPoolRegistry} from \"./IPoolRegistry.sol\";\nimport {IFeeProvider} from \"./IFeeProvider.sol\";\nimport {ISmartFarmingManager} from \"./ISmartFarmingManager.sol\";\nimport {IFeeProvider} from \"../interfaces/IFeeProvider.sol\";\nimport {IPauseable} from \"../interfaces/IPauseable.sol\";\nimport {IGovernable} from \"../interfaces/IGovernable.sol\";\nimport {ISyntheticToken} from \"../interfaces/ISyntheticToken.sol\";\nimport {IMasterOracle} from \"../interfaces/external/IMasterOracle.sol\";\n\n/**\n * @notice Pool interface\n */\ninterface IPool is IPauseable, IGovernable {\n    function debtFloorInUsd() external view returns (uint256);\n\n    function feeCollector() external view returns (address);\n\n    function feeProvider() external view returns (IFeeProvider);\n\n    function maxLiquidable() external view returns (uint256);\n\n    function doesSyntheticTokenExist(ISyntheticToken syntheticToken_) external view returns (bool);\n\n    function doesDebtTokenExist(IDebtToken debtToken_) external view returns (bool);\n\n    function doesDepositTokenExist(IDepositToken depositToken_) external view returns (bool);\n\n    function depositTokenOf(IERC20 underlying_) external view returns (IDepositToken);\n\n    function debtTokenOf(ISyntheticToken syntheticToken_) external view returns (IDebtToken);\n\n    function getDepositTokens() external view returns (address[] memory);\n\n    function getDebtTokens() external view returns (address[] memory);\n\n    function getRewardsDistributors() external view returns (address[] memory);\n\n    function debtOf(address account_) external view returns (uint256 _debtInUsd);\n\n    function depositOf(address account_) external view returns (uint256 _depositInUsd, uint256 _issuableLimitInUsd);\n\n    function debtPositionOf(\n        address account_\n    )\n        external\n        view\n        returns (\n            bool _isHealthy,\n            uint256 _depositInUsd,\n            uint256 _debtInUsd,\n            uint256 _issuableLimitInUsd,\n            uint256 _issuableInUsd\n        );\n\n    function liquidate(\n        ISyntheticToken syntheticToken_,\n        address account_,\n        uint256 amountToRepay_,\n        IDepositToken depositToken_\n    ) external returns (uint256 _totalSeized, uint256 _toLiquidator, uint256 _fee);\n\n    function quoteLiquidateIn(\n        ISyntheticToken syntheticToken_,\n        uint256 totalToSeized_,\n        IDepositToken depositToken_\n    ) external view returns (uint256 _amountToRepay, uint256 _toLiquidator, uint256 _fee);\n\n    function quoteLiquidateMax(\n        ISyntheticToken syntheticToken_,\n        address account_,\n        IDepositToken depositToken_\n    ) external view returns (uint256 _maxAmountToRepay);\n\n    function quoteLiquidateOut(\n        ISyntheticToken syntheticToken_,\n        uint256 amountToRepay_,\n        IDepositToken depositToken_\n    ) external view returns (uint256 _totalSeized, uint256 _toLiquidator, uint256 _fee);\n\n    function quoteSwapIn(\n        ISyntheticToken syntheticTokenIn_,\n        ISyntheticToken syntheticTokenOut_,\n        uint256 amountOut_\n    ) external view returns (uint256 _amountIn, uint256 _fee);\n\n    function quoteSwapOut(\n        ISyntheticToken syntheticTokenIn_,\n        ISyntheticToken syntheticTokenOut_,\n        uint256 amountIn_\n    ) external view returns (uint256 _amountOut, uint256 _fee);\n\n    function swap(\n        ISyntheticToken syntheticTokenIn_,\n        ISyntheticToken syntheticTokenOut_,\n        uint256 amountIn_\n    ) external returns (uint256 _amountOut, uint256 _fee);\n\n    function treasury() external view returns (ITreasury);\n\n    function masterOracle() external view returns (IMasterOracle);\n\n    function poolRegistry() external view returns (IPoolRegistry);\n\n    function addToDepositTokensOfAccount(address account_) external;\n\n    function removeFromDepositTokensOfAccount(address account_) external;\n\n    function addToDebtTokensOfAccount(address account_) external;\n\n    function removeFromDebtTokensOfAccount(address account_) external;\n\n    function getDepositTokensOfAccount(address account_) external view returns (address[] memory);\n\n    function getDebtTokensOfAccount(address account_) external view returns (address[] memory);\n\n    function isSwapActive() external view returns (bool);\n\n    function smartFarmingManager() external view returns (ISmartFarmingManager);\n}\n"},{"file_path":"contracts/mock/MasterOracleMock.sol","source_code":"// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.24;\n\nimport {IERC20Metadata} from \"../dependencies/openzeppelin/token/ERC20/extensions/IERC20Metadata.sol\";\nimport {IMasterOracle} from \"../interfaces/external/IMasterOracle.sol\";\n\ncontract MasterOracleMock is IMasterOracle {\n    mapping(address => uint256) public prices;\n\n    uint256 public expireAt = type(uint256).max;\n    uint256 public expirationPeriod = 100 * 365 days;\n\n    function updatePrice(address _asset, uint256 _price) external {\n        prices[_asset] = _price;\n        expireAt = block.timestamp + expirationPeriod;\n    }\n\n    function quoteTokenToUsd(address _asset, uint256 _amount) public view override returns (uint256 _amountInUsd) {\n        require(block.timestamp <= expireAt, \"price-expired\");\n        _amountInUsd = (_amount * prices[_asset]) / 10 ** IERC20Metadata(address(_asset)).decimals();\n    }\n\n    function quoteUsdToToken(address _asset, uint256 _amountInUsd) public view override returns (uint256 _amount) {\n        require(block.timestamp <= expireAt, \"price-expired\");\n        _amount = (_amountInUsd * 10 ** IERC20Metadata(address(_asset)).decimals()) / prices[_asset];\n    }\n\n    function quote(\n        address _assetIn,\n        address _assetOut,\n        uint256 _amountIn\n    ) public view override returns (uint256 _amountOut) {\n        uint256 _amountInUsd = quoteTokenToUsd(_assetIn, _amountIn);\n        _amountOut = quoteUsdToToken(_assetOut, _amountInUsd);\n    }\n\n    function setExpirationPeriod(uint256 expirationPeriod_) public {\n        expirationPeriod = expirationPeriod_;\n    }\n}\n"},{"file_path":"contracts/SmartFarmingManager.sol","source_code":"// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.24;\n\nimport {SafeERC20} from \"./dependencies/openzeppelin/token/ERC20/utils/SafeERC20.sol\";\nimport {Math} from \"./dependencies/openzeppelin/utils/math/Math.sol\";\nimport {IERC20} from \"./dependencies/openzeppelin/token/ERC20/IERC20.sol\";\nimport {Initializable} from \"./dependencies/openzeppelin-upgradeable/proxy/utils/Initializable.sol\";\nimport {Manageable} from \"./access/Manageable.sol\";\nimport {ReentrancyGuardDeprecated} from \"./utils/ReentrancyGuardDeprecated.sol\";\nimport {ReentrancyGuardTransient} from \"./utils/ReentrancyGuardTransient.sol\";\nimport {WadRayMath} from \"./lib/WadRayMath.sol\";\nimport {ISyntheticToken} from \"./interfaces/ISyntheticToken.sol\";\nimport {IDepositToken} from \"./interfaces/IDepositToken.sol\";\nimport {IPool} from \"./interfaces/IPool.sol\";\nimport {IDebtToken} from \"./interfaces/IDebtToken.sol\";\nimport {ISwapper} from \"./interfaces/external/ISwapper.sol\";\nimport {SmartFarmingManagerStorageV1} from \"./storage/SmartFarmingManagerStorage.sol\";\n\nerror SyntheticDoesNotExist();\nerror PoolIsNull();\nerror FlashRepaySlippageTooHigh();\nerror LeverageTooLow();\nerror LeverageTooHigh();\nerror LeverageSlippageTooHigh();\nerror PositionIsNotHealthy();\nerror AmountIsZero();\nerror AmountIsTooHigh();\nerror DepositTokenDoesNotExist();\n\n/**\n * @title SmartFarmingManager contract\n */\ncontract SmartFarmingManager is\n    Initializable,\n    ReentrancyGuardDeprecated,\n    ReentrancyGuardTransient,\n    Manageable,\n    SmartFarmingManagerStorageV1\n{\n    using SafeERC20 for IERC20;\n    using SafeERC20 for ISyntheticToken;\n    using WadRayMath for uint256;\n\n    string public constant VERSION = \"1.4.1\";\n\n    /// @notice Emitted when debt is flash repaid\n    event FlashRepaid(\n        ISyntheticToken indexed syntheticToken,\n        IDepositToken indexed depositToken,\n        uint256 withdrawn,\n        uint256 repaid\n    );\n\n    /// @notice Emitted when deposit is leveraged\n    event Leveraged(\n        IERC20 indexed tokenIn,\n        IDepositToken indexed depositToken,\n        ISyntheticToken indexed syntheticToken,\n        uint256 leverage,\n        uint256 amountIn,\n        uint256 issued,\n        uint256 deposited\n    );\n\n    /**\n     * @dev Throws if deposit token doesn't exist\n     */\n    modifier onlyIfDepositTokenExists(IDepositToken depositToken_) {\n        if (!pool.doesDepositTokenExist(depositToken_)) revert DepositTokenDoesNotExist();\n        _;\n    }\n\n    /**\n     * @dev Throws if synthetic token doesn't exist\n     */\n    modifier onlyIfSyntheticTokenExists(ISyntheticToken syntheticToken_) {\n        if (!pool.doesSyntheticTokenExist(syntheticToken_)) revert SyntheticDoesNotExist();\n        _;\n    }\n\n    constructor() {\n        _disableInitializers();\n    }\n\n    function initialize(IPool pool_) public initializer {\n        if (address(pool_) == address(0)) revert PoolIsNull();\n        __Manageable_init(pool_);\n    }\n\n    /**\n     * @notice Flash debt repayment\n     * @param syntheticToken_ The debt token to repay\n     * @param depositToken_ The collateral to withdraw\n     * @param withdrawAmount_ The amount to withdraw\n     * @param swapAmountOutMin_ The minimum amount of synthetic tokens to receive (slippage check)\n     */\n    function flashRepay(\n        ISyntheticToken syntheticToken_,\n        IDepositToken depositToken_,\n        uint256 withdrawAmount_,\n        uint256 swapAmountOutMin_\n    )\n        external\n        override\n        whenNotShutdown\n        nonReentrant\n        onlyIfDepositTokenExists(depositToken_)\n        onlyIfSyntheticTokenExists(syntheticToken_)\n        returns (uint256 _withdrawn, uint256 _repaid)\n    {\n        ISyntheticToken _syntheticToken = syntheticToken_; // stack too deep\n\n        address _msgSender = _msgSender();\n        if (withdrawAmount_ == 0) revert AmountIsZero();\n        if (withdrawAmount_ > depositToken_.balanceOf(_msgSender)) revert AmountIsTooHigh();\n\n        // 1. withdraw collateral\n        (_withdrawn, ) = depositToken_.flashWithdraw(_msgSender, withdrawAmount_);\n\n        // 2. swap it for synth\n        // Note: `amountOutMin_` is `0` because slippage is checked below on the actual amount received\n        uint256 _synthAmountOut = _swap(swapper(), _collateralOf(depositToken_), _syntheticToken, _withdrawn, 0);\n        if (_synthAmountOut < swapAmountOutMin_) revert FlashRepaySlippageTooHigh();\n\n        IPool _pool = pool;\n        IDebtToken _debtToken = _pool.debtTokenOf(_syntheticToken);\n        (uint256 _maxRepayAmount, ) = _debtToken.quoteRepayIn(_debtToken.balanceOf(_msgSender));\n        uint256 _amountToRepay = Math.min(_synthAmountOut, _maxRepayAmount);\n\n        // 3. repay debt\n        (_repaid, ) = _debtToken.repay(_msgSender, _amountToRepay);\n\n        // 4. refund synthetic token in excess\n        if (_synthAmountOut > _amountToRepay) {\n            _syntheticToken.safeTransfer(_msgSender, _synthAmountOut - _amountToRepay);\n        }\n\n        // 5. check the health of the outcome position\n        (bool _isHealthy, , , , ) = _pool.debtPositionOf(_msgSender);\n        if (!_isHealthy) revert PositionIsNotHealthy();\n\n        emit FlashRepaid(_syntheticToken, depositToken_, _withdrawn, _repaid);\n    }\n\n    /**\n     * @notice Leverage yield position\n     * @param tokenIn_ The token to transfer\n     * @param depositToken_ The collateral to deposit\n     * @param syntheticToken_ The msAsset to mint\n     * @param amountIn_ The amount to deposit\n     * @param leverage_ The leverage X param (e.g. 1.5e18 for 1.5X)\n     * @param depositAmountMin_ The min final deposit amount (slippage)\n     */\n    function leverage(\n        IERC20 tokenIn_,\n        IDepositToken depositToken_,\n        ISyntheticToken syntheticToken_,\n        uint256 amountIn_,\n        uint256 leverage_,\n        uint256 depositAmountMin_\n    )\n        external\n        override\n        whenNotShutdown\n        nonReentrant\n        onlyIfDepositTokenExists(depositToken_)\n        onlyIfSyntheticTokenExists(syntheticToken_)\n        returns (uint256 _deposited, uint256 _issued)\n    {\n        if (amountIn_ == 0) revert AmountIsZero();\n        if (leverage_ <= 1e18) revert LeverageTooLow();\n        if (leverage_ > uint256(1e18).wadDiv(1e18 - depositToken_.collateralFactor())) revert LeverageTooHigh();\n\n        address _msgSender = _msgSender();\n        ISwapper _swapper = swapper();\n\n        // 1. transfer collateral\n        IERC20 _collateral = _collateralOf(depositToken_);\n        if (address(tokenIn_) == address(0)) tokenIn_ = _collateral;\n        amountIn_ = _safeTransferFrom(tokenIn_, _msgSender, amountIn_);\n        if (tokenIn_ != _collateral) {\n            // Note: `amountOutMin_` is `0` because slippage will be checked later on\n            amountIn_ = _swap(_swapper, tokenIn_, _collateral, amountIn_, 0);\n        }\n\n        {\n            // 2. mint synth + debt\n            uint256 _debtAmount = _calculateLeverageDebtAmount(_collateral, syntheticToken_, amountIn_, leverage_);\n            IDebtToken _debtToken = pool.debtTokenOf(syntheticToken_);\n            (_issued, ) = _debtToken.flashIssue(address(this), _debtAmount);\n            _debtToken.mint(_msgSender, _debtAmount);\n        }\n\n        {\n            // 3. swap synth for collateral\n            uint256 _depositAmount = amountIn_ + _swap(_swapper, syntheticToken_, _collateral, _issued, 0);\n            if (_depositAmount < depositAmountMin_) revert LeverageSlippageTooHigh();\n\n            // 4. deposit collateral\n            _collateral.safeApprove(address(depositToken_), 0);\n            _collateral.safeApprove(address(depositToken_), _depositAmount);\n            (_deposited, ) = depositToken_.deposit(_depositAmount, _msgSender);\n        }\n\n        // 5. check the health of the outcome position\n        (bool _isHealthy, , , , ) = pool.debtPositionOf(_msgSender);\n        if (!_isHealthy) revert PositionIsNotHealthy();\n\n        emit Leveraged(tokenIn_, depositToken_, syntheticToken_, leverage_, amountIn_, _issued, _deposited);\n    }\n\n    /**\n     * @notice Get the swapper contract\n     */\n    function swapper() public view returns (ISwapper _swapper) {\n        return pool.poolRegistry().swapper();\n    }\n\n    /**\n     * @notice Calculate debt to issue for a leverage operation\n     * @param collateral_ The collateral to deposit\n     * @param syntheticToken_ The msAsset to mint\n     * @param amountIn_ The amount to deposit\n     * @param leverage_ The leverage X param (e.g. 1.5e18 for 1.5X)\n     * @return _debtAmount The debt issue\n     */\n    function _calculateLeverageDebtAmount(\n        IERC20 collateral_,\n        ISyntheticToken syntheticToken_,\n        uint256 amountIn_,\n        uint256 leverage_\n    ) private view returns (uint256 _debtAmount) {\n        return\n            pool.masterOracle().quote(\n                address(collateral_),\n                address(syntheticToken_),\n                (leverage_ - 1e18).wadMul(amountIn_)\n            );\n    }\n\n    /**\n     * @dev `collateral` is a better name than `underlying`\n     * See more: https://github.com/autonomoussoftware/metronome-synth/issues/905\n     */\n    function _collateralOf(IDepositToken depositToken_) private view returns (IERC20) {\n        return depositToken_.underlying();\n    }\n\n    /**\n     * @notice Transfer token and check actual amount transferred\n     * @param token_ The token to transfer\n     * @param from_ The account to get tokens from\n     * @param amount_ The amount to transfer\n     * @return _transferred The actual transferred amount\n     */\n    function _safeTransferFrom(IERC20 token_, address from_, uint256 amount_) private returns (uint256 _transferred) {\n        uint256 _before = token_.balanceOf(address(this));\n        token_.safeTransferFrom(from_, address(this), amount_);\n        return token_.balanceOf(address(this)) - _before;\n    }\n\n    /**\n     * @notice Swap assets using Swapper contract\n     * @dev Use `address(this)` as amount out receiver\n     * @param swapper_ The Swapper contract\n     * @param tokenIn_ The token to swap from\n     * @param tokenOut_ The token to swap to\n     * @param amountIn_ The amount in\n     * @param amountOutMin_ The minimum amount out (slippage check)\n     * @return _amountOut The actual amount out\n     */\n    function _swap(\n        ISwapper swapper_,\n        IERC20 tokenIn_,\n        IERC20 tokenOut_,\n        uint256 amountIn_,\n        uint256 amountOutMin_\n    ) private returns (uint256 _amountOut) {\n        return _swap(swapper_, tokenIn_, tokenOut_, amountIn_, amountOutMin_, address(this));\n    }\n\n    /**\n     * @notice Swap assets using Swapper contract\n     * @param swapper_ The Swapper contract\n     * @param tokenIn_ The token to swap from\n     * @param tokenOut_ The token to swap to\n     * @param amountIn_ The amount in\n     * @param amountOutMin_ The minimum amount out (slippage check)\n     * @param to_ The amount out receiver\n     * @return _amountOut The actual amount out\n     */\n    function _swap(\n        ISwapper swapper_,\n        IERC20 tokenIn_,\n        IERC20 tokenOut_,\n        uint256 amountIn_,\n        uint256 amountOutMin_,\n        address to_\n    ) private returns (uint256 _amountOut) {\n        if (tokenIn_ != tokenOut_) {\n            tokenIn_.safeApprove(address(swapper_), 0);\n            tokenIn_.safeApprove(address(swapper_), amountIn_);\n            uint256 _tokenOutBefore = tokenOut_.balanceOf(to_);\n            swapper_.swapExactInput(address(tokenIn_), address(tokenOut_), amountIn_, amountOutMin_, to_);\n            return tokenOut_.balanceOf(to_) - _tokenOutBefore;\n        } else if (to_ != address(this)) {\n            tokenIn_.safeTransfer(to_, amountIn_);\n        }\n        return amountIn_;\n    }\n}\n"},{"file_path":"contracts/interfaces/ISmartFarmingManager.sol","source_code":"// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.24;\n\nimport {IERC20} from \"../dependencies/openzeppelin/token/ERC20/IERC20.sol\";\nimport {IDepositToken} from \"./IDepositToken.sol\";\nimport {ISyntheticToken} from \"./ISyntheticToken.sol\";\n\n/**\n * @notice SmartFarmingManager interface\n */\ninterface ISmartFarmingManager {\n    function flashRepay(\n        ISyntheticToken syntheticToken_,\n        IDepositToken depositToken_,\n        uint256 withdrawAmount_,\n        uint256 swapAmountOutMin_\n    ) external returns (uint256 _withdrawn, uint256 _repaid);\n\n    function leverage(\n        IERC20 tokenIn_,\n        IDepositToken depositToken_,\n        ISyntheticToken syntheticToken_,\n        uint256 amountIn_,\n        uint256 leverage_,\n        uint256 depositAmountMin_\n    ) external returns (uint256 _deposited, uint256 _issued);\n}\n"},{"file_path":"contracts/utils/ReentrancyGuardDeprecated.sol","source_code":"// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/// @dev This contract is used to avoid breaking storage when migrating to `ReentrancyGuardTransient`\nabstract contract ReentrancyGuardDeprecated {\n    uint256 private _status_DEPRECATED;\n}\n"},{"file_path":"contracts/SyntheticToken.sol","source_code":"// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.24;\n\nimport {Initializable} from \"./dependencies/openzeppelin-upgradeable/proxy/utils/Initializable.sol\";\nimport {IERC20} from \"./dependencies/openzeppelin/token/ERC20/IERC20.sol\";\nimport {SynthContext} from \"./utils/SynthContext.sol\";\nimport {WadRayMath} from \"./lib/WadRayMath.sol\";\nimport {IPool} from \"./interfaces/IPool.sol\";\nimport {IProxyOFT} from \"./interfaces/IProxyOFT.sol\";\nimport {IManageable} from \"./interfaces/IManageable.sol\";\nimport {IPoolRegistry} from \"./interfaces/IPoolRegistry.sol\";\nimport {ISyntheticToken} from \"./interfaces/ISyntheticToken.sol\";\nimport {IDebtToken} from \"./interfaces/IDebtToken.sol\";\nimport {SyntheticTokenStorageV2} from \"./storage/SyntheticTokenStorage.sol\";\n\nerror SenderIsNotGovernor();\nerror SenderCanNotBurn();\nerror SenderCanNotMint();\nerror SenderCanNotSeize();\nerror SyntheticIsInactive();\nerror NameIsNull();\nerror SymbolIsNull();\nerror DecimalsIsNull();\nerror PoolRegistryIsNull();\nerror DecreasedAllowanceBelowZero();\nerror AmountExceedsAllowance();\nerror ApproveFromTheZeroAddress();\nerror ApproveToTheZeroAddress();\nerror BurnFromTheZeroAddress();\nerror BurnAmountExceedsBalance();\nerror MintToTheZeroAddress();\nerror SurpassMaxBridgingSupply();\nerror SurpassMaxSynthSupply();\nerror TransferFromTheZeroAddress();\nerror TransferToTheZeroAddress();\nerror TransferAmountExceedsBalance();\nerror NewValueIsSameAsCurrent();\nerror AddressIsNull();\nerror SurpassMaxAmoSupply();\n\n/**\n * @title Synthetic Token contract\n */\ncontract SyntheticToken is SynthContext, Initializable, SyntheticTokenStorageV2 {\n    using WadRayMath for uint256;\n\n    string public constant VERSION = \"1.4.1\";\n\n    /// @notice Emitted when active flag is updated\n    event SyntheticTokenActiveUpdated(bool newActive);\n\n    /// @notice Emitted when max amo supply is updated\n    event MaxAmoSupplyUpdated(uint256 oldMaxAmoSupply, uint256 newMaxAmoSupply);\n\n    /// @notice Emitted when max total supply is updated\n    event MaxTotalSupplyUpdated(uint256 oldMaxTotalSupply, uint256 newMaxTotalSupply);\n\n    /// @notice Emitted when max bridged-in supply is updated\n    event MaxBridgedInSupplyUpdated(uint256 oldMaxBridgedInSupply, uint256 newMaxBridgedInSupply);\n\n    /// @notice Emitted when max bridged-out supply is updated\n    event MaxBridgedOutSupplyUpdated(uint256 oldMaxBridgedOutSupply, uint256 newMaxBridgedOutSupply);\n\n    /// @notice Emitted when proxyOFT is updated\n    event ProxyOFTUpdated(IProxyOFT oldProxyOFT, IProxyOFT newProxyOFT);\n\n    /// @notice Emitted when AMO is updated\n    event AmoUpdated(address oldAmo, address newAmo);\n\n    /**\n     * @notice Throws if caller isn't the governor\n     */\n    modifier onlyGovernor() {\n        if (_msgSender() != _poolRegistry.governor()) revert SenderIsNotGovernor();\n        _;\n    }\n\n    /**\n     * @dev Throws if sender can't burn\n     */\n    modifier onlyIfCanBurn() {\n        address _msgSender = _msgSender();\n        if (!_isProxyOFT(_msgSender) && !_isPool(_msgSender) && !_isDebtToken(_msgSender)) revert SenderCanNotBurn();\n        _;\n    }\n\n    /**\n     * @dev Throws if sender can't mint\n     */\n    modifier onlyIfCanMint() {\n        address _msgSender = _msgSender();\n        if (!_isProxyOFT(_msgSender) && !_isAmo(_msgSender) && !_isPool(_msgSender) && !_isDebtToken(_msgSender))\n            revert SenderCanNotMint();\n        _;\n    }\n\n    /**\n     * @dev Throws if sender can't seize\n     */\n    modifier onlyIfCanSeize() {\n        address _msgSender = _msgSender();\n        if (!_isProxyOFT(_msgSender) && !_isPool(_msgSender) && !_isDebtToken(_msgSender)) revert SenderCanNotSeize();\n        _;\n    }\n\n    /**\n     * @dev Throws if synthetic token isn't enabled\n     */\n    modifier onlyIfSyntheticTokenIsActive() {\n        if (!isActive) revert SyntheticIsInactive();\n        _;\n    }\n\n    constructor() {\n        _disableInitializers();\n    }\n\n    function initialize(\n        string calldata name_,\n        string calldata symbol_,\n        uint8 decimals_,\n        IPoolRegistry poolRegistry_\n    ) external initializer {\n        if (bytes(name_).length == 0) revert NameIsNull();\n        if (bytes(symbol_).length == 0) revert SymbolIsNull();\n        if (decimals_ == 0) revert DecimalsIsNull();\n        if (address(poolRegistry_) == address(0)) revert PoolRegistryIsNull();\n\n        _poolRegistry = poolRegistry_;\n        name = name_;\n        symbol = symbol_;\n        decimals = decimals_;\n        isActive = true;\n        maxTotalSupply = type(uint256).max;\n    }\n\n    /**\n     * @notice Set `amount` as the allowance of `spender` over the caller's tokens\n     */\n    function approve(address spender_, uint256 amount_) external override returns (bool) {\n        _approve(_msgSender(), spender_, amount_);\n        return true;\n    }\n\n    /**\n     * @notice Get net bridged-in circulating supply\n     * @dev The supply is calculated using `MAX(totalBridgedIn - totalBridgedOut, 0)`\n     */\n    function bridgedInSupply() public view returns (uint256 _supply) {\n        uint256 _totalBridgedIn = totalBridgedIn;\n        uint256 _totalBridgedOut = totalBridgedOut;\n\n        if (_totalBridgedIn > _totalBridgedOut) {\n            return _totalBridgedIn - _totalBridgedOut;\n        }\n    }\n\n    /**\n     * @notice Get net bridged-out circulating supply\n     * @dev The supply is calculated using `MAX(totalBridgedOut - totalBridgedIn, 0)`\n     */\n    function bridgedOutSupply() public view returns (uint256 _supply) {\n        uint256 _totalBridgedIn = totalBridgedIn;\n        uint256 _totalBridgedOut = totalBridgedOut;\n\n        if (_totalBridgedOut > _totalBridgedIn) {\n            return _totalBridgedOut - _totalBridgedIn;\n        }\n    }\n\n    /**\n     * @notice Burn synthetic token\n     * @param from_ The account to burn from\n     * @param amount_ The amount to burn\n     */\n    function burnFor(address from_, uint256 amount_) external override onlyIfCanBurn {\n        _burn(from_, amount_);\n    }\n\n    /**\n     * @notice Burn caller's synthetic tokens\n     * @param amount_ The amount to burn\n     */\n    function burn(uint256 amount_) external override {\n        _burn(_msgSender(), amount_);\n    }\n\n    /**\n     * @notice Burn synthetic tokens from `from_`, deducting from the caller's allowance\n     * @param from_ The account to burn from\n     * @param amount_ The amount to burn\n     */\n    function burnFrom(address from_, uint256 amount_) external override {\n        _spendAllowance(from_, _msgSender(), amount_);\n        _burn(from_, amount_);\n    }\n\n    /**\n     * @notice Atomically decrease the allowance granted to `spender` by the caller\n     */\n    function decreaseAllowance(address spender_, uint256 subtractedValue_) external returns (bool) {\n        address _msgSender = _msgSender();\n        uint256 _currentAllowance = allowance[_msgSender][spender_];\n        if (_currentAllowance < subtractedValue_) revert DecreasedAllowanceBelowZero();\n        unchecked {\n            _approve(_msgSender, spender_, _currentAllowance - subtractedValue_);\n        }\n        return true;\n    }\n\n    /**\n     * @notice Atomically increase the allowance granted to `spender` by the caller\n     */\n    function increaseAllowance(address spender_, uint256 addedValue_) external returns (bool) {\n        address _msgSender = _msgSender();\n        _approve(_msgSender, spender_, allowance[_msgSender][spender_] + addedValue_);\n        return true;\n    }\n\n    /**\n     * @notice Mint synthetic token\n     * @param to_ The account to mint to\n     * @param amount_ The amount to mint\n     */\n    function mint(address to_, uint256 amount_) external override onlyIfCanMint {\n        _mint(to_, amount_);\n    }\n\n    /**\n     * @notice Seize synthetic tokens\n     * @dev Same as _transfer\n     * @param to_ The account to seize from\n     * @param to_ The beneficiary account\n     * @param amount_ The amount to seize\n     */\n    function seize(address from_, address to_, uint256 amount_) external override onlyIfCanSeize {\n        if (_isProxyOFT(_msgSender()) && to_ != _poolRegistry.feeCollector()) revert SenderCanNotSeize();\n\n        _transfer(from_, to_, amount_);\n    }\n\n    /// @inheritdoc IERC20\n    function transfer(address to_, uint256 amount_) external override returns (bool) {\n        _transfer(_msgSender(), to_, amount_);\n        return true;\n    }\n\n    /// @inheritdoc IERC20\n    function transferFrom(address from_, address to_, uint256 amount_) external override returns (bool) {\n        _spendAllowance(from_, _msgSender(), amount_);\n\n        _transfer(from_, to_, amount_);\n\n        return true;\n    }\n\n    /**\n     * @notice Update `owner`'s allowance for `spender` based on spent `amount`\n     * @dev Maximum `uint256` means infinite allowance\n     */\n    function _spendAllowance(address owner_, address spender_, uint256 amount_) private {\n        uint256 _currentAllowance = allowance[owner_][spender_];\n        if (_currentAllowance != type(uint256).max) {\n            if (_currentAllowance < amount_) revert AmountExceedsAllowance();\n            unchecked {\n                _approve(owner_, spender_, _currentAllowance - amount_);\n            }\n        }\n    }\n\n    /**\n     * @notice Set `amount` as the allowance of `spender` over the `owner` s tokens\n     */\n    function _approve(address owner_, address spender_, uint256 amount_) private {\n        if (owner_ == address(0)) revert ApproveFromTheZeroAddress();\n        if (spender_ == address(0)) revert ApproveToTheZeroAddress();\n\n        allowance[owner_][spender_] = amount_;\n        emit Approval(owner_, spender_, amount_);\n    }\n\n    /**\n     * @notice Destroy `amount` tokens from `account`, reducing the\n     * total supply\n     */\n    function _burn(address account_, uint256 amount_) private {\n        if (account_ == address(0)) revert BurnFromTheZeroAddress();\n\n        address _msgSender = _msgSender();\n\n        if (_isProxyOFT(_msgSender)) {\n            totalBridgedOut += amount_;\n            if (bridgedOutSupply() > maxBridgedOutSupply) revert SurpassMaxBridgingSupply();\n        } else if (_isAmo(_msgSender)) {\n            amoSupply -= amount_;\n        }\n\n        uint256 _currentBalance = balanceOf[account_];\n        if (_currentBalance < amount_) revert BurnAmountExceedsBalance();\n        unchecked {\n            balanceOf[account_] = _currentBalance - amount_;\n            totalSupply -= amount_;\n        }\n\n        emit Transfer(account_, address(0), amount_);\n    }\n\n    /**\n     * @dev Check if the account is AMO\n     */\n    function _isAmo(address account_) private view returns (bool) {\n        return account_ == amo;\n    }\n\n    /**\n     * @dev Check if the account is proxyOFT\n     */\n    function _isProxyOFT(address account_) private view returns (bool) {\n        return account_ == address(proxyOFT);\n    }\n\n    /**\n     * @notice Check if the account is a valid DebtToken contract\n     */\n    function _isDebtToken(address account_) private view returns (bool) {\n        IPool _pool = IManageable(account_).pool();\n\n        return\n            _poolRegistry.isPoolRegistered(address(_pool)) &&\n            _pool.doesDebtTokenExist(IDebtToken(account_)) &&\n            IDebtToken(account_).syntheticToken() == this;\n    }\n\n    /**\n     * @notice Check if the account is a valid Pool contract\n     */\n    function _isPool(address account_) private view returns (bool) {\n        return _poolRegistry.isPoolRegistered(account_) && IPool(account_).doesSyntheticTokenExist(this);\n    }\n\n    /**\n     * @notice Create `amount` tokens and assigns them to `account`, increasing\n     * the total supply\n     */\n    function _mint(address account_, uint256 amount_) private onlyIfSyntheticTokenIsActive {\n        if (account_ == address(0)) revert MintToTheZeroAddress();\n\n        address _msgSender = _msgSender();\n\n        if (_isProxyOFT(_msgSender)) {\n            totalBridgedIn += amount_;\n            if (bridgedInSupply() > maxBridgedInSupply) revert SurpassMaxBridgingSupply();\n        } else if (_isAmo(_msgSender)) {\n            amoSupply += amount_;\n            if (amoSupply > maxAmoSupply) revert SurpassMaxAmoSupply();\n        }\n\n        totalSupply += amount_;\n        if (totalSupply > maxTotalSupply) revert SurpassMaxSynthSupply();\n        balanceOf[account_] += amount_;\n        emit Transfer(address(0), account_, amount_);\n    }\n\n    /**\n     * @notice Move `amount` of tokens from `sender` to `recipient`\n     */\n    function _transfer(address sender_, address recipient_, uint256 amount_) private {\n        if (sender_ == address(0)) revert TransferFromTheZeroAddress();\n        if (recipient_ == address(0)) revert TransferToTheZeroAddress();\n\n        uint256 senderBalance = balanceOf[sender_];\n        if (senderBalance < amount_) revert TransferAmountExceedsBalance();\n        unchecked {\n            balanceOf[sender_] = senderBalance - amount_;\n            balanceOf[recipient_] += amount_;\n        }\n\n        emit Transfer(sender_, recipient_, amount_);\n    }\n\n    /**\n     * @notice Enable/Disable Synthetic Token\n     */\n    function toggleIsActive() external override onlyGovernor {\n        bool _newIsActive = !isActive;\n        emit SyntheticTokenActiveUpdated(_newIsActive);\n        isActive = _newIsActive;\n    }\n\n    /**\n     * Update AMO (Automated Marker Operator)\n     * @param newAmo_ new AMO address\n     */\n    function updateAmo(address newAmo_) external onlyGovernor {\n        address _currentAmo = amo;\n        if (newAmo_ == _currentAmo) revert NewValueIsSameAsCurrent();\n        emit AmoUpdated(_currentAmo, newAmo_);\n        amo = newAmo_;\n    }\n\n    /**\n     * @notice Update max synth supply for AMO.\n     * @param newMaxAmoSupply_ The new max synth supply for AMO\n     */\n    function updateMaxAmoSupply(uint256 newMaxAmoSupply_) external onlyGovernor {\n        uint256 _currentMaxAmoSupply = maxAmoSupply;\n        if (newMaxAmoSupply_ == _currentMaxAmoSupply) revert NewValueIsSameAsCurrent();\n        emit MaxAmoSupplyUpdated(_currentMaxAmoSupply, newMaxAmoSupply_);\n        maxAmoSupply = newMaxAmoSupply_;\n    }\n\n    /**\n     * @notice Update max total supply\n     * @param newMaxTotalSupply_ The new max total supply\n     */\n    function updateMaxTotalSupply(uint256 newMaxTotalSupply_) external override onlyGovernor {\n        uint256 _currentMaxTotalSupply = maxTotalSupply;\n        if (newMaxTotalSupply_ == _currentMaxTotalSupply) revert NewValueIsSameAsCurrent();\n        emit MaxTotalSupplyUpdated(_currentMaxTotalSupply, newMaxTotalSupply_);\n        maxTotalSupply = newMaxTotalSupply_;\n    }\n\n    /**\n     * @notice Update max bridged-in supply\n     */\n    function updateMaxBridgedInSupply(uint256 maxBridgedInSupply_) external onlyGovernor {\n        uint256 _currentMaxBridgedInBalance = maxBridgedInSupply;\n        if (maxBridgedInSupply_ == _currentMaxBridgedInBalance) revert NewValueIsSameAsCurrent();\n        emit MaxBridgedInSupplyUpdated(_currentMaxBridgedInBalance, maxBridgedInSupply_);\n        maxBridgedInSupply = maxBridgedInSupply_;\n    }\n\n    /**\n     * @notice Update max bridged-out supply\n     */\n    function updateMaxBridgedOutSupply(uint256 maxBridgedOutSupply_) external onlyGovernor {\n        uint256 _currentMaxBridgedOutBalance = maxBridgedOutSupply;\n        if (maxBridgedOutSupply_ == _currentMaxBridgedOutBalance) revert NewValueIsSameAsCurrent();\n        emit MaxBridgedOutSupplyUpdated(_currentMaxBridgedOutBalance, maxBridgedOutSupply_);\n        maxBridgedOutSupply = maxBridgedOutSupply_;\n    }\n\n    /**\n     * @notice Update proxyOFT\n     * @param newProxyOFT_ Address of new ProxyOFT\n     */\n    function updateProxyOFT(IProxyOFT newProxyOFT_) external override onlyGovernor {\n        if (address(newProxyOFT_) == address(0)) revert AddressIsNull();\n        IProxyOFT _currentProxyOFT = proxyOFT;\n        if (newProxyOFT_ == _currentProxyOFT) revert NewValueIsSameAsCurrent();\n        emit ProxyOFTUpdated(_currentProxyOFT, newProxyOFT_);\n        proxyOFT = newProxyOFT_;\n    }\n\n    /// @inheritdoc SynthContext\n    function poolRegistry() public view override(ISyntheticToken, SynthContext) returns (IPoolRegistry) {\n        return _poolRegistry;\n    }\n}\n"},{"file_path":"contracts/dependencies/openzeppelin/proxy/Proxy.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/Proxy.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\n * be specified by overriding the virtual {_implementation} function.\n *\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\n * different contract through the {_delegate} function.\n *\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\n */\nabstract contract Proxy {\n    /**\n     * @dev Delegates the current call to `implementation`.\n     *\n     * This function does not return to its internal call site, it will return directly to the external caller.\n     */\n    function _delegate(address implementation) internal virtual {\n        assembly {\n            // Copy msg.data. We take full control of memory in this inline assembly\n            // block because it will not return to Solidity code. We overwrite the\n            // Solidity scratch pad at memory position 0.\n            calldatacopy(0, 0, calldatasize())\n\n            // Call the implementation.\n            // out and outsize are 0 because we don't know the size yet.\n            let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\n\n            // Copy the returned data.\n            returndatacopy(0, 0, returndatasize())\n\n            switch result\n            // delegatecall returns 0 on error.\n            case 0 {\n                revert(0, returndatasize())\n            }\n            default {\n                return(0, returndatasize())\n            }\n        }\n    }\n\n    /**\n     * @dev This is a virtual function that should be overridden so it returns the address to which the fallback function\n     * and {_fallback} should delegate.\n     */\n    function _implementation() internal view virtual returns (address);\n\n    /**\n     * @dev Delegates the current call to the address returned by `_implementation()`.\n     *\n     * This function does not return to its internal call site, it will return directly to the external caller.\n     */\n    function _fallback() internal virtual {\n        _beforeFallback();\n        _delegate(_implementation());\n    }\n\n    /**\n     * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\n     * function in the contract matches the call data.\n     */\n    fallback() external payable virtual {\n        _fallback();\n    }\n\n    /**\n     * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\n     * is empty.\n     */\n    receive() external payable virtual {\n        _fallback();\n    }\n\n    /**\n     * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\n     * call, or as part of the Solidity `fallback` or `receive` functions.\n     *\n     * If overridden should call `super._beforeFallback()`.\n     */\n    function _beforeFallback() internal virtual {}\n}\n"},{"file_path":"contracts/dependencies/openzeppelin/utils/math/SafeMath.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (utils/math/SafeMath.sol)\n\npragma solidity ^0.8.0;\n\n// CAUTION\n// This version of SafeMath should only be used with Solidity 0.8 or later,\n// because it relies on the compiler's built in overflow checks.\n\n/**\n * @dev Wrappers over Solidity's arithmetic operations.\n *\n * NOTE: `SafeMath` is generally not needed starting with Solidity 0.8, since the compiler\n * now has built in overflow checking.\n */\nlibrary SafeMath {\n    /**\n     * @dev Returns the addition of two unsigned integers, with an overflow flag.\n     *\n     * _Available since v3.4._\n     */\n    function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n        unchecked {\n            uint256 c = a + b;\n            if (c < a) return (false, 0);\n            return (true, c);\n        }\n    }\n\n    /**\n     * @dev Returns the subtraction of two unsigned integers, with an overflow flag.\n     *\n     * _Available since v3.4._\n     */\n    function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n        unchecked {\n            if (b > a) return (false, 0);\n            return (true, a - b);\n        }\n    }\n\n    /**\n     * @dev Returns the multiplication of two unsigned integers, with an overflow flag.\n     *\n     * _Available since v3.4._\n     */\n    function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n        unchecked {\n            // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\n            // benefit is lost if 'b' is also tested.\n            // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\n            if (a == 0) return (true, 0);\n            uint256 c = a * b;\n            if (c / a != b) return (false, 0);\n            return (true, c);\n        }\n    }\n\n    /**\n     * @dev Returns the division of two unsigned integers, with a division by zero flag.\n     *\n     * _Available since v3.4._\n     */\n    function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n        unchecked {\n            if (b == 0) return (false, 0);\n            return (true, a / b);\n        }\n    }\n\n    /**\n     * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.\n     *\n     * _Available since v3.4._\n     */\n    function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n        unchecked {\n            if (b == 0) return (false, 0);\n            return (true, a % b);\n        }\n    }\n\n    /**\n     * @dev Returns the addition of two unsigned integers, reverting on\n     * overflow.\n     *\n     * Counterpart to Solidity's `+` operator.\n     *\n     * Requirements:\n     *\n     * - Addition cannot overflow.\n     */\n    function add(uint256 a, uint256 b) internal pure returns (uint256) {\n        return a + b;\n    }\n\n    /**\n     * @dev Returns the subtraction of two unsigned integers, reverting on\n     * overflow (when the result is negative).\n     *\n     * Counterpart to Solidity's `-` operator.\n     *\n     * Requirements:\n     *\n     * - Subtraction cannot overflow.\n     */\n    function sub(uint256 a, uint256 b) internal pure returns (uint256) {\n        return a - b;\n    }\n\n    /**\n     * @dev Returns the multiplication of two unsigned integers, reverting on\n     * overflow.\n     *\n     * Counterpart to Solidity's `*` operator.\n     *\n     * Requirements:\n     *\n     * - Multiplication cannot overflow.\n     */\n    function mul(uint256 a, uint256 b) internal pure returns (uint256) {\n        return a * b;\n    }\n\n    /**\n     * @dev Returns the integer division of two unsigned integers, reverting on\n     * division by zero. The result is rounded towards zero.\n     *\n     * Counterpart to Solidity's `/` operator.\n     *\n     * Requirements:\n     *\n     * - The divisor cannot be zero.\n     */\n    function div(uint256 a, uint256 b) internal pure returns (uint256) {\n        return a / b;\n    }\n\n    /**\n     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n     * reverting when dividing by zero.\n     *\n     * Counterpart to Solidity's `%` operator. This function uses a `revert`\n     * opcode (which leaves remaining gas untouched) while Solidity uses an\n     * invalid opcode to revert (consuming all remaining gas).\n     *\n     * Requirements:\n     *\n     * - The divisor cannot be zero.\n     */\n    function mod(uint256 a, uint256 b) internal pure returns (uint256) {\n        return a % b;\n    }\n\n    /**\n     * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\n     * overflow (when the result is negative).\n     *\n     * CAUTION: This function is deprecated because it requires allocating memory for the error\n     * message unnecessarily. For custom revert reasons use {trySub}.\n     *\n     * Counterpart to Solidity's `-` operator.\n     *\n     * Requirements:\n     *\n     * - Subtraction cannot overflow.\n     */\n    function sub(\n        uint256 a,\n        uint256 b,\n        string memory errorMessage\n    ) internal pure returns (uint256) {\n        unchecked {\n            require(b <= a, errorMessage);\n            return a - b;\n        }\n    }\n\n    /**\n     * @dev Returns the integer division of two unsigned integers, reverting with custom message on\n     * division by zero. The result is rounded towards zero.\n     *\n     * Counterpart to Solidity's `/` operator. Note: this function uses a\n     * `revert` opcode (which leaves remaining gas untouched) while Solidity\n     * uses an invalid opcode to revert (consuming all remaining gas).\n     *\n     * Requirements:\n     *\n     * - The divisor cannot be zero.\n     */\n    function div(\n        uint256 a,\n        uint256 b,\n        string memory errorMessage\n    ) internal pure returns (uint256) {\n        unchecked {\n            require(b > 0, errorMessage);\n            return a / b;\n        }\n    }\n\n    /**\n     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n     * reverting with custom message when dividing by zero.\n     *\n     * CAUTION: This function is deprecated because it requires allocating memory for the error\n     * message unnecessarily. For custom revert reasons use {tryMod}.\n     *\n     * Counterpart to Solidity's `%` operator. This function uses a `revert`\n     * opcode (which leaves remaining gas untouched) while Solidity uses an\n     * invalid opcode to revert (consuming all remaining gas).\n     *\n     * Requirements:\n     *\n     * - The divisor cannot be zero.\n     */\n    function mod(\n        uint256 a,\n        uint256 b,\n        string memory errorMessage\n    ) internal pure returns (uint256) {\n        unchecked {\n            require(b > 0, errorMessage);\n            return a % b;\n        }\n    }\n}\n"},{"file_path":"contracts/dependencies/openzeppelin/utils/Address.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n    /**\n     * @dev Returns true if `account` is a contract.\n     *\n     * [IMPORTANT]\n     * ====\n     * It is unsafe to assume that an address for which this function returns\n     * false is an externally-owned account (EOA) and not a contract.\n     *\n     * Among others, `isContract` will return false for the following\n     * types of addresses:\n     *\n     *  - an externally-owned account\n     *  - a contract in construction\n     *  - an address where a contract will be created\n     *  - an address where a contract lived, but was destroyed\n     * ====\n     *\n     * [IMPORTANT]\n     * ====\n     * You shouldn't rely on `isContract` to protect against flash loan attacks!\n     *\n     * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n     * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n     * constructor.\n     * ====\n     */\n    function isContract(address account) internal view returns (bool) {\n        // This method relies on extcodesize/address.code.length, which returns 0\n        // for contracts in construction, since the code is only stored at the end\n        // of the constructor execution.\n\n        return account.code.length > 0;\n    }\n\n    /**\n     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n     * `recipient`, forwarding all available gas and reverting on errors.\n     *\n     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n     * of certain opcodes, possibly making contracts go over the 2300 gas limit\n     * imposed by `transfer`, making them unable to receive funds via\n     * `transfer`. {sendValue} removes this limitation.\n     *\n     * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n     *\n     * IMPORTANT: because control is transferred to `recipient`, care must be\n     * taken to not create reentrancy vulnerabilities. Consider using\n     * {ReentrancyGuard} or the\n     * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n     */\n    function sendValue(address payable recipient, uint256 amount) internal {\n        require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n        (bool success, ) = recipient.call{value: amount}(\"\");\n        require(success, \"Address: unable to send value, recipient may have reverted\");\n    }\n\n    /**\n     * @dev Performs a Solidity function call using a low level `call`. A\n     * plain `call` is an unsafe replacement for a function call: use this\n     * function instead.\n     *\n     * If `target` reverts with a revert reason, it is bubbled up by this\n     * function (like regular Solidity function calls).\n     *\n     * Returns the raw returned data. To convert to the expected return value,\n     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n     *\n     * Requirements:\n     *\n     * - `target` must be a contract.\n     * - calling `target` with `data` must not revert.\n     *\n     * _Available since v3.1._\n     */\n    function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n        return functionCall(target, data, \"Address: low-level call failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n     * `errorMessage` as a fallback revert reason when `target` reverts.\n     *\n     * _Available since v3.1._\n     */\n    function functionCall(\n        address target,\n        bytes memory data,\n        string memory errorMessage\n    ) internal returns (bytes memory) {\n        return functionCallWithValue(target, data, 0, errorMessage);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but also transferring `value` wei to `target`.\n     *\n     * Requirements:\n     *\n     * - the calling contract must have an ETH balance of at least `value`.\n     * - the called Solidity function must be `payable`.\n     *\n     * _Available since v3.1._\n     */\n    function functionCallWithValue(\n        address target,\n        bytes memory data,\n        uint256 value\n    ) internal returns (bytes memory) {\n        return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n     * with `errorMessage` as a fallback revert reason when `target` reverts.\n     *\n     * _Available since v3.1._\n     */\n    function functionCallWithValue(\n        address target,\n        bytes memory data,\n        uint256 value,\n        string memory errorMessage\n    ) internal returns (bytes memory) {\n        require(address(this).balance >= value, \"Address: insufficient balance for call\");\n        require(isContract(target), \"Address: call to non-contract\");\n\n        (bool success, bytes memory returndata) = target.call{value: value}(data);\n        return verifyCallResult(success, returndata, errorMessage);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but performing a static call.\n     *\n     * _Available since v3.3._\n     */\n    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n        return functionStaticCall(target, data, \"Address: low-level static call failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n     * but performing a static call.\n     *\n     * _Available since v3.3._\n     */\n    function functionStaticCall(\n        address target,\n        bytes memory data,\n        string memory errorMessage\n    ) internal view returns (bytes memory) {\n        require(isContract(target), \"Address: static call to non-contract\");\n\n        (bool success, bytes memory returndata) = target.staticcall(data);\n        return verifyCallResult(success, returndata, errorMessage);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but performing a delegate call.\n     *\n     * _Available since v3.4._\n     */\n    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n        return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n     * but performing a delegate call.\n     *\n     * _Available since v3.4._\n     */\n    function functionDelegateCall(\n        address target,\n        bytes memory data,\n        string memory errorMessage\n    ) internal returns (bytes memory) {\n        require(isContract(target), \"Address: delegate call to non-contract\");\n\n        (bool success, bytes memory returndata) = target.delegatecall(data);\n        return verifyCallResult(success, returndata, errorMessage);\n    }\n\n    /**\n     * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n     * revert reason using the provided one.\n     *\n     * _Available since v4.3._\n     */\n    function verifyCallResult(\n        bool success,\n        bytes memory returndata,\n        string memory errorMessage\n    ) internal pure returns (bytes memory) {\n        if (success) {\n            return returndata;\n        } else {\n            // Look for revert reason and bubble it up if present\n            if (returndata.length > 0) {\n                // The easiest way to bubble the revert reason is using memory via assembly\n\n                assembly {\n                    let returndata_size := mload(returndata)\n                    revert(add(32, returndata), returndata_size)\n                }\n            } else {\n                revert(errorMessage);\n            }\n        }\n    }\n}\n"},{"file_path":"contracts/dependencies/openzeppelin-upgradeable/proxy/utils/Initializable.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../../utils/AddressUpgradeable.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n *     function initialize() initializer public {\n *         __ERC20_init(\"MyToken\", \"MTK\");\n *     }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n *     function initializeV2() reinitializer(2) public {\n *         __ERC20Permit_init(\"MyToken\");\n *     }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n *     _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n    /**\n     * @dev Indicates that the contract has been initialized.\n     * @custom:oz-retyped-from bool\n     */\n    uint8 private _initialized;\n\n    /**\n     * @dev Indicates that the contract is in the process of being initialized.\n     */\n    bool private _initializing;\n\n    /**\n     * @dev Triggered when the contract has been initialized or reinitialized.\n     */\n    event Initialized(uint8 version);\n\n    /**\n     * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n     * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n     */\n    modifier initializer() {\n        bool isTopLevelCall = _setInitializedVersion(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     * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n     * initialization step. This is essential to configure modules that are added through upgrades and that require\n     * initialization.\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    modifier reinitializer(uint8 version) {\n        bool isTopLevelCall = _setInitializedVersion(version);\n        if (isTopLevelCall) {\n            _initializing = true;\n        }\n        _;\n        if (isTopLevelCall) {\n            _initializing = false;\n            emit Initialized(version);\n        }\n    }\n\n    /**\n     * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n     * {initializer} and {reinitializer} modifiers, directly or indirectly.\n     */\n    modifier onlyInitializing() {\n        require(_initializing, \"Initializable: contract is not initializing\");\n        _;\n    }\n\n    /**\n     * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n     * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n     * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n     * through proxies.\n     */\n    function _disableInitializers() internal virtual {\n        _setInitializedVersion(type(uint8).max);\n    }\n\n    function _setInitializedVersion(uint8 version) private returns (bool) {\n        // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n        // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n        // of initializers, because in other contexts the contract may have been reentered.\n        if (_initializing) {\n            require(\n                version == 1 && !AddressUpgradeable.isContract(address(this)),\n                \"Initializable: contract is already initialized\"\n            );\n            return false;\n        } else {\n            require(_initialized < version, \"Initializable: contract is already initialized\");\n            _initialized = version;\n            return true;\n        }\n    }\n}\n"},{"file_path":"contracts/MetAirdrop.sol","source_code":"// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.24;\n\nimport {SafeERC20} from \"./dependencies/openzeppelin/token/ERC20/utils/SafeERC20.sol\";\nimport {IERC20} from \"./dependencies/openzeppelin/token/ERC20/IERC20.sol\";\nimport {Math} from \"./dependencies/openzeppelin/utils/math/Math.sol\";\nimport {RecurringAirdrop} from \"./utils/RecurringAirdrop.sol\";\nimport {IESMET} from \"./interfaces/external/IESMET.sol\";\n\n/**\n * @title MET Airdrop contract\n */\ncontract MetAirdrop is RecurringAirdrop {\n    using SafeERC20 for IERC20;\n    using Math for uint256;\n\n    IESMET public constant ESMET = IESMET(0xA28D70795a61Dc925D4c220762A4344803876bb8);\n    IERC20 public constant MET = IERC20(0x2Ebd53d035150f328bd754D6DC66B99B0eDB89aa);\n\n    /// @notice For how long `MET` tokens will be locked\n    uint256 public lockPeriod = 7 days;\n\n    constructor() RecurringAirdrop(MET) {}\n\n    /**\n     * @inheritdoc RecurringAirdrop\n     * @dev Locks the `MET` into `esMET` on user's behalf.\n     * The `lockPeriod` starts from the current merkle root update (i.e. `updatedAt`)\n     */\n    function _transferReward(address to_, uint256 amount_) internal override {\n        uint256 _end = updatedAt + lockPeriod;\n\n        if (_end < block.timestamp) {\n            MET.safeTransfer(to_, amount_);\n            return;\n        }\n\n        uint256 _min = ESMET.MINIMUM_LOCK_PERIOD() + 1;\n        uint256 _max = ESMET.MAXIMUM_LOCK_PERIOD();\n\n        // Ensures valid lock period\n        uint256 _remainLockPeriod = Math.min(Math.max(_end - block.timestamp, _min), _max);\n\n        token.safeApprove(address(ESMET), 0);\n        token.safeApprove(address(ESMET), amount_);\n        ESMET.lockFor(to_, amount_, _remainLockPeriod);\n    }\n\n    /**\n     * @notice Update esMET lock period\n     * @param lockPeriod_ The new value\n     */\n    function updateLockPeriod(uint256 lockPeriod_) public onlyGovernor {\n        lockPeriod = lockPeriod_;\n    }\n}\n"},{"file_path":"contracts/mock/PauseableMock.sol","source_code":"// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.24;\n\nimport {Pauseable} from \"../utils/Pauseable.sol\";\n\ncontract PauseableMock is Pauseable {\n    mapping(address => bool) internal _isGuardian;\n\n    function setGuardian(address address_, bool isGuardian_) external {\n        _isGuardian[address_] = isGuardian_;\n    }\n\n    function isGuardian(address sender_) public view override returns (bool) {\n        return _isGuardian[sender_];\n    }\n}\n"},{"file_path":"contracts/dependencies/@layerzerolabs/solidity-examples/libraries/LzLib.sol","source_code":"// SPDX-License-Identifier: BUSL-1.1\n\npragma solidity >=0.6.0;\npragma experimental ABIEncoderV2;\n\nlibrary LzLib {\n    // LayerZero communication\n    struct CallParams {\n        address payable refundAddress;\n        address zroPaymentAddress;\n    }\n\n    //---------------------------------------------------------------------------\n    // Address type handling\n\n    struct AirdropParams {\n        uint airdropAmount;\n        bytes32 airdropAddress;\n    }\n\n    function buildAdapterParams(\n        LzLib.AirdropParams memory _airdropParams,\n        uint _uaGasLimit\n    ) internal pure returns (bytes memory adapterParams) {\n        if (_airdropParams.airdropAmount == 0 && _airdropParams.airdropAddress == bytes32(0x0)) {\n            adapterParams = buildDefaultAdapterParams(_uaGasLimit);\n        } else {\n            adapterParams = buildAirdropAdapterParams(_uaGasLimit, _airdropParams);\n        }\n    }\n\n    // Build Adapter Params\n    function buildDefaultAdapterParams(uint _uaGas) internal pure returns (bytes memory) {\n        // txType 1\n        // bytes  [2       32      ]\n        // fields [txType  extraGas]\n        return abi.encodePacked(uint16(1), _uaGas);\n    }\n\n    function buildAirdropAdapterParams(uint _uaGas, AirdropParams memory _params) internal pure returns (bytes memory) {\n        require(_params.airdropAmount > 0, \"Airdrop amount must be greater than 0\");\n        require(_params.airdropAddress != bytes32(0x0), \"Airdrop address must be set\");\n\n        // txType 2\n        // bytes  [2       32        32            bytes[]         ]\n        // fields [txType  extraGas  dstNativeAmt  dstNativeAddress]\n        return abi.encodePacked(uint16(2), _uaGas, _params.airdropAmount, _params.airdropAddress);\n    }\n\n    function getGasLimit(bytes memory _adapterParams) internal pure returns (uint gasLimit) {\n        require(_adapterParams.length == 34 || _adapterParams.length > 66, \"Invalid adapterParams\");\n        assembly {\n            gasLimit := mload(add(_adapterParams, 34))\n        }\n    }\n\n    // Decode Adapter Params\n    function decodeAdapterParams(\n        bytes memory _adapterParams\n    ) internal pure returns (uint16 txType, uint uaGas, uint airdropAmount, address payable airdropAddress) {\n        require(_adapterParams.length == 34 || _adapterParams.length > 66, \"Invalid adapterParams\");\n        assembly {\n            txType := mload(add(_adapterParams, 2))\n            uaGas := mload(add(_adapterParams, 34))\n        }\n        require(txType == 1 || txType == 2, \"Unsupported txType\");\n        require(uaGas > 0, \"Gas too low\");\n\n        if (txType == 2) {\n            assembly {\n                airdropAmount := mload(add(_adapterParams, 66))\n                airdropAddress := mload(add(_adapterParams, 86))\n            }\n        }\n    }\n\n    //---------------------------------------------------------------------------\n    // Address type handling\n    function bytes32ToAddress(bytes32 _bytes32Address) internal pure returns (address _address) {\n        return address(uint160(uint(_bytes32Address)));\n    }\n\n    function addressToBytes32(address _address) internal pure returns (bytes32 _bytes32Address) {\n        return bytes32(uint(uint160(_address)));\n    }\n}\n"},{"file_path":"contracts/dependencies/openzeppelin-upgradeable/utils/AddressUpgradeable.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n    /**\n     * @dev Returns true if `account` is a contract.\n     *\n     * [IMPORTANT]\n     * ====\n     * It is unsafe to assume that an address for which this function returns\n     * false is an externally-owned account (EOA) and not a contract.\n     *\n     * Among others, `isContract` will return false for the following\n     * types of addresses:\n     *\n     *  - an externally-owned account\n     *  - a contract in construction\n     *  - an address where a contract will be created\n     *  - an address where a contract lived, but was destroyed\n     * ====\n     *\n     * [IMPORTANT]\n     * ====\n     * You shouldn't rely on `isContract` to protect against flash loan attacks!\n     *\n     * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n     * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n     * constructor.\n     * ====\n     */\n    function isContract(address account) internal view returns (bool) {\n        // This method relies on extcodesize/address.code.length, which returns 0\n        // for contracts in construction, since the code is only stored at the end\n        // of the constructor execution.\n\n        return account.code.length > 0;\n    }\n\n    /**\n     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n     * `recipient`, forwarding all available gas and reverting on errors.\n     *\n     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n     * of certain opcodes, possibly making contracts go over the 2300 gas limit\n     * imposed by `transfer`, making them unable to receive funds via\n     * `transfer`. {sendValue} removes this limitation.\n     *\n     * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n     *\n     * IMPORTANT: because control is transferred to `recipient`, care must be\n     * taken to not create reentrancy vulnerabilities. Consider using\n     * {ReentrancyGuard} or the\n     * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n     */\n    function sendValue(address payable recipient, uint256 amount) internal {\n        require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n        (bool success, ) = recipient.call{value: amount}(\"\");\n        require(success, \"Address: unable to send value, recipient may have reverted\");\n    }\n\n    /**\n     * @dev Performs a Solidity function call using a low level `call`. A\n     * plain `call` is an unsafe replacement for a function call: use this\n     * function instead.\n     *\n     * If `target` reverts with a revert reason, it is bubbled up by this\n     * function (like regular Solidity function calls).\n     *\n     * Returns the raw returned data. To convert to the expected return value,\n     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n     *\n     * Requirements:\n     *\n     * - `target` must be a contract.\n     * - calling `target` with `data` must not revert.\n     *\n     * _Available since v3.1._\n     */\n    function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n        return functionCall(target, data, \"Address: low-level call failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n     * `errorMessage` as a fallback revert reason when `target` reverts.\n     *\n     * _Available since v3.1._\n     */\n    function functionCall(\n        address target,\n        bytes memory data,\n        string memory errorMessage\n    ) internal returns (bytes memory) {\n        return functionCallWithValue(target, data, 0, errorMessage);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but also transferring `value` wei to `target`.\n     *\n     * Requirements:\n     *\n     * - the calling contract must have an ETH balance of at least `value`.\n     * - the called Solidity function must be `payable`.\n     *\n     * _Available since v3.1._\n     */\n    function functionCallWithValue(\n        address target,\n        bytes memory data,\n        uint256 value\n    ) internal returns (bytes memory) {\n        return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n     * with `errorMessage` as a fallback revert reason when `target` reverts.\n     *\n     * _Available since v3.1._\n     */\n    function functionCallWithValue(\n        address target,\n        bytes memory data,\n        uint256 value,\n        string memory errorMessage\n    ) internal returns (bytes memory) {\n        require(address(this).balance >= value, \"Address: insufficient balance for call\");\n        require(isContract(target), \"Address: call to non-contract\");\n\n        (bool success, bytes memory returndata) = target.call{value: value}(data);\n        return verifyCallResult(success, returndata, errorMessage);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but performing a static call.\n     *\n     * _Available since v3.3._\n     */\n    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n        return functionStaticCall(target, data, \"Address: low-level static call failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n     * but performing a static call.\n     *\n     * _Available since v3.3._\n     */\n    function functionStaticCall(\n        address target,\n        bytes memory data,\n        string memory errorMessage\n    ) internal view returns (bytes memory) {\n        require(isContract(target), \"Address: static call to non-contract\");\n\n        (bool success, bytes memory returndata) = target.staticcall(data);\n        return verifyCallResult(success, returndata, errorMessage);\n    }\n\n    /**\n     * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n     * revert reason using the provided one.\n     *\n     * _Available since v4.3._\n     */\n    function verifyCallResult(\n        bool success,\n        bytes memory returndata,\n        string memory errorMessage\n    ) internal pure returns (bytes memory) {\n        if (success) {\n            return returndata;\n        } else {\n            // Look for revert reason and bubble it up if present\n            if (returndata.length > 0) {\n                // The easiest way to bubble the revert reason is using memory via assembly\n\n                assembly {\n                    let returndata_size := mload(returndata)\n                    revert(add(32, returndata), returndata_size)\n                }\n            } else {\n                revert(errorMessage);\n            }\n        }\n    }\n}\n"},{"file_path":"contracts/interfaces/external/IMasterOracle.sol","source_code":"// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.24;\n\ninterface IMasterOracle {\n    function quoteTokenToUsd(address _asset, uint256 _amount) external view returns (uint256 _amountInUsd);\n\n    function quoteUsdToToken(address _asset, uint256 _amountInUsd) external view returns (uint256 _amount);\n\n    function quote(address _assetIn, address _assetOut, uint256 _amountIn) external view returns (uint256 _amountOut);\n}\n"},{"file_path":"contracts/mock/TokenHolderMock.sol","source_code":"// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.24;\n\nimport {TokenHolder} from \"../utils/TokenHolder.sol\";\n\ncontract TokenHolderMock is TokenHolder {\n    address public sweeper;\n    bool public acceptETH;\n\n    constructor(address _sweeper) {\n        sweeper = _sweeper;\n    }\n\n    function _requireCanSweep() internal view override {\n        require(msg.sender == sweeper, \"not-sweeper\");\n    }\n\n    function toggleAcceptETH() public {\n        acceptETH = !acceptETH;\n    }\n\n    receive() external payable override {\n        require(acceptETH, \"not-allowed-to-receive-eth\");\n    }\n}\n"},{"file_path":"contracts/dependencies/openzeppelin/security/ReentrancyGuard.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Contract module that helps prevent reentrant calls to a function.\n *\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\n * available, which can be applied to functions to make sure there are no nested\n * (reentrant) calls to them.\n *\n * Note that because there is a single `nonReentrant` guard, functions marked as\n * `nonReentrant` may not call one another. This can be worked around by making\n * those functions `private`, and then adding `external` `nonReentrant` entry\n * points to them.\n *\n * TIP: If you would like to learn more about reentrancy and alternative ways\n * to protect against it, check out our blog post\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\n */\nabstract contract ReentrancyGuard {\n    // Booleans are more expensive than uint256 or any type that takes up a full\n    // word because each write operation emits an extra SLOAD to first read the\n    // slot's contents, replace the bits taken up by the boolean, and then write\n    // back. This is the compiler's defense against contract upgrades and\n    // pointer aliasing, and it cannot be disabled.\n\n    // The values being non-zero value makes deployment a bit more expensive,\n    // but in exchange the refund on every call to nonReentrant will be lower in\n    // amount. Since refunds are capped to a percentage of the total\n    // transaction's gas, it is best to keep them low in cases like this one, to\n    // increase the likelihood of the full refund coming into effect.\n    uint256 private constant _NOT_ENTERED = 1;\n    uint256 private constant _ENTERED = 2;\n\n    uint256 private _status;\n\n    constructor() {\n        _status = _NOT_ENTERED;\n    }\n\n    /**\n     * @dev Prevents a contract from calling itself, directly or indirectly.\n     * Calling a `nonReentrant` function from another `nonReentrant`\n     * function is not supported. It is possible to prevent this from happening\n     * by making the `nonReentrant` function external, and making it call a\n     * `private` function that does the actual work.\n     */\n    modifier nonReentrant() {\n        // On the first call to nonReentrant, _notEntered will be true\n        require(_status != _ENTERED, \"ReentrancyGuard: reentrant call\");\n\n        // Any calls to nonReentrant after this point will fail\n        _status = _ENTERED;\n\n        _;\n\n        // By storing the original value once again, a refund is triggered (see\n        // https://eips.ethereum.org/EIPS/eip-2200)\n        _status = _NOT_ENTERED;\n    }\n}\n"},{"file_path":"contracts/dependencies/openzeppelin-upgradeable/utils/introspection/IERC165Upgradeable.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165Upgradeable {\n    /**\n     * @dev Returns true if this contract implements the interface defined by\n     * `interfaceId`. See the corresponding\n     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n     * to learn more about how these ids are created.\n     *\n     * This function call must use less than 30 000 gas.\n     */\n    function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n"},{"file_path":"contracts/dependencies/openzeppelin/utils/math/Math.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary Math {\n    /**\n     * @dev Returns the largest of two numbers.\n     */\n    function max(uint256 a, uint256 b) internal pure returns (uint256) {\n        return 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 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        // (a + b) / 2 can overflow.\n        return (a & b) + (a ^ b) / 2;\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 up instead\n     * of rounding down.\n     */\n    function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n        // (a + b - 1) / b can overflow on addition, so we distribute.\n        return a / b + (a % b == 0 ? 0 : 1);\n    }\n}\n"},{"file_path":"contracts/storage/TreasuryStorage.sol","source_code":"// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.24;\n\nimport {ITreasury} from \"../interfaces/ITreasury.sol\";\n\n// solhint-disable-next-line no-empty-blocks\nabstract contract TreasuryStorageV1 is ITreasury {\n\n}\n"},{"file_path":"contracts/dependencies/openzeppelin/utils/structs/EnumerableSet.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (utils/structs/EnumerableSet.sol)\n\npragma solidity ^0.8.0;\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 *\n * ```\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 * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\n * and `uint256` (`UintSet`) are supported.\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 of the value in the `values` array, plus 1 because index 0\n        // means a value is not in the set.\n        mapping(bytes32 => uint256) _indexes;\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._indexes[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 read and store the value's index to prevent multiple reads from the same storage slot\n        uint256 valueIndex = set._indexes[value];\n\n        if (valueIndex != 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 toDeleteIndex = valueIndex - 1;\n            uint256 lastIndex = set._values.length - 1;\n\n            if (lastIndex != toDeleteIndex) {\n                bytes32 lastValue = set._values[lastIndex];\n\n                // Move the last value to the index where the value to delete is\n                set._values[toDeleteIndex] = lastValue;\n                // Update the index for the moved value\n                set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n            }\n\n            // Delete the slot where the moved value was stored\n            set._values.pop();\n\n            // Delete the index for the deleted slot\n            delete set._indexes[value];\n\n            return true;\n        } else {\n            return false;\n        }\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._indexes[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    // 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 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        return _values(set._inner);\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 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 {\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 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 on 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 {\n            result := store\n        }\n\n        return result;\n    }\n}\n"},{"file_path":"contracts/interfaces/IProxyOFT.sol","source_code":"// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.24;\n\nimport {IComposableOFTCoreUpgradeable} from \"../dependencies/@layerzerolabs/solidity-examples/contracts-upgradeable/token/oft/composable/IComposableOFTCoreUpgradeable.sol\";\n\ninterface IProxyOFT is IComposableOFTCoreUpgradeable {\n    function getProxyOFTOf(uint16 chainId_) external view returns (address _proxyOFT);\n\n    function approvalRequired() external view returns (bool);\n\n    function oftFee() external view returns (uint256);\n\n    function quoteSendFromIn(uint256 amountOut_) external view returns (uint256 _amountIn, uint256 _fee);\n\n    function quoteSendFromOut(uint256 amountIn_) external view returns (uint256 _amountOut, uint256 _fee);\n\n    function updateOftFee(uint256 newOftFee_) external;\n}\n"},{"file_path":"contracts/interfaces/IPoolRegistry.sol","source_code":"// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.24;\n\nimport {IMasterOracle} from \"./external/IMasterOracle.sol\";\nimport {IPauseable} from \"./IPauseable.sol\";\nimport {IGovernable} from \"./IGovernable.sol\";\nimport {ISyntheticToken} from \"./ISyntheticToken.sol\";\nimport {ISwapper} from \"./external/ISwapper.sol\";\nimport {IOperator} from \"./IOperator.sol\";\n\ninterface IPoolRegistry is IPauseable, IGovernable {\n    function feeCollector() external view returns (address);\n\n    function isPoolRegistered(address pool_) external view returns (bool);\n\n    function nativeTokenGateway() external view returns (address);\n\n    function getPools() external view returns (address[] memory);\n\n    function registerPool(address pool_) external;\n\n    function unregisterPool(address pool_) external;\n\n    function masterOracle() external view returns (IMasterOracle);\n\n    function updateFeeCollector(address newFeeCollector_) external;\n\n    function idOfPool(address pool_) external view returns (uint256);\n\n    function nextPoolId() external view returns (uint256);\n\n    function swapper() external view returns (ISwapper);\n\n    function doesSyntheticTokenExist(ISyntheticToken syntheticToken_) external view returns (bool _exists);\n\n    function operator() external view returns (IOperator);\n\n    function isGuardian(address) external view returns (bool);\n\n    function isBridgingActive() external view returns (bool);\n\n    function lzBaseGasLimit() external view returns (uint256);\n\n    function isDestinationChainSupported(uint16 dstChainId_) external view returns (bool);\n}\n"},{"file_path":"contracts/dependencies/@layerzerolabs/solidity-examples/token/oft/composable/IComposableOFTCore.sol","source_code":"// SPDX-License-Identifier: MIT\n\npragma solidity >=0.5.0;\n\nimport \"../IOFTCore.sol\";\n\n/**\n * @dev Interface of the composable OFT core standard\n */\ninterface IComposableOFTCore is IOFTCore {\n    function estimateSendAndCallFee(\n        uint16 _dstChainId,\n        bytes calldata _toAddress,\n        uint _amount,\n        bytes calldata _payload,\n        uint64 _dstGasForCall,\n        bool _useZro,\n        bytes calldata _adapterParams\n    ) external view returns (uint nativeFee, uint zroFee);\n\n    function sendAndCall(\n        address _from,\n        uint16 _dstChainId,\n        bytes calldata _toAddress,\n        uint _amount,\n        bytes calldata _payload,\n        uint64 _dstGasForCall,\n        address payable _refundAddress,\n        address _zroPaymentAddress,\n        bytes calldata _adapterParams\n    ) external payable;\n\n    function retryOFTReceived(\n        uint16 _srcChainId,\n        bytes calldata _srcAddress,\n        uint64 _nonce,\n        bytes calldata _from,\n        address _to,\n        uint _amount,\n        bytes calldata _payload\n    ) external;\n\n    event CallOFTReceivedFailure(\n        uint16 indexed _srcChainId,\n        bytes _srcAddress,\n        uint64 _nonce,\n        bytes _from,\n        address indexed _to,\n        uint _amount,\n        bytes _payload,\n        bytes _reason\n    );\n\n    event CallOFTReceivedSuccess(uint16 indexed _srcChainId, bytes _srcAddress, uint64 _nonce, bytes32 _hash);\n\n    event RetryOFTReceivedSuccess(bytes32 _messageHash);\n\n    event NonContractAddress(address _address);\n}\n"},{"file_path":"contracts/interfaces/IVesperGateway.sol","source_code":"// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.24;\n\nimport {IPool} from \"./IPool.sol\";\nimport {IVPool} from \"./external/IVPool.sol\";\n\ninterface IVesperGateway {\n    function deposit(IPool pool_, IVPool vToken_, uint256 amount_) external;\n\n    function withdraw(IPool pool_, IVPool vToken_, uint256 amount_) external;\n}\n"},{"file_path":"contracts/dependencies/@layerzerolabs/solidity-examples/contracts-upgradeable/token/oft/composable/ComposableOFTCoreUpgradeable.sol","source_code":"// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../OFTCoreUpgradeable.sol\";\nimport \"./IOFTReceiverUpgradeable.sol\";\nimport \"./IComposableOFTCoreUpgradeable.sol\";\nimport \"../../../../util/ExcessivelySafeCall.sol\";\n\nabstract contract ComposableOFTCoreUpgradeable is OFTCoreUpgradeable, IComposableOFTCoreUpgradeable {\n    using ExcessivelySafeCall for address;\n    using BytesLib for bytes;\n\n    // packet type\n    uint16 public constant PT_SEND_AND_CALL = 1;\n\n    mapping(uint16 => mapping(bytes => mapping(uint64 => bytes32))) public failedOFTReceivedMessages;\n\n    function __ComposableOFTCoreUpgradeable_init(address _lzEndpoint) internal onlyInitializing {\n        __OFTCoreUpgradeable_init(_lzEndpoint);\n    }\n\n    function __ComposableOFTCoreUpgradeable_init_unchained() internal onlyInitializing {}\n\n    function supportsInterface(\n        bytes4 interfaceId\n    ) public view virtual override(OFTCoreUpgradeable, IERC165Upgradeable) returns (bool) {\n        return interfaceId == type(IComposableOFTCoreUpgradeable).interfaceId || super.supportsInterface(interfaceId);\n    }\n\n    function estimateSendAndCallFee(\n        uint16 _dstChainId,\n        bytes calldata _toAddress,\n        uint _amount,\n        bytes calldata _payload,\n        uint64 _dstGasForCall,\n        bool _useZro,\n        bytes calldata _adapterParams\n    ) public view virtual override returns (uint nativeFee, uint zroFee) {\n        // mock the payload for sendAndCall()\n        bytes memory payload = abi.encode(\n            PT_SEND_AND_CALL,\n            abi.encodePacked(_msgSender()),\n            _toAddress,\n            _amount,\n            _payload,\n            _dstGasForCall\n        );\n        return lzEndpoint.estimateFees(_dstChainId, address(this), payload, _useZro, _adapterParams);\n    }\n\n    function sendAndCall(\n        address _from,\n        uint16 _dstChainId,\n        bytes calldata _toAddress,\n        uint _amount,\n        bytes calldata _payload,\n        uint64 _dstGasForCall,\n        address payable _refundAddress,\n        address _zroPaymentAddress,\n        bytes calldata _adapterParams\n    ) public payable virtual override {\n        _sendAndCall(\n            _from,\n            _dstChainId,\n            _toAddress,\n            _amount,\n            _payload,\n            _dstGasForCall,\n            _refundAddress,\n            _zroPaymentAddress,\n            _adapterParams\n        );\n    }\n\n    function retryOFTReceived(\n        uint16 _srcChainId,\n        bytes calldata _srcAddress,\n        uint64 _nonce,\n        bytes calldata _from,\n        address _to,\n        uint _amount,\n        bytes calldata _payload\n    ) public virtual override {\n        bytes32 msgHash = failedOFTReceivedMessages[_srcChainId][_srcAddress][_nonce];\n        require(msgHash != bytes32(0), \"ComposableOFTCore: no failed message to retry\");\n\n        bytes32 hash = keccak256(abi.encode(_from, _to, _amount, _payload));\n        require(hash == msgHash, \"ComposableOFTCore: failed message hash mismatch\");\n\n        delete failedOFTReceivedMessages[_srcChainId][_srcAddress][_nonce];\n        IOFTReceiverUpgradeable(_to).onOFTReceived(_srcChainId, _srcAddress, _nonce, _from, _amount, _payload);\n        emit RetryOFTReceivedSuccess(hash);\n    }\n\n    function _nonblockingLzReceive(\n        uint16 _srcChainId,\n        bytes memory _srcAddress,\n        uint64 _nonce,\n        bytes memory _payload\n    ) internal virtual override {\n        uint16 packetType;\n        assembly {\n            packetType := mload(add(_payload, 32))\n        }\n\n        if (packetType == PT_SEND) {\n            _sendAck(_srcChainId, _srcAddress, _nonce, _payload);\n        } else if (packetType == PT_SEND_AND_CALL) {\n            _sendAndCallAck(_srcChainId, _srcAddress, _nonce, _payload);\n        } else {\n            revert(\"ComposableOFTCore: unknown packet type\");\n        }\n    }\n\n    function _sendAndCall(\n        address _from,\n        uint16 _dstChainId,\n        bytes memory _toAddress,\n        uint _amount,\n        bytes calldata _payload,\n        uint64 _dstGasForCall,\n        address payable _refundAddress,\n        address _zroPaymentAddress,\n        bytes memory _adapterParams\n    ) internal virtual {\n        _checkAdapterParams(_dstChainId, PT_SEND_AND_CALL, _adapterParams, _dstGasForCall);\n\n        uint amount = _debitFrom(_from, _dstChainId, _toAddress, _amount);\n\n        bytes memory lzPayload = abi.encode(\n            PT_SEND_AND_CALL,\n            abi.encodePacked(_msgSender()),\n            _toAddress,\n            amount,\n            _payload,\n            _dstGasForCall\n        );\n        _lzSend(_dstChainId, lzPayload, _refundAddress, _zroPaymentAddress, _adapterParams, msg.value);\n\n        emit SendToChain(_dstChainId, _from, _toAddress, amount);\n    }\n\n    function _sendAndCallAck(\n        uint16 _srcChainId,\n        bytes memory _srcAddress,\n        uint64 _nonce,\n        bytes memory _payload\n    ) internal virtual {\n        (, bytes memory from, bytes memory toAddress, uint amount, bytes memory payload, uint64 gasForCall) = abi\n            .decode(_payload, (uint16, bytes, bytes, uint, bytes, uint64));\n\n        address to = toAddress.toAddress(0);\n\n        amount = _creditTo(_srcChainId, to, amount);\n        emit ReceiveFromChain(_srcChainId, to, amount);\n\n        if (!_isContract(to)) {\n            emit NonContractAddress(to);\n            return;\n        }\n\n        _safeCallOnOFTReceived(_srcChainId, _srcAddress, _nonce, from, to, amount, payload, gasForCall);\n    }\n\n    function _safeCallOnOFTReceived(\n        uint16 _srcChainId,\n        bytes memory _srcAddress,\n        uint64 _nonce,\n        bytes memory _from,\n        address _to,\n        uint _amount,\n        bytes memory _payload,\n        uint _gasForCall\n    ) internal virtual {\n        (bool success, bytes memory reason) = _to.excessivelySafeCall(\n            _gasForCall,\n            150,\n            abi.encodeWithSelector(\n                IOFTReceiverUpgradeable.onOFTReceived.selector,\n                _srcChainId,\n                _srcAddress,\n                _nonce,\n                _from,\n                _amount,\n                _payload\n            )\n        );\n        if (!success) {\n            failedOFTReceivedMessages[_srcChainId][_srcAddress][_nonce] = keccak256(\n                abi.encode(_from, _to, _amount, _payload)\n            );\n            emit CallOFTReceivedFailure(_srcChainId, _srcAddress, _nonce, _from, _to, _amount, _payload, reason);\n        } else {\n            bytes32 hash = keccak256(abi.encode(_from, _to, _amount, _payload));\n            emit CallOFTReceivedSuccess(_srcChainId, _srcAddress, _nonce, hash);\n        }\n    }\n\n    function _isContract(address _account) internal view returns (bool) {\n        return _account.code.length > 0;\n    }\n\n    /**\n     * @dev This empty reserved space is put in place to allow future versions to add new\n     * variables without shifting down storage in the inheritance chain.\n     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n     */\n    uint[49] private __gap;\n}\n"},{"file_path":"contracts/dependencies/openzeppelin/token/ERC20/IERC20.sol","source_code":"// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n    /**\n     * @dev Returns the amount of tokens in existence.\n     */\n    function totalSupply() external view returns (uint256);\n\n    /**\n     * @dev Returns the amount of tokens owned by `account`.\n     */\n    function balanceOf(address account) external view returns (uint256);\n\n    /**\n     * @dev Moves `amount` tokens from the caller's account to `recipient`.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transfer(address recipient, uint256 amount) external returns (bool);\n\n    /**\n     * @dev Returns the remaining number of tokens that `spender` will be\n     * allowed to spend on behalf of `owner` through {transferFrom}. This is\n     * zero by default.\n     *\n     * This value changes when {approve} or {transferFrom} are called.\n     */\n    function allowance(address owner, address spender) external view returns (uint256);\n\n    /**\n     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * IMPORTANT: Beware that changing an allowance with this method brings the risk\n     * that someone may use both the old and the new allowance by unfortunate\n     * transaction ordering. One possible solution to mitigate this race\n     * condition is to first reduce the spender's allowance to 0 and set the\n     * desired value afterwards:\n     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n     *\n     * Emits an {Approval} event.\n     */\n    function approve(address spender, uint256 amount) external returns (bool);\n\n    /**\n     * @dev Moves `amount` tokens from `sender` to `recipient` using the\n     * allowance mechanism. `amount` is then deducted from the caller's\n     * allowance.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transferFrom(\n        address sender,\n        address recipient,\n        uint256 amount\n    ) external returns (bool);\n\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"},{"file_path":"contracts/dependencies/@layerzerolabs/solidity-examples/lzApp/NonblockingLzApp.sol","source_code":"// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"./LzApp.sol\";\nimport \"../util/ExcessivelySafeCall.sol\";\n\n/*\n * the default LayerZero messaging behaviour is blocking, i.e. any failed message will block the channel\n * this abstract class try-catch all fail messages and store locally for future retry. hence, non-blocking\n * NOTE: if the srcAddress is not configured properly, it will still block the message pathway from (srcChainId, srcAddress)\n */\nabstract contract NonblockingLzApp is LzApp {\n    using ExcessivelySafeCall for address;\n\n    constructor(address _endpoint) LzApp(_endpoint) {}\n\n    mapping(uint16 => mapping(bytes => mapping(uint64 => bytes32))) public failedMessages;\n\n    event MessageFailed(uint16 _srcChainId, bytes _srcAddress, uint64 _nonce, bytes _payload, bytes _reason);\n    event RetryMessageSuccess(uint16 _srcChainId, bytes _srcAddress, uint64 _nonce, bytes32 _payloadHash);\n\n    // overriding the virtual function in LzReceiver\n    function _blockingLzReceive(\n        uint16 _srcChainId,\n        bytes memory _srcAddress,\n        uint64 _nonce,\n        bytes memory _payload\n    ) internal virtual override {\n        (bool success, bytes memory reason) = address(this).excessivelySafeCall(\n            gasleft(),\n            150,\n            abi.encodeWithSelector(this.nonblockingLzReceive.selector, _srcChainId, _srcAddress, _nonce, _payload)\n        );\n        // try-catch all errors/exceptions\n        if (!success) {\n            _storeFailedMessage(_srcChainId, _srcAddress, _nonce, _payload, reason);\n        }\n    }\n\n    function _storeFailedMessage(\n        uint16 _srcChainId,\n        bytes memory _srcAddress,\n        uint64 _nonce,\n        bytes memory _payload,\n        bytes memory _reason\n    ) internal virtual {\n        failedMessages[_srcChainId][_srcAddress][_nonce] = keccak256(_payload);\n        emit MessageFailed(_srcChainId, _srcAddress, _nonce, _payload, _reason);\n    }\n\n    function nonblockingLzReceive(\n        uint16 _srcChainId,\n        bytes calldata _srcAddress,\n        uint64 _nonce,\n        bytes calldata _payload\n    ) public virtual {\n        // only internal transaction\n        require(_msgSender() == address(this), \"NonblockingLzApp: caller must be LzApp\");\n        _nonblockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload);\n    }\n\n    //@notice override this function\n    function _nonblockingLzReceive(\n        uint16 _srcChainId,\n        bytes memory _srcAddress,\n        uint64 _nonce,\n        bytes memory _payload\n    ) internal virtual;\n\n    function retryMessage(\n        uint16 _srcChainId,\n        bytes calldata _srcAddress,\n        uint64 _nonce,\n        bytes calldata _payload\n    ) public payable virtual {\n        // assert there is message to retry\n        bytes32 payloadHash = failedMessages[_srcChainId][_srcAddress][_nonce];\n        require(payloadHash != bytes32(0), \"NonblockingLzApp: no stored message\");\n        require(keccak256(_payload) == payloadHash, \"NonblockingLzApp: invalid payload\");\n        // clear the stored message\n        failedMessages[_srcChainId][_srcAddress][_nonce] = bytes32(0);\n        // execute the message. revert if it fails again\n        _nonblockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload);\n        emit RetryMessageSuccess(_srcChainId, _srcAddress, _nonce, payloadHash);\n    }\n}\n"},{"file_path":"contracts/dependencies/@layerzerolabs/solidity-examples/util/BytesLib.sol","source_code":"// SPDX-License-Identifier: Unlicense\n/*\n * @title Solidity Bytes Arrays Utils\n * @author Gonçalo Sá <goncalo.sa@consensys.net>\n *\n * @dev Bytes tightly packed arrays utility library for ethereum contracts written in Solidity.\n *      The library lets you concatenate, slice and type cast bytes arrays both in memory and storage.\n */\npragma solidity >=0.8.0 <0.9.0;\n\nlibrary BytesLib {\n    function concat(bytes memory _preBytes, bytes memory _postBytes) internal pure returns (bytes memory) {\n        bytes memory tempBytes;\n\n        assembly {\n            // Get a location of some free memory and store it in tempBytes as\n            // Solidity does for memory variables.\n            tempBytes := mload(0x40)\n\n            // Store the length of the first bytes array at the beginning of\n            // the memory for tempBytes.\n            let length := mload(_preBytes)\n            mstore(tempBytes, length)\n\n            // Maintain a memory counter for the current write location in the\n            // temp bytes array by adding the 32 bytes for the array length to\n            // the starting location.\n            let mc := add(tempBytes, 0x20)\n            // Stop copying when the memory counter reaches the length of the\n            // first bytes array.\n            let end := add(mc, length)\n\n            for {\n                // Initialize a copy counter to the start of the _preBytes data,\n                // 32 bytes into its memory.\n                let cc := add(_preBytes, 0x20)\n            } lt(mc, end) {\n                // Increase both counters by 32 bytes each iteration.\n                mc := add(mc, 0x20)\n                cc := add(cc, 0x20)\n            } {\n                // Write the _preBytes data into the tempBytes memory 32 bytes\n                // at a time.\n                mstore(mc, mload(cc))\n            }\n\n            // Add the length of _postBytes to the current length of tempBytes\n            // and store it as the new length in the first 32 bytes of the\n            // tempBytes memory.\n            length := mload(_postBytes)\n            mstore(tempBytes, add(length, mload(tempBytes)))\n\n            // Move the memory counter back from a multiple of 0x20 to the\n            // actual end of the _preBytes data.\n            mc := end\n            // Stop copying when the memory counter reaches the new combined\n            // length of the arrays.\n            end := add(mc, length)\n\n            for {\n                let cc := add(_postBytes, 0x20)\n            } lt(mc, end) {\n                mc := add(mc, 0x20)\n                cc := add(cc, 0x20)\n            } {\n                mstore(mc, mload(cc))\n            }\n\n            // Update the free-memory pointer by padding our last write location\n            // to 32 bytes: add 31 bytes to the end of tempBytes to move to the\n            // next 32 byte block, then round down to the nearest multiple of\n            // 32. If the sum of the length of the two arrays is zero then add\n            // one before rounding down to leave a blank 32 bytes (the length block with 0).\n            mstore(\n                0x40,\n                and(\n                    add(add(end, iszero(add(length, mload(_preBytes)))), 31),\n                    not(31) // Round down to the nearest 32 bytes.\n                )\n            )\n        }\n\n        return tempBytes;\n    }\n\n    function concatStorage(bytes storage _preBytes, bytes memory _postBytes) internal {\n        assembly {\n            // Read the first 32 bytes of _preBytes storage, which is the length\n            // of the array. (We don't need to use the offset into the slot\n            // because arrays use the entire slot.)\n            let fslot := sload(_preBytes.slot)\n            // Arrays of 31 bytes or less have an even value in their slot,\n            // while longer arrays have an odd value. The actual length is\n            // the slot divided by two for odd values, and the lowest order\n            // byte divided by two for even values.\n            // If the slot is even, bitwise and the slot with 255 and divide by\n            // two to get the length. If the slot is odd, bitwise and the slot\n            // with -1 and divide by two.\n            let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2)\n            let mlength := mload(_postBytes)\n            let newlength := add(slength, mlength)\n            // slength can contain both the length and contents of the array\n            // if length < 32 bytes so let's prepare for that\n            // v. http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage\n            switch add(lt(slength, 32), lt(newlength, 32))\n            case 2 {\n                // Since the new array still fits in the slot, we just need to\n                // update the contents of the slot.\n                // uint256(bytes_storage) = uint256(bytes_storage) + uint256(bytes_memory) + new_length\n                sstore(\n                    _preBytes.slot,\n                    // all the modifications to the slot are inside this\n                    // next block\n                    add(\n                        // we can just add to the slot contents because the\n                        // bytes we want to change are the LSBs\n                        fslot,\n                        add(\n                            mul(\n                                div(\n                                    // load the bytes from memory\n                                    mload(add(_postBytes, 0x20)),\n                                    // zero all bytes to the right\n                                    exp(0x100, sub(32, mlength))\n                                ),\n                                // and now shift left the number of bytes to\n                                // leave space for the length in the slot\n                                exp(0x100, sub(32, newlength))\n                            ),\n                            // increase length by the double of the memory\n                            // bytes length\n                            mul(mlength, 2)\n                        )\n                    )\n                )\n            }\n            case 1 {\n                // The stored value fits in the slot, but the combined value\n                // will exceed it.\n                // get the keccak hash to get the contents of the array\n                mstore(0x0, _preBytes.slot)\n                let sc := add(keccak256(0x0, 0x20), div(slength, 32))\n\n                // save new length\n                sstore(_preBytes.slot, add(mul(newlength, 2), 1))\n\n                // The contents of the _postBytes array start 32 bytes into\n                // the structure. Our first read should obtain the `submod`\n                // bytes that can fit into the unused space in the last word\n                // of the stored array. To get this, we read 32 bytes starting\n                // from `submod`, so the data we read overlaps with the array\n                // contents by `submod` bytes. Masking the lowest-order\n                // `submod` bytes allows us to add that value directly to the\n                // stored value.\n\n                let submod := sub(32, slength)\n                let mc := add(_postBytes, submod)\n                let end := add(_postBytes, mlength)\n                let mask := sub(exp(0x100, submod), 1)\n\n                sstore(\n                    sc,\n                    add(\n                        and(fslot, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00),\n                        and(mload(mc), mask)\n                    )\n                )\n\n                for {\n                    mc := add(mc, 0x20)\n                    sc := add(sc, 1)\n                } lt(mc, end) {\n                    sc := add(sc, 1)\n                    mc := add(mc, 0x20)\n                } {\n                    sstore(sc, mload(mc))\n                }\n\n                mask := exp(0x100, sub(mc, end))\n\n                sstore(sc, mul(div(mload(mc), mask), mask))\n            }\n            default {\n                // get the keccak hash to get the contents of the array\n                mstore(0x0, _preBytes.slot)\n                // Start copying to the last used word of the stored array.\n                let sc := add(keccak256(0x0, 0x20), div(slength, 32))\n\n                // save new length\n                sstore(_preBytes.slot, add(mul(newlength, 2), 1))\n\n                // Copy over the first `submod` bytes of the new data as in\n                // case 1 above.\n                let slengthmod := mod(slength, 32)\n                let mlengthmod := mod(mlength, 32)\n                let submod := sub(32, slengthmod)\n                let mc := add(_postBytes, submod)\n                let end := add(_postBytes, mlength)\n                let mask := sub(exp(0x100, submod), 1)\n\n                sstore(sc, add(sload(sc), and(mload(mc), mask)))\n\n                for {\n                    sc := add(sc, 1)\n                    mc := add(mc, 0x20)\n                } lt(mc, end) {\n                    sc := add(sc, 1)\n                    mc := add(mc, 0x20)\n                } {\n                    sstore(sc, mload(mc))\n                }\n\n                mask := exp(0x100, sub(mc, end))\n\n                sstore(sc, mul(div(mload(mc), mask), mask))\n            }\n        }\n    }\n\n    function slice(bytes memory _bytes, uint256 _start, uint256 _length) internal pure returns (bytes memory) {\n        require(_length + 31 >= _length, \"slice_overflow\");\n        require(_bytes.length >= _start + _length, \"slice_outOfBounds\");\n\n        bytes memory tempBytes;\n\n        assembly {\n            switch iszero(_length)\n            case 0 {\n                // Get a location of some free memory and store it in tempBytes as\n                // Solidity does for memory variables.\n                tempBytes := mload(0x40)\n\n                // The first word of the slice result is potentially a partial\n                // word read from the original array. To read it, we calculate\n                // the length of that partial word and start copying that many\n                // bytes into the array. The first word we copy will start with\n                // data we don't care about, but the last `lengthmod` bytes will\n                // land at the beginning of the contents of the new array. When\n                // we're done copying, we overwrite the full first word with\n                // the actual length of the slice.\n                let lengthmod := and(_length, 31)\n\n                // The multiplication in the next line is necessary\n                // because when slicing multiples of 32 bytes (lengthmod == 0)\n                // the following copy loop was copying the origin's length\n                // and then ending prematurely not copying everything it should.\n                let mc := add(add(tempBytes, lengthmod), mul(0x20, iszero(lengthmod)))\n                let end := add(mc, _length)\n\n                for {\n                    // The multiplication in the next line has the same exact purpose\n                    // as the one above.\n                    let cc := add(add(add(_bytes, lengthmod), mul(0x20, iszero(lengthmod))), _start)\n                } lt(mc, end) {\n                    mc := add(mc, 0x20)\n                    cc := add(cc, 0x20)\n                } {\n                    mstore(mc, mload(cc))\n                }\n\n                mstore(tempBytes, _length)\n\n                //update free-memory pointer\n                //allocating the array padded to 32 bytes like the compiler does now\n                mstore(0x40, and(add(mc, 31), not(31)))\n            }\n            //if we want a zero-length slice let's just return a zero-length array\n            default {\n                tempBytes := mload(0x40)\n                //zero out the 32 bytes slice we are about to return\n                //we need to do it because Solidity does not garbage collect\n                mstore(tempBytes, 0)\n\n                mstore(0x40, add(tempBytes, 0x20))\n            }\n        }\n\n        return tempBytes;\n    }\n\n    function toAddress(bytes memory _bytes, uint256 _start) internal pure returns (address) {\n        require(_bytes.length >= _start + 20, \"toAddress_outOfBounds\");\n        address tempAddress;\n\n        assembly {\n            tempAddress := div(mload(add(add(_bytes, 0x20), _start)), 0x1000000000000000000000000)\n        }\n\n        return tempAddress;\n    }\n\n    function toUint8(bytes memory _bytes, uint256 _start) internal pure returns (uint8) {\n        require(_bytes.length >= _start + 1, \"toUint8_outOfBounds\");\n        uint8 tempUint;\n\n        assembly {\n            tempUint := mload(add(add(_bytes, 0x1), _start))\n        }\n\n        return tempUint;\n    }\n\n    function toUint16(bytes memory _bytes, uint256 _start) internal pure returns (uint16) {\n        require(_bytes.length >= _start + 2, \"toUint16_outOfBounds\");\n        uint16 tempUint;\n\n        assembly {\n            tempUint := mload(add(add(_bytes, 0x2), _start))\n        }\n\n        return tempUint;\n    }\n\n    function toUint32(bytes memory _bytes, uint256 _start) internal pure returns (uint32) {\n        require(_bytes.length >= _start + 4, \"toUint32_outOfBounds\");\n        uint32 tempUint;\n\n        assembly {\n            tempUint := mload(add(add(_bytes, 0x4), _start))\n        }\n\n        return tempUint;\n    }\n\n    function toUint64(bytes memory _bytes, uint256 _start) internal pure returns (uint64) {\n        require(_bytes.length >= _start + 8, \"toUint64_outOfBounds\");\n        uint64 tempUint;\n\n        assembly {\n            tempUint := mload(add(add(_bytes, 0x8), _start))\n        }\n\n        return tempUint;\n    }\n\n    function toUint96(bytes memory _bytes, uint256 _start) internal pure returns (uint96) {\n        require(_bytes.length >= _start + 12, \"toUint96_outOfBounds\");\n        uint96 tempUint;\n\n        assembly {\n            tempUint := mload(add(add(_bytes, 0xc), _start))\n        }\n\n        return tempUint;\n    }\n\n    function toUint128(bytes memory _bytes, uint256 _start) internal pure returns (uint128) {\n        require(_bytes.length >= _start + 16, \"toUint128_outOfBounds\");\n        uint128 tempUint;\n\n        assembly {\n            tempUint := mload(add(add(_bytes, 0x10), _start))\n        }\n\n        return tempUint;\n    }\n\n    function toUint256(bytes memory _bytes, uint256 _start) internal pure returns (uint256) {\n        require(_bytes.length >= _start + 32, \"toUint256_outOfBounds\");\n        uint256 tempUint;\n\n        assembly {\n            tempUint := mload(add(add(_bytes, 0x20), _start))\n        }\n\n        return tempUint;\n    }\n\n    function toBytes32(bytes memory _bytes, uint256 _start) internal pure returns (bytes32) {\n        require(_bytes.length >= _start + 32, \"toBytes32_outOfBounds\");\n        bytes32 tempBytes32;\n\n        assembly {\n            tempBytes32 := mload(add(add(_bytes, 0x20), _start))\n        }\n\n        return tempBytes32;\n    }\n\n    function equal(bytes memory _preBytes, bytes memory _postBytes) internal pure returns (bool) {\n        bool success = true;\n\n        assembly {\n            let length := mload(_preBytes)\n\n            // if lengths don't match the arrays are not equal\n            switch eq(length, mload(_postBytes))\n            case 1 {\n                // cb is a circuit breaker in the for loop since there's\n                //  no said feature for inline assembly loops\n                // cb = 1 - don't breaker\n                // cb = 0 - break\n                let cb := 1\n\n                let mc := add(_preBytes, 0x20)\n                let end := add(mc, length)\n\n                for {\n                    let cc := add(_postBytes, 0x20)\n                    // the next line is the loop condition:\n                    // while(uint256(mc < end) + cb == 2)\n                } eq(add(lt(mc, end), cb), 2) {\n                    mc := add(mc, 0x20)\n                    cc := add(cc, 0x20)\n                } {\n                    // if any of these checks fails then arrays are not equal\n                    if iszero(eq(mload(mc), mload(cc))) {\n                        // unsuccess:\n                        success := 0\n                        cb := 0\n                    }\n                }\n            }\n            default {\n                // unsuccess:\n                success := 0\n            }\n        }\n\n        return success;\n    }\n\n    function equalStorage(bytes storage _preBytes, bytes memory _postBytes) internal view returns (bool) {\n        bool success = true;\n\n        assembly {\n            // we know _preBytes_offset is 0\n            let fslot := sload(_preBytes.slot)\n            // Decode the length of the stored array like in concatStorage().\n            let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2)\n            let mlength := mload(_postBytes)\n\n            // if lengths don't match the arrays are not equal\n            switch eq(slength, mlength)\n            case 1 {\n                // slength can contain both the length and contents of the array\n                // if length < 32 bytes so let's prepare for that\n                // v. http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage\n                if iszero(iszero(slength)) {\n                    switch lt(slength, 32)\n                    case 1 {\n                        // blank the last byte which is the length\n                        fslot := mul(div(fslot, 0x100), 0x100)\n\n                        if iszero(eq(fslot, mload(add(_postBytes, 0x20)))) {\n                            // unsuccess:\n                            success := 0\n                        }\n                    }\n                    default {\n                        // cb is a circuit breaker in the for loop since there's\n                        //  no said feature for inline assembly loops\n                        // cb = 1 - don't breaker\n                        // cb = 0 - break\n                        let cb := 1\n\n                        // get the keccak hash to get the contents of the array\n                        mstore(0x0, _preBytes.slot)\n                        let sc := keccak256(0x0, 0x20)\n\n                        let mc := add(_postBytes, 0x20)\n                        let end := add(mc, mlength)\n\n                        // the next line is the loop condition:\n                        // while(uint256(mc < end) + cb == 2)\n                        for {\n\n                        } eq(add(lt(mc, end), cb), 2) {\n                            sc := add(sc, 1)\n                            mc := add(mc, 0x20)\n                        } {\n                            if iszero(eq(sload(sc), mload(mc))) {\n                                // unsuccess:\n                                success := 0\n                                cb := 0\n                            }\n                        }\n                    }\n                }\n            }\n            default {\n                // unsuccess:\n                success := 0\n            }\n        }\n\n        return success;\n    }\n}\n"},{"file_path":"contracts/storage/SmartFarmingManagerStorage.sol","source_code":"// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.24;\n\nimport {IERC20} from \"../dependencies/openzeppelin/token/ERC20/IERC20.sol\";\nimport {ISmartFarmingManager} from \"../interfaces/ISmartFarmingManager.sol\";\nimport {IDepositToken} from \"../interfaces/IDepositToken.sol\";\nimport {ISyntheticToken} from \"../interfaces/ISyntheticToken.sol\";\n\n// solhint-disable var-name-mixedcase, max-states-count\nabstract contract SmartFarmingManagerStorageV1 is ISmartFarmingManager {\n    struct CrossChainLeverage {\n        uint16 dstChainId;\n        IERC20 bridgeToken;\n        IDepositToken depositToken;\n        ISyntheticToken syntheticToken;\n        uint256 amountIn;\n        uint256 debtAmount;\n        uint256 depositAmountMin;\n        address account;\n        bool finished;\n        IERC20 tokenIn;\n    }\n\n    struct CrossChainFlashRepay {\n        uint16 dstChainId;\n        ISyntheticToken syntheticToken;\n        uint256 repayAmountMin;\n        address account;\n        bool finished;\n    }\n\n    uint256 private crossChainRequestsLength__DEPRECATED;\n\n    mapping(uint256 => CrossChainLeverage) private crossChainLeverages__DEPRECATED;\n\n    mapping(uint256 => CrossChainFlashRepay) private crossChainFlashRepays__DEPRECATED;\n}\n"},{"file_path":"contracts/dependencies/openzeppelin/utils/introspection/ERC165.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n *     return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n *\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\n */\nabstract contract ERC165 is IERC165 {\n    /**\n     * @dev See {IERC165-supportsInterface}.\n     */\n    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n        return interfaceId == type(IERC165).interfaceId;\n    }\n}\n"},{"file_path":"contracts/RewardsDistributor.sol","source_code":"// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.24;\n\nimport {Initializable} from \"./dependencies/openzeppelin-upgradeable/proxy/utils/Initializable.sol\";\nimport {IERC20} from \"./dependencies/openzeppelin/token/ERC20/IERC20.sol\";\nimport {SafeCast} from \"./dependencies/openzeppelin/utils/math/SafeCast.sol\";\nimport {SafeERC20} from \"./dependencies/openzeppelin/token/ERC20/utils/SafeERC20.sol\";\nimport {ReentrancyGuardDeprecated} from \"./utils/ReentrancyGuardDeprecated.sol\";\nimport {ReentrancyGuardTransient} from \"./utils/ReentrancyGuardTransient.sol\";\nimport {IDebtToken} from \"./interfaces/IDebtToken.sol\";\nimport {IDepositToken} from \"./interfaces/IDepositToken.sol\";\nimport {Manageable} from \"./access/Manageable.sol\";\nimport {RewardsDistributorStorageV2} from \"./storage/RewardsDistributorStorage.sol\";\nimport {WadRayMath} from \"./lib/WadRayMath.sol\";\nimport {IPool} from \"./interfaces/IPool.sol\";\nimport {IVPool} from \"./interfaces/external/IVPool.sol\";\nimport {IPoolRewards} from \"./interfaces/external/IPoolRewards.sol\";\n\n/// @notice Updated to IPoolRewards will trigger treasury upgrade and we want to avoid it.\n/// Hence defining new interface here.\ninterface IPoolRewardsExt is IPoolRewards {\n    function rewardRates(address rewardToken_) external returns (uint256);\n\n    function periodFinish(address rewardToken_) external returns (uint256);\n}\n\nerror AddressIsNull();\nerror NotTokenSpeedKeeper();\nerror DistributorDoesNotExist();\nerror InvalidToken();\nerror RewardTokenIsNull();\nerror ReachedMaxRewardTokens();\nerror ArraysLengthDoNotMatch();\n\n/**\n * @title RewardsDistributor contract\n */\ncontract RewardsDistributor is\n    Initializable,\n    ReentrancyGuardDeprecated,\n    ReentrancyGuardTransient,\n    Manageable,\n    RewardsDistributorStorageV2\n{\n    using SafeERC20 for IERC20;\n    using SafeCast for uint256;\n    using WadRayMath for uint256;\n\n    string public constant VERSION = \"1.4.1\";\n\n    /// @notice The initial index\n    uint224 public constant INITIAL_INDEX = 1e18;\n\n    /// @notice Max reward tokens to avoid DoS scenario\n    uint224 public constant MAX_REWARD_TOKENS = 20;\n\n    /// @notice Emitted when reward is claimed\n    event RewardClaimed(address indexed account, uint256 amount);\n\n    /// @notice Emitted when updating accrued token\n    event TokensAccruedUpdated(IERC20 indexed token, address indexed account, uint256 tokensDelta, uint256 supplyIndex);\n\n    /// @notice Emitted when updating token speed\n    event TokenSpeedUpdated(IERC20 indexed token, uint256 oldSpeed, uint256 newSpeed);\n\n    /// @notice Emitted when updating token index\n    event TokenIndexUpdated(uint224 newIndex, uint32 newTimestamp);\n\n    /**\n     * @dev Throws if this contract isn't registered on pool\n     */\n    modifier onlyIfDistributorExists() {\n        bool _distributorAdded = false;\n        address[] memory _rewardsDistributors = pool.getRewardsDistributors();\n        uint256 _length = _rewardsDistributors.length;\n        for (uint256 i; i < _length; ++i) {\n            if (_rewardsDistributors[i] == address(this)) {\n                _distributorAdded = true;\n                break;\n            }\n        }\n        if (!_distributorAdded) revert DistributorDoesNotExist();\n        _;\n    }\n\n    /**\n     * @dev Throws if token doesn't exist\n     * @dev Should be a DepositToken (suppliers) or DebtToken (borrowers)\n     */\n    modifier onlyIfTokenExists(address token_) {\n        IPool _pool = pool;\n        if (!_pool.doesDebtTokenExist(IDebtToken(token_)) && !_pool.doesDepositTokenExist(IDepositToken(token_))) {\n            revert InvalidToken();\n        }\n        _;\n    }\n\n    constructor() {\n        _disableInitializers();\n    }\n\n    function initialize(IPool pool_, IERC20 rewardToken_) external initializer {\n        if (address(rewardToken_) == address(0)) revert RewardTokenIsNull();\n\n        __Manageable_init(pool_);\n\n        rewardToken = rewardToken_;\n    }\n\n    /**\n     * @notice Returns claimable amount consider all tokens\n     */\n    function claimable(address account_) external view override returns (uint256 _claimable) {\n        _claimable = tokensAccruedOf[account_];\n        uint256 _len = tokens.length;\n        for (uint256 i; i < _len; ++i) {\n            _claimable += _claimableRewards(account_, tokens[i]);\n        }\n    }\n\n    /**\n     * @notice Returns updated claimable amount for given token\n     * @dev Removing this function will change interface and will result\n     * updating other contracts using interface.\n     */\n    function claimable(address, IERC20) public view override returns (uint256) {\n        revert(\"Unsupported\");\n    }\n\n    /**\n     * @notice Claim tokens accrued by account in all tokens\n     */\n    function claimRewards(address account_) external override {\n        claimRewards(account_, tokens);\n    }\n\n    /**\n     * @notice Claim tokens accrued by account in the specified tokens\n     */\n    function claimRewards(address account_, IERC20[] memory tokens_) public override {\n        address[] memory _accounts = new address[](1);\n        _accounts[0] = account_;\n        claimRewards(_accounts, tokens_);\n    }\n\n    /**\n     * @notice Claim tokens accrued by the accounts in the specified tokens\n     */\n    function claimRewards(address[] memory accounts_, IERC20[] memory tokens_) public override nonReentrant {\n        uint256 _accountsLength = accounts_.length;\n        uint256 _tokensLength = tokens_.length;\n        for (uint256 i; i < _tokensLength; ++i) {\n            IERC20 _token = tokens_[i];\n\n            if (tokenStates[_token].index > 0) {\n                _updateTokenIndex(_token);\n                for (uint256 j; j < _accountsLength; j++) {\n                    _updateTokensAccruedOf(_token, accounts_[j]);\n                }\n            }\n        }\n\n        for (uint256 j; j < _accountsLength; j++) {\n            address _account = accounts_[j];\n            _transferRewardIfEnoughTokens(_account, tokensAccruedOf[_account]);\n        }\n    }\n\n    /**\n     * @notice Update indexes on pre-mint and pre-burn\n     * @dev Called by DepositToken and DebtToken contracts\n     * This function also may be called by anyone to update stored indexes\n     */\n    function updateBeforeMintOrBurn(IERC20 token_, address account_) external override {\n        if (tokenStates[token_].index > 0) {\n            _updateTokenIndex(token_);\n            _updateTokensAccruedOf(token_, account_);\n        }\n    }\n\n    /**\n     * @notice Update indexes on pre-transfer\n     * @dev Called by DepositToken and DebtToken contracts\n     */\n    function updateBeforeTransfer(IERC20 token_, address from_, address to_) external override {\n        if (tokenStates[token_].index > 0) {\n            _updateTokenIndex(token_);\n            _updateTokensAccruedOf(token_, from_);\n            _updateTokensAccruedOf(token_, to_);\n        }\n    }\n\n    /**\n     * @notice Calculate updated token index values\n     */\n    function _calculateTokenIndex(\n        TokenState memory _supplyState,\n        IERC20 token_\n    ) private view returns (uint224 _newIndex, uint32 _newTimestamp) {\n        uint256 _speed = tokenSpeeds[token_];\n        uint256 _deltaTimestamps = block.timestamp - uint256(_supplyState.timestamp);\n        if (_deltaTimestamps > 0 && _speed > 0) {\n            uint256 _totalSupply = token_.totalSupply();\n            uint256 _tokensAccrued = _deltaTimestamps * _speed;\n            uint256 _ratio = _totalSupply > 0 ? _tokensAccrued.wadDiv(_totalSupply) : 0;\n            _newIndex = (_supplyState.index + _ratio).toUint224();\n            _newTimestamp = block.timestamp.toUint32();\n        } else if (_deltaTimestamps > 0 && _supplyState.index > 0) {\n            _newTimestamp = block.timestamp.toUint32();\n        }\n    }\n\n    /**\n     * @notice Calculate updated account index and claimable values\n     */\n    function _calculateTokenDelta(\n        TokenState memory _tokenState,\n        IERC20 token_,\n        address account_\n    ) private view returns (uint256 _tokenIndex, uint256 _tokensDelta) {\n        _tokenIndex = _tokenState.index;\n        uint256 _accountIndex = accountIndexOf[token_][account_];\n\n        if (_accountIndex == 0 && _tokenIndex > INITIAL_INDEX) {\n            _accountIndex = INITIAL_INDEX;\n        }\n\n        uint256 _deltaIndex = _tokenIndex - _accountIndex;\n        _tokensDelta = token_.balanceOf(account_).wadMul(_deltaIndex);\n    }\n\n    function _claimableRewards(address account_, IERC20 token_) internal view returns (uint256 _claimableDelta) {\n        TokenState memory _tokenState = tokenStates[token_];\n        (uint224 _newIndex, uint32 _newTimestamp) = _calculateTokenIndex(_tokenState, token_);\n        if (_newIndex > 0 && _newTimestamp > 0) {\n            _tokenState = TokenState({index: _newIndex, timestamp: _newTimestamp});\n        } else if (_newTimestamp > 0) {\n            _tokenState.timestamp = _newTimestamp;\n        }\n        (, _claimableDelta) = _calculateTokenDelta(_tokenState, token_, account_);\n    }\n\n    /**\n     * @notice Transfer tokens to the user\n     * @dev If there is not enough tokens, we do not perform the transfer\n     */\n    function _transferRewardIfEnoughTokens(address account_, uint256 amount_) private {\n        IERC20 _rewardToken = rewardToken;\n        uint256 _balance = _rewardToken.balanceOf(address(this));\n        if (amount_ > 0 && amount_ <= _balance) {\n            tokensAccruedOf[account_] = 0;\n            _rewardToken.safeTransfer(account_, amount_);\n            emit RewardClaimed(account_, amount_);\n        }\n    }\n\n    /**\n     * @notice Calculate tokens accrued by an account\n     */\n    function _updateTokensAccruedOf(IERC20 token_, address account_) private {\n        (uint256 _tokenIndex, uint256 _tokensDelta) = _calculateTokenDelta(tokenStates[token_], token_, account_);\n        accountIndexOf[token_][account_] = _tokenIndex;\n        tokensAccruedOf[account_] = tokensAccruedOf[account_] + _tokensDelta;\n        emit TokensAccruedUpdated(token_, account_, _tokensDelta, _tokenIndex);\n    }\n\n    /**\n     * @notice Accrue reward token by updating the index\n     */\n    function _updateTokenIndex(IERC20 token_) private {\n        TokenState storage _supplyState = tokenStates[token_];\n        (uint224 _newIndex, uint32 _newTimestamp) = _calculateTokenIndex(_supplyState, token_);\n        if (_newIndex > 0 && _newTimestamp > 0) {\n            _supplyState.index = _newIndex;\n            _supplyState.timestamp = _newTimestamp;\n            emit TokenIndexUpdated(_newIndex, _newTimestamp);\n        } else if (_newTimestamp > 0) {\n            _supplyState.timestamp = _newTimestamp;\n            emit TokenIndexUpdated(_supplyState.index, _newTimestamp);\n        }\n    }\n\n    /**\n     * @notice Update the speed for token\n     */\n    function _updateTokenSpeed(\n        IERC20 token_,\n        uint256 newSpeed_\n    ) private onlyIfDistributorExists onlyIfTokenExists(address(token_)) {\n        uint256 _currentSpeed = tokenSpeeds[token_];\n        if (_currentSpeed > 0) {\n            _updateTokenIndex(token_);\n        } else if (newSpeed_ > 0) {\n            // Add token to the list\n            if (tokenStates[token_].index == 0) {\n                if (tokens.length == MAX_REWARD_TOKENS) revert ReachedMaxRewardTokens();\n                tokenStates[token_] = TokenState({index: INITIAL_INDEX, timestamp: block.timestamp.toUint32()});\n                tokens.push(token_);\n            } else {\n                // Update timestamp to ensure extra interest is not accrued during the prior period\n                tokenStates[token_].timestamp = block.timestamp.toUint32();\n            }\n        }\n\n        if (_currentSpeed != newSpeed_) {\n            tokenSpeeds[token_] = newSpeed_;\n            emit TokenSpeedUpdated(token_, _currentSpeed, newSpeed_);\n        }\n    }\n\n    /**\n     * @notice Update speed for a single deposit token\n     */\n    function updateTokenSpeed(IERC20 token_, uint256 newSpeed_) external override onlyGovernor {\n        _updateTokenSpeed(token_, newSpeed_);\n    }\n\n    /**\n     * @notice Update token speeds\n     */\n    function updateTokenSpeeds(IERC20[] calldata tokens_, uint256[] calldata speeds_) external override onlyGovernor {\n        uint256 _tokensLength = tokens_.length;\n        if (_tokensLength != speeds_.length) revert ArraysLengthDoNotMatch();\n\n        for (uint256 i; i < _tokensLength; ++i) {\n            _updateTokenSpeed(tokens_[i], speeds_[i]);\n        }\n    }\n\n    //********************************  TokenSpeed and RewardRate sync fix ***********************************/\n    /// @notice This is temporary fix to keep tokenSpeed and rewardRate from Vesper in sync.\n    function syncTokenSpeed(IDepositToken depositToken_) external {\n        if (_msgSender() != tokenSpeedKeeper) revert NotTokenSpeedKeeper();\n\n        IVPool _vPool = IVPool(address(depositToken_.underlying()));\n        IPoolRewardsExt _rewards = IPoolRewardsExt(_vPool.poolRewards());\n\n        uint256 _speed;\n\n        if (block.timestamp < _rewards.periodFinish(address(rewardToken))) {\n            _speed =\n                (_rewards.rewardRates(address(rewardToken)) * _vPool.balanceOf(address(pool.treasury()))) /\n                _vPool.totalSupply();\n        }\n\n        _updateTokenSpeed(IERC20(address(depositToken_)), _speed);\n    }\n\n    /// @notice This function is part of temporary fix to keep tokenSpeed and rewardRate in sync.\n    function updateTokenSpeedKeeper(address keeper_) external onlyGovernor {\n        if (keeper_ == address(0)) revert AddressIsNull();\n        tokenSpeedKeeper = keeper_;\n    }\n}\n"},{"file_path":"contracts/dependencies/stargate-protocol/LPTokenERC20.sol","source_code":"// SPDX-License-Identifier: BUSL-1.1\n\npragma solidity ^0.8.9;\n\n// libraries\nimport \"../openzeppelin/utils/math/SafeMath.sol\";\n\ncontract LPTokenERC20 {\n    using SafeMath for uint256;\n\n    //---------------------------------------------------------------------------\n    // CONSTANTS\n    string public name;\n    string public symbol;\n    bytes32 public constant PERMIT_TYPEHASH = 0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9;\n    // set in constructor\n    bytes32 public DOMAIN_SEPARATOR;\n\n    //---------------------------------------------------------------------------\n    // VARIABLES\n    uint256 public decimals;\n    uint256 public totalSupply;\n    mapping(address => uint256) public balanceOf;\n    mapping(address => mapping(address => uint256)) public allowance;\n    mapping(address => uint256) public nonces;\n\n    //---------------------------------------------------------------------------\n    // EVENTS\n    event Approval(address indexed owner, address indexed spender, uint256 value);\n    event Transfer(address indexed from, address indexed to, uint256 value);\n\n    constructor(string memory _name, string memory _symbol) {\n        name = _name;\n        symbol = _symbol;\n        uint256 chainId;\n        assembly {\n            chainId := chainid()\n        }\n        DOMAIN_SEPARATOR = keccak256(\n            abi.encode(\n                keccak256(\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\"),\n                keccak256(bytes(name)),\n                keccak256(bytes(\"1\")),\n                chainId,\n                address(this)\n            )\n        );\n    }\n\n    function _mint(address to, uint256 value) internal {\n        totalSupply = totalSupply.add(value);\n        balanceOf[to] = balanceOf[to].add(value);\n        emit Transfer(address(0), to, value);\n    }\n\n    function _burn(address from, uint256 value) internal {\n        balanceOf[from] = balanceOf[from].sub(value);\n        totalSupply = totalSupply.sub(value);\n        emit Transfer(from, address(0), value);\n    }\n\n    function _approve(address owner, address spender, uint256 value) private {\n        allowance[owner][spender] = value;\n        emit Approval(owner, spender, value);\n    }\n\n    function _transfer(address from, address to, uint256 value) private {\n        balanceOf[from] = balanceOf[from].sub(value);\n        balanceOf[to] = balanceOf[to].add(value);\n        emit Transfer(from, to, value);\n    }\n\n    function approve(address spender, uint256 value) external returns (bool) {\n        _approve(msg.sender, spender, value);\n        return true;\n    }\n\n    function transfer(address to, uint256 value) external returns (bool) {\n        _transfer(msg.sender, to, value);\n        return true;\n    }\n\n    function transferFrom(address from, address to, uint256 value) external returns (bool) {\n        if (allowance[from][msg.sender] != type(uint256).max) {\n            allowance[from][msg.sender] = allowance[from][msg.sender].sub(value);\n        }\n        _transfer(from, to, value);\n        return true;\n    }\n\n    function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n        _approve(msg.sender, spender, allowance[msg.sender][spender].add(addedValue));\n        return true;\n    }\n\n    function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n        _approve(\n            msg.sender,\n            spender,\n            allowance[msg.sender][spender].sub(subtractedValue, \"ERC20: decreased allowance below zero\")\n        );\n        return true;\n    }\n\n    function permit(\n        address owner,\n        address spender,\n        uint256 value,\n        uint256 deadline,\n        uint8 v,\n        bytes32 r,\n        bytes32 s\n    ) external {\n        require(deadline >= block.timestamp, \"Bridge: EXPIRED\");\n        bytes32 digest = keccak256(\n            abi.encodePacked(\n                \"\\x19\\x01\",\n                DOMAIN_SEPARATOR,\n                keccak256(abi.encode(PERMIT_TYPEHASH, owner, spender, value, nonces[owner]++, deadline))\n            )\n        );\n        address recoveredAddress = ecrecover(digest, v, r, s);\n        require(recoveredAddress != address(0) && recoveredAddress == owner, \"Bridge: INVALID_SIGNATURE\");\n        _approve(owner, spender, value);\n    }\n}\n"},{"file_path":"contracts/dependencies/stargate-protocol/interfaces/IStargateReceiver.sol","source_code":"// SPDX-License-Identifier: BUSL-1.1\n\npragma solidity ^0.8.9;\n\ninterface IStargateReceiver {\n    function sgReceive(\n        uint16 _chainId,\n        bytes memory _srcAddress,\n        uint256 _nonce,\n        address _token,\n        uint256 amountLD,\n        bytes memory payload\n    ) external;\n}\n"},{"file_path":"contracts/interfaces/IDepositToken.sol","source_code":"// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.24;\n\nimport {IERC20Metadata, IERC20} from \"../dependencies/openzeppelin/token/ERC20/extensions/IERC20Metadata.sol\";\n\ninterface IDepositToken is IERC20Metadata {\n    function underlying() external view returns (IERC20);\n\n    function collateralFactor() external view returns (uint256);\n\n    function unlockedBalanceOf(address account_) external view returns (uint256);\n\n    function lockedBalanceOf(address account_) external view returns (uint256);\n\n    function flashWithdraw(address account_, uint256 amount_) external returns (uint256 _withdrawn, uint256 _fee);\n\n    function deposit(uint256 amount_, address onBehalfOf_) external returns (uint256 _deposited, uint256 _fee);\n\n    function quoteDepositIn(uint256 amountToDeposit_) external view returns (uint256 _amount, uint256 _fee);\n\n    function quoteDepositOut(uint256 amount_) external view returns (uint256 _amountToDeposit, uint256 _fee);\n\n    function quoteWithdrawIn(uint256 amountToWithdraw_) external view returns (uint256 _amount, uint256 _fee);\n\n    function quoteWithdrawOut(uint256 amount_) external view returns (uint256 _amountToWithdraw, uint256 _fee);\n\n    function withdraw(uint256 amount_, address to_) external returns (uint256 _withdrawn, uint256 _fee);\n\n    function seize(address from_, address to_, uint256 amount_) external;\n\n    function updateCollateralFactor(uint128 newCollateralFactor_) external;\n\n    function isActive() external view returns (bool);\n\n    function toggleIsActive() external;\n\n    function maxTotalSupply() external view returns (uint256);\n\n    function updateMaxTotalSupply(uint256 newMaxTotalSupply_) external;\n\n    function withdrawFrom(address from_, uint256 amount_) external returns (uint256 _withdrawn, uint256 _fee);\n}\n"},{"file_path":"contracts/dependencies/openzeppelin/utils/TransientSlot.sol","source_code":"// SPDX-License-Identifier: MIT\n// This file was procedurally generated from scripts/generate/templates/TransientSlot.js.\n\npragma solidity ^0.8.24;\n\n/**\n * @dev Library for reading and writing value-types to specific transient storage slots.\n *\n * Transient slots are often used to store temporary values that are removed after the current transaction.\n * This library helps with reading and writing to such slots without the need for inline assembly.\n *\n *  * Example reading and writing values using transient storage:\n * ```solidity\n * contract Lock {\n *     using TransientSlot for *;\n *\n *     // Define the slot. Alternatively, use the SlotDerivation library to derive the slot.\n *     bytes32 internal constant _LOCK_SLOT = 0xf4678858b2b588224636b8522b729e7722d32fc491da849ed75b3fdf3c84f542;\n *\n *     modifier locked() {\n *         require(!_LOCK_SLOT.asBoolean().tload());\n *\n *         _LOCK_SLOT.asBoolean().tstore(true);\n *         _;\n *         _LOCK_SLOT.asBoolean().tstore(false);\n *     }\n * }\n * ```\n *\n * TIP: Consider using this library along with {SlotDerivation}.\n */\nlibrary TransientSlot {\n    /**\n     * @dev UDVT that represent a slot holding a address.\n     */\n    type AddressSlot is bytes32;\n\n    /**\n     * @dev Cast an arbitrary slot to a AddressSlot.\n     */\n    function asAddress(bytes32 slot) internal pure returns (AddressSlot) {\n        return AddressSlot.wrap(slot);\n    }\n\n    /**\n     * @dev UDVT that represent a slot holding a bool.\n     */\n    type BooleanSlot is bytes32;\n\n    /**\n     * @dev Cast an arbitrary slot to a BooleanSlot.\n     */\n    function asBoolean(bytes32 slot) internal pure returns (BooleanSlot) {\n        return BooleanSlot.wrap(slot);\n    }\n\n    /**\n     * @dev UDVT that represent a slot holding a bytes32.\n     */\n    type Bytes32Slot is bytes32;\n\n    /**\n     * @dev Cast an arbitrary slot to a Bytes32Slot.\n     */\n    function asBytes32(bytes32 slot) internal pure returns (Bytes32Slot) {\n        return Bytes32Slot.wrap(slot);\n    }\n\n    /**\n     * @dev UDVT that represent a slot holding a uint256.\n     */\n    type Uint256Slot is bytes32;\n\n    /**\n     * @dev Cast an arbitrary slot to a Uint256Slot.\n     */\n    function asUint256(bytes32 slot) internal pure returns (Uint256Slot) {\n        return Uint256Slot.wrap(slot);\n    }\n\n    /**\n     * @dev UDVT that represent a slot holding a int256.\n     */\n    type Int256Slot is bytes32;\n\n    /**\n     * @dev Cast an arbitrary slot to a Int256Slot.\n     */\n    function asInt256(bytes32 slot) internal pure returns (Int256Slot) {\n        return Int256Slot.wrap(slot);\n    }\n\n    /**\n     * @dev Load the value held at location `slot` in transient storage.\n     */\n    function tload(AddressSlot slot) internal view returns (address value) {\n        assembly (\"memory-safe\") {\n            value := tload(slot)\n        }\n    }\n\n    /**\n     * @dev Store `value` at location `slot` in transient storage.\n     */\n    function tstore(AddressSlot slot, address value) internal {\n        assembly (\"memory-safe\") {\n            tstore(slot, value)\n        }\n    }\n\n    /**\n     * @dev Load the value held at location `slot` in transient storage.\n     */\n    function tload(BooleanSlot slot) internal view returns (bool value) {\n        assembly (\"memory-safe\") {\n            value := tload(slot)\n        }\n    }\n\n    /**\n     * @dev Store `value` at location `slot` in transient storage.\n     */\n    function tstore(BooleanSlot slot, bool value) internal {\n        assembly (\"memory-safe\") {\n            tstore(slot, value)\n        }\n    }\n\n    /**\n     * @dev Load the value held at location `slot` in transient storage.\n     */\n    function tload(Bytes32Slot slot) internal view returns (bytes32 value) {\n        assembly (\"memory-safe\") {\n            value := tload(slot)\n        }\n    }\n\n    /**\n     * @dev Store `value` at location `slot` in transient storage.\n     */\n    function tstore(Bytes32Slot slot, bytes32 value) internal {\n        assembly (\"memory-safe\") {\n            tstore(slot, value)\n        }\n    }\n\n    /**\n     * @dev Load the value held at location `slot` in transient storage.\n     */\n    function tload(Uint256Slot slot) internal view returns (uint256 value) {\n        assembly (\"memory-safe\") {\n            value := tload(slot)\n        }\n    }\n\n    /**\n     * @dev Store `value` at location `slot` in transient storage.\n     */\n    function tstore(Uint256Slot slot, uint256 value) internal {\n        assembly (\"memory-safe\") {\n            tstore(slot, value)\n        }\n    }\n\n    /**\n     * @dev Load the value held at location `slot` in transient storage.\n     */\n    function tload(Int256Slot slot) internal view returns (int256 value) {\n        assembly (\"memory-safe\") {\n            value := tload(slot)\n        }\n    }\n\n    /**\n     * @dev Store `value` at location `slot` in transient storage.\n     */\n    function tstore(Int256Slot slot, int256 value) internal {\n        assembly (\"memory-safe\") {\n            tstore(slot, value)\n        }\n    }\n}\n"},{"file_path":"contracts/lib/WadRayMath.sol","source_code":"// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.24;\n\n/**\n * @title Math library\n * @dev Provides mul and div function for wads (decimal numbers with 18 digits precision) and rays (decimals with 27 digits)\n * @dev Based on https://github.com/dapphub/ds-math/blob/master/src/math.sol\n */\nlibrary WadRayMath {\n    uint256 internal constant WAD = 1e18;\n    uint256 internal constant HALF_WAD = WAD / 2;\n\n    uint256 internal constant RAY = 1e27;\n    uint256 internal constant HALF_RAY = RAY / 2;\n\n    uint256 internal constant WAD_RAY_RATIO = 1e9;\n\n    /**\n     * @dev Multiplies two wad, rounding half up to the nearest wad\n     * @param a Wad\n     * @param b Wad\n     * @return The result of a*b, in wad\n     */\n    function wadMul(uint256 a, uint256 b) internal pure returns (uint256) {\n        if (a == 0 || b == 0) {\n            return 0;\n        }\n\n        return (a * b + HALF_WAD) / WAD;\n    }\n\n    /**\n     * @dev Divides two wad, rounding half up to the nearest wad\n     * @param a Wad\n     * @param b Wad\n     * @return The result of a/b, in wad\n     */\n    function wadDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n        return (a * WAD + b / 2) / b;\n    }\n}\n"},{"file_path":"contracts/mock/ERC20Mock.sol","source_code":"// SPDX-License-Identifier: MIT\n\n// Note: Minimalist ERC20 based on https://github.com/maple-labs/erc20\n\npragma solidity 0.8.24;\n\nimport {IERC20Metadata} from \"../dependencies/openzeppelin/token/ERC20/extensions/IERC20Metadata.sol\";\n\ncontract ERC20Mock is IERC20Metadata {\n    string public override name;\n    string public override symbol;\n\n    uint8 public immutable override decimals;\n\n    uint256 public override totalSupply;\n\n    mapping(address => uint256) public override balanceOf;\n\n    mapping(address => mapping(address => uint256)) public override allowance;\n\n    uint256 public fee;\n\n    constructor(string memory name_, string memory symbol_, uint8 decimals_) {\n        name = name_;\n        symbol = symbol_;\n        decimals = decimals_;\n    }\n\n    /**************************/\n    /*** External Functions ***/\n    /**************************/\n\n    function approve(address spender_, uint256 amount_) external override returns (bool success_) {\n        _approve(msg.sender, spender_, amount_);\n        return true;\n    }\n\n    function transfer(address recipient_, uint256 amount_) external override returns (bool success_) {\n        _transfer(msg.sender, recipient_, amount_);\n        return true;\n    }\n\n    function transferFrom(\n        address owner_,\n        address recipient_,\n        uint256 amount_\n    ) external override returns (bool success_) {\n        _approve(owner_, msg.sender, allowance[owner_][msg.sender] - amount_);\n        _transfer(owner_, recipient_, amount_);\n        return true;\n    }\n\n    function mint(address _to, uint256 _amount) external {\n        _mint(_to, _amount);\n    }\n\n    function burn(address _to, uint256 _amount) external {\n        _burn(_to, _amount);\n    }\n\n    function updateFee(uint256 _fee) external {\n        fee = _fee;\n    }\n\n    /**************************/\n    /*** Internal Functions ***/\n    /**************************/\n\n    function _approve(address owner_, address spender_, uint256 amount_) internal {\n        emit Approval(owner_, spender_, allowance[owner_][spender_] = amount_);\n    }\n\n    function _transfer(address owner_, address recipient_, uint256 amount_) internal {\n        uint256 feeAmount = fee > 0 ? (amount_ * fee) / 1e18 : 0;\n        balanceOf[owner_] -= amount_;\n        balanceOf[recipient_] += amount_ - feeAmount;\n\n        if (feeAmount > 0) {\n            balanceOf[address(0)] = feeAmount;\n        }\n\n        emit Transfer(owner_, recipient_, amount_);\n    }\n\n    function _mint(address recipient_, uint256 amount_) internal {\n        totalSupply += amount_;\n        balanceOf[recipient_] += amount_;\n\n        emit Transfer(address(0), recipient_, amount_);\n    }\n\n    function _burn(address owner_, uint256 amount_) internal {\n        balanceOf[owner_] -= amount_;\n        totalSupply -= amount_;\n\n        emit Transfer(owner_, address(0), amount_);\n    }\n}\n"},{"file_path":"contracts/dependencies/@layerzerolabs/solidity-examples/token/oft/IOFTCore.sol","source_code":"// SPDX-License-Identifier: MIT\n\npragma solidity >=0.5.0;\n\nimport \"../../../../openzeppelin/utils/introspection/IERC165.sol\";\n\n/**\n * @dev Interface of the IOFT core standard\n */\ninterface IOFTCore is IERC165 {\n    /**\n     * @dev estimate send token `_tokenId` to (`_dstChainId`, `_toAddress`)\n     * _dstChainId - L0 defined chain id to send tokens too\n     * _toAddress - dynamic bytes array which contains the address to whom you are sending tokens to on the dstChain\n     * _amount - amount of the tokens to transfer\n     * _useZro - indicates to use zro to pay L0 fees\n     * _adapterParam - flexible bytes array to indicate messaging adapter services in L0\n     */\n    function estimateSendFee(\n        uint16 _dstChainId,\n        bytes calldata _toAddress,\n        uint _amount,\n        bool _useZro,\n        bytes calldata _adapterParams\n    ) external view returns (uint nativeFee, uint zroFee);\n\n    /**\n     * @dev send `_amount` amount of token to (`_dstChainId`, `_toAddress`) from `_from`\n     * `_from` the owner of token\n     * `_dstChainId` the destination chain identifier\n     * `_toAddress` can be any size depending on the `dstChainId`.\n     * `_amount` the quantity of tokens in wei\n     * `_refundAddress` the address LayerZero refunds if too much message fee is sent\n     * `_zroPaymentAddress` set to address(0x0) if not paying in ZRO (LayerZero Token)\n     * `_adapterParams` is a flexible bytes array to indicate messaging adapter services\n     */\n    function sendFrom(\n        address _from,\n        uint16 _dstChainId,\n        bytes calldata _toAddress,\n        uint _amount,\n        address payable _refundAddress,\n        address _zroPaymentAddress,\n        bytes calldata _adapterParams\n    ) external payable;\n\n    /**\n     * @dev returns the circulating amount of tokens on current chain\n     */\n    function circulatingSupply() external view returns (uint);\n\n    /**\n     * @dev returns the address of the ERC20 token\n     */\n    function token() external view returns (address);\n\n    /**\n     * @dev Emitted when `_amount` tokens are moved from the `_sender` to (`_dstChainId`, `_toAddress`)\n     * `_nonce` is the outbound nonce\n     */\n    event SendToChain(uint16 indexed _dstChainId, address indexed _from, bytes _toAddress, uint _amount);\n\n    /**\n     * @dev Emitted when `_amount` tokens are received from `_srcChainId` into the `_toAddress` on the local chain.\n     * `_nonce` is the inbound nonce.\n     */\n    event ReceiveFromChain(uint16 indexed _srcChainId, address indexed _to, uint _amount);\n\n    event SetUseCustomAdapterParams(bool _useCustomAdapterParams);\n}\n"},{"file_path":"contracts/access/Manageable.sol","source_code":"// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.24;\n\nimport {Initializable} from \"../dependencies/openzeppelin-upgradeable/proxy/utils/Initializable.sol\";\nimport {SynthContext} from \"../utils/SynthContext.sol\";\nimport {IGovernable} from \"../interfaces/IGovernable.sol\";\nimport {IManageable} from \"../interfaces/IManageable.sol\";\nimport {IPool} from \"../interfaces/IPool.sol\";\nimport {IPoolRegistry} from \"../interfaces/IPoolRegistry.sol\";\n\nerror SenderIsNotPool();\nerror SenderIsNotGovernor();\nerror IsPaused();\nerror IsShutdown();\nerror PoolAddressIsNull();\n\n/**\n * @title Reusable contract that handles accesses\n */\nabstract contract Manageable is IManageable, SynthContext, Initializable {\n    /**\n     * @notice Pool contract\n     */\n    IPool public pool;\n\n    /**\n     * @dev Throws if `_msgSender()` isn't the pool\n     */\n    modifier onlyPool() {\n        if (_msgSender() != address(pool)) revert SenderIsNotPool();\n        _;\n    }\n\n    /**\n     * @dev Throws if `_msgSender()` isn't the governor\n     */\n    modifier onlyGovernor() {\n        if (_msgSender() != governor()) revert SenderIsNotGovernor();\n        _;\n    }\n\n    /**\n     * @dev Throws if contract is paused\n     */\n    modifier whenNotPaused() {\n        if (pool.paused()) revert IsPaused();\n        _;\n    }\n\n    /**\n     * @dev Throws if contract is shutdown\n     */\n    modifier whenNotShutdown() {\n        if (pool.everythingStopped()) revert IsShutdown();\n        _;\n    }\n\n    // solhint-disable-next-line func-name-mixedcase\n    function __Manageable_init(IPool pool_) internal onlyInitializing {\n        if (address(pool_) == address(0)) revert PoolAddressIsNull();\n        pool = pool_;\n    }\n\n    /**\n     * @notice Get the governor\n     * @return _governor The governor\n     */\n    function governor() public view returns (address _governor) {\n        _governor = IGovernable(address(pool)).governor();\n    }\n\n    /// @inheritdoc SynthContext\n    function poolRegistry() public view override returns (IPoolRegistry) {\n        return pool.poolRegistry();\n    }\n\n    uint256[49] private __gap;\n}\n"},{"file_path":"contracts/dependencies/openzeppelin/proxy/ERC1967/ERC1967Proxy.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (proxy/ERC1967/ERC1967Proxy.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../Proxy.sol\";\nimport \"./ERC1967Upgrade.sol\";\n\n/**\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\n * implementation address that can be changed. This address is stored in storage in the location specified by\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\n * implementation behind the proxy.\n */\ncontract ERC1967Proxy is Proxy, ERC1967Upgrade {\n    /**\n     * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\n     *\n     * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\n     * function call, and allows initializating the storage of the proxy like a Solidity constructor.\n     */\n    constructor(address _logic, bytes memory _data) payable {\n        assert(_IMPLEMENTATION_SLOT == bytes32(uint256(keccak256(\"eip1967.proxy.implementation\")) - 1));\n        _upgradeToAndCall(_logic, _data, false);\n    }\n\n    /**\n     * @dev Returns the current implementation address.\n     */\n    function _implementation() internal view virtual override returns (address impl) {\n        return ERC1967Upgrade._getImplementation();\n    }\n}\n"},{"file_path":"contracts/dependencies/stargate-protocol/interfaces/IStargateFeeLibrary.sol","source_code":"// SPDX-License-Identifier: BUSL-1.1\n\npragma solidity ^0.8.9;\npragma abicoder v2;\nimport \"../Pool.sol\";\n\ninterface IStargateFeeLibrary {\n    function getFees(\n        uint256 _srcPoolId,\n        uint256 _dstPoolId,\n        uint16 _dstChainId,\n        address _from,\n        uint256 _amountSD\n    ) external returns (Pool.SwapObj memory s);\n\n    function getVersion() external view returns (string memory);\n}\n"},{"file_path":"contracts/dependencies/@layerzerolabs/solidity-examples/token/oft/composable/ComposableOFTCore.sol","source_code":"// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../OFTCore.sol\";\nimport \"./IOFTReceiver.sol\";\nimport \"./IComposableOFTCore.sol\";\nimport \"../../../util/ExcessivelySafeCall.sol\";\n\nabstract contract ComposableOFTCore is OFTCore, IComposableOFTCore {\n    using ExcessivelySafeCall for address;\n    using BytesLib for bytes;\n\n    // packet type\n    uint16 public constant PT_SEND_AND_CALL = 1;\n\n    mapping(uint16 => mapping(bytes => mapping(uint64 => bytes32))) public failedOFTReceivedMessages;\n\n    constructor(address _lzEndpoint) OFTCore(_lzEndpoint) {}\n\n    function supportsInterface(bytes4 interfaceId) public view virtual override(OFTCore, IERC165) returns (bool) {\n        return interfaceId == type(IComposableOFTCore).interfaceId || super.supportsInterface(interfaceId);\n    }\n\n    function estimateSendAndCallFee(\n        uint16 _dstChainId,\n        bytes calldata _toAddress,\n        uint _amount,\n        bytes calldata _payload,\n        uint64 _dstGasForCall,\n        bool _useZro,\n        bytes calldata _adapterParams\n    ) public view virtual override returns (uint nativeFee, uint zroFee) {\n        // mock the payload for sendAndCall()\n        bytes memory payload = abi.encode(\n            PT_SEND_AND_CALL,\n            abi.encodePacked(_msgSender()),\n            _toAddress,\n            _amount,\n            _payload,\n            _dstGasForCall\n        );\n        return lzEndpoint.estimateFees(_dstChainId, address(this), payload, _useZro, _adapterParams);\n    }\n\n    function sendAndCall(\n        address _from,\n        uint16 _dstChainId,\n        bytes calldata _toAddress,\n        uint _amount,\n        bytes calldata _payload,\n        uint64 _dstGasForCall,\n        address payable _refundAddress,\n        address _zroPaymentAddress,\n        bytes calldata _adapterParams\n    ) public payable virtual override {\n        _sendAndCall(\n            _from,\n            _dstChainId,\n            _toAddress,\n            _amount,\n            _payload,\n            _dstGasForCall,\n            _refundAddress,\n            _zroPaymentAddress,\n            _adapterParams\n        );\n    }\n\n    function retryOFTReceived(\n        uint16 _srcChainId,\n        bytes calldata _srcAddress,\n        uint64 _nonce,\n        bytes calldata _from,\n        address _to,\n        uint _amount,\n        bytes calldata _payload\n    ) public virtual override {\n        bytes32 msgHash = failedOFTReceivedMessages[_srcChainId][_srcAddress][_nonce];\n        require(msgHash != bytes32(0), \"ComposableOFTCore: no failed message to retry\");\n\n        bytes32 hash = keccak256(abi.encode(_from, _to, _amount, _payload));\n        require(hash == msgHash, \"ComposableOFTCore: failed message hash mismatch\");\n\n        delete failedOFTReceivedMessages[_srcChainId][_srcAddress][_nonce];\n        IOFTReceiver(_to).onOFTReceived(_srcChainId, _srcAddress, _nonce, _from, _amount, _payload);\n        emit RetryOFTReceivedSuccess(hash);\n    }\n\n    function _nonblockingLzReceive(\n        uint16 _srcChainId,\n        bytes memory _srcAddress,\n        uint64 _nonce,\n        bytes memory _payload\n    ) internal virtual override {\n        uint16 packetType;\n        assembly {\n            packetType := mload(add(_payload, 32))\n        }\n\n        if (packetType == PT_SEND) {\n            _sendAck(_srcChainId, _srcAddress, _nonce, _payload);\n        } else if (packetType == PT_SEND_AND_CALL) {\n            _sendAndCallAck(_srcChainId, _srcAddress, _nonce, _payload);\n        } else {\n            revert(\"ComposableOFTCore: unknown packet type\");\n        }\n    }\n\n    function _sendAndCall(\n        address _from,\n        uint16 _dstChainId,\n        bytes memory _toAddress,\n        uint _amount,\n        bytes calldata _payload,\n        uint64 _dstGasForCall,\n        address payable _refundAddress,\n        address _zroPaymentAddress,\n        bytes memory _adapterParams\n    ) internal virtual {\n        _checkAdapterParams(_dstChainId, PT_SEND_AND_CALL, _adapterParams, _dstGasForCall);\n\n        uint amount = _debitFrom(_from, _dstChainId, _toAddress, _amount);\n\n        bytes memory lzPayload = abi.encode(\n            PT_SEND_AND_CALL,\n            abi.encodePacked(_msgSender()),\n            _toAddress,\n            amount,\n            _payload,\n            _dstGasForCall\n        );\n        _lzSend(_dstChainId, lzPayload, _refundAddress, _zroPaymentAddress, _adapterParams, msg.value);\n\n        emit SendToChain(_dstChainId, _from, _toAddress, amount);\n    }\n\n    function _sendAndCallAck(\n        uint16 _srcChainId,\n        bytes memory _srcAddress,\n        uint64 _nonce,\n        bytes memory _payload\n    ) internal virtual {\n        (, bytes memory from, bytes memory toAddress, uint amount, bytes memory payload, uint64 gasForCall) = abi\n            .decode(_payload, (uint16, bytes, bytes, uint, bytes, uint64));\n\n        address to = toAddress.toAddress(0);\n\n        amount = _creditTo(_srcChainId, to, amount);\n        emit ReceiveFromChain(_srcChainId, to, amount);\n\n        if (!_isContract(to)) {\n            emit NonContractAddress(to);\n            return;\n        }\n\n        _safeCallOnOFTReceived(_srcChainId, _srcAddress, _nonce, from, to, amount, payload, gasForCall);\n    }\n\n    function _safeCallOnOFTReceived(\n        uint16 _srcChainId,\n        bytes memory _srcAddress,\n        uint64 _nonce,\n        bytes memory _from,\n        address _to,\n        uint _amount,\n        bytes memory _payload,\n        uint _gasForCall\n    ) internal virtual {\n        (bool success, bytes memory reason) = _to.excessivelySafeCall(\n            _gasForCall,\n            150,\n            abi.encodeWithSelector(\n                IOFTReceiver.onOFTReceived.selector,\n                _srcChainId,\n                _srcAddress,\n                _nonce,\n                _from,\n                _amount,\n                _payload\n            )\n        );\n        if (!success) {\n            failedOFTReceivedMessages[_srcChainId][_srcAddress][_nonce] = keccak256(\n                abi.encode(_from, _to, _amount, _payload)\n            );\n            emit CallOFTReceivedFailure(_srcChainId, _srcAddress, _nonce, _from, _to, _amount, _payload, reason);\n        } else {\n            bytes32 hash = keccak256(abi.encode(_from, _to, _amount, _payload));\n            emit CallOFTReceivedSuccess(_srcChainId, _srcAddress, _nonce, hash);\n        }\n    }\n\n    function _isContract(address _account) internal view returns (bool) {\n        return _account.code.length > 0;\n    }\n}\n"},{"file_path":"contracts/dependencies/openzeppelin-upgradeable/utils/ContextUpgradeable.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\nimport \"../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    /**\n     * @dev This empty reserved space is put in place to allow future versions to add new\n     * variables without shifting down storage in the inheritance chain.\n     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n     */\n    uint256[50] private __gap;\n}\n"},{"file_path":"contracts/dependencies/@layerzerolabs/solidity-examples/token/oft/composable/ComposableBasedOFT.sol","source_code":"// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"./ComposableOFT.sol\";\n\ncontract ComposableBasedOFT is ComposableOFT {\n    constructor(\n        string memory _name,\n        string memory _symbol,\n        address _lzEndpoint\n    ) ComposableOFT(_name, _symbol, _lzEndpoint) {}\n\n    function circulatingSupply() public view virtual override returns (uint) {\n        unchecked {\n            return totalSupply() - balanceOf(address(this));\n        }\n    }\n\n    function _debitFrom(address _from, uint16, bytes memory, uint _amount) internal virtual override returns (uint) {\n        address spender = _msgSender();\n        if (_from != spender) _spendAllowance(_from, spender, _amount);\n        _transfer(_from, address(this), _amount);\n        return _amount;\n    }\n\n    function _creditTo(uint16, address _toAddress, uint _amount) internal virtual override returns (uint) {\n        _transfer(address(this), _toAddress, _amount);\n        return _amount;\n    }\n}\n"},{"file_path":"contracts/dependencies/@layerzerolabs/solidity-examples/contracts-upgradeable/lzApp/NonblockingLzAppUpgradeable.sol","source_code":"// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.2;\n\nimport \"./LzAppUpgradeable.sol\";\nimport \"../../util/ExcessivelySafeCall.sol\";\n\n/*\n * the default LayerZero messaging behaviour is blocking, i.e. any failed message will block the channel\n * this abstract class try-catch all fail messages and store locally for future retry. hence, non-blocking\n * NOTE: if the srcAddress is not configured properly, it will still block the message pathway from (srcChainId, srcAddress)\n */\nabstract contract NonblockingLzAppUpgradeable is Initializable, LzAppUpgradeable {\n    using ExcessivelySafeCall for address;\n\n    function __NonblockingLzAppUpgradeable_init(address _endpoint) internal onlyInitializing {\n        __Ownable_init_unchained();\n        __LzAppUpgradeable_init_unchained(_endpoint);\n    }\n\n    function __NonblockingLzAppUpgradeable_init_unchained(address _endpoint) internal onlyInitializing {}\n\n    mapping(uint16 => mapping(bytes => mapping(uint64 => bytes32))) public failedMessages;\n\n    event MessageFailed(uint16 _srcChainId, bytes _srcAddress, uint64 _nonce, bytes _payload, bytes _reason);\n    event RetryMessageSuccess(uint16 _srcChainId, bytes _srcAddress, uint64 _nonce, bytes32 _payloadHash);\n\n    // overriding the virtual function in LzReceiver\n    function _blockingLzReceive(uint16 _srcChainId, bytes memory _srcAddress, uint64 _nonce, bytes memory _payload) internal virtual override {\n        (bool success, bytes memory reason) = address(this).excessivelySafeCall(gasleft(), 150, abi.encodeWithSelector(this.nonblockingLzReceive.selector, _srcChainId, _srcAddress, _nonce, _payload));\n        // try-catch all errors/exceptions\n        if (!success) {\n            _storeFailedMessage(_srcChainId, _srcAddress, _nonce, _payload, reason);\n        }\n    }\n\n    function _storeFailedMessage(uint16 _srcChainId, bytes memory _srcAddress, uint64 _nonce, bytes memory _payload, bytes memory _reason) internal virtual {\n        failedMessages[_srcChainId][_srcAddress][_nonce] = keccak256(_payload);\n        emit MessageFailed(_srcChainId, _srcAddress, _nonce, _payload, _reason);\n    }\n\n    function nonblockingLzReceive(uint16 _srcChainId, bytes calldata _srcAddress, uint64 _nonce, bytes calldata _payload) public virtual {\n        // only internal transaction\n        require(_msgSender() == address(this), \"NonblockingLzApp: caller must be LzApp\");\n        _nonblockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload);\n    }\n\n    //@notice override this function\n    function _nonblockingLzReceive(uint16 _srcChainId, bytes memory _srcAddress, uint64 _nonce, bytes memory _payload) internal virtual;\n\n    function retryMessage(uint16 _srcChainId, bytes calldata _srcAddress, uint64 _nonce, bytes calldata _payload) public payable virtual {\n        // assert there is message to retry\n        bytes32 payloadHash = failedMessages[_srcChainId][_srcAddress][_nonce];\n        require(payloadHash != bytes32(0), \"NonblockingLzApp: no stored message\");\n        require(keccak256(_payload) == payloadHash, \"NonblockingLzApp: invalid payload\");\n        // clear the stored message\n        failedMessages[_srcChainId][_srcAddress][_nonce] = bytes32(0);\n        // execute the message. revert if it fails again\n        _nonblockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload);\n        emit RetryMessageSuccess(_srcChainId, _srcAddress, _nonce, payloadHash);\n    }\n\n    /**\n     * @dev This empty reserved space is put in place to allow future versions to add new\n     * variables without shifting down storage in the inheritance chain.\n     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n     */\n    uint[49] private __gap;\n}\n"},{"file_path":"contracts/interfaces/IManageable.sol","source_code":"// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.24;\n\nimport {IPool} from \"./IPool.sol\";\n\n/**\n * @notice Manageable interface\n */\ninterface IManageable {\n    function pool() external view returns (IPool _pool);\n}\n"},{"file_path":"contracts/dependencies/openzeppelin-upgradeable/access/OwnableUpgradeable.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n    address private _owner;\n\n    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n    /**\n     * @dev Initializes the contract setting the deployer as the initial owner.\n     */\n    function __Ownable_init() internal onlyInitializing {\n        __Ownable_init_unchained();\n    }\n\n    function __Ownable_init_unchained() internal onlyInitializing {\n        _transferOwnership(_msgSender());\n    }\n\n    /**\n     * @dev Returns the address of the current owner.\n     */\n    function owner() public view virtual returns (address) {\n        return _owner;\n    }\n\n    /**\n     * @dev Throws if called by any account other than the owner.\n     */\n    modifier onlyOwner() {\n        require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n        _;\n    }\n\n    /**\n     * @dev Leaves the contract without owner. It will not be possible to call\n     * `onlyOwner` functions anymore. Can only be called by the current owner.\n     *\n     * NOTE: Renouncing ownership will leave the contract without an owner,\n     * thereby removing any functionality that is only available to the owner.\n     */\n    function renounceOwnership() public virtual onlyOwner {\n        _transferOwnership(address(0));\n    }\n\n    /**\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\n     * Can only be called by the current owner.\n     */\n    function transferOwnership(address newOwner) public virtual onlyOwner {\n        require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n        _transferOwnership(newOwner);\n    }\n\n    /**\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\n     * Internal function without access restriction.\n     */\n    function _transferOwnership(address newOwner) internal virtual {\n        address oldOwner = _owner;\n        _owner = newOwner;\n        emit OwnershipTransferred(oldOwner, newOwner);\n    }\n\n    /**\n     * @dev This empty reserved space is put in place to allow future versions to add new\n     * variables without shifting down storage in the inheritance chain.\n     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n     */\n    uint256[49] private __gap;\n}\n"},{"file_path":"contracts/dependencies/openzeppelin/proxy/transparent/TransparentUpgradeableProxy.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (proxy/transparent/TransparentUpgradeableProxy.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC1967/ERC1967Proxy.sol\";\n\n/**\n * @dev This contract implements a proxy that is upgradeable by an admin.\n *\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\n * clashing], which can potentially be used in an attack, this contract uses the\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\n * things that go hand in hand:\n *\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\n * that call matches one of the admin functions exposed by the proxy itself.\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\n * \"admin cannot fallback to proxy target\".\n *\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\n * to sudden errors when trying to call a function from the proxy implementation.\n *\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\n */\ncontract TransparentUpgradeableProxy is ERC1967Proxy {\n    /**\n     * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\n     * optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\n     */\n    constructor(\n        address _logic,\n        address admin_,\n        bytes memory _data\n    ) payable ERC1967Proxy(_logic, _data) {\n        assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\"eip1967.proxy.admin\")) - 1));\n        _changeAdmin(admin_);\n    }\n\n    /**\n     * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\n     */\n    modifier ifAdmin() {\n        if (msg.sender == _getAdmin()) {\n            _;\n        } else {\n            _fallback();\n        }\n    }\n\n    /**\n     * @dev Returns the current admin.\n     *\n     * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\n     *\n     * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\n     * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\n     * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\n     */\n    function admin() external ifAdmin returns (address admin_) {\n        admin_ = _getAdmin();\n    }\n\n    /**\n     * @dev Returns the current implementation.\n     *\n     * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\n     *\n     * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\n     * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\n     * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\n     */\n    function implementation() external ifAdmin returns (address implementation_) {\n        implementation_ = _implementation();\n    }\n\n    /**\n     * @dev Changes the admin of the proxy.\n     *\n     * Emits an {AdminChanged} event.\n     *\n     * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\n     */\n    function changeAdmin(address newAdmin) external virtual ifAdmin {\n        _changeAdmin(newAdmin);\n    }\n\n    /**\n     * @dev Upgrade the implementation of the proxy.\n     *\n     * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\n     */\n    function upgradeTo(address newImplementation) external ifAdmin {\n        _upgradeToAndCall(newImplementation, bytes(\"\"), false);\n    }\n\n    /**\n     * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\n     * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\n     * proxied contract.\n     *\n     * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\n     */\n    function upgradeToAndCall(address newImplementation, bytes calldata data) external payable ifAdmin {\n        _upgradeToAndCall(newImplementation, data, true);\n    }\n\n    /**\n     * @dev Returns the current admin.\n     */\n    function _admin() internal view virtual returns (address) {\n        return _getAdmin();\n    }\n\n    /**\n     * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\n     */\n    function _beforeFallback() internal virtual override {\n        require(msg.sender != _getAdmin(), \"TransparentUpgradeableProxy: admin cannot fallback to proxy target\");\n        super._beforeFallback();\n    }\n}\n"},{"file_path":"contracts/dependencies/@layerzerolabs/solidity-examples/token/oft/OFTCore.sol","source_code":"// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../../lzApp/NonblockingLzApp.sol\";\nimport \"./IOFTCore.sol\";\nimport \"../../../../../dependencies/openzeppelin/utils/introspection/ERC165.sol\";\n\nabstract contract OFTCore is NonblockingLzApp, ERC165, IOFTCore {\n    using BytesLib for bytes;\n\n    uint public constant NO_EXTRA_GAS = 0;\n\n    // packet type\n    uint16 public constant PT_SEND = 0;\n\n    bool public useCustomAdapterParams;\n\n    constructor(address _lzEndpoint) NonblockingLzApp(_lzEndpoint) {}\n\n    function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {\n        return interfaceId == type(IOFTCore).interfaceId || super.supportsInterface(interfaceId);\n    }\n\n    function estimateSendFee(\n        uint16 _dstChainId,\n        bytes calldata _toAddress,\n        uint _amount,\n        bool _useZro,\n        bytes calldata _adapterParams\n    ) public view virtual override returns (uint nativeFee, uint zroFee) {\n        // mock the payload for sendFrom()\n        bytes memory payload = abi.encode(PT_SEND, _toAddress, _amount);\n        return lzEndpoint.estimateFees(_dstChainId, address(this), payload, _useZro, _adapterParams);\n    }\n\n    function sendFrom(\n        address _from,\n        uint16 _dstChainId,\n        bytes calldata _toAddress,\n        uint _amount,\n        address payable _refundAddress,\n        address _zroPaymentAddress,\n        bytes calldata _adapterParams\n    ) public payable virtual override {\n        _send(_from, _dstChainId, _toAddress, _amount, _refundAddress, _zroPaymentAddress, _adapterParams);\n    }\n\n    function setUseCustomAdapterParams(bool _useCustomAdapterParams) public virtual onlyOwner {\n        useCustomAdapterParams = _useCustomAdapterParams;\n        emit SetUseCustomAdapterParams(_useCustomAdapterParams);\n    }\n\n    function _nonblockingLzReceive(\n        uint16 _srcChainId,\n        bytes memory _srcAddress,\n        uint64 _nonce,\n        bytes memory _payload\n    ) internal virtual override {\n        uint16 packetType;\n        assembly {\n            packetType := mload(add(_payload, 32))\n        }\n\n        if (packetType == PT_SEND) {\n            _sendAck(_srcChainId, _srcAddress, _nonce, _payload);\n        } else {\n            revert(\"OFTCore: unknown packet type\");\n        }\n    }\n\n    function _send(\n        address _from,\n        uint16 _dstChainId,\n        bytes memory _toAddress,\n        uint _amount,\n        address payable _refundAddress,\n        address _zroPaymentAddress,\n        bytes memory _adapterParams\n    ) internal virtual {\n        _checkAdapterParams(_dstChainId, PT_SEND, _adapterParams, NO_EXTRA_GAS);\n\n        uint amount = _debitFrom(_from, _dstChainId, _toAddress, _amount);\n\n        bytes memory lzPayload = abi.encode(PT_SEND, _toAddress, amount);\n        _lzSend(_dstChainId, lzPayload, _refundAddress, _zroPaymentAddress, _adapterParams, msg.value);\n\n        emit SendToChain(_dstChainId, _from, _toAddress, amount);\n    }\n\n    function _sendAck(uint16 _srcChainId, bytes memory, uint64, bytes memory _payload) internal virtual {\n        (, bytes memory toAddressBytes, uint amount) = abi.decode(_payload, (uint16, bytes, uint));\n\n        address to = toAddressBytes.toAddress(0);\n\n        amount = _creditTo(_srcChainId, to, amount);\n        emit ReceiveFromChain(_srcChainId, to, amount);\n    }\n\n    function _checkAdapterParams(\n        uint16 _dstChainId,\n        uint16 _pkType,\n        bytes memory _adapterParams,\n        uint _extraGas\n    ) internal virtual {\n        if (useCustomAdapterParams) {\n            _checkGasLimit(_dstChainId, _pkType, _adapterParams, _extraGas);\n        } else {\n            require(_adapterParams.length == 0, \"OFTCore: _adapterParams must be empty.\");\n        }\n    }\n\n    function _debitFrom(\n        address _from,\n        uint16 _dstChainId,\n        bytes memory _toAddress,\n        uint _amount\n    ) internal virtual returns (uint);\n\n    function _creditTo(uint16 _srcChainId, address _toAddress, uint _amount) internal virtual returns (uint);\n}\n"},{"file_path":"contracts/utils/RecurringAirdrop.sol","source_code":"// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.24;\n\nimport {SafeERC20, IERC20} from \"../dependencies/openzeppelin/token/ERC20/utils/SafeERC20.sol\";\nimport {ReentrancyGuardTransient} from \"../utils/ReentrancyGuardTransient.sol\";\nimport {MerkleProof} from \"../dependencies/openzeppelin/utils/cryptography/MerkleProof.sol\";\nimport {Governable} from \"../access/Governable.sol\";\n\nerror NothingToClaim();\nerror InvalidProof();\nerror NewMerkleRootSameAsCurrent();\nerror ProofsFileIsNull();\n\n/**\n * @title Generic Recurring Airdrop contract\n */\ncontract RecurringAirdrop is ReentrancyGuardTransient, Governable {\n    using SafeERC20 for IERC20;\n\n    /// @notice The token to distribute\n    IERC20 public immutable token;\n\n    /// @notice The merkle root for the current distribution\n    bytes32 public merkleRoot;\n\n    /// @notice The proofs file's IPFS hash\n    bytes32 public proofsFileHash;\n\n    /// @notice The timestamp of the latest merkle root update\n    uint256 public updatedAt;\n\n    /// @notice The Accumulated amount claimed for a given account\n    mapping(address => uint256) public claimed;\n\n    /// @notice Emitted when an account claims reward\n    event RewardClaimed(address indexed to, uint256 amount);\n\n    /// @notice Emitted when the merkle root is updated\n    event MerkleRootUpdated(bytes32 merkleRoot, uint256 createdAt);\n\n    constructor(IERC20 token_) {\n        token = token_;\n    }\n\n    /**\n     * @notice Claim reward\n     * @dev Every tree leaf is a `[account, amount]` tuple, we assume that the `msg.sender` is the account\n     * @param amount_ The amount to claim\n     * @param proof_ The merkle tree proof for the given leaf\n     */\n    function claim(uint256 amount_, bytes32[] calldata proof_) external nonReentrant {\n        if (merkleRoot == bytes32(0)) revert NothingToClaim();\n\n        bytes32 _leaf = keccak256(abi.encodePacked(msg.sender, amount_));\n        if (!MerkleProof.verify(proof_, merkleRoot, _leaf)) revert InvalidProof();\n\n        uint256 _claimable = amount_ - claimed[msg.sender];\n        if (_claimable == 0) revert NothingToClaim();\n\n        claimed[msg.sender] += _claimable;\n\n        _transferReward(msg.sender, _claimable);\n\n        emit RewardClaimed(msg.sender, _claimable);\n    }\n\n    /**\n     * @notice Transfer reward to the user\n     * @param to_ The claim account\n     * @param amount_ The reward amount\n     */\n    function _transferReward(address to_, uint256 amount_) internal virtual {\n        token.safeTransfer(to_, amount_);\n    }\n\n    /**\n     * @notice Update merkle tree root\n     * @param merkleRoot_ The merkle root\n     */\n    function updateMerkleRoot(bytes32 merkleRoot_, bytes32 proofsFileHash_) external onlyGovernor {\n        if (merkleRoot_ == merkleRoot) revert NewMerkleRootSameAsCurrent();\n        if (proofsFileHash_ == bytes32(0)) revert ProofsFileIsNull();\n\n        merkleRoot = merkleRoot_;\n        updatedAt = block.timestamp;\n        proofsFileHash = proofsFileHash_;\n\n        emit MerkleRootUpdated(merkleRoot_, block.timestamp);\n    }\n}\n"},{"file_path":"contracts/interfaces/IGovernable.sol","source_code":"// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.24;\n\n/**\n * @notice Governable interface\n */\ninterface IGovernable {\n    function governor() external view returns (address _governor);\n\n    function transferGovernorship(address _proposedGovernor) external;\n}\n"}],"certified":false,"conflicting_implementations":null,"abi":[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AddressIsNull","type":"error"},{"inputs":[],"name":"AmountGreaterThanMaxLiquidable","type":"error"},{"inputs":[],"name":"AmountInIsInvalid","type":"error"},{"inputs":[],"name":"AmountIsTooHigh","type":"error"},{"inputs":[],"name":"AmountIsZero","type":"error"},{"inputs":[],"name":"CanNotLiquidateOwnPosition","type":"error"},{"inputs":[],"name":"CollateralFactorTooHigh","type":"error"},{"inputs":[],"name":"DebtTokenAlreadyExists","type":"error"},{"inputs":[],"name":"DebtTokenDoesNotExist","type":"error"},{"inputs":[],"name":"DepositTokenAlreadyExists","type":"error"},{"inputs":[],"name":"DepositTokenDoesNotExist","type":"error"},{"inputs":[],"name":"FallbackIsNotAllowed","type":"error"},{"inputs":[],"name":"InvalidDepositToken","type":"error"},{"inputs":[],"name":"IsNotPaused","type":"error"},{"inputs":[],"name":"IsNotShutdown","type":"error"},{"inputs":[],"name":"IsPaused","type":"error"},{"inputs":[],"name":"IsShutdown","type":"error"},{"inputs":[],"name":"MaxLiquidableTooHigh","type":"error"},{"inputs":[],"name":"NewValueIsSameAsCurrent","type":"error"},{"inputs":[],"name":"PoolRegistryIsNull","type":"error"},{"inputs":[],"name":"PositionIsHealthy","type":"error"},{"inputs":[],"name":"ProposedGovernorIsNull","type":"error"},{"inputs":[],"name":"ReachedMaxDepositTokens","type":"error"},{"inputs":[],"name":"ReceiveIsNotAllowed","type":"error"},{"inputs":[],"name":"ReentrancyGuardReentrantCall","type":"error"},{"inputs":[],"name":"RemainingDebtIsLowerThanTheFloor","type":"error"},{"inputs":[],"name":"RewardDistributorAlreadyExists","type":"error"},{"inputs":[],"name":"RewardDistributorDoesNotExist","type":"error"},{"inputs":[],"name":"SenderIsNotAuthorized","type":"error"},{"inputs":[],"name":"SenderIsNotDebtToken","type":"error"},{"inputs":[],"name":"SenderIsNotDepositToken","type":"error"},{"inputs":[],"name":"SenderIsNotGovernor","type":"error"},{"inputs":[],"name":"SenderIsNotTheProposedGovernor","type":"error"},{"inputs":[],"name":"SwapFeatureIsInactive","type":"error"},{"inputs":[],"name":"SyntheticDoesNotExist","type":"error"},{"inputs":[],"name":"SyntheticIsInUse","type":"error"},{"inputs":[],"name":"SyntheticIsNull","type":"error"},{"inputs":[],"name":"TotalSupplyIsNotZero","type":"error"},{"inputs":[],"name":"UnderlyingAssetInUse","type":"error"},{"inputs":[],"name":"UserReachedMaxTokens","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldDebtFloorInUsd","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newDebtFloorInUsd","type":"uint256"}],"name":"DebtFloorUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"contract IDebtToken","name":"debtToken","type":"address"}],"name":"DebtTokenAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"contract IDebtToken","name":"debtToken","type":"address"}],"name":"DebtTokenRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"depositToken","type":"address"}],"name":"DepositTokenAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"contract IDepositToken","name":"depositToken","type":"address"}],"name":"DepositTokenRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"contract IFeeProvider","name":"oldFeeProvider","type":"address"},{"indexed":true,"internalType":"contract IFeeProvider","name":"newFeeProvider","type":"address"}],"name":"FeeProviderUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldMaxLiquidable","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newMaxLiquidable","type":"uint256"}],"name":"MaxLiquidableUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"caller","type":"address"}],"name":"Open","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"caller","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"liquidator","type":"address"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"contract ISyntheticToken","name":"syntheticToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"amountRepaid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"depositSeized","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"fee","type":"uint256"}],"name":"PositionLiquidated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"contract IRewardsDistributor","name":"_distributor","type":"address"}],"name":"RewardsDistributorAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"contract IRewardsDistributor","name":"_distributor","type":"address"}],"name":"RewardsDistributorRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"caller","type":"address"}],"name":"Shutdown","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"contract ISmartFarmingManager","name":"oldSmartFarmingManager","type":"address"},{"indexed":false,"internalType":"contract ISmartFarmingManager","name":"newSmartFarmingManager","type":"address"}],"name":"SmartFarmingManagerUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"newActive","type":"bool"}],"name":"SwapActiveUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"contract ISyntheticToken","name":"syntheticTokenIn","type":"address"},{"indexed":true,"internalType":"contract ISyntheticToken","name":"syntheticTokenOut","type":"address"},{"indexed":false,"internalType":"uint256","name":"amountIn","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amountOut","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"fee","type":"uint256"}],"name":"SyntheticTokenSwapped","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"contract ITreasury","name":"oldTreasury","type":"address"},{"indexed":true,"internalType":"contract ITreasury","name":"newTreasury","type":"address"}],"name":"TreasuryUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"caller","type":"address"}],"name":"Unpaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousGovernor","type":"address"},{"indexed":true,"internalType":"address","name":"proposedGovernor","type":"address"}],"name":"UpdatedGovernor","type":"event"},{"stateMutability":"payable","type":"fallback"},{"inputs":[],"name":"MAX_TOKENS_PER_USER","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"VERSION","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"acceptGovernorship","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IDebtToken","name":"debtToken_","type":"address"}],"name":"addDebtToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"depositToken_","type":"address"}],"name":"addDepositToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IRewardsDistributor","name":"distributor_","type":"address"}],"name":"addRewardsDistributor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account_","type":"address"}],"name":"addToDebtTokensOfAccount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account_","type":"address"}],"name":"addToDepositTokensOfAccount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"debtFloorInUsd","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account_","type":"address"}],"name":"debtOf","outputs":[{"internalType":"uint256","name":"_debtInUsd","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account_","type":"address"}],"name":"debtPositionOf","outputs":[{"internalType":"bool","name":"_isHealthy","type":"bool"},{"internalType":"uint256","name":"_depositInUsd","type":"uint256"},{"internalType":"uint256","name":"_debtInUsd","type":"uint256"},{"internalType":"uint256","name":"_issuableLimitInUsd","type":"uint256"},{"internalType":"uint256","name":"_issuableInUsd","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract ISyntheticToken","name":"","type":"address"}],"name":"debtTokenOf","outputs":[{"internalType":"contract IDebtToken","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account_","type":"address"}],"name":"depositOf","outputs":[{"internalType":"uint256","name":"_depositInUsd","type":"uint256"},{"internalType":"uint256","name":"_issuableLimitInUsd","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"name":"depositTokenOf","outputs":[{"internalType":"contract IDepositToken","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IDebtToken","name":"debtToken_","type":"address"}],"name":"doesDebtTokenExist","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IDepositToken","name":"depositToken_","type":"address"}],"name":"doesDepositTokenExist","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract ISyntheticToken","name":"syntheticToken_","type":"address"}],"name":"doesSyntheticTokenExist","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"everythingStopped","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"feeCollector","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"feeProvider","outputs":[{"internalType":"contract IFeeProvider","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getDebtTokens","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account_","type":"address"}],"name":"getDebtTokensOfAccount","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getDepositTokens","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account_","type":"address"}],"name":"getDepositTokensOfAccount","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getRewardsDistributors","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"governor","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IPoolRegistry","name":"poolRegistry_","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sender_","type":"address"}],"name":"isGuardian","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isSwapActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract ISyntheticToken","name":"syntheticToken_","type":"address"},{"internalType":"address","name":"account_","type":"address"},{"internalType":"uint256","name":"amountToRepay_","type":"uint256"},{"internalType":"contract IDepositToken","name":"depositToken_","type":"address"}],"name":"liquidate","outputs":[{"internalType":"uint256","name":"_totalSeized","type":"uint256"},{"internalType":"uint256","name":"_toLiquidator","type":"uint256"},{"internalType":"uint256","name":"_fee","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"masterOracle","outputs":[{"internalType":"contract IMasterOracle","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxLiquidable","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"open","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"poolRegistry","outputs":[{"internalType":"contract IPoolRegistry","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"proposedGovernor","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract ISyntheticToken","name":"syntheticToken_","type":"address"},{"internalType":"uint256","name":"totalToSeize_","type":"uint256"},{"internalType":"contract IDepositToken","name":"depositToken_","type":"address"}],"name":"quoteLiquidateIn","outputs":[{"internalType":"uint256","name":"_amountToRepay","type":"uint256"},{"internalType":"uint256","name":"_toLiquidator","type":"uint256"},{"internalType":"uint256","name":"_fee","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract ISyntheticToken","name":"syntheticToken_","type":"address"},{"internalType":"address","name":"account_","type":"address"},{"internalType":"contract IDepositToken","name":"depositToken_","type":"address"}],"name":"quoteLiquidateMax","outputs":[{"internalType":"uint256","name":"_maxAmountToRepay","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract ISyntheticToken","name":"syntheticToken_","type":"address"},{"internalType":"uint256","name":"amountToRepay_","type":"uint256"},{"internalType":"contract IDepositToken","name":"depositToken_","type":"address"}],"name":"quoteLiquidateOut","outputs":[{"internalType":"uint256","name":"_totalToSeize","type":"uint256"},{"internalType":"uint256","name":"_toLiquidator","type":"uint256"},{"internalType":"uint256","name":"_fee","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract ISyntheticToken","name":"syntheticTokenIn_","type":"address"},{"internalType":"contract ISyntheticToken","name":"syntheticTokenOut_","type":"address"},{"internalType":"uint256","name":"amountOut_","type":"uint256"}],"name":"quoteSwapIn","outputs":[{"internalType":"uint256","name":"_amountIn","type":"uint256"},{"internalType":"uint256","name":"_fee","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract ISyntheticToken","name":"syntheticTokenIn_","type":"address"},{"internalType":"contract ISyntheticToken","name":"syntheticTokenOut_","type":"address"},{"internalType":"uint256","name":"amountIn_","type":"uint256"}],"name":"quoteSwapOut","outputs":[{"internalType":"uint256","name":"_amountOut","type":"uint256"},{"internalType":"uint256","name":"_fee","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IDebtToken","name":"debtToken_","type":"address"}],"name":"removeDebtToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IDepositToken","name":"depositToken_","type":"address"}],"name":"removeDepositToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account_","type":"address"}],"name":"removeFromDebtTokensOfAccount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account_","type":"address"}],"name":"removeFromDepositTokensOfAccount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IRewardsDistributor","name":"distributor_","type":"address"}],"name":"removeRewardsDistributor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"shutdown","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"smartFarmingManager","outputs":[{"internalType":"contract ISmartFarmingManager","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract ISyntheticToken","name":"syntheticTokenIn_","type":"address"},{"internalType":"contract ISyntheticToken","name":"syntheticTokenOut_","type":"address"},{"internalType":"uint256","name":"amountIn_","type":"uint256"}],"name":"swap","outputs":[{"internalType":"uint256","name":"_amountOut","type":"uint256"},{"internalType":"uint256","name":"_fee","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"token_","type":"address"},{"internalType":"address","name":"to_","type":"address"},{"internalType":"uint256","name":"amount_","type":"uint256"}],"name":"sweep","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"toggleIsSwapActive","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"proposedGovernor_","type":"address"}],"name":"transferGovernorship","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"treasury","outputs":[{"internalType":"contract ITreasury","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newDebtFloorInUsd_","type":"uint256"}],"name":"updateDebtFloor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IFeeProvider","name":"feeProvider_","type":"address"}],"name":"updateFeeProvider","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newMaxLiquidable_","type":"uint256"}],"name":"updateMaxLiquidable","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract ISmartFarmingManager","name":"newSmartFarmingManager_","type":"address"}],"name":"updateSmartFarmingManager","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract ITreasury","name":"newTreasury_","type":"address"}],"name":"updateTreasury","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}],"is_changed_bytecode":false,"is_partially_verified":false,"constructor_args":null}