ETH Price: $3,062.20 (-4.05%)

Contract

0x2E2630fE0649457FD3c47fbC714dBC4AA0A0fFC0
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To

There are no matching entries

Please try again later

Latest 1 internal transaction

Advanced mode:
Parent Transaction Hash Block From To
210338192024-10-24 6:59:2321 days ago1729753163  Contract Creation0 ETH
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
FluidDexResolver

Compiler Version
v0.8.21+commit.d9974bed

Optimization Enabled:
Yes with 5000 runs

Other Settings:
paris EvmVersion
File 1 of 13 : main.sol
// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.21;

import { AddressCalcs } from "../../../libraries/addressCalcs.sol";
import { DexSlotsLink } from "../../../libraries/dexSlotsLink.sol";
import { DexCalcs } from "../../../libraries/dexCalcs.sol";
import { BigMathMinified } from "../../../libraries/bigMathMinified.sol";
import { BytesSliceAndConcat } from "../../../libraries/bytesSliceAndConcat.sol";
import { IFluidDexT1 } from "../../../protocols/dex/interfaces/iDexT1.sol";
import { Structs as FluidLiquidityResolverStructs } from "../liquidity/structs.sol";
import { Structs } from "./structs.sol";
import { Variables } from "./variables.sol";

/// @title DexFactoryViews
/// @notice Abstract contract providing view functions for DEX factory-related operations
abstract contract DexFactoryViews is Variables {
    /// @notice Get the address of a DEX given its ID
    /// @param dexId_ The ID of the DEX
    /// @return dex_ The address of the DEX
    function getDexAddress(uint256 dexId_) public view returns (address dex_) {
        return AddressCalcs.addressCalc(address(FACTORY), dexId_);
    }

    /// @notice Get the ID of a DEX given its address
    /// @param dex_ The address of the DEX
    /// @return id_ The ID of the DEX
    function getDexId(address dex_) public view returns (uint id_) {
        id_ = IFluidDexT1(dex_).DEX_ID();
    }

    /// @notice Get the total number of DEXes
    /// @return The total number of DEXes
    function getTotalDexes() public view returns (uint) {
        return FACTORY.totalDexes();
    }

    /// @notice Get an array of all DEX addresses
    /// @return dexes_ An array containing all DEX addresses
    function getAllDexAddresses() public view returns (address[] memory dexes_) {
        uint totalDexes_ = getTotalDexes();
        dexes_ = new address[](totalDexes_);
        for (uint i = 0; i < totalDexes_; i++) {
            dexes_[i] = getDexAddress((i + 1));
        }
    }
}

/// @title DexStorageVars
/// @notice Abstract contract providing view functions for DEX storage variables
abstract contract DexStorageVars is Variables {
    /// @notice Get the raw DEX variables
    /// @param dex_ The address of the DEX
    /// @return The raw DEX variables
    function getDexVariablesRaw(address dex_) public view returns (uint) {
        return IFluidDexT1(dex_).readFromStorage(bytes32(DexSlotsLink.DEX_VARIABLES_SLOT));
    }

    /// @notice Get the raw DEX variables2
    /// @param dex_ The address of the DEX
    /// @return The raw DEX variables2
    function getDexVariables2Raw(address dex_) public view returns (uint) {
        return IFluidDexT1(dex_).readFromStorage(bytes32(DexSlotsLink.DEX_VARIABLES2_SLOT));
    }

    /// @notice Get the total supply shares slot data of a DEX
    /// @param dex_ The address of the DEX
    /// @return The total supply shares
    function getTotalSupplySharesRaw(address dex_) public view returns (uint) {
        return IFluidDexT1(dex_).readFromStorage(bytes32(DexSlotsLink.DEX_TOTAL_SUPPLY_SHARES_SLOT));
    }

    /// @notice Get the raw user supply data for a specific user and DEX
    /// @param dex_ The address of the DEX
    /// @param user_ The address of the user
    /// @return The raw user supply data
    function getUserSupplyDataRaw(address dex_, address user_) public view returns (uint) {
        return
            IFluidDexT1(dex_).readFromStorage(
                DexSlotsLink.calculateMappingStorageSlot(DexSlotsLink.DEX_USER_SUPPLY_MAPPING_SLOT, user_)
            );
    }

    /// @notice Get the total borrow shares slot data of a DEX
    /// @param dex_ The address of the DEX
    /// @return The total borrow shares
    function getTotalBorrowSharesRaw(address dex_) public view returns (uint) {
        return IFluidDexT1(dex_).readFromStorage(bytes32(DexSlotsLink.DEX_TOTAL_BORROW_SHARES_SLOT));
    }

    /// @notice Get the raw user borrow data for a specific user and DEX
    /// @param dex_ The address of the DEX
    /// @param user_ The address of the user
    /// @return The raw user borrow data
    function getUserBorrowDataRaw(address dex_, address user_) public view returns (uint) {
        return
            IFluidDexT1(dex_).readFromStorage(
                DexSlotsLink.calculateMappingStorageSlot(DexSlotsLink.DEX_USER_BORROW_MAPPING_SLOT, user_)
            );
    }

    /// @notice Get the raw oracle data for a specific DEX and index
    /// @param dex_ The address of the DEX
    /// @param index_ The index of the oracle data
    /// @return The raw oracle data
    function getOracleRaw(address dex_, uint index_) public view returns (uint) {
        return
            IFluidDexT1(dex_).readFromStorage(
                _calculateStorageSlotUintMapping(DexSlotsLink.DEX_ORACLE_MAPPING_SLOT, index_)
            );
    }

    /// @notice Get the raw range shift for a DEX
    /// @param dex_ The address of the DEX
    /// @return The raw range shift
    function getRangeShiftRaw(address dex_) public view returns (uint) {
        return
            IFluidDexT1(dex_).readFromStorage(bytes32(DexSlotsLink.DEX_RANGE_THRESHOLD_SHIFTS_SLOT)) &
            type(uint128).max;
    }

    /// @notice Get the raw threshold shift for a DEX
    /// @param dex_ The address of the DEX
    /// @return The raw threshold shift
    function getThresholdShiftRaw(address dex_) public view returns (uint) {
        return IFluidDexT1(dex_).readFromStorage(bytes32(DexSlotsLink.DEX_RANGE_THRESHOLD_SHIFTS_SLOT)) >> 128;
    }

    /// @notice Get the raw center price shift for a DEX
    /// @param dex_ The address of the DEX
    /// @return The raw center price shift
    function getCenterPriceShiftRaw(address dex_) public view returns (uint) {
        return IFluidDexT1(dex_).readFromStorage(bytes32(DexSlotsLink.DEX_CENTER_PRICE_SHIFT_SLOT));
    }

    /// @dev Calculate the storage slot for a uint mapping
    /// @param slot_ The base slot of the mapping
    /// @param key_ The key of the mapping
    /// @return The calculated storage slot
    function _calculateStorageSlotUintMapping(uint256 slot_, uint key_) internal pure returns (bytes32) {
        return keccak256(abi.encode(key_, slot_));
    }
}

abstract contract DexActionEstimates {
    address private constant ADDRESS_DEAD = 0x000000000000000000000000000000000000dEaD;

    /// @notice estimates swap IN tokens execution
    /// @param dex_ Dex pool
    /// @param swap0to1_ Direction of swap. If true, swaps token0 for token1; if false, swaps token1 for token0
    /// @param amountIn_ The exact amount of input tokens to swap
    /// @param amountOutMin_ The minimum amount of output tokens the user is willing to accept
    /// @return amountOut_ The amount of output tokens received from the swap
    function estimateSwapIn(
        address dex_,
        bool swap0to1_,
        uint256 amountIn_,
        uint256 amountOutMin_
    ) public payable returns (uint256 amountOut_) {
        try IFluidDexT1(dex_).swapIn{ value: msg.value }(swap0to1_, amountIn_, amountOutMin_, ADDRESS_DEAD) {} catch (
            bytes memory lowLevelData_
        ) {
            (amountOut_) = _decodeLowLevelUint1x(lowLevelData_, IFluidDexT1.FluidDexSwapResult.selector);
        }
    }

    /// @notice estimates swap OUT tokens execution
    /// @param dex_ Dex pool
    /// @param swap0to1_ Direction of swap. If true, swaps token0 for token1; if false, swaps token1 for token0
    /// @param amountOut_ The exact amount of tokens to receive after swap
    /// @param amountInMax_ Maximum amount of tokens to swap in
    /// @return amountIn_ The amount of input tokens used for the swap
    function estimateSwapOut(
        address dex_,
        bool swap0to1_,
        uint256 amountOut_,
        uint256 amountInMax_
    ) public payable returns (uint256 amountIn_) {
        try IFluidDexT1(dex_).swapOut{ value: msg.value }(swap0to1_, amountOut_, amountInMax_, ADDRESS_DEAD) {} catch (
            bytes memory lowLevelData_
        ) {
            (amountIn_) = _decodeLowLevelUint1x(lowLevelData_, IFluidDexT1.FluidDexSwapResult.selector);
        }
    }

    /// @dev Estimate deposit tokens in equal proportion to the current pool ratio
    /// @param dex_ The address of the DEX contract
    /// @param shares_ The number of shares to mint
    /// @param maxToken0Deposit_ Maximum amount of token0 to deposit
    /// @param maxToken1Deposit_ Maximum amount of token1 to deposit
    /// @return token0Amt_ Estimated amount of token0 to deposit
    /// @return token1Amt_ Estimated amount of token1 to deposit
    function estimateDepositPerfect(
        address dex_,
        uint shares_,
        uint maxToken0Deposit_,
        uint maxToken1Deposit_
    ) public payable returns (uint token0Amt_, uint token1Amt_) {
        try
            IFluidDexT1(dex_).depositPerfect{ value: msg.value }(shares_, maxToken0Deposit_, maxToken1Deposit_, true)
        {} catch (bytes memory lowLevelData_) {
            (token0Amt_, token1Amt_) = _decodeLowLevelUint2x(
                lowLevelData_,
                IFluidDexT1.FluidDexPerfectLiquidityOutput.selector
            );
        }
    }

    /// @dev Estimate withdrawal of a perfect amount of collateral liquidity
    /// @param dex_ The address of the DEX contract
    /// @param shares_ The number of shares to withdraw
    /// @param minToken0Withdraw_ The minimum amount of token0 the user is willing to accept
    /// @param minToken1Withdraw_ The minimum amount of token1 the user is willing to accept
    /// @return token0Amt_ Estimated amount of token0 to be withdrawn
    /// @return token1Amt_ Estimated amount of token1 to be withdrawn
    function estimateWithdrawPerfect(
        address dex_,
        uint shares_,
        uint minToken0Withdraw_,
        uint minToken1Withdraw_
    ) public returns (uint token0Amt_, uint token1Amt_) {
        try IFluidDexT1(dex_).withdrawPerfect(shares_, minToken0Withdraw_, minToken1Withdraw_, ADDRESS_DEAD) {} catch (
            bytes memory lowLevelData_
        ) {
            (token0Amt_, token1Amt_) = _decodeLowLevelUint2x(
                lowLevelData_,
                IFluidDexT1.FluidDexPerfectLiquidityOutput.selector
            );
        }
    }

    /// @dev Estimate borrowing tokens in equal proportion to the current debt pool ratio
    /// @param dex_ The address of the DEX contract
    /// @param shares_ The number of shares to borrow
    /// @param minToken0Borrow_ Minimum amount of token0 to borrow
    /// @param minToken1Borrow_ Minimum amount of token1 to borrow
    /// @return token0Amt_ Estimated amount of token0 to be borrowed
    /// @return token1Amt_ Estimated amount of token1 to be borrowed
    function estimateBorrowPerfect(
        address dex_,
        uint shares_,
        uint minToken0Borrow_,
        uint minToken1Borrow_
    ) public returns (uint token0Amt_, uint token1Amt_) {
        try IFluidDexT1(dex_).borrowPerfect(shares_, minToken0Borrow_, minToken1Borrow_, ADDRESS_DEAD) {} catch (
            bytes memory lowLevelData_
        ) {
            (token0Amt_, token1Amt_) = _decodeLowLevelUint2x(
                lowLevelData_,
                IFluidDexT1.FluidDexPerfectLiquidityOutput.selector
            );
        }
    }

    /// @dev Estimate paying back borrowed tokens in equal proportion to the current debt pool ratio
    /// @param dex_ The address of the DEX contract
    /// @param shares_ The number of shares to pay back
    /// @param maxToken0Payback_ Maximum amount of token0 to pay back
    /// @param maxToken1Payback_ Maximum amount of token1 to pay back
    /// @return token0Amt_ Estimated amount of token0 to be paid back
    /// @return token1Amt_ Estimated amount of token1 to be paid back
    function estimatePaybackPerfect(
        address dex_,
        uint shares_,
        uint maxToken0Payback_,
        uint maxToken1Payback_
    ) public payable returns (uint token0Amt_, uint token1Amt_) {
        try
            IFluidDexT1(dex_).paybackPerfect{ value: msg.value }(shares_, maxToken0Payback_, maxToken1Payback_, true)
        {} catch (bytes memory lowLevelData_) {
            (token0Amt_, token1Amt_) = _decodeLowLevelUint2x(
                lowLevelData_,
                IFluidDexT1.FluidDexPerfectLiquidityOutput.selector
            );
        }
    }

    /// @dev Estimate deposit of tokens
    /// @param dex_ The address of the DEX contract
    /// @param token0Amt_ Amount of token0 to deposit
    /// @param token1Amt_ Amount of token1 to deposit
    /// @param minSharesAmt_ Minimum amount of shares to receive
    /// @return shares_ Estimated amount of shares to be minted
    function estimateDeposit(
        address dex_,
        uint token0Amt_,
        uint token1Amt_,
        uint minSharesAmt_
    ) public payable returns (uint shares_) {
        try IFluidDexT1(dex_).deposit{ value: msg.value }(token0Amt_, token1Amt_, minSharesAmt_, true) {} catch (
            bytes memory lowLevelData_
        ) {
            (shares_) = _decodeLowLevelUint1x(lowLevelData_, IFluidDexT1.FluidDexLiquidityOutput.selector);
        }
    }

    /// @dev Estimate withdrawal of tokens
    /// @param dex_ The address of the DEX contract
    /// @param token0Amt_ Amount of token0 to withdraw
    /// @param token1Amt_ Amount of token1 to withdraw
    /// @param maxSharesAmt_ Maximum amount of shares to burn
    /// @return shares_ Estimated amount of shares to be burned
    function estimateWithdraw(
        address dex_,
        uint token0Amt_,
        uint token1Amt_,
        uint maxSharesAmt_
    ) public returns (uint shares_) {
        try IFluidDexT1(dex_).withdraw(token0Amt_, token1Amt_, maxSharesAmt_, ADDRESS_DEAD) {} catch (
            bytes memory lowLevelData_
        ) {
            (shares_) = _decodeLowLevelUint1x(lowLevelData_, IFluidDexT1.FluidDexLiquidityOutput.selector);
        }
    }

    /// @dev Estimate borrowing of tokens
    /// @param dex_ The address of the DEX contract
    /// @param token0Amt_ Amount of token0 to borrow
    /// @param token1Amt_ Amount of token1 to borrow
    /// @param maxSharesAmt_ Maximum amount of shares to mint
    /// @return shares_ Estimated amount of shares to be minted
    function estimateBorrow(
        address dex_,
        uint token0Amt_,
        uint token1Amt_,
        uint maxSharesAmt_
    ) public returns (uint shares_) {
        try IFluidDexT1(dex_).borrow(token0Amt_, token1Amt_, maxSharesAmt_, ADDRESS_DEAD) {} catch (
            bytes memory lowLevelData_
        ) {
            (shares_) = _decodeLowLevelUint1x(lowLevelData_, IFluidDexT1.FluidDexLiquidityOutput.selector);
        }
    }

    /// @dev Estimate paying back of borrowed tokens
    /// @param dex_ The address of the DEX contract
    /// @param token0Amt_ Amount of token0 to pay back
    /// @param token1Amt_ Amount of token1 to pay back
    /// @param minSharesAmt_ Minimum amount of shares to burn
    /// @return shares_ Estimated amount of shares to be burned
    function estimatePayback(
        address dex_,
        uint token0Amt_,
        uint token1Amt_,
        uint minSharesAmt_
    ) public payable returns (uint shares_) {
        try IFluidDexT1(dex_).payback{ value: msg.value }(token0Amt_, token1Amt_, minSharesAmt_, true) {} catch (
            bytes memory lowLevelData_
        ) {
            (shares_) = _decodeLowLevelUint1x(lowLevelData_, IFluidDexT1.FluidDexLiquidityOutput.selector);
        }
    }

    /// @dev Estimate withdrawal of a perfect amount of collateral liquidity in one token
    /// @param dex_ The address of the DEX contract
    /// @param shares_ The number of shares to withdraw
    /// @param minToken0_ The minimum amount of token0 the user is willing to accept
    /// @param minToken1_ The minimum amount of token1 the user is willing to accept
    /// @return withdrawAmt_ Estimated amount of tokens to be withdrawn
    function estimateWithdrawPerfectInOneToken(
        address dex_,
        uint shares_,
        uint minToken0_,
        uint minToken1_
    ) public returns (uint withdrawAmt_) {
        try IFluidDexT1(dex_).withdrawPerfectInOneToken(shares_, minToken0_, minToken1_, ADDRESS_DEAD) {} catch (
            bytes memory lowLevelData_
        ) {
            (withdrawAmt_) = _decodeLowLevelUint1x(lowLevelData_, IFluidDexT1.FluidDexSingleTokenOutput.selector);
        }
    }

    /// @dev Estimate paying back of a perfect amount of borrowed tokens in one token
    /// @param dex_ The address of the DEX contract
    /// @param shares_ The number of shares to pay back
    /// @param maxToken0_ Maximum amount of token0 to pay back
    /// @param maxToken1_ Maximum amount of token1 to pay back
    /// @return paybackAmt_ Estimated amount of tokens to be paid back
    function estimatePaybackPerfectInOneToken(
        address dex_,
        uint shares_,
        uint maxToken0_,
        uint maxToken1_
    ) public payable returns (uint paybackAmt_) {
        try
            IFluidDexT1(dex_).paybackPerfectInOneToken{ value: msg.value }(shares_, maxToken0_, maxToken1_, true)
        {} catch (bytes memory lowLevelData_) {
            (paybackAmt_) = _decodeLowLevelUint1x(lowLevelData_, IFluidDexT1.FluidDexSingleTokenOutput.selector);
        }
    }

    function _decodeLowLevelUint2x(
        bytes memory lowLevelData_,
        bytes4 targetErrorSelector_
    ) internal pure returns (uint value1_, uint value2_) {
        if (lowLevelData_.length < 68) {
            return (0, 0);
        }

        bytes4 errorSelector_;
        assembly {
            // Extract the selector from the error data
            errorSelector_ := mload(add(lowLevelData_, 0x20))
        }
        if (errorSelector_ == targetErrorSelector_) {
            assembly {
                value1_ := mload(add(lowLevelData_, 36))
                value2_ := mload(add(lowLevelData_, 68))
            }
        }
        // else => values remain 0
    }

    function _decodeLowLevelUint1x(
        bytes memory lowLevelData_,
        bytes4 targetErrorSelector_
    ) internal pure returns (uint value1_) {
        if (lowLevelData_.length < 36) {
            return 0;
        }

        bytes4 errorSelector_;
        assembly {
            // Extract the selector from the error data
            errorSelector_ := mload(add(lowLevelData_, 0x20))
        }
        if (errorSelector_ == targetErrorSelector_) {
            assembly {
                value1_ := mload(add(lowLevelData_, 36))
            }
        }
        // else => values remain 0
    }
}

abstract contract DexConstantsViews {
    /// @notice returns all Dex constants
    function getDexConstantsView(address dex_) public view returns (IFluidDexT1.ConstantViews memory constantsView_) {
        return IFluidDexT1(dex_).constantsView();
    }

    /// @notice returns all Dex constants 2
    function getDexConstantsView2(
        address dex_
    ) public view returns (IFluidDexT1.ConstantViews2 memory constantsView2_) {
        return IFluidDexT1(dex_).constantsView2();
    }

    /// @notice Get the addresses of the tokens in a DEX
    /// @param dex_ The address of the DEX
    /// @return token0_ The address of token0 in the DEX
    /// @return token1_ The address of token1 in the DEX
    function getDexTokens(address dex_) public view returns (address token0_, address token1_) {
        IFluidDexT1.ConstantViews memory constantsView_ = IFluidDexT1(dex_).constantsView();
        return (constantsView_.token0, constantsView_.token1);
    }
}

abstract contract DexPublicViews is DexStorageVars, DexConstantsViews {
    /// @notice Get the prices and exchange prices for a DEX
    /// @param dex_ The address of the DEX
    /// @return pex_ A struct containing prices and exchange prices
    /// @dev expected to be called via callStatic
    function getDexPricesAndExchangePrices(
        address dex_
    ) public returns (IFluidDexT1.PricesAndExchangePrice memory pex_) {
        try IFluidDexT1(dex_).getPricesAndExchangePrices() {} catch (bytes memory lowLevelData_) {
            bytes4 errorSelector_;
            assembly {
                // Extract the selector from the error data
                errorSelector_ := mload(add(lowLevelData_, 0x20))
            }
            if (errorSelector_ == IFluidDexT1.FluidDexPricesAndExchangeRates.selector) {
                pex_ = abi.decode(
                    BytesSliceAndConcat.bytesSlice(lowLevelData_, 4, lowLevelData_.length - 4),
                    (IFluidDexT1.PricesAndExchangePrice)
                );
            }
        }
    }

    /// @notice Get the collateral reserves for a DEX
    /// @param dex_ The address of the DEX
    /// @return reserves_ A struct containing collateral reserve information
    /// @dev expected to be called via callStatic
    function getDexCollateralReserves(address dex_) public returns (IFluidDexT1.CollateralReserves memory reserves_) {
        return _getDexCollateralReserves(dex_, getDexConstantsView2(dex_));
    }

    /// @notice Get the debt reserves for a DEX
    /// @param dex_ The address of the DEX
    /// @return reserves_ A struct containing debt reserve information
    /// @dev expected to be called via callStatic
    function getDexDebtReserves(address dex_) public returns (IFluidDexT1.DebtReserves memory reserves_) {
        return _getDexDebtReserves(dex_, getDexConstantsView2(dex_));
    }

    /// @notice get Dex oracle price TWAP data
    /// @param secondsAgos_ array of seconds ago for which TWAP is needed. If user sends [10, 30, 60] then twaps_ will return [10-0, 30-10, 60-30]
    /// @return twaps_ twap price, lowest price (aka minima) & highest price (aka maxima) between secondsAgo checkpoints
    /// @return currentPrice_ price of pool after the most recent swap
    function getDexOraclePrice(
        address dex_,
        uint[] memory secondsAgos_
    ) external view returns (IFluidDexT1.Oracle[] memory twaps_, uint currentPrice_) {
        return IFluidDexT1(dex_).oraclePrice(secondsAgos_);
    }

    /// @dev Get the collateral reserves for a DEX scaled to token decimals
    function _getDexCollateralReserves(
        address dex_,
        IFluidDexT1.ConstantViews2 memory constantsView2_
    ) internal returns (IFluidDexT1.CollateralReserves memory reserves_) {
        uint256 dexVariables2_ = getDexVariables2Raw(dex_);
        if ((dexVariables2_ & 1) != 1) {
            // smart col not enabled
            return IFluidDexT1.CollateralReserves(0, 0, 0, 0);
        }

        try this.getDexPricesAndExchangePrices(dex_) returns (IFluidDexT1.PricesAndExchangePrice memory pex_) {
            try
                IFluidDexT1(dex_).getCollateralReserves(
                    pex_.geometricMean,
                    pex_.upperRange,
                    pex_.lowerRange,
                    pex_.supplyToken0ExchangePrice,
                    pex_.supplyToken1ExchangePrice
                )
            returns (IFluidDexT1.CollateralReserves memory colReserves_) {
                // returned reserves are in 1e12 decimals -> normalize to token decimals
                reserves_.token0RealReserves =
                    (colReserves_.token0RealReserves * constantsView2_.token0DenominatorPrecision) /
                    constantsView2_.token0NumeratorPrecision;
                reserves_.token0ImaginaryReserves =
                    (colReserves_.token0ImaginaryReserves * constantsView2_.token0DenominatorPrecision) /
                    constantsView2_.token0NumeratorPrecision;
                reserves_.token1RealReserves =
                    (colReserves_.token1RealReserves * constantsView2_.token1DenominatorPrecision) /
                    constantsView2_.token1NumeratorPrecision;
                reserves_.token1ImaginaryReserves =
                    (colReserves_.token1ImaginaryReserves * constantsView2_.token1DenominatorPrecision) /
                    constantsView2_.token1NumeratorPrecision;
            } catch {
                reserves_ = IFluidDexT1.CollateralReserves(0, 0, 0, 0);
            }
        } catch {
            reserves_ = IFluidDexT1.CollateralReserves(0, 0, 0, 0);
        }
    }

    /// @dev Get the debt reserves for a DEX scaled to token decimals
    function _getDexDebtReserves(
        address dex_,
        IFluidDexT1.ConstantViews2 memory constantsView2_
    ) internal returns (IFluidDexT1.DebtReserves memory reserves_) {
        uint256 dexVariables2_ = getDexVariables2Raw(dex_);
        if ((dexVariables2_ & 2) != 2) {
            // smart debt not enabled
            return IFluidDexT1.DebtReserves(0, 0, 0, 0, 0, 0);
        }

        try this.getDexPricesAndExchangePrices(dex_) returns (IFluidDexT1.PricesAndExchangePrice memory pex_) {
            try
                IFluidDexT1(dex_).getDebtReserves(
                    pex_.geometricMean,
                    pex_.upperRange,
                    pex_.lowerRange,
                    pex_.borrowToken0ExchangePrice,
                    pex_.borrowToken1ExchangePrice
                )
            returns (IFluidDexT1.DebtReserves memory debtReserves_) {
                // returned reserves are in 1e12 decimals -> normalize to token decimals
                reserves_.token0Debt =
                    (debtReserves_.token0Debt * constantsView2_.token0DenominatorPrecision) /
                    constantsView2_.token0NumeratorPrecision;
                reserves_.token0RealReserves =
                    (debtReserves_.token0RealReserves * constantsView2_.token0DenominatorPrecision) /
                    constantsView2_.token0NumeratorPrecision;
                reserves_.token0ImaginaryReserves =
                    (debtReserves_.token0ImaginaryReserves * constantsView2_.token0DenominatorPrecision) /
                    constantsView2_.token0NumeratorPrecision;
                reserves_.token1Debt =
                    (debtReserves_.token1Debt * constantsView2_.token1DenominatorPrecision) /
                    constantsView2_.token1NumeratorPrecision;
                reserves_.token1RealReserves =
                    (debtReserves_.token1RealReserves * constantsView2_.token1DenominatorPrecision) /
                    constantsView2_.token1NumeratorPrecision;
                reserves_.token1ImaginaryReserves =
                    (debtReserves_.token1ImaginaryReserves * constantsView2_.token1DenominatorPrecision) /
                    constantsView2_.token1NumeratorPrecision;
            } catch {
                reserves_ = IFluidDexT1.DebtReserves(0, 0, 0, 0, 0, 0);
            }
        } catch {
            reserves_ = IFluidDexT1.DebtReserves(0, 0, 0, 0, 0, 0);
        }
    }
}

abstract contract DexUserViews is Variables, Structs, DexConstantsViews, DexPublicViews {
    /// @notice Get user supply data for a specific DEX and user
    /// @param dex_ The address of the DEX
    /// @param user_ The address of the user
    /// @return userSupplyData_ Struct containing user supply data
    function getUserSupplyData(
        address dex_,
        address user_
    ) public view returns (UserSupplyData memory userSupplyData_) {
        uint256 userSupply_ = getUserSupplyDataRaw(dex_, user_);

        if (userSupply_ > 0) {
            // if userSupply_ == 0 -> user not configured yet
            userSupplyData_.isAllowed = userSupply_ & 1 == 1;
            userSupplyData_.supply = BigMathMinified.fromBigNumber(
                (userSupply_ >> DexSlotsLink.BITS_USER_SUPPLY_AMOUNT) & DexCalcs.X64,
                DexCalcs.DEFAULT_EXPONENT_SIZE,
                DexCalcs.DEFAULT_EXPONENT_MASK
            );

            // get updated expanded withdrawal limit
            userSupplyData_.withdrawalLimit = DexCalcs.calcWithdrawalLimitBeforeOperate(
                userSupply_,
                userSupplyData_.supply
            );

            userSupplyData_.lastUpdateTimestamp =
                (userSupply_ >> DexSlotsLink.BITS_USER_SUPPLY_LAST_UPDATE_TIMESTAMP) &
                DexCalcs.X33;
            userSupplyData_.expandPercent =
                (userSupply_ >> DexSlotsLink.BITS_USER_SUPPLY_EXPAND_PERCENT) &
                DexCalcs.X14;
            userSupplyData_.expandDuration =
                (userSupply_ >> DexSlotsLink.BITS_USER_SUPPLY_EXPAND_DURATION) &
                DexCalcs.X24;
            userSupplyData_.baseWithdrawalLimit = BigMathMinified.fromBigNumber(
                (userSupply_ >> DexSlotsLink.BITS_USER_SUPPLY_BASE_WITHDRAWAL_LIMIT) & DexCalcs.X18,
                DexCalcs.DEFAULT_EXPONENT_SIZE,
                DexCalcs.DEFAULT_EXPONENT_MASK
            );

            userSupplyData_.withdrawableUntilLimit = userSupplyData_.supply > userSupplyData_.withdrawalLimit
                ? userSupplyData_.supply - userSupplyData_.withdrawalLimit
                : 0;

            userSupplyData_.withdrawable = userSupplyData_.withdrawableUntilLimit;

            (address token0_, address token1_) = getDexTokens(dex_);
            (userSupplyData_.liquidityUserSupplyDataToken0, ) = LIQUIDITY_RESOLVER.getUserSupplyData(dex_, token0_);
            (userSupplyData_.liquidityUserSupplyDataToken1, ) = LIQUIDITY_RESOLVER.getUserSupplyData(dex_, token1_);
        }
    }

    /// @notice Get user supply data for multiple users in a specific DEX
    /// @param dex_ The address of the DEX
    /// @param users_ Array of user addresses
    /// @return userSuppliesData_ Array of UserSupplyData structs for each user
    function getUserSupplyDatas(
        address dex_,
        address[] calldata users_
    ) public view returns (UserSupplyData[] memory userSuppliesData_) {
        uint256 length_ = users_.length;
        userSuppliesData_ = new UserSupplyData[](length_);

        for (uint256 i; i < length_; i++) {
            (userSuppliesData_[i]) = getUserSupplyData(dex_, users_[i]);
        }
    }

    /// @notice Get user borrow data for a specific DEX and user
    /// @param dex_ The address of the DEX
    /// @param user_ The address of the user
    /// @return userBorrowData_ Struct containing user borrow data
    function getUserBorrowData(
        address dex_,
        address user_
    ) public view returns (UserBorrowData memory userBorrowData_) {
        uint256 userBorrow_ = getUserBorrowDataRaw(dex_, user_);

        if (userBorrow_ > 0) {
            // if userBorrow_ == 0 -> user not configured yet

            userBorrowData_.isAllowed = userBorrow_ & 1 == 1;

            userBorrowData_.borrow = BigMathMinified.fromBigNumber(
                (userBorrow_ >> DexSlotsLink.BITS_USER_BORROW_AMOUNT) & DexCalcs.X64,
                DexCalcs.DEFAULT_EXPONENT_SIZE,
                DexCalcs.DEFAULT_EXPONENT_MASK
            );

            // get updated expanded borrow limit
            userBorrowData_.borrowLimit = DexCalcs.calcBorrowLimitBeforeOperate(userBorrow_, userBorrowData_.borrow);

            userBorrowData_.lastUpdateTimestamp =
                (userBorrow_ >> DexSlotsLink.BITS_USER_BORROW_LAST_UPDATE_TIMESTAMP) &
                DexCalcs.X33;
            userBorrowData_.expandPercent =
                (userBorrow_ >> DexSlotsLink.BITS_USER_BORROW_EXPAND_PERCENT) &
                DexCalcs.X14;
            userBorrowData_.expandDuration =
                (userBorrow_ >> DexSlotsLink.BITS_USER_BORROW_EXPAND_DURATION) &
                DexCalcs.X24;
            userBorrowData_.baseBorrowLimit = BigMathMinified.fromBigNumber(
                (userBorrow_ >> DexSlotsLink.BITS_USER_BORROW_BASE_BORROW_LIMIT) & DexCalcs.X18,
                DexCalcs.DEFAULT_EXPONENT_SIZE,
                DexCalcs.DEFAULT_EXPONENT_MASK
            );
            userBorrowData_.maxBorrowLimit = BigMathMinified.fromBigNumber(
                (userBorrow_ >> DexSlotsLink.BITS_USER_BORROW_MAX_BORROW_LIMIT) & DexCalcs.X18,
                DexCalcs.DEFAULT_EXPONENT_SIZE,
                DexCalcs.DEFAULT_EXPONENT_MASK
            );

            userBorrowData_.borrowableUntilLimit = userBorrowData_.borrowLimit > userBorrowData_.borrow
                ? userBorrowData_.borrowLimit - userBorrowData_.borrow
                : 0;

            userBorrowData_.borrowable = userBorrowData_.borrowableUntilLimit;

            (address token0_, address token1_) = getDexTokens(dex_);
            (userBorrowData_.liquidityUserBorrowDataToken0, ) = LIQUIDITY_RESOLVER.getUserBorrowData(dex_, token0_);
            (userBorrowData_.liquidityUserBorrowDataToken1, ) = LIQUIDITY_RESOLVER.getUserBorrowData(dex_, token1_);
        }
    }

    /// @notice Get user borrow data for multiple users in a specific DEX
    /// @param dex_ The address of the DEX
    /// @param users_ Array of user addresses
    /// @return userBorrowingsData_ Array of UserBorrowData structs for each user
    function getUserBorrowDatas(
        address dex_,
        address[] calldata users_
    ) public view returns (UserBorrowData[] memory userBorrowingsData_) {
        uint256 length_ = users_.length;
        userBorrowingsData_ = new UserBorrowData[](length_);

        for (uint256 i; i < length_; i++) {
            (userBorrowingsData_[i]) = getUserBorrowData(dex_, users_[i]);
        }
    }

    /// @notice Get both user supply and borrow data for multiple users in a specific DEX
    /// @param dex_ The address of the DEX
    /// @param users_ Array of user addresses
    /// @return userSuppliesData_ Array of UserSupplyData structs for each user
    /// @return userBorrowingsData_ Array of UserBorrowData structs for each user
    function getUserBorrowSupplyDatas(
        address dex_,
        address[] calldata users_
    ) public view returns (UserSupplyData[] memory userSuppliesData_, UserBorrowData[] memory userBorrowingsData_) {
        uint256 length_ = users_.length;
        userSuppliesData_ = new UserSupplyData[](length_);
        userBorrowingsData_ = new UserBorrowData[](length_);
        for (uint256 i; i < length_; i++) {
            (userSuppliesData_[i]) = getUserSupplyData(dex_, users_[i]);
            (userBorrowingsData_[i]) = getUserBorrowData(dex_, users_[i]);
        }
    }
}

/// @notice Fluid Dex protocol resolver
/// Implements various view-only methods to give easy access to Dex protocol data.
contract FluidDexResolver is Variables, DexFactoryViews, DexActionEstimates, DexUserViews {
    constructor(
        address factory_,
        address liquidity_,
        address liquidityResolver_,
        address deployer_
    ) Variables(factory_, liquidity_, liquidityResolver_, deployer_) {}

    /// @notice Get the current state of a DEX
    /// @param dex_ The address of the DEX
    /// @return state_ A struct containing the current state of the DEX
    /// @dev expected to be called via callStatic
    function getDexState(address dex_) public returns (DexState memory state_) {
        return _getDexState(dex_, getDexCollateralReserves(dex_), getDexDebtReserves(dex_));
    }

    /// @notice Get the current configurations of a DEX
    /// @param dex_ The address of the DEX
    /// @return configs_ A struct containing the current configurations of the DEX
    function getDexConfigs(address dex_) public view returns (Configs memory configs_) {
        uint256 dexVariables2_ = getDexVariables2Raw(dex_);

        configs_.isSmartCollateralEnabled = (dexVariables2_ & 1) == 1;
        configs_.isSmartDebtEnabled = (dexVariables2_ & 2) == 2;
        configs_.fee = (dexVariables2_ >> 2) & X17;
        configs_.revenueCut = (dexVariables2_ >> 19) & X7;
        configs_.upperRange = (dexVariables2_ >> 27) & X20;
        configs_.lowerRange = (dexVariables2_ >> 47) & X20;
        configs_.upperShiftThreshold = (dexVariables2_ >> 68) & X10;
        configs_.lowerShiftThreshold = (dexVariables2_ >> 78) & X10;
        configs_.shiftingTime = (dexVariables2_ >> 88) & X24;

        configs_.maxSupplyShares = getTotalSupplySharesRaw(dex_) >> 128;
        configs_.maxBorrowShares = getTotalBorrowSharesRaw(dex_) >> 128;

        uint256 addressNonce_ = (dexVariables2_ >> 112) & X30;
        if (addressNonce_ > 0) {
            configs_.centerPriceAddress = AddressCalcs.addressCalc(DEPLOYER_CONTRACT, addressNonce_);
        }

        addressNonce_ = (dexVariables2_ >> 142) & X30;
        if (addressNonce_ > 0) {
            configs_.hookAddress = AddressCalcs.addressCalc(DEPLOYER_CONTRACT, addressNonce_);
        }

        configs_.maxCenterPrice = BigMathMinified.fromBigNumber(
            (dexVariables2_ >> 172) & X28,
            DexCalcs.DEFAULT_EXPONENT_SIZE,
            DexCalcs.DEFAULT_EXPONENT_MASK
        );
        configs_.minCenterPrice = BigMathMinified.fromBigNumber(
            (dexVariables2_ >> 200) & X28,
            DexCalcs.DEFAULT_EXPONENT_SIZE,
            DexCalcs.DEFAULT_EXPONENT_MASK
        );

        configs_.utilizationLimitToken0 = (dexVariables2_ >> 228) & X10;
        configs_.utilizationLimitToken1 = (dexVariables2_ >> 238) & X10;
    }

    /// @notice Get the swap limits and availability for a DEX
    /// @param dex_ The address of the DEX
    /// @return limitsAndAvailability_ A struct containing the swap limits and availability for the DEX
    function getDexSwapLimitsAndAvailability(
        address dex_
    ) public view returns (SwapLimitsAndAvailability memory limitsAndAvailability_) {
        (address token0_, address token1_) = getDexTokens(dex_);

        uint256 dexVariables2_ = getDexVariables2Raw(dex_);
        uint256 utilizationLimitToken0_ = (dexVariables2_ >> 228) & X10;
        uint256 utilizationLimitToken1_ = (dexVariables2_ >> 238) & X10;

        return
            _getDexSwapLimitsAndAvailability(dex_, token0_, token1_, utilizationLimitToken0_, utilizationLimitToken1_);
    }

    /// @notice Get the entire data for a DEX
    /// @param dex_ The address of the DEX
    /// @return data_ A struct containing all the data for the DEX
    /// @dev expected to be called via callStatic
    function getDexEntireData(address dex_) public returns (DexEntireData memory data_) {
        data_.dex = dex_;
        data_.constantViews = getDexConstantsView(dex_);
        data_.constantViews2 = getDexConstantsView2(dex_);
        data_.configs = getDexConfigs(dex_);
        data_.pex = getDexPricesAndExchangePrices(dex_);
        data_.colReserves = _getDexCollateralReserves(dex_, data_.constantViews2);
        data_.debtReserves = _getDexDebtReserves(dex_, data_.constantViews2);
        data_.dexState = _getDexState(dex_, data_.colReserves, data_.debtReserves);
        data_.limitsAndAvailability = _getDexSwapLimitsAndAvailability(
            dex_,
            data_.constantViews.token0,
            data_.constantViews.token1,
            data_.configs.utilizationLimitToken0,
            data_.configs.utilizationLimitToken1
        );
    }

    /// @notice Get the entire data for multiple DEXes
    /// @param dexes_ An array of DEX addresses
    /// @return datas_ An array of structs containing all the data for each DEX
    /// @dev expected to be called via callStatic
    function getDexEntireDatas(address[] memory dexes_) public returns (DexEntireData[] memory datas_) {
        uint256 length_ = dexes_.length;
        datas_ = new DexEntireData[](length_);

        for (uint256 i; i < length_; i++) {
            datas_[i] = getDexEntireData(dexes_[i]);
        }
    }

    /// @notice Get the entire data for all DEXes
    /// @return datas_ An array of structs containing all the data for all DEXes
    /// @dev expected to be called via callStatic
    function getAllDexEntireDatas() external returns (DexEntireData[] memory datas_) {
        return getDexEntireDatas(getAllDexAddresses());
    }

    /// @dev get the swap limits and availability for a DEX
    /// @param dex_ The address of the DEX
    /// @param token0_ The address of token0
    /// @param token1_ The address of token1
    /// @param utilizationLimitToken0Percent_ The utilization limit percentage for token0
    /// @param utilizationLimitToken1Percent_ The utilization limit percentage for token1
    /// @return limitsAndAvailability_ A struct containing the swap limits and availability for the DEX
    function _getDexSwapLimitsAndAvailability(
        address dex_,
        address token0_,
        address token1_,
        uint256 utilizationLimitToken0Percent_,
        uint256 utilizationLimitToken1Percent_
    ) internal view returns (SwapLimitsAndAvailability memory limitsAndAvailability_) {
        FluidLiquidityResolverStructs.OverallTokenData memory tokenData0_;
        FluidLiquidityResolverStructs.OverallTokenData memory tokenData1_;
        (limitsAndAvailability_.liquidityUserSupplyDataToken0, tokenData0_) = LIQUIDITY_RESOLVER.getUserSupplyData(
            dex_,
            token0_
        );
        (limitsAndAvailability_.liquidityUserSupplyDataToken1, tokenData1_) = LIQUIDITY_RESOLVER.getUserSupplyData(
            dex_,
            token1_
        );

        (limitsAndAvailability_.liquidityUserBorrowDataToken0, ) = LIQUIDITY_RESOLVER.getUserBorrowData(dex_, token0_);
        (limitsAndAvailability_.liquidityUserBorrowDataToken1, ) = LIQUIDITY_RESOLVER.getUserBorrowData(dex_, token1_);

        limitsAndAvailability_.liquiditySupplyToken0 = tokenData0_.totalSupply;
        limitsAndAvailability_.liquiditySupplyToken1 = tokenData1_.totalSupply;
        limitsAndAvailability_.liquidityBorrowToken0 = tokenData0_.totalBorrow;
        limitsAndAvailability_.liquidityBorrowToken1 = tokenData1_.totalBorrow;

        limitsAndAvailability_.liquidityWithdrawableToken0 = limitsAndAvailability_
            .liquidityUserSupplyDataToken0
            .withdrawable;
        limitsAndAvailability_.liquidityWithdrawableToken1 = limitsAndAvailability_
            .liquidityUserSupplyDataToken1
            .withdrawable;

        limitsAndAvailability_.liquidityBorrowableToken0 = limitsAndAvailability_
            .liquidityUserBorrowDataToken0
            .borrowable;
        limitsAndAvailability_.liquidityBorrowableToken1 = limitsAndAvailability_
            .liquidityUserBorrowDataToken1
            .borrowable;

        limitsAndAvailability_.utilizationLimitToken0 =
            (limitsAndAvailability_.liquiditySupplyToken0 * utilizationLimitToken0Percent_) /
            1e3;
        limitsAndAvailability_.utilizationLimitToken1 =
            (limitsAndAvailability_.liquiditySupplyToken1 * utilizationLimitToken1Percent_) /
            1e3;

        if (limitsAndAvailability_.liquidityBorrowToken0 < limitsAndAvailability_.utilizationLimitToken0) {
            limitsAndAvailability_.withdrawableUntilUtilizationLimitToken0 =
                (1e3 * limitsAndAvailability_.liquidityBorrowToken0) /
                utilizationLimitToken0Percent_;
            limitsAndAvailability_.withdrawableUntilUtilizationLimitToken0 = limitsAndAvailability_
                .liquiditySupplyToken0 > limitsAndAvailability_.withdrawableUntilUtilizationLimitToken0
                ? limitsAndAvailability_.liquiditySupplyToken0 -
                    limitsAndAvailability_.withdrawableUntilUtilizationLimitToken0
                : 0;

            limitsAndAvailability_.borrowableUntilUtilizationLimitToken0 =
                limitsAndAvailability_.utilizationLimitToken0 -
                limitsAndAvailability_.liquidityBorrowToken0;
        }

        if (limitsAndAvailability_.liquidityBorrowToken1 < limitsAndAvailability_.utilizationLimitToken1) {
            limitsAndAvailability_.withdrawableUntilUtilizationLimitToken1 =
                (1e3 * limitsAndAvailability_.liquidityBorrowToken1) /
                utilizationLimitToken1Percent_;
            limitsAndAvailability_.withdrawableUntilUtilizationLimitToken1 = limitsAndAvailability_
                .liquiditySupplyToken1 > limitsAndAvailability_.withdrawableUntilUtilizationLimitToken1
                ? limitsAndAvailability_.liquiditySupplyToken1 -
                    limitsAndAvailability_.withdrawableUntilUtilizationLimitToken1
                : 0;

            limitsAndAvailability_.borrowableUntilUtilizationLimitToken1 =
                limitsAndAvailability_.utilizationLimitToken1 -
                limitsAndAvailability_.liquidityBorrowToken1;
        }
    }

    /// @dev Get the current state of a DEX
    function _getDexState(
        address dex_,
        IFluidDexT1.CollateralReserves memory colReserves_,
        IFluidDexT1.DebtReserves memory debtReserves_
    ) internal view returns (DexState memory state_) {
        uint256 storageVar_ = getDexVariablesRaw(dex_);

        state_.lastToLastStoredPrice = (storageVar_ >> 1) & X40;
        state_.lastStoredPrice = (storageVar_ >> 41) & X40;
        state_.centerPrice = (storageVar_ >> 81) & X40;
        state_.lastUpdateTimestamp = (storageVar_ >> 121) & X33;
        state_.lastPricesTimeDiff = (storageVar_ >> 154) & X22;
        state_.oracleCheckPoint = (storageVar_ >> 176) & X3;
        state_.oracleMapping = (storageVar_ >> 179) & X16;

        state_.totalSupplyShares = getTotalSupplySharesRaw(dex_) & X128;
        state_.totalBorrowShares = getTotalBorrowSharesRaw(dex_) & X128;

        storageVar_ = getDexVariables2Raw(dex_);
        state_.isSwapAndArbitragePaused = storageVar_ >> 255 == 1;

        state_.shifts.isRangeChangeActive = (storageVar_ >> 26) & 1 == 1;
        state_.shifts.isThresholdChangeActive = (storageVar_ >> 67) & 1 == 1;
        state_.shifts.isCenterPriceShiftActive = (storageVar_ >> 248) & 1 == 1;

        storageVar_ = getRangeShiftRaw(dex_);
        state_.shifts.rangeShift.oldUpper = storageVar_ & X20;
        state_.shifts.rangeShift.oldLower = (storageVar_ >> 20) & X20;
        state_.shifts.rangeShift.duration = (storageVar_ >> 40) & X20;
        state_.shifts.rangeShift.startTimestamp = (storageVar_ >> 60) & X33;

        storageVar_ = getThresholdShiftRaw(dex_);
        state_.shifts.thresholdShift.oldUpper = storageVar_ & X10;
        state_.shifts.thresholdShift.oldLower = (storageVar_ >> 20) & X10;
        state_.shifts.thresholdShift.duration = (storageVar_ >> 40) & X20;
        state_.shifts.thresholdShift.startTimestamp = (storageVar_ >> 60) & X33;
        state_.shifts.thresholdShift.oldTime = (storageVar_ >> 93) & X24;

        storageVar_ = getCenterPriceShiftRaw(dex_);
        state_.shifts.centerPriceShift.startTimestamp = storageVar_ & X33;
        state_.shifts.centerPriceShift.shiftPercentage = (storageVar_ >> 33) & X20;
        state_.shifts.centerPriceShift.duration = (storageVar_ >> 53) & X20;

        state_.token0PerSupplyShare = (colReserves_.token0RealReserves * 1e18) / state_.totalSupplyShares;
        state_.token1PerSupplyShare = (colReserves_.token1RealReserves * 1e18) / state_.totalSupplyShares;
        state_.token0PerBorrowShare = (debtReserves_.token0Debt * 1e18) / state_.totalBorrowShares;
        state_.token1PerBorrowShare = (debtReserves_.token1Debt * 1e18) / state_.totalBorrowShares;
    }
}

File 2 of 13 : addressCalcs.sol
// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.21;

/// @notice implements calculation of address for contracts deployed through CREATE.
/// Accepts contract deployed from which address & nonce
library AddressCalcs {

    /// @notice                         Computes the address of a contract based
    /// @param deployedFrom_            Address from which the contract was deployed
    /// @param nonce_                   Nonce at which the contract was deployed
    /// @return contract_               Address of deployed contract
    function addressCalc(address deployedFrom_, uint nonce_) internal pure returns (address contract_) {
        // @dev based on https://ethereum.stackexchange.com/a/61413

        // nonce of smart contract always starts with 1. so, with nonce 0 there won't be any deployment
        // hence, nonce of vault deployment starts with 1.
        bytes memory data;
        if (nonce_ == 0x00) {
            return address(0);
        } else if (nonce_ <= 0x7f) {
            data = abi.encodePacked(bytes1(0xd6), bytes1(0x94), deployedFrom_, uint8(nonce_));
        } else if (nonce_ <= 0xff) {
            data = abi.encodePacked(bytes1(0xd7), bytes1(0x94), deployedFrom_, bytes1(0x81), uint8(nonce_));
        } else if (nonce_ <= 0xffff) {
            data = abi.encodePacked(bytes1(0xd8), bytes1(0x94), deployedFrom_, bytes1(0x82), uint16(nonce_));
        } else if (nonce_ <= 0xffffff) {
            data = abi.encodePacked(bytes1(0xd9), bytes1(0x94), deployedFrom_, bytes1(0x83), uint24(nonce_));
        } else {
            data = abi.encodePacked(bytes1(0xda), bytes1(0x94), deployedFrom_, bytes1(0x84), uint32(nonce_));
        }

        return address(uint160(uint256(keccak256(data))));
    }

}

File 3 of 13 : bigMathMinified.sol
// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.21;

/// @title library that represents a number in BigNumber(coefficient and exponent) format to store in smaller bits.
/// @notice the number is divided into two parts: a coefficient and an exponent. This comes at a cost of losing some precision
/// at the end of the number because the exponent simply fills it with zeroes. This precision is oftentimes negligible and can
/// result in significant gas cost reduction due to storage space reduction.
/// Also note, a valid big number is as follows: if the exponent is > 0, then coefficient last bits should be occupied to have max precision.
/// @dev roundUp is more like a increase 1, which happens everytime for the same number.
/// roundDown simply sets trailing digits after coefficientSize to zero (floor), only once for the same number.
library BigMathMinified {
    /// @dev constants to use for `roundUp` input param to increase readability
    bool internal constant ROUND_DOWN = false;
    bool internal constant ROUND_UP = true;

    /// @dev converts `normal` number to BigNumber with `exponent` and `coefficient` (or precision).
    /// e.g.:
    /// 5035703444687813576399599 (normal) = (coefficient[32bits], exponent[8bits])[40bits]
    /// 5035703444687813576399599 (decimal) => 10000101010010110100000011111011110010100110100000000011100101001101001101011101111 (binary)
    ///                                     => 10000101010010110100000011111011000000000000000000000000000000000000000000000000000
    ///                                                                        ^-------------------- 51(exponent) -------------- ^
    /// coefficient = 1000,0101,0100,1011,0100,0000,1111,1011               (2236301563)
    /// exponent =                                            0011,0011     (51)
    /// bigNumber =   1000,0101,0100,1011,0100,0000,1111,1011,0011,0011     (572493200179)
    ///
    /// @param normal number which needs to be converted into Big Number
    /// @param coefficientSize at max how many bits of precision there should be (64 = uint64 (64 bits precision))
    /// @param exponentSize at max how many bits of exponent there should be (8 = uint8 (8 bits exponent))
    /// @param roundUp signals if result should be rounded down or up
    /// @return bigNumber converted bigNumber (coefficient << exponent)
    function toBigNumber(
        uint256 normal,
        uint256 coefficientSize,
        uint256 exponentSize,
        bool roundUp
    ) internal pure returns (uint256 bigNumber) {
        assembly {
            let lastBit_
            let number_ := normal
            if gt(number_, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) {
                number_ := shr(0x80, number_)
                lastBit_ := 0x80
            }
            if gt(number_, 0xFFFFFFFFFFFFFFFF) {
                number_ := shr(0x40, number_)
                lastBit_ := add(lastBit_, 0x40)
            }
            if gt(number_, 0xFFFFFFFF) {
                number_ := shr(0x20, number_)
                lastBit_ := add(lastBit_, 0x20)
            }
            if gt(number_, 0xFFFF) {
                number_ := shr(0x10, number_)
                lastBit_ := add(lastBit_, 0x10)
            }
            if gt(number_, 0xFF) {
                number_ := shr(0x8, number_)
                lastBit_ := add(lastBit_, 0x8)
            }
            if gt(number_, 0xF) {
                number_ := shr(0x4, number_)
                lastBit_ := add(lastBit_, 0x4)
            }
            if gt(number_, 0x3) {
                number_ := shr(0x2, number_)
                lastBit_ := add(lastBit_, 0x2)
            }
            if gt(number_, 0x1) {
                lastBit_ := add(lastBit_, 1)
            }
            if gt(number_, 0) {
                lastBit_ := add(lastBit_, 1)
            }
            if lt(lastBit_, coefficientSize) {
                // for throw exception
                lastBit_ := coefficientSize
            }
            let exponent := sub(lastBit_, coefficientSize)
            let coefficient := shr(exponent, normal)
            if and(roundUp, gt(exponent, 0)) {
                // rounding up is only needed if exponent is > 0, as otherwise the coefficient fully holds the original number
                coefficient := add(coefficient, 1)
                if eq(shl(coefficientSize, 1), coefficient) {
                    // case were coefficient was e.g. 111, with adding 1 it became 1000 (in binary) and coefficientSize 3 bits
                    // final coefficient would exceed it's size. -> reduce coefficent to 100 and increase exponent by 1.
                    coefficient := shl(sub(coefficientSize, 1), 1)
                    exponent := add(exponent, 1)
                }
            }
            if iszero(lt(exponent, shl(exponentSize, 1))) {
                // if exponent is >= exponentSize, the normal number is too big to fit within
                // BigNumber with too small sizes for coefficient and exponent
                revert(0, 0)
            }
            bigNumber := shl(exponentSize, coefficient)
            bigNumber := add(bigNumber, exponent)
        }
    }

    /// @dev get `normal` number from `bigNumber`, `exponentSize` and `exponentMask`
    function fromBigNumber(
        uint256 bigNumber,
        uint256 exponentSize,
        uint256 exponentMask
    ) internal pure returns (uint256 normal) {
        assembly {
            let coefficient := shr(exponentSize, bigNumber)
            let exponent := and(bigNumber, exponentMask)
            normal := shl(exponent, coefficient)
        }
    }

    /// @dev gets the most significant bit `lastBit` of a `normal` number (length of given number of binary format).
    /// e.g.
    /// 5035703444687813576399599 = 10000101010010110100000011111011110010100110100000000011100101001101001101011101111
    /// lastBit =                   ^---------------------------------   83   ----------------------------------------^
    function mostSignificantBit(uint256 normal) internal pure returns (uint lastBit) {
        assembly {
            let number_ := normal
            if gt(normal, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) {
                number_ := shr(0x80, number_)
                lastBit := 0x80
            }
            if gt(number_, 0xFFFFFFFFFFFFFFFF) {
                number_ := shr(0x40, number_)
                lastBit := add(lastBit, 0x40)
            }
            if gt(number_, 0xFFFFFFFF) {
                number_ := shr(0x20, number_)
                lastBit := add(lastBit, 0x20)
            }
            if gt(number_, 0xFFFF) {
                number_ := shr(0x10, number_)
                lastBit := add(lastBit, 0x10)
            }
            if gt(number_, 0xFF) {
                number_ := shr(0x8, number_)
                lastBit := add(lastBit, 0x8)
            }
            if gt(number_, 0xF) {
                number_ := shr(0x4, number_)
                lastBit := add(lastBit, 0x4)
            }
            if gt(number_, 0x3) {
                number_ := shr(0x2, number_)
                lastBit := add(lastBit, 0x2)
            }
            if gt(number_, 0x1) {
                lastBit := add(lastBit, 1)
            }
            if gt(number_, 0) {
                lastBit := add(lastBit, 1)
            }
        }
    }
}

File 4 of 13 : bytesSliceAndConcat.sol
// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.21;

library BytesSliceAndConcat {
    // @dev taken from https://github.com/GNSPS/solidity-bytes-utils/blob/master/contracts/BytesLib.sol
    function bytesConcat(
        bytes memory _preBytes,
        bytes memory _postBytes
    ) internal pure returns (bytes memory tempBytes) {
        assembly {
            // Get a location of some free memory and store it in tempBytes as
            // Solidity does for memory variables.
            tempBytes := mload(0x40)

            // Store the length of the first bytes array at the beginning of
            // the memory for tempBytes.
            let length := mload(_preBytes)
            mstore(tempBytes, length)

            // Maintain a memory counter for the current write location in the
            // temp bytes array by adding the 32 bytes for the array length to
            // the starting location.
            let mc := add(tempBytes, 0x20)
            // Stop copying when the memory counter reaches the length of the
            // first bytes array.
            let end := add(mc, length)

            for {
                // Initialize a copy counter to the start of the _preBytes data,
                // 32 bytes into its memory.
                let cc := add(_preBytes, 0x20)
            } lt(mc, end) {
                // Increase both counters by 32 bytes each iteration.
                mc := add(mc, 0x20)
                cc := add(cc, 0x20)
            } {
                // Write the _preBytes data into the tempBytes memory 32 bytes
                // at a time.
                mstore(mc, mload(cc))
            }

            // Add the length of _postBytes to the current length of tempBytes
            // and store it as the new length in the first 32 bytes of the
            // tempBytes memory.
            length := mload(_postBytes)
            mstore(tempBytes, add(length, mload(tempBytes)))

            // Move the memory counter back from a multiple of 0x20 to the
            // actual end of the _preBytes data.
            mc := end
            // Stop copying when the memory counter reaches the new combined
            // length of the arrays.
            end := add(mc, length)

            for {
                let cc := add(_postBytes, 0x20)
            } lt(mc, end) {
                mc := add(mc, 0x20)
                cc := add(cc, 0x20)
            } {
                mstore(mc, mload(cc))
            }

            // Update the free-memory pointer by padding our last write location
            // to 32 bytes: add 31 bytes to the end of tempBytes to move to the
            // next 32 byte block, then round down to the nearest multiple of
            // 32. If the sum of the length of the two arrays is zero then add
            // one before rounding down to leave a blank 32 bytes (the length block with 0).
            mstore(
                0x40,
                and(
                    add(add(end, iszero(add(length, mload(_preBytes)))), 31),
                    not(31) // Round down to the nearest 32 bytes.
                )
            )
        }

        return tempBytes;
    }

    // @dev taken from https://github.com/GNSPS/solidity-bytes-utils/blob/master/contracts/BytesLib.sol
    function bytesSlice(
        bytes memory _bytes,
        uint256 _start,
        uint256 _length
    ) internal pure returns (bytes memory tempBytes) {
        require(_length + 31 >= _length, "slice_overflow");
        require(_bytes.length >= _start + _length, "slice_outOfBounds");

        assembly {
            switch iszero(_length)
            case 0 {
                // Get a location of some free memory and store it in tempBytes as
                // Solidity does for memory variables.
                tempBytes := mload(0x40)

                // The first word of the slice result is potentially a partial
                // word read from the original array. To read it, we calculate
                // the length of that partial word and start copying that many
                // bytes into the array. The first word we copy will start with
                // data we don't care about, but the last `lengthmod` bytes will
                // land at the beginning of the contents of the new array. When
                // we're done copying, we overwrite the full first word with
                // the actual length of the slice.
                let lengthmod := and(_length, 31)

                // The multiplication in the next line is necessary
                // because when slicing multiples of 32 bytes (lengthmod == 0)
                // the following copy loop was copying the origin's length
                // and then ending prematurely not copying everything it should.
                let mc := add(add(tempBytes, lengthmod), mul(0x20, iszero(lengthmod)))
                let end := add(mc, _length)

                for {
                    // The multiplication in the next line has the same exact purpose
                    // as the one above.
                    let cc := add(add(add(_bytes, lengthmod), mul(0x20, iszero(lengthmod))), _start)
                } lt(mc, end) {
                    mc := add(mc, 0x20)
                    cc := add(cc, 0x20)
                } {
                    mstore(mc, mload(cc))
                }

                mstore(tempBytes, _length)

                //update free-memory pointer
                //allocating the array padded to 32 bytes like the compiler does now
                mstore(0x40, and(add(mc, 31), not(31)))
            }
            //if we want a zero-length slice let's just return a zero-length array
            default {
                tempBytes := mload(0x40)
                //zero out the 32 bytes slice we are about to return
                //we need to do it because Solidity does not garbage collect
                mstore(tempBytes, 0)

                mstore(0x40, add(tempBytes, 0x20))
            }
        }

        return tempBytes;
    }
}

File 5 of 13 : dexCalcs.sol
// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.21;

import { BigMathMinified } from "./bigMathMinified.sol";
import { DexSlotsLink } from "./dexSlotsLink.sol";

// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// @DEV ATTENTION: ON ANY CHANGES HERE, MAKE SURE THAT LOGIC IN VAULTS WILL STILL BE VALID.
// SOME CODE THERE ASSUMES DEXCALCS == LIQUIDITYCALCS.
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

/// @notice implements calculation methods used for Fluid Dex such as updated withdrawal / borrow limits.
library DexCalcs {
    // constants used for BigMath conversion from and to storage
    uint256 internal constant DEFAULT_EXPONENT_SIZE = 8;
    uint256 internal constant DEFAULT_EXPONENT_MASK = 0xFF;

    uint256 internal constant FOUR_DECIMALS = 1e4;
    uint256 internal constant X14 = 0x3fff;
    uint256 internal constant X18 = 0x3ffff;
    uint256 internal constant X24 = 0xffffff;
    uint256 internal constant X33 = 0x1ffffffff;
    uint256 internal constant X64 = 0xffffffffffffffff;

    ///////////////////////////////////////////////////////////////////////////
    //////////                      CALC LIMITS                       /////////
    ///////////////////////////////////////////////////////////////////////////

    /// @dev calculates withdrawal limit before an operate execution:
    /// amount of user supply that must stay supplied (not amount that can be withdrawn).
    /// i.e. if user has supplied 100m and can withdraw 5M, this method returns the 95M, not the withdrawable amount 5M
    /// @param userSupplyData_ user supply data packed uint256 from storage
    /// @param userSupply_ current user supply amount already extracted from `userSupplyData_` and converted from BigMath
    /// @return currentWithdrawalLimit_ current withdrawal limit updated for expansion since last interaction.
    ///         returned value is in raw for with interest mode, normal amount for interest free mode!
    function calcWithdrawalLimitBeforeOperate(
        uint256 userSupplyData_,
        uint256 userSupply_
    ) internal view returns (uint256 currentWithdrawalLimit_) {
        // @dev must support handling the case where timestamp is 0 (config is set but no interactions yet).
        // first tx where timestamp is 0 will enter `if (lastWithdrawalLimit_ == 0)` because lastWithdrawalLimit_ is not set yet.
        // returning max withdrawal allowed, which is not exactly right but doesn't matter because the first interaction must be
        // a deposit anyway. Important is that it would not revert.

        // Note the first time a deposit brings the user supply amount to above the base withdrawal limit, the active limit
        // is the fully expanded limit immediately.

        // extract last set withdrawal limit
        uint256 lastWithdrawalLimit_ = (userSupplyData_ >> DexSlotsLink.BITS_USER_SUPPLY_PREVIOUS_WITHDRAWAL_LIMIT) &
            X64;
        lastWithdrawalLimit_ =
            (lastWithdrawalLimit_ >> DEFAULT_EXPONENT_SIZE) <<
            (lastWithdrawalLimit_ & DEFAULT_EXPONENT_MASK);
        if (lastWithdrawalLimit_ == 0) {
            // withdrawal limit is not activated. Max withdrawal allowed
            return 0;
        }

        uint256 maxWithdrawableLimit_;
        uint256 temp_;
        unchecked {
            // extract max withdrawable percent of user supply and
            // calculate maximum withdrawable amount expandPercentage of user supply at full expansion duration elapsed
            // e.g.: if 10% expandPercentage, meaning 10% is withdrawable after full expandDuration has elapsed.

            // userSupply_ needs to be atleast 1e73 to overflow max limit of ~1e77 in uint256 (no token in existence where this is possible).
            maxWithdrawableLimit_ =
                (((userSupplyData_ >> DexSlotsLink.BITS_USER_SUPPLY_EXPAND_PERCENT) & X14) * userSupply_) /
                FOUR_DECIMALS;

            // time elapsed since last withdrawal limit was set (in seconds)
            // @dev last process timestamp is guaranteed to exist for withdrawal, as a supply must have happened before.
            // last timestamp can not be > current timestamp
            temp_ = block.timestamp - ((userSupplyData_ >> DexSlotsLink.BITS_USER_SUPPLY_LAST_UPDATE_TIMESTAMP) & X33);
        }
        // calculate withdrawable amount of expandPercent that is elapsed of expandDuration.
        // e.g. if 60% of expandDuration has elapsed, then user should be able to withdraw 6% of user supply, down to 94%.
        // Note: no explicit check for this needed, it is covered by setting minWithdrawalLimit_ if needed.
        temp_ =
            (maxWithdrawableLimit_ * temp_) /
            // extract expand duration: After this, decrement won't happen (user can withdraw 100% of withdraw limit)
            ((userSupplyData_ >> DexSlotsLink.BITS_USER_SUPPLY_EXPAND_DURATION) & X24); // expand duration can never be 0
        // calculate expanded withdrawal limit: last withdrawal limit - withdrawable amount.
        // Note: withdrawable amount here can grow bigger than userSupply if timeElapsed is a lot bigger than expandDuration,
        // which would cause the subtraction `lastWithdrawalLimit_ - withdrawableAmount_` to revert. In that case, set 0
        // which will cause minimum (fully expanded) withdrawal limit to be set in lines below.
        unchecked {
            // underflow explicitly checked & handled
            currentWithdrawalLimit_ = lastWithdrawalLimit_ > temp_ ? lastWithdrawalLimit_ - temp_ : 0;
            // calculate minimum withdrawal limit: minimum amount of user supply that must stay supplied at full expansion.
            // subtraction can not underflow as maxWithdrawableLimit_ is a percentage amount (<=100%) of userSupply_
            temp_ = userSupply_ - maxWithdrawableLimit_;
        }
        // if withdrawal limit is decreased below minimum then set minimum
        // (e.g. when more than expandDuration time has elapsed)
        if (temp_ > currentWithdrawalLimit_) {
            currentWithdrawalLimit_ = temp_;
        }
    }

    /// @dev calculates withdrawal limit after an operate execution:
    /// amount of user supply that must stay supplied (not amount that can be withdrawn).
    /// i.e. if user has supplied 100m and can withdraw 5M, this method returns the 95M, not the withdrawable amount 5M
    /// @param userSupplyData_ user supply data packed uint256 from storage
    /// @param userSupply_ current user supply amount already extracted from `userSupplyData_` and added / subtracted with the executed operate amount
    /// @param newWithdrawalLimit_ current withdrawal limit updated for expansion since last interaction, result from `calcWithdrawalLimitBeforeOperate`
    /// @return withdrawalLimit_ updated withdrawal limit that should be written to storage. returned value is in
    ///                          raw for with interest mode, normal amount for interest free mode!
    function calcWithdrawalLimitAfterOperate(
        uint256 userSupplyData_,
        uint256 userSupply_,
        uint256 newWithdrawalLimit_
    ) internal pure returns (uint256) {
        // temp_ => base withdrawal limit. below this, maximum withdrawals are allowed
        uint256 temp_ = (userSupplyData_ >> DexSlotsLink.BITS_USER_SUPPLY_BASE_WITHDRAWAL_LIMIT) & X18;
        temp_ = (temp_ >> DEFAULT_EXPONENT_SIZE) << (temp_ & DEFAULT_EXPONENT_MASK);

        // if user supply is below base limit then max withdrawals are allowed
        if (userSupply_ < temp_) {
            return 0;
        }
        // temp_ => withdrawal limit expandPercent (is in 1e2 decimals)
        temp_ = (userSupplyData_ >> DexSlotsLink.BITS_USER_SUPPLY_EXPAND_PERCENT) & X14;
        unchecked {
            // temp_ => minimum withdrawal limit: userSupply - max withdrawable limit (userSupply * expandPercent))
            // userSupply_ needs to be atleast 1e73 to overflow max limit of ~1e77 in uint256 (no token in existence where this is possible).
            // subtraction can not underflow as maxWithdrawableLimit_ is a percentage amount (<=100%) of userSupply_
            temp_ = userSupply_ - ((userSupply_ * temp_) / FOUR_DECIMALS);
        }
        // if new (before operation) withdrawal limit is less than minimum limit then set minimum limit.
        // e.g. can happen on new deposits. withdrawal limit is instantly fully expanded in a scenario where
        // increased deposit amount outpaces withrawals.
        if (temp_ > newWithdrawalLimit_) {
            return temp_;
        }
        return newWithdrawalLimit_;
    }

    /// @dev calculates borrow limit before an operate execution:
    /// total amount user borrow can reach (not borrowable amount in current operation).
    /// i.e. if user has borrowed 50M and can still borrow 5M, this method returns the total 55M, not the borrowable amount 5M
    /// @param userBorrowData_ user borrow data packed uint256 from storage
    /// @param userBorrow_ current user borrow amount already extracted from `userBorrowData_`
    /// @return currentBorrowLimit_ current borrow limit updated for expansion since last interaction. returned value is in
    ///                             raw for with interest mode, normal amount for interest free mode!
    function calcBorrowLimitBeforeOperate(
        uint256 userBorrowData_,
        uint256 userBorrow_
    ) internal view returns (uint256 currentBorrowLimit_) {
        // @dev must support handling the case where timestamp is 0 (config is set but no interactions yet) -> base limit.
        // first tx where timestamp is 0 will enter `if (maxExpandedBorrowLimit_ < baseBorrowLimit_)` because `userBorrow_` and thus
        // `maxExpansionLimit_` and thus `maxExpandedBorrowLimit_` is 0 and `baseBorrowLimit_` can not be 0.

        // temp_ = extract borrow expand percent (is in 1e2 decimals)
        uint256 temp_ = (userBorrowData_ >> DexSlotsLink.BITS_USER_BORROW_EXPAND_PERCENT) & X14;

        uint256 maxExpansionLimit_;
        uint256 maxExpandedBorrowLimit_;
        unchecked {
            // calculate max expansion limit: Max amount limit can expand to since last interaction
            // userBorrow_ needs to be atleast 1e73 to overflow max limit of ~1e77 in uint256 (no token in existence where this is possible).
            maxExpansionLimit_ = ((userBorrow_ * temp_) / FOUR_DECIMALS);

            // calculate max borrow limit: Max point limit can increase to since last interaction
            maxExpandedBorrowLimit_ = userBorrow_ + maxExpansionLimit_;
        }

        // currentBorrowLimit_ = extract base borrow limit
        currentBorrowLimit_ = (userBorrowData_ >> DexSlotsLink.BITS_USER_BORROW_BASE_BORROW_LIMIT) & X18;
        currentBorrowLimit_ =
            (currentBorrowLimit_ >> DEFAULT_EXPONENT_SIZE) <<
            (currentBorrowLimit_ & DEFAULT_EXPONENT_MASK);

        if (maxExpandedBorrowLimit_ < currentBorrowLimit_) {
            return currentBorrowLimit_;
        }
        // time elapsed since last borrow limit was set (in seconds)
        unchecked {
            // temp_ = timeElapsed_ (last timestamp can not be > current timestamp)
            temp_ = block.timestamp - ((userBorrowData_ >> DexSlotsLink.BITS_USER_BORROW_LAST_UPDATE_TIMESTAMP) & X33); // extract last update timestamp
        }

        // currentBorrowLimit_ = expandedBorrowableAmount + extract last set borrow limit
        currentBorrowLimit_ =
            // calculate borrow limit expansion since last interaction for `expandPercent` that is elapsed of `expandDuration`.
            // divisor is extract expand duration (after this, full expansion to expandPercentage happened).
            ((maxExpansionLimit_ * temp_) /
                ((userBorrowData_ >> DexSlotsLink.BITS_USER_BORROW_EXPAND_DURATION) & X24)) + // expand duration can never be 0
            //  extract last set borrow limit
            BigMathMinified.fromBigNumber(
                (userBorrowData_ >> DexSlotsLink.BITS_USER_BORROW_PREVIOUS_BORROW_LIMIT) & X64,
                DEFAULT_EXPONENT_SIZE,
                DEFAULT_EXPONENT_MASK
            );

        // if timeElapsed is bigger than expandDuration, new borrow limit would be > max expansion,
        // so set to `maxExpandedBorrowLimit_` in that case.
        // also covers the case where last process timestamp = 0 (timeElapsed would simply be very big)
        if (currentBorrowLimit_ > maxExpandedBorrowLimit_) {
            currentBorrowLimit_ = maxExpandedBorrowLimit_;
        }
        // temp_ = extract hard max borrow limit. Above this user can never borrow (not expandable above)
        temp_ = (userBorrowData_ >> DexSlotsLink.BITS_USER_BORROW_MAX_BORROW_LIMIT) & X18;
        temp_ = (temp_ >> DEFAULT_EXPONENT_SIZE) << (temp_ & DEFAULT_EXPONENT_MASK);

        if (currentBorrowLimit_ > temp_) {
            currentBorrowLimit_ = temp_;
        }
    }

    /// @dev calculates borrow limit after an operate execution:
    /// total amount user borrow can reach (not borrowable amount in current operation).
    /// i.e. if user has borrowed 50M and can still borrow 5M, this method returns the total 55M, not the borrowable amount 5M
    /// @param userBorrowData_ user borrow data packed uint256 from storage
    /// @param userBorrow_ current user borrow amount already extracted from `userBorrowData_` and added / subtracted with the executed operate amount
    /// @param newBorrowLimit_ current borrow limit updated for expansion since last interaction, result from `calcBorrowLimitBeforeOperate`
    /// @return borrowLimit_ updated borrow limit that should be written to storage.
    ///                      returned value is in raw for with interest mode, normal amount for interest free mode!
    function calcBorrowLimitAfterOperate(
        uint256 userBorrowData_,
        uint256 userBorrow_,
        uint256 newBorrowLimit_
    ) internal pure returns (uint256 borrowLimit_) {
        // temp_ = extract borrow expand percent
        uint256 temp_ = (userBorrowData_ >> DexSlotsLink.BITS_USER_BORROW_EXPAND_PERCENT) & X14; // (is in 1e2 decimals)

        unchecked {
            // borrowLimit_ = calculate maximum borrow limit at full expansion.
            // userBorrow_ needs to be at least 1e73 to overflow max limit of ~1e77 in uint256 (no token in existence where this is possible).
            borrowLimit_ = userBorrow_ + ((userBorrow_ * temp_) / FOUR_DECIMALS);
        }

        // temp_ = extract base borrow limit
        temp_ = (userBorrowData_ >> DexSlotsLink.BITS_USER_BORROW_BASE_BORROW_LIMIT) & X18;
        temp_ = (temp_ >> DEFAULT_EXPONENT_SIZE) << (temp_ & DEFAULT_EXPONENT_MASK);

        if (borrowLimit_ < temp_) {
            // below base limit, borrow limit is always base limit
            return temp_;
        }
        // temp_ = extract hard max borrow limit. Above this user can never borrow (not expandable above)
        temp_ = (userBorrowData_ >> DexSlotsLink.BITS_USER_BORROW_MAX_BORROW_LIMIT) & X18;
        temp_ = (temp_ >> DEFAULT_EXPONENT_SIZE) << (temp_ & DEFAULT_EXPONENT_MASK);

        // make sure fully expanded borrow limit is not above hard max borrow limit
        if (borrowLimit_ > temp_) {
            borrowLimit_ = temp_;
        }
        // if new borrow limit (from before operate) is > max borrow limit, set max borrow limit.
        // (e.g. on a repay shrinking instantly to fully expanded borrow limit from new borrow amount. shrinking is instant)
        if (newBorrowLimit_ > borrowLimit_) {
            return borrowLimit_;
        }
        return newBorrowLimit_;
    }
}

File 6 of 13 : dexSlotsLink.sol
// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.21;

/// @notice library that helps in reading / working with storage slot data of Fluid Dex.
/// @dev as all data for Fluid Dex is internal, any data must be fetched directly through manual
/// slot reading through this library or, if gas usage is less important, through the FluidDexResolver.
library DexSlotsLink {
    /// @dev storage slot for variables at Dex
    uint256 internal constant DEX_VARIABLES_SLOT = 0;
    /// @dev storage slot for variables2 at Dex
    uint256 internal constant DEX_VARIABLES2_SLOT = 1;
    /// @dev storage slot for total supply shares at Dex
    uint256 internal constant DEX_TOTAL_SUPPLY_SHARES_SLOT = 2;
    /// @dev storage slot for user supply mapping at Dex
    uint256 internal constant DEX_USER_SUPPLY_MAPPING_SLOT = 3;
    /// @dev storage slot for total borrow shares at Dex
    uint256 internal constant DEX_TOTAL_BORROW_SHARES_SLOT = 4;
    /// @dev storage slot for user borrow mapping at Dex
    uint256 internal constant DEX_USER_BORROW_MAPPING_SLOT = 5;
    /// @dev storage slot for oracle mapping at Dex
    uint256 internal constant DEX_ORACLE_MAPPING_SLOT = 6;
    /// @dev storage slot for range and threshold shifts at Dex
    uint256 internal constant DEX_RANGE_THRESHOLD_SHIFTS_SLOT = 7;
    /// @dev storage slot for center price shift at Dex
    uint256 internal constant DEX_CENTER_PRICE_SHIFT_SLOT = 8;

    // --------------------------------
    // @dev stacked uint256 storage slots bits position data for each:

    // UserSupplyData
    uint256 internal constant BITS_USER_SUPPLY_ALLOWED = 0;
    uint256 internal constant BITS_USER_SUPPLY_AMOUNT = 1;
    uint256 internal constant BITS_USER_SUPPLY_PREVIOUS_WITHDRAWAL_LIMIT = 65;
    uint256 internal constant BITS_USER_SUPPLY_LAST_UPDATE_TIMESTAMP = 129;
    uint256 internal constant BITS_USER_SUPPLY_EXPAND_PERCENT = 162;
    uint256 internal constant BITS_USER_SUPPLY_EXPAND_DURATION = 176;
    uint256 internal constant BITS_USER_SUPPLY_BASE_WITHDRAWAL_LIMIT = 200;

    // UserBorrowData
    uint256 internal constant BITS_USER_BORROW_ALLOWED = 0;
    uint256 internal constant BITS_USER_BORROW_AMOUNT = 1;
    uint256 internal constant BITS_USER_BORROW_PREVIOUS_BORROW_LIMIT = 65;
    uint256 internal constant BITS_USER_BORROW_LAST_UPDATE_TIMESTAMP = 129;
    uint256 internal constant BITS_USER_BORROW_EXPAND_PERCENT = 162;
    uint256 internal constant BITS_USER_BORROW_EXPAND_DURATION = 176;
    uint256 internal constant BITS_USER_BORROW_BASE_BORROW_LIMIT = 200;
    uint256 internal constant BITS_USER_BORROW_MAX_BORROW_LIMIT = 218;

    // --------------------------------

    /// @notice Calculating the slot ID for Dex contract for single mapping at `slot_` for `key_`
    function calculateMappingStorageSlot(uint256 slot_, address key_) internal pure returns (bytes32) {
        return keccak256(abi.encode(key_, slot_));
    }

    /// @notice Calculating the slot ID for Dex contract for double mapping at `slot_` for `key1_` and `key2_`
    function calculateDoubleMappingStorageSlot(
        uint256 slot_,
        address key1_,
        address key2_
    ) internal pure returns (bytes32) {
        bytes32 intermediateSlot_ = keccak256(abi.encode(key1_, slot_));
        return keccak256(abi.encode(key2_, intermediateSlot_));
    }
}

File 7 of 13 : structs.sol
// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.21;

abstract contract Structs {
    struct AddressBool {
        address addr;
        bool value;
    }

    struct AddressUint256 {
        address addr;
        uint256 value;
    }

    /// @notice struct to set borrow rate data for version 1
    struct RateDataV1Params {
        ///
        /// @param token for rate data
        address token;
        ///
        /// @param kink in borrow rate. in 1e2: 100% = 10_000; 1% = 100
        /// utilization below kink usually means slow increase in rate, once utilization is above kink borrow rate increases fast
        uint256 kink;
        ///
        /// @param rateAtUtilizationZero desired borrow rate when utilization is zero. in 1e2: 100% = 10_000; 1% = 100
        /// i.e. constant minimum borrow rate
        /// e.g. at utilization = 0.01% rate could still be at least 4% (rateAtUtilizationZero would be 400 then)
        uint256 rateAtUtilizationZero;
        ///
        /// @param rateAtUtilizationKink borrow rate when utilization is at kink. in 1e2: 100% = 10_000; 1% = 100
        /// e.g. when rate should be 7% at kink then rateAtUtilizationKink would be 700
        uint256 rateAtUtilizationKink;
        ///
        /// @param rateAtUtilizationMax borrow rate when utilization is maximum at 100%. in 1e2: 100% = 10_000; 1% = 100
        /// e.g. when rate should be 125% at 100% then rateAtUtilizationMax would be 12_500
        uint256 rateAtUtilizationMax;
    }

    /// @notice struct to set borrow rate data for version 2
    struct RateDataV2Params {
        ///
        /// @param token for rate data
        address token;
        ///
        /// @param kink1 first kink in borrow rate. in 1e2: 100% = 10_000; 1% = 100
        /// utilization below kink 1 usually means slow increase in rate, once utilization is above kink 1 borrow rate increases faster
        uint256 kink1;
        ///
        /// @param kink2 second kink in borrow rate. in 1e2: 100% = 10_000; 1% = 100
        /// utilization below kink 2 usually means slow / medium increase in rate, once utilization is above kink 2 borrow rate increases fast
        uint256 kink2;
        ///
        /// @param rateAtUtilizationZero desired borrow rate when utilization is zero. in 1e2: 100% = 10_000; 1% = 100
        /// i.e. constant minimum borrow rate
        /// e.g. at utilization = 0.01% rate could still be at least 4% (rateAtUtilizationZero would be 400 then)
        uint256 rateAtUtilizationZero;
        ///
        /// @param rateAtUtilizationKink1 desired borrow rate when utilization is at first kink. in 1e2: 100% = 10_000; 1% = 100
        /// e.g. when rate should be 7% at first kink then rateAtUtilizationKink would be 700
        uint256 rateAtUtilizationKink1;
        ///
        /// @param rateAtUtilizationKink2 desired borrow rate when utilization is at second kink. in 1e2: 100% = 10_000; 1% = 100
        /// e.g. when rate should be 7% at second kink then rateAtUtilizationKink would be 1_200
        uint256 rateAtUtilizationKink2;
        ///
        /// @param rateAtUtilizationMax desired borrow rate when utilization is maximum at 100%. in 1e2: 100% = 10_000; 1% = 100
        /// e.g. when rate should be 125% at 100% then rateAtUtilizationMax would be 12_500
        uint256 rateAtUtilizationMax;
    }

    /// @notice struct to set token config
    struct TokenConfig {
        ///
        /// @param token address
        address token;
        ///
        /// @param fee charges on borrower's interest. in 1e2: 100% = 10_000; 1% = 100
        uint256 fee;
        ///
        /// @param threshold on when to update the storage slot. in 1e2: 100% = 10_000; 1% = 100
        uint256 threshold;
        ///
        /// @param maxUtilization maximum allowed utilization. in 1e2: 100% = 10_000; 1% = 100
        ///                       set to 100% to disable and have default limit of 100% (avoiding SLOAD).
        uint256 maxUtilization;
    }

    /// @notice struct to set user supply & withdrawal config
    struct UserSupplyConfig {
        ///
        /// @param user address
        address user;
        ///
        /// @param token address
        address token;
        ///
        /// @param mode: 0 = without interest. 1 = with interest
        uint8 mode;
        ///
        /// @param expandPercent withdrawal limit expand percent. in 1e2: 100% = 10_000; 1% = 100
        /// Also used to calculate rate at which withdrawal limit should decrease (instant).
        uint256 expandPercent;
        ///
        /// @param expandDuration withdrawal limit expand duration in seconds.
        /// used to calculate rate together with expandPercent
        uint256 expandDuration;
        ///
        /// @param baseWithdrawalLimit base limit, below this, user can withdraw the entire amount.
        /// amount in raw (to be multiplied with exchange price) or normal depends on configured mode in user config for the token:
        /// with interest -> raw, without interest -> normal
        uint256 baseWithdrawalLimit;
    }

    /// @notice struct to set user borrow & payback config
    struct UserBorrowConfig {
        ///
        /// @param user address
        address user;
        ///
        /// @param token address
        address token;
        ///
        /// @param mode: 0 = without interest. 1 = with interest
        uint8 mode;
        ///
        /// @param expandPercent debt limit expand percent. in 1e2: 100% = 10_000; 1% = 100
        /// Also used to calculate rate at which debt limit should decrease (instant).
        uint256 expandPercent;
        ///
        /// @param expandDuration debt limit expand duration in seconds.
        /// used to calculate rate together with expandPercent
        uint256 expandDuration;
        ///
        /// @param baseDebtCeiling base borrow limit. until here, borrow limit remains as baseDebtCeiling
        /// (user can borrow until this point at once without stepped expansion). Above this, automated limit comes in place.
        /// amount in raw (to be multiplied with exchange price) or normal depends on configured mode in user config for the token:
        /// with interest -> raw, without interest -> normal
        uint256 baseDebtCeiling;
        ///
        /// @param maxDebtCeiling max borrow ceiling, maximum amount the user can borrow.
        /// amount in raw (to be multiplied with exchange price) or normal depends on configured mode in user config for the token:
        /// with interest -> raw, without interest -> normal
        uint256 maxDebtCeiling;
    }
}

File 8 of 13 : structs.sol
// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.21;

import { IFluidDexT1 } from "../../../protocols/dex/interfaces/iDexT1.sol";
import { Structs as FluidLiquidityResolverStructs } from "../liquidity/structs.sol";

abstract contract Structs {
    struct DexState {
        uint256 lastToLastStoredPrice;
        uint256 lastStoredPrice; // price of pool after the most recent swap
        uint256 centerPrice;
        uint256 lastUpdateTimestamp;
        uint256 lastPricesTimeDiff;
        uint256 oracleCheckPoint;
        uint256 oracleMapping;
        uint256 totalSupplyShares;
        uint256 totalBorrowShares;
        bool isSwapAndArbitragePaused; // if true, only perfect functions will be usable
        ShiftChanges shifts;
        // below values have to be combined with Oracle price data at the VaultResolver
        uint256 token0PerSupplyShare; // token0 amount per 1e18 supply shares
        uint256 token1PerSupplyShare; // token1 amount per 1e18 supply shares
        uint256 token0PerBorrowShare; // token0 amount per 1e18 borrow shares
        uint256 token1PerBorrowShare; // token1 amount per 1e18 borrow shares
    }

    struct ShiftData {
        uint256 oldUpper;
        uint256 oldLower;
        uint256 duration;
        uint256 startTimestamp;
        uint256 oldTime; // only for thresholdShift
    }

    struct CenterPriceShift {
        uint256 shiftPercentage;
        uint256 duration;
        uint256 startTimestamp;
    }

    struct ShiftChanges {
        bool isRangeChangeActive;
        bool isThresholdChangeActive;
        bool isCenterPriceShiftActive;
        ShiftData rangeShift;
        ShiftData thresholdShift;
        CenterPriceShift centerPriceShift;
    }

    struct Configs {
        bool isSmartCollateralEnabled;
        bool isSmartDebtEnabled;
        uint256 fee;
        uint256 revenueCut;
        uint256 upperRange;
        uint256 lowerRange;
        uint256 upperShiftThreshold;
        uint256 lowerShiftThreshold;
        uint256 shiftingTime;
        address centerPriceAddress;
        address hookAddress;
        uint256 maxCenterPrice;
        uint256 minCenterPrice;
        uint256 utilizationLimitToken0;
        uint256 utilizationLimitToken1;
        uint256 maxSupplyShares;
        uint256 maxBorrowShares;
    }

    // @dev note there might be other things that act as effective limits which are not fully considered here.
    // e.g. such as maximum 5% oracle shift in one swap, withdraws & borrowing together affecting each other etc.
    struct SwapLimitsAndAvailability {
        // liquidity total amounts
        uint liquiditySupplyToken0;
        uint liquiditySupplyToken1;
        uint liquidityBorrowToken0;
        uint liquidityBorrowToken1;
        // liquidity limits
        uint liquidityWithdrawableToken0;
        uint liquidityWithdrawableToken1;
        uint liquidityBorrowableToken0;
        uint liquidityBorrowableToken1;
        // utilization limits based on config at Dex. (e.g. liquiditySupplyToken0 * Configs.utilizationLimitToken0 / 1e3)
        uint utilizationLimitToken0;
        uint utilizationLimitToken1;
        // swappable amounts until utilization limit.
        // In a swap that does both withdraw and borrow, the effective amounts might be less because withdraw / borrow affect each other
        // (both increase utilization).
        uint withdrawableUntilUtilizationLimitToken0; // x = totalSupply - totalBorrow / maxUtilizationPercentage
        uint withdrawableUntilUtilizationLimitToken1;
        uint borrowableUntilUtilizationLimitToken0; // x = maxUtilizationPercentage * totalSupply - totalBorrow.
        uint borrowableUntilUtilizationLimitToken1;
        // additional liquidity related data such as supply amount, limits, expansion etc.
        FluidLiquidityResolverStructs.UserSupplyData liquidityUserSupplyDataToken0;
        FluidLiquidityResolverStructs.UserSupplyData liquidityUserSupplyDataToken1;
        // additional liquidity related data such as borrow amount, limits, expansion etc.
        FluidLiquidityResolverStructs.UserBorrowData liquidityUserBorrowDataToken0;
        FluidLiquidityResolverStructs.UserBorrowData liquidityUserBorrowDataToken1;
    }

    struct DexEntireData {
        address dex;
        IFluidDexT1.ConstantViews constantViews;
        IFluidDexT1.ConstantViews2 constantViews2;
        Configs configs;
        IFluidDexT1.PricesAndExchangePrice pex;
        IFluidDexT1.CollateralReserves colReserves;
        IFluidDexT1.DebtReserves debtReserves;
        DexState dexState;
        SwapLimitsAndAvailability limitsAndAvailability;
    }

    // amounts are always in normal (for withInterest already multiplied with exchange price)
    struct UserSupplyData {
        bool isAllowed;
        uint256 supply; // user supply amount/shares
        // the withdrawal limit (e.g. if 10% is the limit, and 100M is supplied, it would be 90M)
        uint256 withdrawalLimit;
        uint256 lastUpdateTimestamp;
        uint256 expandPercent; // withdrawal limit expand percent in 1e2
        uint256 expandDuration; // withdrawal limit expand duration in seconds
        uint256 baseWithdrawalLimit;
        // the current actual max withdrawable amount (e.g. if 10% is the limit, and 100M is supplied, it would be 10M)
        uint256 withdrawableUntilLimit;
        uint256 withdrawable; // actual currently withdrawable amount (supply - withdrawal Limit) & considering balance
        // liquidity related data such as supply amount, limits, expansion etc.
        FluidLiquidityResolverStructs.UserSupplyData liquidityUserSupplyDataToken0;
        FluidLiquidityResolverStructs.UserSupplyData liquidityUserSupplyDataToken1;
    }

    // amounts are always in normal (for withInterest already multiplied with exchange price)
    struct UserBorrowData {
        bool isAllowed;
        uint256 borrow; // user borrow amount/shares
        uint256 borrowLimit;
        uint256 lastUpdateTimestamp;
        uint256 expandPercent;
        uint256 expandDuration;
        uint256 baseBorrowLimit;
        uint256 maxBorrowLimit;
        uint256 borrowableUntilLimit; // borrowable amount until any borrow limit (incl. max utilization limit)
        uint256 borrowable; // actual currently borrowable amount (borrow limit - already borrowed) & considering balance, max utilization
        // liquidity related data such as borrow amount, limits, expansion etc.
        FluidLiquidityResolverStructs.UserBorrowData liquidityUserBorrowDataToken0;
        FluidLiquidityResolverStructs.UserBorrowData liquidityUserBorrowDataToken1;
    }
}

File 9 of 13 : variables.sol
// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.21;

import { IFluidLiquidityResolver } from "../liquidity/iLiquidityResolver.sol";
import { IFluidDexFactory } from "../../../protocols/dex/interfaces/iDexFactory.sol";

interface IFluidLiquidity {
    function readFromStorage(bytes32 slot_) external view returns (uint256 result_);
}

abstract contract Variables {
    IFluidDexFactory public immutable FACTORY;
    IFluidLiquidity public immutable LIQUIDITY;
    IFluidLiquidityResolver public immutable LIQUIDITY_RESOLVER;
    /// @dev Address of contract used for deploying center price & hook related contract
    address public immutable DEPLOYER_CONTRACT;

    uint256 internal constant X2 = 0x3;
    uint256 internal constant X3 = 0x7;
    uint256 internal constant X5 = 0x1f;
    uint256 internal constant X7 = 0x7f;
    uint256 internal constant X8 = 0xff;
    uint256 internal constant X9 = 0x1ff;
    uint256 internal constant X10 = 0x3ff;
    uint256 internal constant X11 = 0x7ff;
    uint256 internal constant X14 = 0x3fff;
    uint256 internal constant X16 = 0xffff;
    uint256 internal constant X17 = 0x1ffff;
    uint256 internal constant X20 = 0xfffff;
    uint256 internal constant X22 = 0x3fffff;
    uint256 internal constant X23 = 0x7fffff;
    uint256 internal constant X24 = 0xffffff;
    uint256 internal constant X28 = 0xfffffff;
    uint256 internal constant X30 = 0x3fffffff;
    uint256 internal constant X32 = 0xffffffff;
    uint256 internal constant X33 = 0x1ffffffff;
    uint256 internal constant X40 = 0xffffffffff;
    uint256 internal constant X64 = 0xffffffffffffffff;
    uint256 internal constant X128 = 0xffffffffffffffffffffffffffffffff;

    /// @dev address that is mapped to the chain native token
    address internal constant NATIVE_TOKEN_ADDRESS = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;

    constructor(address factory_, address liquidity_, address liquidityResolver_, address deployer_) {
        FACTORY = IFluidDexFactory(factory_);
        LIQUIDITY = IFluidLiquidity(liquidity_);
        LIQUIDITY_RESOLVER = IFluidLiquidityResolver(liquidityResolver_);
        DEPLOYER_CONTRACT = deployer_;
    }
}

File 10 of 13 : iLiquidityResolver.sol
//SPDX-License-Identifier: MIT
pragma solidity 0.8.21;

import { Structs as LiquidityStructs } from "../../../periphery/resolvers/liquidity/structs.sol";

interface IFluidLiquidityResolver {
    /// @notice gets the `revenueAmount_` for a `token_`.
    function getRevenue(address token_) external view returns (uint256 revenueAmount_);

    /// @notice address of contract that gets sent the revenue. Configurable by governance
    function getRevenueCollector() external view returns (address);

    /// @notice Liquidity contract paused status: status = 1 -> normal. status = 2 -> paused.
    function getStatus() external view returns (uint256);

    /// @notice checks if `auth_` is an allowed auth on Liquidity.
    /// Auths can set most config values. E.g. contracts that automate certain flows like e.g. adding a new fToken.
    /// Governance can add/remove auths. Governance is auth by default.
    function isAuth(address auth_) external view returns (uint256);

    /// @notice checks if `guardian_` is an allowed Guardian on Liquidity.
    /// Guardians can pause lower class users.
    /// Governance can add/remove guardians. Governance is guardian by default.
    function isGuardian(address guardian_) external view returns (uint256);

    /// @notice gets user class for `user_`. Class defines which protocols can be paused by guardians.
    /// Currently there are 2 classes: 0 can be paused by guardians. 1 cannot be paused by guardians.
    /// New protocols are added as class 0 and will be upgraded to 1 over time.
    function getUserClass(address user_) external view returns (uint256);

    /// @notice gets exchangePricesAndConfig packed uint256 storage slot for `token_`.
    function getExchangePricesAndConfig(address token_) external view returns (uint256);

    /// @notice gets rateConfig packed uint256 storage slot for `token_`.
    function getRateConfig(address token_) external view returns (uint256);

    /// @notice gets totalAmounts packed uint256 storage slot for `token_`.
    function getTotalAmounts(address token_) external view returns (uint256);

    /// @notice gets configs2 packed uint256 storage slot for `token_`.
    function getConfigs2(address token_) external view returns (uint256);

    /// @notice gets userSupply data packed uint256 storage slot for `user_` and `token_`.
    function getUserSupply(address user_, address token_) external view returns (uint256);

    /// @notice gets userBorrow data packed uint256 storage slot for `user_` and `token_`.
    function getUserBorrow(address user_, address token_) external view returns (uint256);

    /// @notice returns all `listedTokens_` at the Liquidity contract. Once configured, a token can never be removed.
    function listedTokens() external view returns (address[] memory listedTokens_);

    /// @notice get the Rate config data `rateData_` for a `token_` compiled from the packed uint256 rateConfig storage slot
    function getTokenRateData(address token_) external view returns (LiquidityStructs.RateData memory rateData_);

    /// @notice get the Rate config datas `rateDatas_` for multiple `tokens_` compiled from the packed uint256 rateConfig storage slot
    function getTokensRateData(
        address[] calldata tokens_
    ) external view returns (LiquidityStructs.RateData[] memory rateDatas_);

    /// @notice returns general data for `token_` such as rates, exchange prices, utilization, fee, total amounts etc.
    function getOverallTokenData(
        address token_
    ) external view returns (LiquidityStructs.OverallTokenData memory overallTokenData_);

    /// @notice returns general data for multiple `tokens_` such as rates, exchange prices, utilization, fee, total amounts etc.
    function getOverallTokensData(
        address[] calldata tokens_
    ) external view returns (LiquidityStructs.OverallTokenData[] memory overallTokensData_);

    /// @notice returns general data for all `listedTokens()` such as rates, exchange prices, utilization, fee, total amounts etc.
    function getAllOverallTokensData()
        external
        view
        returns (LiquidityStructs.OverallTokenData[] memory overallTokensData_);

    /// @notice returns `user_` supply data and general data (such as rates, exchange prices, utilization, fee, total amounts etc.) for `token_`
    function getUserSupplyData(
        address user_,
        address token_
    )
        external
        view
        returns (
            LiquidityStructs.UserSupplyData memory userSupplyData_,
            LiquidityStructs.OverallTokenData memory overallTokenData_
        );

    /// @notice returns `user_` supply data and general data (such as rates, exchange prices, utilization, fee, total amounts etc.) for multiple `tokens_`
    function getUserMultipleSupplyData(
        address user_,
        address[] calldata tokens_
    )
        external
        view
        returns (
            LiquidityStructs.UserSupplyData[] memory userSuppliesData_,
            LiquidityStructs.OverallTokenData[] memory overallTokensData_
        );

    /// @notice returns `user_` borrow data and general data (such as rates, exchange prices, utilization, fee, total amounts etc.) for `token_`
    function getUserBorrowData(
        address user_,
        address token_
    )
        external
        view
        returns (
            LiquidityStructs.UserBorrowData memory userBorrowData_,
            LiquidityStructs.OverallTokenData memory overallTokenData_
        );

    /// @notice returns `user_` borrow data and general data (such as rates, exchange prices, utilization, fee, total amounts etc.) for multiple `tokens_`
    function getUserMultipleBorrowData(
        address user_,
        address[] calldata tokens_
    )
        external
        view
        returns (
            LiquidityStructs.UserBorrowData[] memory userBorrowingsData_,
            LiquidityStructs.OverallTokenData[] memory overallTokensData_
        );

    /// @notice returns `user_` supply data and general data (such as rates, exchange prices, utilization, fee, total amounts etc.) for multiple `supplyTokens_`
    ///     and returns `user_` borrow data and general data (such as rates, exchange prices, utilization, fee, total amounts etc.) for multiple `borrowTokens_`
    function getUserMultipleBorrowSupplyData(
        address user_,
        address[] calldata supplyTokens_,
        address[] calldata borrowTokens_
    )
        external
        view
        returns (
            LiquidityStructs.UserSupplyData[] memory userSuppliesData_,
            LiquidityStructs.OverallTokenData[] memory overallSupplyTokensData_,
            LiquidityStructs.UserBorrowData[] memory userBorrowingsData_,
            LiquidityStructs.OverallTokenData[] memory overallBorrowTokensData_
        );
}

File 11 of 13 : structs.sol
// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.21;

import { Structs as AdminModuleStructs } from "../../../liquidity/adminModule/structs.sol";

abstract contract Structs {
    struct RateData {
        uint256 version;
        AdminModuleStructs.RateDataV1Params rateDataV1;
        AdminModuleStructs.RateDataV2Params rateDataV2;
    }

    struct OverallTokenData {
        uint256 borrowRate;
        uint256 supplyRate;
        uint256 fee; // revenue fee
        uint256 lastStoredUtilization;
        uint256 storageUpdateThreshold;
        uint256 lastUpdateTimestamp;
        uint256 supplyExchangePrice;
        uint256 borrowExchangePrice;
        uint256 supplyRawInterest;
        uint256 supplyInterestFree;
        uint256 borrowRawInterest;
        uint256 borrowInterestFree;
        uint256 totalSupply;
        uint256 totalBorrow;
        uint256 revenue;
        uint256 maxUtilization; // maximum allowed utilization
        RateData rateData;
    }

    // amounts are always in normal (for withInterest already multiplied with exchange price)
    struct UserSupplyData {
        bool modeWithInterest; // true if mode = with interest, false = without interest
        uint256 supply; // user supply amount
        // the withdrawal limit (e.g. if 10% is the limit, and 100M is supplied, it would be 90M)
        uint256 withdrawalLimit;
        uint256 lastUpdateTimestamp;
        uint256 expandPercent; // withdrawal limit expand percent in 1e2
        uint256 expandDuration; // withdrawal limit expand duration in seconds
        uint256 baseWithdrawalLimit;
        // the current actual max withdrawable amount (e.g. if 10% is the limit, and 100M is supplied, it would be 10M)
        uint256 withdrawableUntilLimit;
        uint256 withdrawable; // actual currently withdrawable amount (supply - withdrawal Limit) & considering balance
    }

    // amounts are always in normal (for withInterest already multiplied with exchange price)
    struct UserBorrowData {
        bool modeWithInterest; // true if mode = with interest, false = without interest
        uint256 borrow; // user borrow amount
        uint256 borrowLimit;
        uint256 lastUpdateTimestamp;
        uint256 expandPercent;
        uint256 expandDuration;
        uint256 baseBorrowLimit;
        uint256 maxBorrowLimit;
        uint256 borrowableUntilLimit; // borrowable amount until any borrow limit (incl. max utilization limit)
        uint256 borrowable; // actual currently borrowable amount (borrow limit - already borrowed) & considering balance, max utilization
        uint256 borrowLimitUtilization; // borrow limit for `maxUtilization`
    }
}

File 12 of 13 : iDexFactory.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.21;

interface IFluidDexFactory {
    /// @notice Global auth is auth for all dexes
    function isGlobalAuth(address auth_) external view returns (bool);

    /// @notice Dex auth is auth for a specific dex
    function isDexAuth(address vault_, address auth_) external view returns (bool);

    /// @notice Total dexes deployed.
    function totalDexes() external view returns (uint256);

    /// @notice Compute dexAddress
    function getDexAddress(uint256 dexId_) external view returns (address);

    /// @notice read uint256 `result_` for a storage `slot_` key
    function readFromStorage(bytes32 slot_) external view returns (uint256 result_);
}

File 13 of 13 : iDexT1.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.21;

interface IFluidDexT1 {
    error FluidDexError(uint256 errorId);

    /// @notice used to simulate swap to find the output amount
    error FluidDexSwapResult(uint256 amountOut);

    error FluidDexPerfectLiquidityOutput(uint256 token0Amt, uint token1Amt);

    error FluidDexSingleTokenOutput(uint256 tokenAmt);

    error FluidDexLiquidityOutput(uint256 shares);

    error FluidDexPricesAndExchangeRates(PricesAndExchangePrice pex_);

    /// @notice returns the dex id
    function DEX_ID() external view returns (uint256);

    /// @notice reads uint256 data `result_` from storage at a bytes32 storage `slot_` key.
    function readFromStorage(bytes32 slot_) external view returns (uint256 result_);

    struct Implementations {
        address shift;
        address admin;
        address colOperations;
        address debtOperations;
        address perfectOperationsAndOracle;
    }

    struct ConstantViews {
        uint256 dexId;
        address liquidity;
        address factory;
        Implementations implementations;
        address deployerContract;
        address token0;
        address token1;
        bytes32 supplyToken0Slot;
        bytes32 borrowToken0Slot;
        bytes32 supplyToken1Slot;
        bytes32 borrowToken1Slot;
        bytes32 exchangePriceToken0Slot;
        bytes32 exchangePriceToken1Slot;
        uint256 oracleMapping;
    }

    struct ConstantViews2 {
        uint token0NumeratorPrecision;
        uint token0DenominatorPrecision;
        uint token1NumeratorPrecision;
        uint token1DenominatorPrecision;
    }

    struct PricesAndExchangePrice {
        uint lastStoredPrice; // last stored price in 1e27 decimals
        uint centerPrice; // last stored price in 1e27 decimals
        uint upperRange; // price at upper range in 1e27 decimals
        uint lowerRange; // price at lower range in 1e27 decimals
        uint geometricMean; // geometric mean of upper range & lower range in 1e27 decimals
        uint supplyToken0ExchangePrice;
        uint borrowToken0ExchangePrice;
        uint supplyToken1ExchangePrice;
        uint borrowToken1ExchangePrice;
    }

    struct CollateralReserves {
        uint token0RealReserves;
        uint token1RealReserves;
        uint token0ImaginaryReserves;
        uint token1ImaginaryReserves;
    }

    struct DebtReserves {
        uint token0Debt;
        uint token1Debt;
        uint token0RealReserves;
        uint token1RealReserves;
        uint token0ImaginaryReserves;
        uint token1ImaginaryReserves;
    }

    function getCollateralReserves(
        uint geometricMean_,
        uint upperRange_,
        uint lowerRange_,
        uint token0SupplyExchangePrice_,
        uint token1SupplyExchangePrice_
    ) external view returns (CollateralReserves memory c_);

    function getDebtReserves(
        uint geometricMean_,
        uint upperRange_,
        uint lowerRange_,
        uint token0BorrowExchangePrice_,
        uint token1BorrowExchangePrice_
    ) external view returns (DebtReserves memory d_);

    // reverts with FluidDexPricesAndExchangeRates(pex_);
    function getPricesAndExchangePrices() external;

    function constantsView() external view returns (ConstantViews memory constantsView_);

    function constantsView2() external view returns (ConstantViews2 memory constantsView2_);

    struct Oracle {
        uint twap1by0; // TWAP price
        uint lowestPrice1by0; // lowest price point
        uint highestPrice1by0; // highest price point
        uint twap0by1; // TWAP price
        uint lowestPrice0by1; // lowest price point
        uint highestPrice0by1; // highest price point
    }

    /// @dev This function allows users to swap a specific amount of input tokens for output tokens
    /// @param swap0to1_ Direction of swap. If true, swaps token0 for token1; if false, swaps token1 for token0
    /// @param amountIn_ The exact amount of input tokens to swap
    /// @param amountOutMin_ The minimum amount of output tokens the user is willing to accept
    /// @param to_ Recipient of swapped tokens. If to_ == address(0) then out tokens will be sent to msg.sender. If to_ == ADDRESS_DEAD then function will revert with amountOut_
    /// @return amountOut_ The amount of output tokens received from the swap
    function swapIn(
        bool swap0to1_,
        uint256 amountIn_,
        uint256 amountOutMin_,
        address to_
    ) external payable returns (uint256 amountOut_);

    /// @dev Swap tokens with perfect amount out
    /// @param swap0to1_ Direction of swap. If true, swaps token0 for token1; if false, swaps token1 for token0
    /// @param amountOut_ The exact amount of tokens to receive after swap
    /// @param amountInMax_ Maximum amount of tokens to swap in
    /// @param to_ Recipient of swapped tokens. If to_ == address(0) then out tokens will be sent to msg.sender. If to_ == ADDRESS_DEAD then function will revert with amountIn_
    /// @return amountIn_ The amount of input tokens used for the swap
    function swapOut(
        bool swap0to1_,
        uint256 amountOut_,
        uint256 amountInMax_,
        address to_
    ) external payable returns (uint256 amountIn_);

    /// @dev Deposit tokens in equal proportion to the current pool ratio
    /// @param shares_ The number of shares to mint
    /// @param maxToken0Deposit_ Maximum amount of token0 to deposit
    /// @param maxToken1Deposit_ Maximum amount of token1 to deposit
    /// @param estimate_ If true, function will revert with estimated deposit amounts without executing the deposit
    /// @return token0Amt_ Amount of token0 deposited
    /// @return token1Amt_ Amount of token1 deposited
    function depositPerfect(
        uint shares_,
        uint maxToken0Deposit_,
        uint maxToken1Deposit_,
        bool estimate_
    ) external payable returns (uint token0Amt_, uint token1Amt_);

    /// @dev This function allows users to withdraw a perfect amount of collateral liquidity
    /// @param shares_ The number of shares to withdraw
    /// @param minToken0Withdraw_ The minimum amount of token0 the user is willing to accept
    /// @param minToken1Withdraw_ The minimum amount of token1 the user is willing to accept
    /// @param to_ Recipient of swapped tokens. If to_ == address(0) then out tokens will be sent to msg.sender. If to_ == ADDRESS_DEAD then function will revert with token0Amt_ & token1Amt_
    /// @return token0Amt_ The amount of token0 withdrawn
    /// @return token1Amt_ The amount of token1 withdrawn
    function withdrawPerfect(
        uint shares_,
        uint minToken0Withdraw_,
        uint minToken1Withdraw_,
        address to_
    ) external returns (uint token0Amt_, uint token1Amt_);

    /// @dev This function allows users to borrow tokens in equal proportion to the current debt pool ratio
    /// @param shares_ The number of shares to borrow
    /// @param minToken0Borrow_ Minimum amount of token0 to borrow
    /// @param minToken1Borrow_ Minimum amount of token1 to borrow
    /// @param to_ Recipient of swapped tokens. If to_ == address(0) then out tokens will be sent to msg.sender. If to_ == ADDRESS_DEAD then function will revert with token0Amt_ & token1Amt_
    /// @return token0Amt_ Amount of token0 borrowed
    /// @return token1Amt_ Amount of token1 borrowed
    function borrowPerfect(
        uint shares_,
        uint minToken0Borrow_,
        uint minToken1Borrow_,
        address to_
    ) external returns (uint token0Amt_, uint token1Amt_);

    /// @dev This function allows users to pay back borrowed tokens in equal proportion to the current debt pool ratio
    /// @param shares_ The number of shares to pay back
    /// @param maxToken0Payback_ Maximum amount of token0 to pay back
    /// @param maxToken1Payback_ Maximum amount of token1 to pay back
    /// @param estimate_ If true, function will revert with estimated payback amounts without executing the payback
    /// @return token0Amt_ Amount of token0 paid back
    /// @return token1Amt_ Amount of token1 paid back
    function paybackPerfect(
        uint shares_,
        uint maxToken0Payback_,
        uint maxToken1Payback_,
        bool estimate_
    ) external payable returns (uint token0Amt_, uint token1Amt_);

    /// @dev This function allows users to deposit tokens in any proportion into the col pool
    /// @param token0Amt_ The amount of token0 to deposit
    /// @param token1Amt_ The amount of token1 to deposit
    /// @param minSharesAmt_ The minimum amount of shares the user expects to receive
    /// @param estimate_ If true, function will revert with estimated shares without executing the deposit
    /// @return shares_ The amount of shares minted for the deposit
    function deposit(
        uint token0Amt_,
        uint token1Amt_,
        uint minSharesAmt_,
        bool estimate_
    ) external payable returns (uint shares_);

    /// @dev This function allows users to withdraw tokens in any proportion from the col pool
    /// @param token0Amt_ The amount of token0 to withdraw
    /// @param token1Amt_ The amount of token1 to withdraw
    /// @param maxSharesAmt_ The maximum number of shares the user is willing to burn
    /// @param to_ Recipient of swapped tokens. If to_ == address(0) then out tokens will be sent to msg.sender. If to_ == ADDRESS_DEAD then function will revert with shares_
    /// @return shares_ The number of shares burned for the withdrawal
    function withdraw(
        uint token0Amt_,
        uint token1Amt_,
        uint maxSharesAmt_,
        address to_
    ) external returns (uint shares_);

    /// @dev This function allows users to borrow tokens in any proportion from the debt pool
    /// @param token0Amt_ The amount of token0 to borrow
    /// @param token1Amt_ The amount of token1 to borrow
    /// @param maxSharesAmt_ The maximum amount of shares the user is willing to receive
    /// @param to_ Recipient of swapped tokens. If to_ == address(0) then out tokens will be sent to msg.sender. If to_ == ADDRESS_DEAD then function will revert with shares_
    /// @return shares_ The amount of borrow shares minted to represent the borrowed amount
    function borrow(
        uint token0Amt_,
        uint token1Amt_,
        uint maxSharesAmt_,
        address to_
    ) external returns (uint shares_);

    /// @dev This function allows users to payback tokens in any proportion to the debt pool
    /// @param token0Amt_ The amount of token0 to payback
    /// @param token1Amt_ The amount of token1 to payback
    /// @param minSharesAmt_ The minimum amount of shares the user expects to burn
    /// @param estimate_ If true, function will revert with estimated shares without executing the payback
    /// @return shares_ The amount of borrow shares burned for the payback
    function payback(
        uint token0Amt_,
        uint token1Amt_,
        uint minSharesAmt_,
        bool estimate_
    ) external payable returns (uint shares_);

    /// @dev This function allows users to withdraw their collateral with perfect shares in one token
    /// @param shares_ The number of shares to burn for withdrawal
    /// @param minToken0_ The minimum amount of token0 the user expects to receive (set to 0 if withdrawing in token1)
    /// @param minToken1_ The minimum amount of token1 the user expects to receive (set to 0 if withdrawing in token0)
    /// @param to_ Recipient of swapped tokens. If to_ == address(0) then out tokens will be sent to msg.sender. If to_ == ADDRESS_DEAD then function will revert with withdrawAmt_
    /// @return withdrawAmt_ The amount of tokens withdrawn in the chosen token
    function withdrawPerfectInOneToken(
        uint shares_,
        uint minToken0_,
        uint minToken1_,
        address to_
    ) external returns (
        uint withdrawAmt_
    );

    /// @dev This function allows users to payback their debt with perfect shares in one token
    /// @param shares_ The number of shares to burn for payback
    /// @param maxToken0_ The maximum amount of token0 the user is willing to pay (set to 0 if paying back in token1)
    /// @param maxToken1_ The maximum amount of token1 the user is willing to pay (set to 0 if paying back in token0)
    /// @param estimate_ If true, the function will revert with the estimated payback amount without executing the payback
    /// @return paybackAmt_ The amount of tokens paid back in the chosen token
    function paybackPerfectInOneToken(
        uint shares_,
        uint maxToken0_,
        uint maxToken1_,
        bool estimate_
    ) external payable returns (
        uint paybackAmt_
    );

    /// @dev the oracle assumes last set price of pool till the next swap happens.
    /// There's a possibility that during that time some interest is generated hence the last stored price is not the 100% correct price for the whole duration
    /// but the difference due to interest will be super low so this difference is ignored
    /// For example 2 swaps happened 10min (600 seconds) apart and 1 token has 10% higher interest than other.
    /// then that token will accrue about 10% * 600 / secondsInAYear = ~0.0002%
    /// @param secondsAgos_ array of seconds ago for which TWAP is needed. If user sends [10, 30, 60] then twaps_ will return [10-0, 30-10, 60-30]
    /// @return twaps_ twap price, lowest price (aka minima) & highest price (aka maxima) between secondsAgo checkpoints
    /// @return currentPrice_ price of pool after the most recent swap
    function oraclePrice(
        uint[] memory secondsAgos_
    ) external view returns (
        Oracle[] memory twaps_,
        uint currentPrice_
    );
}

Settings
{
  "optimizer": {
    "enabled": true,
    "runs": 5000
  },
  "evmVersion": "paris",
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "libraries": {}
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"factory_","type":"address"},{"internalType":"address","name":"liquidity_","type":"address"},{"internalType":"address","name":"liquidityResolver_","type":"address"},{"internalType":"address","name":"deployer_","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"DEPLOYER_CONTRACT","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"FACTORY","outputs":[{"internalType":"contract IFluidDexFactory","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"LIQUIDITY","outputs":[{"internalType":"contract IFluidLiquidity","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"LIQUIDITY_RESOLVER","outputs":[{"internalType":"contract IFluidLiquidityResolver","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"dex_","type":"address"},{"internalType":"uint256","name":"token0Amt_","type":"uint256"},{"internalType":"uint256","name":"token1Amt_","type":"uint256"},{"internalType":"uint256","name":"maxSharesAmt_","type":"uint256"}],"name":"estimateBorrow","outputs":[{"internalType":"uint256","name":"shares_","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"dex_","type":"address"},{"internalType":"uint256","name":"shares_","type":"uint256"},{"internalType":"uint256","name":"minToken0Borrow_","type":"uint256"},{"internalType":"uint256","name":"minToken1Borrow_","type":"uint256"}],"name":"estimateBorrowPerfect","outputs":[{"internalType":"uint256","name":"token0Amt_","type":"uint256"},{"internalType":"uint256","name":"token1Amt_","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"dex_","type":"address"},{"internalType":"uint256","name":"token0Amt_","type":"uint256"},{"internalType":"uint256","name":"token1Amt_","type":"uint256"},{"internalType":"uint256","name":"minSharesAmt_","type":"uint256"}],"name":"estimateDeposit","outputs":[{"internalType":"uint256","name":"shares_","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"dex_","type":"address"},{"internalType":"uint256","name":"shares_","type":"uint256"},{"internalType":"uint256","name":"maxToken0Deposit_","type":"uint256"},{"internalType":"uint256","name":"maxToken1Deposit_","type":"uint256"}],"name":"estimateDepositPerfect","outputs":[{"internalType":"uint256","name":"token0Amt_","type":"uint256"},{"internalType":"uint256","name":"token1Amt_","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"dex_","type":"address"},{"internalType":"uint256","name":"token0Amt_","type":"uint256"},{"internalType":"uint256","name":"token1Amt_","type":"uint256"},{"internalType":"uint256","name":"minSharesAmt_","type":"uint256"}],"name":"estimatePayback","outputs":[{"internalType":"uint256","name":"shares_","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"dex_","type":"address"},{"internalType":"uint256","name":"shares_","type":"uint256"},{"internalType":"uint256","name":"maxToken0Payback_","type":"uint256"},{"internalType":"uint256","name":"maxToken1Payback_","type":"uint256"}],"name":"estimatePaybackPerfect","outputs":[{"internalType":"uint256","name":"token0Amt_","type":"uint256"},{"internalType":"uint256","name":"token1Amt_","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"dex_","type":"address"},{"internalType":"uint256","name":"shares_","type":"uint256"},{"internalType":"uint256","name":"maxToken0_","type":"uint256"},{"internalType":"uint256","name":"maxToken1_","type":"uint256"}],"name":"estimatePaybackPerfectInOneToken","outputs":[{"internalType":"uint256","name":"paybackAmt_","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"dex_","type":"address"},{"internalType":"bool","name":"swap0to1_","type":"bool"},{"internalType":"uint256","name":"amountIn_","type":"uint256"},{"internalType":"uint256","name":"amountOutMin_","type":"uint256"}],"name":"estimateSwapIn","outputs":[{"internalType":"uint256","name":"amountOut_","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"dex_","type":"address"},{"internalType":"bool","name":"swap0to1_","type":"bool"},{"internalType":"uint256","name":"amountOut_","type":"uint256"},{"internalType":"uint256","name":"amountInMax_","type":"uint256"}],"name":"estimateSwapOut","outputs":[{"internalType":"uint256","name":"amountIn_","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"dex_","type":"address"},{"internalType":"uint256","name":"token0Amt_","type":"uint256"},{"internalType":"uint256","name":"token1Amt_","type":"uint256"},{"internalType":"uint256","name":"maxSharesAmt_","type":"uint256"}],"name":"estimateWithdraw","outputs":[{"internalType":"uint256","name":"shares_","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"dex_","type":"address"},{"internalType":"uint256","name":"shares_","type":"uint256"},{"internalType":"uint256","name":"minToken0Withdraw_","type":"uint256"},{"internalType":"uint256","name":"minToken1Withdraw_","type":"uint256"}],"name":"estimateWithdrawPerfect","outputs":[{"internalType":"uint256","name":"token0Amt_","type":"uint256"},{"internalType":"uint256","name":"token1Amt_","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"dex_","type":"address"},{"internalType":"uint256","name":"shares_","type":"uint256"},{"internalType":"uint256","name":"minToken0_","type":"uint256"},{"internalType":"uint256","name":"minToken1_","type":"uint256"}],"name":"estimateWithdrawPerfectInOneToken","outputs":[{"internalType":"uint256","name":"withdrawAmt_","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getAllDexAddresses","outputs":[{"internalType":"address[]","name":"dexes_","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getAllDexEntireDatas","outputs":[{"components":[{"internalType":"address","name":"dex","type":"address"},{"components":[{"internalType":"uint256","name":"dexId","type":"uint256"},{"internalType":"address","name":"liquidity","type":"address"},{"internalType":"address","name":"factory","type":"address"},{"components":[{"internalType":"address","name":"shift","type":"address"},{"internalType":"address","name":"admin","type":"address"},{"internalType":"address","name":"colOperations","type":"address"},{"internalType":"address","name":"debtOperations","type":"address"},{"internalType":"address","name":"perfectOperationsAndOracle","type":"address"}],"internalType":"struct IFluidDexT1.Implementations","name":"implementations","type":"tuple"},{"internalType":"address","name":"deployerContract","type":"address"},{"internalType":"address","name":"token0","type":"address"},{"internalType":"address","name":"token1","type":"address"},{"internalType":"bytes32","name":"supplyToken0Slot","type":"bytes32"},{"internalType":"bytes32","name":"borrowToken0Slot","type":"bytes32"},{"internalType":"bytes32","name":"supplyToken1Slot","type":"bytes32"},{"internalType":"bytes32","name":"borrowToken1Slot","type":"bytes32"},{"internalType":"bytes32","name":"exchangePriceToken0Slot","type":"bytes32"},{"internalType":"bytes32","name":"exchangePriceToken1Slot","type":"bytes32"},{"internalType":"uint256","name":"oracleMapping","type":"uint256"}],"internalType":"struct IFluidDexT1.ConstantViews","name":"constantViews","type":"tuple"},{"components":[{"internalType":"uint256","name":"token0NumeratorPrecision","type":"uint256"},{"internalType":"uint256","name":"token0DenominatorPrecision","type":"uint256"},{"internalType":"uint256","name":"token1NumeratorPrecision","type":"uint256"},{"internalType":"uint256","name":"token1DenominatorPrecision","type":"uint256"}],"internalType":"struct IFluidDexT1.ConstantViews2","name":"constantViews2","type":"tuple"},{"components":[{"internalType":"bool","name":"isSmartCollateralEnabled","type":"bool"},{"internalType":"bool","name":"isSmartDebtEnabled","type":"bool"},{"internalType":"uint256","name":"fee","type":"uint256"},{"internalType":"uint256","name":"revenueCut","type":"uint256"},{"internalType":"uint256","name":"upperRange","type":"uint256"},{"internalType":"uint256","name":"lowerRange","type":"uint256"},{"internalType":"uint256","name":"upperShiftThreshold","type":"uint256"},{"internalType":"uint256","name":"lowerShiftThreshold","type":"uint256"},{"internalType":"uint256","name":"shiftingTime","type":"uint256"},{"internalType":"address","name":"centerPriceAddress","type":"address"},{"internalType":"address","name":"hookAddress","type":"address"},{"internalType":"uint256","name":"maxCenterPrice","type":"uint256"},{"internalType":"uint256","name":"minCenterPrice","type":"uint256"},{"internalType":"uint256","name":"utilizationLimitToken0","type":"uint256"},{"internalType":"uint256","name":"utilizationLimitToken1","type":"uint256"},{"internalType":"uint256","name":"maxSupplyShares","type":"uint256"},{"internalType":"uint256","name":"maxBorrowShares","type":"uint256"}],"internalType":"struct Structs.Configs","name":"configs","type":"tuple"},{"components":[{"internalType":"uint256","name":"lastStoredPrice","type":"uint256"},{"internalType":"uint256","name":"centerPrice","type":"uint256"},{"internalType":"uint256","name":"upperRange","type":"uint256"},{"internalType":"uint256","name":"lowerRange","type":"uint256"},{"internalType":"uint256","name":"geometricMean","type":"uint256"},{"internalType":"uint256","name":"supplyToken0ExchangePrice","type":"uint256"},{"internalType":"uint256","name":"borrowToken0ExchangePrice","type":"uint256"},{"internalType":"uint256","name":"supplyToken1ExchangePrice","type":"uint256"},{"internalType":"uint256","name":"borrowToken1ExchangePrice","type":"uint256"}],"internalType":"struct IFluidDexT1.PricesAndExchangePrice","name":"pex","type":"tuple"},{"components":[{"internalType":"uint256","name":"token0RealReserves","type":"uint256"},{"internalType":"uint256","name":"token1RealReserves","type":"uint256"},{"internalType":"uint256","name":"token0ImaginaryReserves","type":"uint256"},{"internalType":"uint256","name":"token1ImaginaryReserves","type":"uint256"}],"internalType":"struct IFluidDexT1.CollateralReserves","name":"colReserves","type":"tuple"},{"components":[{"internalType":"uint256","name":"token0Debt","type":"uint256"},{"internalType":"uint256","name":"token1Debt","type":"uint256"},{"internalType":"uint256","name":"token0RealReserves","type":"uint256"},{"internalType":"uint256","name":"token1RealReserves","type":"uint256"},{"internalType":"uint256","name":"token0ImaginaryReserves","type":"uint256"},{"internalType":"uint256","name":"token1ImaginaryReserves","type":"uint256"}],"internalType":"struct IFluidDexT1.DebtReserves","name":"debtReserves","type":"tuple"},{"components":[{"internalType":"uint256","name":"lastToLastStoredPrice","type":"uint256"},{"internalType":"uint256","name":"lastStoredPrice","type":"uint256"},{"internalType":"uint256","name":"centerPrice","type":"uint256"},{"internalType":"uint256","name":"lastUpdateTimestamp","type":"uint256"},{"internalType":"uint256","name":"lastPricesTimeDiff","type":"uint256"},{"internalType":"uint256","name":"oracleCheckPoint","type":"uint256"},{"internalType":"uint256","name":"oracleMapping","type":"uint256"},{"internalType":"uint256","name":"totalSupplyShares","type":"uint256"},{"internalType":"uint256","name":"totalBorrowShares","type":"uint256"},{"internalType":"bool","name":"isSwapAndArbitragePaused","type":"bool"},{"components":[{"internalType":"bool","name":"isRangeChangeActive","type":"bool"},{"internalType":"bool","name":"isThresholdChangeActive","type":"bool"},{"internalType":"bool","name":"isCenterPriceShiftActive","type":"bool"},{"components":[{"internalType":"uint256","name":"oldUpper","type":"uint256"},{"internalType":"uint256","name":"oldLower","type":"uint256"},{"internalType":"uint256","name":"duration","type":"uint256"},{"internalType":"uint256","name":"startTimestamp","type":"uint256"},{"internalType":"uint256","name":"oldTime","type":"uint256"}],"internalType":"struct Structs.ShiftData","name":"rangeShift","type":"tuple"},{"components":[{"internalType":"uint256","name":"oldUpper","type":"uint256"},{"internalType":"uint256","name":"oldLower","type":"uint256"},{"internalType":"uint256","name":"duration","type":"uint256"},{"internalType":"uint256","name":"startTimestamp","type":"uint256"},{"internalType":"uint256","name":"oldTime","type":"uint256"}],"internalType":"struct Structs.ShiftData","name":"thresholdShift","type":"tuple"},{"components":[{"internalType":"uint256","name":"shiftPercentage","type":"uint256"},{"internalType":"uint256","name":"duration","type":"uint256"},{"internalType":"uint256","name":"startTimestamp","type":"uint256"}],"internalType":"struct Structs.CenterPriceShift","name":"centerPriceShift","type":"tuple"}],"internalType":"struct Structs.ShiftChanges","name":"shifts","type":"tuple"},{"internalType":"uint256","name":"token0PerSupplyShare","type":"uint256"},{"internalType":"uint256","name":"token1PerSupplyShare","type":"uint256"},{"internalType":"uint256","name":"token0PerBorrowShare","type":"uint256"},{"internalType":"uint256","name":"token1PerBorrowShare","type":"uint256"}],"internalType":"struct Structs.DexState","name":"dexState","type":"tuple"},{"components":[{"internalType":"uint256","name":"liquiditySupplyToken0","type":"uint256"},{"internalType":"uint256","name":"liquiditySupplyToken1","type":"uint256"},{"internalType":"uint256","name":"liquidityBorrowToken0","type":"uint256"},{"internalType":"uint256","name":"liquidityBorrowToken1","type":"uint256"},{"internalType":"uint256","name":"liquidityWithdrawableToken0","type":"uint256"},{"internalType":"uint256","name":"liquidityWithdrawableToken1","type":"uint256"},{"internalType":"uint256","name":"liquidityBorrowableToken0","type":"uint256"},{"internalType":"uint256","name":"liquidityBorrowableToken1","type":"uint256"},{"internalType":"uint256","name":"utilizationLimitToken0","type":"uint256"},{"internalType":"uint256","name":"utilizationLimitToken1","type":"uint256"},{"internalType":"uint256","name":"withdrawableUntilUtilizationLimitToken0","type":"uint256"},{"internalType":"uint256","name":"withdrawableUntilUtilizationLimitToken1","type":"uint256"},{"internalType":"uint256","name":"borrowableUntilUtilizationLimitToken0","type":"uint256"},{"internalType":"uint256","name":"borrowableUntilUtilizationLimitToken1","type":"uint256"},{"components":[{"internalType":"bool","name":"modeWithInterest","type":"bool"},{"internalType":"uint256","name":"supply","type":"uint256"},{"internalType":"uint256","name":"withdrawalLimit","type":"uint256"},{"internalType":"uint256","name":"lastUpdateTimestamp","type":"uint256"},{"internalType":"uint256","name":"expandPercent","type":"uint256"},{"internalType":"uint256","name":"expandDuration","type":"uint256"},{"internalType":"uint256","name":"baseWithdrawalLimit","type":"uint256"},{"internalType":"uint256","name":"withdrawableUntilLimit","type":"uint256"},{"internalType":"uint256","name":"withdrawable","type":"uint256"}],"internalType":"struct Structs.UserSupplyData","name":"liquidityUserSupplyDataToken0","type":"tuple"},{"components":[{"internalType":"bool","name":"modeWithInterest","type":"bool"},{"internalType":"uint256","name":"supply","type":"uint256"},{"internalType":"uint256","name":"withdrawalLimit","type":"uint256"},{"internalType":"uint256","name":"lastUpdateTimestamp","type":"uint256"},{"internalType":"uint256","name":"expandPercent","type":"uint256"},{"internalType":"uint256","name":"expandDuration","type":"uint256"},{"internalType":"uint256","name":"baseWithdrawalLimit","type":"uint256"},{"internalType":"uint256","name":"withdrawableUntilLimit","type":"uint256"},{"internalType":"uint256","name":"withdrawable","type":"uint256"}],"internalType":"struct Structs.UserSupplyData","name":"liquidityUserSupplyDataToken1","type":"tuple"},{"components":[{"internalType":"bool","name":"modeWithInterest","type":"bool"},{"internalType":"uint256","name":"borrow","type":"uint256"},{"internalType":"uint256","name":"borrowLimit","type":"uint256"},{"internalType":"uint256","name":"lastUpdateTimestamp","type":"uint256"},{"internalType":"uint256","name":"expandPercent","type":"uint256"},{"internalType":"uint256","name":"expandDuration","type":"uint256"},{"internalType":"uint256","name":"baseBorrowLimit","type":"uint256"},{"internalType":"uint256","name":"maxBorrowLimit","type":"uint256"},{"internalType":"uint256","name":"borrowableUntilLimit","type":"uint256"},{"internalType":"uint256","name":"borrowable","type":"uint256"},{"internalType":"uint256","name":"borrowLimitUtilization","type":"uint256"}],"internalType":"struct Structs.UserBorrowData","name":"liquidityUserBorrowDataToken0","type":"tuple"},{"components":[{"internalType":"bool","name":"modeWithInterest","type":"bool"},{"internalType":"uint256","name":"borrow","type":"uint256"},{"internalType":"uint256","name":"borrowLimit","type":"uint256"},{"internalType":"uint256","name":"lastUpdateTimestamp","type":"uint256"},{"internalType":"uint256","name":"expandPercent","type":"uint256"},{"internalType":"uint256","name":"expandDuration","type":"uint256"},{"internalType":"uint256","name":"baseBorrowLimit","type":"uint256"},{"internalType":"uint256","name":"maxBorrowLimit","type":"uint256"},{"internalType":"uint256","name":"borrowableUntilLimit","type":"uint256"},{"internalType":"uint256","name":"borrowable","type":"uint256"},{"internalType":"uint256","name":"borrowLimitUtilization","type":"uint256"}],"internalType":"struct Structs.UserBorrowData","name":"liquidityUserBorrowDataToken1","type":"tuple"}],"internalType":"struct Structs.SwapLimitsAndAvailability","name":"limitsAndAvailability","type":"tuple"}],"internalType":"struct Structs.DexEntireData[]","name":"datas_","type":"tuple[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"dex_","type":"address"}],"name":"getCenterPriceShiftRaw","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"dexId_","type":"uint256"}],"name":"getDexAddress","outputs":[{"internalType":"address","name":"dex_","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"dex_","type":"address"}],"name":"getDexCollateralReserves","outputs":[{"components":[{"internalType":"uint256","name":"token0RealReserves","type":"uint256"},{"internalType":"uint256","name":"token1RealReserves","type":"uint256"},{"internalType":"uint256","name":"token0ImaginaryReserves","type":"uint256"},{"internalType":"uint256","name":"token1ImaginaryReserves","type":"uint256"}],"internalType":"struct IFluidDexT1.CollateralReserves","name":"reserves_","type":"tuple"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"dex_","type":"address"}],"name":"getDexConfigs","outputs":[{"components":[{"internalType":"bool","name":"isSmartCollateralEnabled","type":"bool"},{"internalType":"bool","name":"isSmartDebtEnabled","type":"bool"},{"internalType":"uint256","name":"fee","type":"uint256"},{"internalType":"uint256","name":"revenueCut","type":"uint256"},{"internalType":"uint256","name":"upperRange","type":"uint256"},{"internalType":"uint256","name":"lowerRange","type":"uint256"},{"internalType":"uint256","name":"upperShiftThreshold","type":"uint256"},{"internalType":"uint256","name":"lowerShiftThreshold","type":"uint256"},{"internalType":"uint256","name":"shiftingTime","type":"uint256"},{"internalType":"address","name":"centerPriceAddress","type":"address"},{"internalType":"address","name":"hookAddress","type":"address"},{"internalType":"uint256","name":"maxCenterPrice","type":"uint256"},{"internalType":"uint256","name":"minCenterPrice","type":"uint256"},{"internalType":"uint256","name":"utilizationLimitToken0","type":"uint256"},{"internalType":"uint256","name":"utilizationLimitToken1","type":"uint256"},{"internalType":"uint256","name":"maxSupplyShares","type":"uint256"},{"internalType":"uint256","name":"maxBorrowShares","type":"uint256"}],"internalType":"struct Structs.Configs","name":"configs_","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"dex_","type":"address"}],"name":"getDexConstantsView","outputs":[{"components":[{"internalType":"uint256","name":"dexId","type":"uint256"},{"internalType":"address","name":"liquidity","type":"address"},{"internalType":"address","name":"factory","type":"address"},{"components":[{"internalType":"address","name":"shift","type":"address"},{"internalType":"address","name":"admin","type":"address"},{"internalType":"address","name":"colOperations","type":"address"},{"internalType":"address","name":"debtOperations","type":"address"},{"internalType":"address","name":"perfectOperationsAndOracle","type":"address"}],"internalType":"struct IFluidDexT1.Implementations","name":"implementations","type":"tuple"},{"internalType":"address","name":"deployerContract","type":"address"},{"internalType":"address","name":"token0","type":"address"},{"internalType":"address","name":"token1","type":"address"},{"internalType":"bytes32","name":"supplyToken0Slot","type":"bytes32"},{"internalType":"bytes32","name":"borrowToken0Slot","type":"bytes32"},{"internalType":"bytes32","name":"supplyToken1Slot","type":"bytes32"},{"internalType":"bytes32","name":"borrowToken1Slot","type":"bytes32"},{"internalType":"bytes32","name":"exchangePriceToken0Slot","type":"bytes32"},{"internalType":"bytes32","name":"exchangePriceToken1Slot","type":"bytes32"},{"internalType":"uint256","name":"oracleMapping","type":"uint256"}],"internalType":"struct IFluidDexT1.ConstantViews","name":"constantsView_","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"dex_","type":"address"}],"name":"getDexConstantsView2","outputs":[{"components":[{"internalType":"uint256","name":"token0NumeratorPrecision","type":"uint256"},{"internalType":"uint256","name":"token0DenominatorPrecision","type":"uint256"},{"internalType":"uint256","name":"token1NumeratorPrecision","type":"uint256"},{"internalType":"uint256","name":"token1DenominatorPrecision","type":"uint256"}],"internalType":"struct IFluidDexT1.ConstantViews2","name":"constantsView2_","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"dex_","type":"address"}],"name":"getDexDebtReserves","outputs":[{"components":[{"internalType":"uint256","name":"token0Debt","type":"uint256"},{"internalType":"uint256","name":"token1Debt","type":"uint256"},{"internalType":"uint256","name":"token0RealReserves","type":"uint256"},{"internalType":"uint256","name":"token1RealReserves","type":"uint256"},{"internalType":"uint256","name":"token0ImaginaryReserves","type":"uint256"},{"internalType":"uint256","name":"token1ImaginaryReserves","type":"uint256"}],"internalType":"struct IFluidDexT1.DebtReserves","name":"reserves_","type":"tuple"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"dex_","type":"address"}],"name":"getDexEntireData","outputs":[{"components":[{"internalType":"address","name":"dex","type":"address"},{"components":[{"internalType":"uint256","name":"dexId","type":"uint256"},{"internalType":"address","name":"liquidity","type":"address"},{"internalType":"address","name":"factory","type":"address"},{"components":[{"internalType":"address","name":"shift","type":"address"},{"internalType":"address","name":"admin","type":"address"},{"internalType":"address","name":"colOperations","type":"address"},{"internalType":"address","name":"debtOperations","type":"address"},{"internalType":"address","name":"perfectOperationsAndOracle","type":"address"}],"internalType":"struct IFluidDexT1.Implementations","name":"implementations","type":"tuple"},{"internalType":"address","name":"deployerContract","type":"address"},{"internalType":"address","name":"token0","type":"address"},{"internalType":"address","name":"token1","type":"address"},{"internalType":"bytes32","name":"supplyToken0Slot","type":"bytes32"},{"internalType":"bytes32","name":"borrowToken0Slot","type":"bytes32"},{"internalType":"bytes32","name":"supplyToken1Slot","type":"bytes32"},{"internalType":"bytes32","name":"borrowToken1Slot","type":"bytes32"},{"internalType":"bytes32","name":"exchangePriceToken0Slot","type":"bytes32"},{"internalType":"bytes32","name":"exchangePriceToken1Slot","type":"bytes32"},{"internalType":"uint256","name":"oracleMapping","type":"uint256"}],"internalType":"struct IFluidDexT1.ConstantViews","name":"constantViews","type":"tuple"},{"components":[{"internalType":"uint256","name":"token0NumeratorPrecision","type":"uint256"},{"internalType":"uint256","name":"token0DenominatorPrecision","type":"uint256"},{"internalType":"uint256","name":"token1NumeratorPrecision","type":"uint256"},{"internalType":"uint256","name":"token1DenominatorPrecision","type":"uint256"}],"internalType":"struct IFluidDexT1.ConstantViews2","name":"constantViews2","type":"tuple"},{"components":[{"internalType":"bool","name":"isSmartCollateralEnabled","type":"bool"},{"internalType":"bool","name":"isSmartDebtEnabled","type":"bool"},{"internalType":"uint256","name":"fee","type":"uint256"},{"internalType":"uint256","name":"revenueCut","type":"uint256"},{"internalType":"uint256","name":"upperRange","type":"uint256"},{"internalType":"uint256","name":"lowerRange","type":"uint256"},{"internalType":"uint256","name":"upperShiftThreshold","type":"uint256"},{"internalType":"uint256","name":"lowerShiftThreshold","type":"uint256"},{"internalType":"uint256","name":"shiftingTime","type":"uint256"},{"internalType":"address","name":"centerPriceAddress","type":"address"},{"internalType":"address","name":"hookAddress","type":"address"},{"internalType":"uint256","name":"maxCenterPrice","type":"uint256"},{"internalType":"uint256","name":"minCenterPrice","type":"uint256"},{"internalType":"uint256","name":"utilizationLimitToken0","type":"uint256"},{"internalType":"uint256","name":"utilizationLimitToken1","type":"uint256"},{"internalType":"uint256","name":"maxSupplyShares","type":"uint256"},{"internalType":"uint256","name":"maxBorrowShares","type":"uint256"}],"internalType":"struct Structs.Configs","name":"configs","type":"tuple"},{"components":[{"internalType":"uint256","name":"lastStoredPrice","type":"uint256"},{"internalType":"uint256","name":"centerPrice","type":"uint256"},{"internalType":"uint256","name":"upperRange","type":"uint256"},{"internalType":"uint256","name":"lowerRange","type":"uint256"},{"internalType":"uint256","name":"geometricMean","type":"uint256"},{"internalType":"uint256","name":"supplyToken0ExchangePrice","type":"uint256"},{"internalType":"uint256","name":"borrowToken0ExchangePrice","type":"uint256"},{"internalType":"uint256","name":"supplyToken1ExchangePrice","type":"uint256"},{"internalType":"uint256","name":"borrowToken1ExchangePrice","type":"uint256"}],"internalType":"struct IFluidDexT1.PricesAndExchangePrice","name":"pex","type":"tuple"},{"components":[{"internalType":"uint256","name":"token0RealReserves","type":"uint256"},{"internalType":"uint256","name":"token1RealReserves","type":"uint256"},{"internalType":"uint256","name":"token0ImaginaryReserves","type":"uint256"},{"internalType":"uint256","name":"token1ImaginaryReserves","type":"uint256"}],"internalType":"struct IFluidDexT1.CollateralReserves","name":"colReserves","type":"tuple"},{"components":[{"internalType":"uint256","name":"token0Debt","type":"uint256"},{"internalType":"uint256","name":"token1Debt","type":"uint256"},{"internalType":"uint256","name":"token0RealReserves","type":"uint256"},{"internalType":"uint256","name":"token1RealReserves","type":"uint256"},{"internalType":"uint256","name":"token0ImaginaryReserves","type":"uint256"},{"internalType":"uint256","name":"token1ImaginaryReserves","type":"uint256"}],"internalType":"struct IFluidDexT1.DebtReserves","name":"debtReserves","type":"tuple"},{"components":[{"internalType":"uint256","name":"lastToLastStoredPrice","type":"uint256"},{"internalType":"uint256","name":"lastStoredPrice","type":"uint256"},{"internalType":"uint256","name":"centerPrice","type":"uint256"},{"internalType":"uint256","name":"lastUpdateTimestamp","type":"uint256"},{"internalType":"uint256","name":"lastPricesTimeDiff","type":"uint256"},{"internalType":"uint256","name":"oracleCheckPoint","type":"uint256"},{"internalType":"uint256","name":"oracleMapping","type":"uint256"},{"internalType":"uint256","name":"totalSupplyShares","type":"uint256"},{"internalType":"uint256","name":"totalBorrowShares","type":"uint256"},{"internalType":"bool","name":"isSwapAndArbitragePaused","type":"bool"},{"components":[{"internalType":"bool","name":"isRangeChangeActive","type":"bool"},{"internalType":"bool","name":"isThresholdChangeActive","type":"bool"},{"internalType":"bool","name":"isCenterPriceShiftActive","type":"bool"},{"components":[{"internalType":"uint256","name":"oldUpper","type":"uint256"},{"internalType":"uint256","name":"oldLower","type":"uint256"},{"internalType":"uint256","name":"duration","type":"uint256"},{"internalType":"uint256","name":"startTimestamp","type":"uint256"},{"internalType":"uint256","name":"oldTime","type":"uint256"}],"internalType":"struct Structs.ShiftData","name":"rangeShift","type":"tuple"},{"components":[{"internalType":"uint256","name":"oldUpper","type":"uint256"},{"internalType":"uint256","name":"oldLower","type":"uint256"},{"internalType":"uint256","name":"duration","type":"uint256"},{"internalType":"uint256","name":"startTimestamp","type":"uint256"},{"internalType":"uint256","name":"oldTime","type":"uint256"}],"internalType":"struct Structs.ShiftData","name":"thresholdShift","type":"tuple"},{"components":[{"internalType":"uint256","name":"shiftPercentage","type":"uint256"},{"internalType":"uint256","name":"duration","type":"uint256"},{"internalType":"uint256","name":"startTimestamp","type":"uint256"}],"internalType":"struct Structs.CenterPriceShift","name":"centerPriceShift","type":"tuple"}],"internalType":"struct Structs.ShiftChanges","name":"shifts","type":"tuple"},{"internalType":"uint256","name":"token0PerSupplyShare","type":"uint256"},{"internalType":"uint256","name":"token1PerSupplyShare","type":"uint256"},{"internalType":"uint256","name":"token0PerBorrowShare","type":"uint256"},{"internalType":"uint256","name":"token1PerBorrowShare","type":"uint256"}],"internalType":"struct Structs.DexState","name":"dexState","type":"tuple"},{"components":[{"internalType":"uint256","name":"liquiditySupplyToken0","type":"uint256"},{"internalType":"uint256","name":"liquiditySupplyToken1","type":"uint256"},{"internalType":"uint256","name":"liquidityBorrowToken0","type":"uint256"},{"internalType":"uint256","name":"liquidityBorrowToken1","type":"uint256"},{"internalType":"uint256","name":"liquidityWithdrawableToken0","type":"uint256"},{"internalType":"uint256","name":"liquidityWithdrawableToken1","type":"uint256"},{"internalType":"uint256","name":"liquidityBorrowableToken0","type":"uint256"},{"internalType":"uint256","name":"liquidityBorrowableToken1","type":"uint256"},{"internalType":"uint256","name":"utilizationLimitToken0","type":"uint256"},{"internalType":"uint256","name":"utilizationLimitToken1","type":"uint256"},{"internalType":"uint256","name":"withdrawableUntilUtilizationLimitToken0","type":"uint256"},{"internalType":"uint256","name":"withdrawableUntilUtilizationLimitToken1","type":"uint256"},{"internalType":"uint256","name":"borrowableUntilUtilizationLimitToken0","type":"uint256"},{"internalType":"uint256","name":"borrowableUntilUtilizationLimitToken1","type":"uint256"},{"components":[{"internalType":"bool","name":"modeWithInterest","type":"bool"},{"internalType":"uint256","name":"supply","type":"uint256"},{"internalType":"uint256","name":"withdrawalLimit","type":"uint256"},{"internalType":"uint256","name":"lastUpdateTimestamp","type":"uint256"},{"internalType":"uint256","name":"expandPercent","type":"uint256"},{"internalType":"uint256","name":"expandDuration","type":"uint256"},{"internalType":"uint256","name":"baseWithdrawalLimit","type":"uint256"},{"internalType":"uint256","name":"withdrawableUntilLimit","type":"uint256"},{"internalType":"uint256","name":"withdrawable","type":"uint256"}],"internalType":"struct Structs.UserSupplyData","name":"liquidityUserSupplyDataToken0","type":"tuple"},{"components":[{"internalType":"bool","name":"modeWithInterest","type":"bool"},{"internalType":"uint256","name":"supply","type":"uint256"},{"internalType":"uint256","name":"withdrawalLimit","type":"uint256"},{"internalType":"uint256","name":"lastUpdateTimestamp","type":"uint256"},{"internalType":"uint256","name":"expandPercent","type":"uint256"},{"internalType":"uint256","name":"expandDuration","type":"uint256"},{"internalType":"uint256","name":"baseWithdrawalLimit","type":"uint256"},{"internalType":"uint256","name":"withdrawableUntilLimit","type":"uint256"},{"internalType":"uint256","name":"withdrawable","type":"uint256"}],"internalType":"struct Structs.UserSupplyData","name":"liquidityUserSupplyDataToken1","type":"tuple"},{"components":[{"internalType":"bool","name":"modeWithInterest","type":"bool"},{"internalType":"uint256","name":"borrow","type":"uint256"},{"internalType":"uint256","name":"borrowLimit","type":"uint256"},{"internalType":"uint256","name":"lastUpdateTimestamp","type":"uint256"},{"internalType":"uint256","name":"expandPercent","type":"uint256"},{"internalType":"uint256","name":"expandDuration","type":"uint256"},{"internalType":"uint256","name":"baseBorrowLimit","type":"uint256"},{"internalType":"uint256","name":"maxBorrowLimit","type":"uint256"},{"internalType":"uint256","name":"borrowableUntilLimit","type":"uint256"},{"internalType":"uint256","name":"borrowable","type":"uint256"},{"internalType":"uint256","name":"borrowLimitUtilization","type":"uint256"}],"internalType":"struct Structs.UserBorrowData","name":"liquidityUserBorrowDataToken0","type":"tuple"},{"components":[{"internalType":"bool","name":"modeWithInterest","type":"bool"},{"internalType":"uint256","name":"borrow","type":"uint256"},{"internalType":"uint256","name":"borrowLimit","type":"uint256"},{"internalType":"uint256","name":"lastUpdateTimestamp","type":"uint256"},{"internalType":"uint256","name":"expandPercent","type":"uint256"},{"internalType":"uint256","name":"expandDuration","type":"uint256"},{"internalType":"uint256","name":"baseBorrowLimit","type":"uint256"},{"internalType":"uint256","name":"maxBorrowLimit","type":"uint256"},{"internalType":"uint256","name":"borrowableUntilLimit","type":"uint256"},{"internalType":"uint256","name":"borrowable","type":"uint256"},{"internalType":"uint256","name":"borrowLimitUtilization","type":"uint256"}],"internalType":"struct Structs.UserBorrowData","name":"liquidityUserBorrowDataToken1","type":"tuple"}],"internalType":"struct Structs.SwapLimitsAndAvailability","name":"limitsAndAvailability","type":"tuple"}],"internalType":"struct Structs.DexEntireData","name":"data_","type":"tuple"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"dexes_","type":"address[]"}],"name":"getDexEntireDatas","outputs":[{"components":[{"internalType":"address","name":"dex","type":"address"},{"components":[{"internalType":"uint256","name":"dexId","type":"uint256"},{"internalType":"address","name":"liquidity","type":"address"},{"internalType":"address","name":"factory","type":"address"},{"components":[{"internalType":"address","name":"shift","type":"address"},{"internalType":"address","name":"admin","type":"address"},{"internalType":"address","name":"colOperations","type":"address"},{"internalType":"address","name":"debtOperations","type":"address"},{"internalType":"address","name":"perfectOperationsAndOracle","type":"address"}],"internalType":"struct IFluidDexT1.Implementations","name":"implementations","type":"tuple"},{"internalType":"address","name":"deployerContract","type":"address"},{"internalType":"address","name":"token0","type":"address"},{"internalType":"address","name":"token1","type":"address"},{"internalType":"bytes32","name":"supplyToken0Slot","type":"bytes32"},{"internalType":"bytes32","name":"borrowToken0Slot","type":"bytes32"},{"internalType":"bytes32","name":"supplyToken1Slot","type":"bytes32"},{"internalType":"bytes32","name":"borrowToken1Slot","type":"bytes32"},{"internalType":"bytes32","name":"exchangePriceToken0Slot","type":"bytes32"},{"internalType":"bytes32","name":"exchangePriceToken1Slot","type":"bytes32"},{"internalType":"uint256","name":"oracleMapping","type":"uint256"}],"internalType":"struct IFluidDexT1.ConstantViews","name":"constantViews","type":"tuple"},{"components":[{"internalType":"uint256","name":"token0NumeratorPrecision","type":"uint256"},{"internalType":"uint256","name":"token0DenominatorPrecision","type":"uint256"},{"internalType":"uint256","name":"token1NumeratorPrecision","type":"uint256"},{"internalType":"uint256","name":"token1DenominatorPrecision","type":"uint256"}],"internalType":"struct IFluidDexT1.ConstantViews2","name":"constantViews2","type":"tuple"},{"components":[{"internalType":"bool","name":"isSmartCollateralEnabled","type":"bool"},{"internalType":"bool","name":"isSmartDebtEnabled","type":"bool"},{"internalType":"uint256","name":"fee","type":"uint256"},{"internalType":"uint256","name":"revenueCut","type":"uint256"},{"internalType":"uint256","name":"upperRange","type":"uint256"},{"internalType":"uint256","name":"lowerRange","type":"uint256"},{"internalType":"uint256","name":"upperShiftThreshold","type":"uint256"},{"internalType":"uint256","name":"lowerShiftThreshold","type":"uint256"},{"internalType":"uint256","name":"shiftingTime","type":"uint256"},{"internalType":"address","name":"centerPriceAddress","type":"address"},{"internalType":"address","name":"hookAddress","type":"address"},{"internalType":"uint256","name":"maxCenterPrice","type":"uint256"},{"internalType":"uint256","name":"minCenterPrice","type":"uint256"},{"internalType":"uint256","name":"utilizationLimitToken0","type":"uint256"},{"internalType":"uint256","name":"utilizationLimitToken1","type":"uint256"},{"internalType":"uint256","name":"maxSupplyShares","type":"uint256"},{"internalType":"uint256","name":"maxBorrowShares","type":"uint256"}],"internalType":"struct Structs.Configs","name":"configs","type":"tuple"},{"components":[{"internalType":"uint256","name":"lastStoredPrice","type":"uint256"},{"internalType":"uint256","name":"centerPrice","type":"uint256"},{"internalType":"uint256","name":"upperRange","type":"uint256"},{"internalType":"uint256","name":"lowerRange","type":"uint256"},{"internalType":"uint256","name":"geometricMean","type":"uint256"},{"internalType":"uint256","name":"supplyToken0ExchangePrice","type":"uint256"},{"internalType":"uint256","name":"borrowToken0ExchangePrice","type":"uint256"},{"internalType":"uint256","name":"supplyToken1ExchangePrice","type":"uint256"},{"internalType":"uint256","name":"borrowToken1ExchangePrice","type":"uint256"}],"internalType":"struct IFluidDexT1.PricesAndExchangePrice","name":"pex","type":"tuple"},{"components":[{"internalType":"uint256","name":"token0RealReserves","type":"uint256"},{"internalType":"uint256","name":"token1RealReserves","type":"uint256"},{"internalType":"uint256","name":"token0ImaginaryReserves","type":"uint256"},{"internalType":"uint256","name":"token1ImaginaryReserves","type":"uint256"}],"internalType":"struct IFluidDexT1.CollateralReserves","name":"colReserves","type":"tuple"},{"components":[{"internalType":"uint256","name":"token0Debt","type":"uint256"},{"internalType":"uint256","name":"token1Debt","type":"uint256"},{"internalType":"uint256","name":"token0RealReserves","type":"uint256"},{"internalType":"uint256","name":"token1RealReserves","type":"uint256"},{"internalType":"uint256","name":"token0ImaginaryReserves","type":"uint256"},{"internalType":"uint256","name":"token1ImaginaryReserves","type":"uint256"}],"internalType":"struct IFluidDexT1.DebtReserves","name":"debtReserves","type":"tuple"},{"components":[{"internalType":"uint256","name":"lastToLastStoredPrice","type":"uint256"},{"internalType":"uint256","name":"lastStoredPrice","type":"uint256"},{"internalType":"uint256","name":"centerPrice","type":"uint256"},{"internalType":"uint256","name":"lastUpdateTimestamp","type":"uint256"},{"internalType":"uint256","name":"lastPricesTimeDiff","type":"uint256"},{"internalType":"uint256","name":"oracleCheckPoint","type":"uint256"},{"internalType":"uint256","name":"oracleMapping","type":"uint256"},{"internalType":"uint256","name":"totalSupplyShares","type":"uint256"},{"internalType":"uint256","name":"totalBorrowShares","type":"uint256"},{"internalType":"bool","name":"isSwapAndArbitragePaused","type":"bool"},{"components":[{"internalType":"bool","name":"isRangeChangeActive","type":"bool"},{"internalType":"bool","name":"isThresholdChangeActive","type":"bool"},{"internalType":"bool","name":"isCenterPriceShiftActive","type":"bool"},{"components":[{"internalType":"uint256","name":"oldUpper","type":"uint256"},{"internalType":"uint256","name":"oldLower","type":"uint256"},{"internalType":"uint256","name":"duration","type":"uint256"},{"internalType":"uint256","name":"startTimestamp","type":"uint256"},{"internalType":"uint256","name":"oldTime","type":"uint256"}],"internalType":"struct Structs.ShiftData","name":"rangeShift","type":"tuple"},{"components":[{"internalType":"uint256","name":"oldUpper","type":"uint256"},{"internalType":"uint256","name":"oldLower","type":"uint256"},{"internalType":"uint256","name":"duration","type":"uint256"},{"internalType":"uint256","name":"startTimestamp","type":"uint256"},{"internalType":"uint256","name":"oldTime","type":"uint256"}],"internalType":"struct Structs.ShiftData","name":"thresholdShift","type":"tuple"},{"components":[{"internalType":"uint256","name":"shiftPercentage","type":"uint256"},{"internalType":"uint256","name":"duration","type":"uint256"},{"internalType":"uint256","name":"startTimestamp","type":"uint256"}],"internalType":"struct Structs.CenterPriceShift","name":"centerPriceShift","type":"tuple"}],"internalType":"struct Structs.ShiftChanges","name":"shifts","type":"tuple"},{"internalType":"uint256","name":"token0PerSupplyShare","type":"uint256"},{"internalType":"uint256","name":"token1PerSupplyShare","type":"uint256"},{"internalType":"uint256","name":"token0PerBorrowShare","type":"uint256"},{"internalType":"uint256","name":"token1PerBorrowShare","type":"uint256"}],"internalType":"struct Structs.DexState","name":"dexState","type":"tuple"},{"components":[{"internalType":"uint256","name":"liquiditySupplyToken0","type":"uint256"},{"internalType":"uint256","name":"liquiditySupplyToken1","type":"uint256"},{"internalType":"uint256","name":"liquidityBorrowToken0","type":"uint256"},{"internalType":"uint256","name":"liquidityBorrowToken1","type":"uint256"},{"internalType":"uint256","name":"liquidityWithdrawableToken0","type":"uint256"},{"internalType":"uint256","name":"liquidityWithdrawableToken1","type":"uint256"},{"internalType":"uint256","name":"liquidityBorrowableToken0","type":"uint256"},{"internalType":"uint256","name":"liquidityBorrowableToken1","type":"uint256"},{"internalType":"uint256","name":"utilizationLimitToken0","type":"uint256"},{"internalType":"uint256","name":"utilizationLimitToken1","type":"uint256"},{"internalType":"uint256","name":"withdrawableUntilUtilizationLimitToken0","type":"uint256"},{"internalType":"uint256","name":"withdrawableUntilUtilizationLimitToken1","type":"uint256"},{"internalType":"uint256","name":"borrowableUntilUtilizationLimitToken0","type":"uint256"},{"internalType":"uint256","name":"borrowableUntilUtilizationLimitToken1","type":"uint256"},{"components":[{"internalType":"bool","name":"modeWithInterest","type":"bool"},{"internalType":"uint256","name":"supply","type":"uint256"},{"internalType":"uint256","name":"withdrawalLimit","type":"uint256"},{"internalType":"uint256","name":"lastUpdateTimestamp","type":"uint256"},{"internalType":"uint256","name":"expandPercent","type":"uint256"},{"internalType":"uint256","name":"expandDuration","type":"uint256"},{"internalType":"uint256","name":"baseWithdrawalLimit","type":"uint256"},{"internalType":"uint256","name":"withdrawableUntilLimit","type":"uint256"},{"internalType":"uint256","name":"withdrawable","type":"uint256"}],"internalType":"struct Structs.UserSupplyData","name":"liquidityUserSupplyDataToken0","type":"tuple"},{"components":[{"internalType":"bool","name":"modeWithInterest","type":"bool"},{"internalType":"uint256","name":"supply","type":"uint256"},{"internalType":"uint256","name":"withdrawalLimit","type":"uint256"},{"internalType":"uint256","name":"lastUpdateTimestamp","type":"uint256"},{"internalType":"uint256","name":"expandPercent","type":"uint256"},{"internalType":"uint256","name":"expandDuration","type":"uint256"},{"internalType":"uint256","name":"baseWithdrawalLimit","type":"uint256"},{"internalType":"uint256","name":"withdrawableUntilLimit","type":"uint256"},{"internalType":"uint256","name":"withdrawable","type":"uint256"}],"internalType":"struct Structs.UserSupplyData","name":"liquidityUserSupplyDataToken1","type":"tuple"},{"components":[{"internalType":"bool","name":"modeWithInterest","type":"bool"},{"internalType":"uint256","name":"borrow","type":"uint256"},{"internalType":"uint256","name":"borrowLimit","type":"uint256"},{"internalType":"uint256","name":"lastUpdateTimestamp","type":"uint256"},{"internalType":"uint256","name":"expandPercent","type":"uint256"},{"internalType":"uint256","name":"expandDuration","type":"uint256"},{"internalType":"uint256","name":"baseBorrowLimit","type":"uint256"},{"internalType":"uint256","name":"maxBorrowLimit","type":"uint256"},{"internalType":"uint256","name":"borrowableUntilLimit","type":"uint256"},{"internalType":"uint256","name":"borrowable","type":"uint256"},{"internalType":"uint256","name":"borrowLimitUtilization","type":"uint256"}],"internalType":"struct Structs.UserBorrowData","name":"liquidityUserBorrowDataToken0","type":"tuple"},{"components":[{"internalType":"bool","name":"modeWithInterest","type":"bool"},{"internalType":"uint256","name":"borrow","type":"uint256"},{"internalType":"uint256","name":"borrowLimit","type":"uint256"},{"internalType":"uint256","name":"lastUpdateTimestamp","type":"uint256"},{"internalType":"uint256","name":"expandPercent","type":"uint256"},{"internalType":"uint256","name":"expandDuration","type":"uint256"},{"internalType":"uint256","name":"baseBorrowLimit","type":"uint256"},{"internalType":"uint256","name":"maxBorrowLimit","type":"uint256"},{"internalType":"uint256","name":"borrowableUntilLimit","type":"uint256"},{"internalType":"uint256","name":"borrowable","type":"uint256"},{"internalType":"uint256","name":"borrowLimitUtilization","type":"uint256"}],"internalType":"struct Structs.UserBorrowData","name":"liquidityUserBorrowDataToken1","type":"tuple"}],"internalType":"struct Structs.SwapLimitsAndAvailability","name":"limitsAndAvailability","type":"tuple"}],"internalType":"struct Structs.DexEntireData[]","name":"datas_","type":"tuple[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"dex_","type":"address"}],"name":"getDexId","outputs":[{"internalType":"uint256","name":"id_","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"dex_","type":"address"},{"internalType":"uint256[]","name":"secondsAgos_","type":"uint256[]"}],"name":"getDexOraclePrice","outputs":[{"components":[{"internalType":"uint256","name":"twap1by0","type":"uint256"},{"internalType":"uint256","name":"lowestPrice1by0","type":"uint256"},{"internalType":"uint256","name":"highestPrice1by0","type":"uint256"},{"internalType":"uint256","name":"twap0by1","type":"uint256"},{"internalType":"uint256","name":"lowestPrice0by1","type":"uint256"},{"internalType":"uint256","name":"highestPrice0by1","type":"uint256"}],"internalType":"struct IFluidDexT1.Oracle[]","name":"twaps_","type":"tuple[]"},{"internalType":"uint256","name":"currentPrice_","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"dex_","type":"address"}],"name":"getDexPricesAndExchangePrices","outputs":[{"components":[{"internalType":"uint256","name":"lastStoredPrice","type":"uint256"},{"internalType":"uint256","name":"centerPrice","type":"uint256"},{"internalType":"uint256","name":"upperRange","type":"uint256"},{"internalType":"uint256","name":"lowerRange","type":"uint256"},{"internalType":"uint256","name":"geometricMean","type":"uint256"},{"internalType":"uint256","name":"supplyToken0ExchangePrice","type":"uint256"},{"internalType":"uint256","name":"borrowToken0ExchangePrice","type":"uint256"},{"internalType":"uint256","name":"supplyToken1ExchangePrice","type":"uint256"},{"internalType":"uint256","name":"borrowToken1ExchangePrice","type":"uint256"}],"internalType":"struct IFluidDexT1.PricesAndExchangePrice","name":"pex_","type":"tuple"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"dex_","type":"address"}],"name":"getDexState","outputs":[{"components":[{"internalType":"uint256","name":"lastToLastStoredPrice","type":"uint256"},{"internalType":"uint256","name":"lastStoredPrice","type":"uint256"},{"internalType":"uint256","name":"centerPrice","type":"uint256"},{"internalType":"uint256","name":"lastUpdateTimestamp","type":"uint256"},{"internalType":"uint256","name":"lastPricesTimeDiff","type":"uint256"},{"internalType":"uint256","name":"oracleCheckPoint","type":"uint256"},{"internalType":"uint256","name":"oracleMapping","type":"uint256"},{"internalType":"uint256","name":"totalSupplyShares","type":"uint256"},{"internalType":"uint256","name":"totalBorrowShares","type":"uint256"},{"internalType":"bool","name":"isSwapAndArbitragePaused","type":"bool"},{"components":[{"internalType":"bool","name":"isRangeChangeActive","type":"bool"},{"internalType":"bool","name":"isThresholdChangeActive","type":"bool"},{"internalType":"bool","name":"isCenterPriceShiftActive","type":"bool"},{"components":[{"internalType":"uint256","name":"oldUpper","type":"uint256"},{"internalType":"uint256","name":"oldLower","type":"uint256"},{"internalType":"uint256","name":"duration","type":"uint256"},{"internalType":"uint256","name":"startTimestamp","type":"uint256"},{"internalType":"uint256","name":"oldTime","type":"uint256"}],"internalType":"struct Structs.ShiftData","name":"rangeShift","type":"tuple"},{"components":[{"internalType":"uint256","name":"oldUpper","type":"uint256"},{"internalType":"uint256","name":"oldLower","type":"uint256"},{"internalType":"uint256","name":"duration","type":"uint256"},{"internalType":"uint256","name":"startTimestamp","type":"uint256"},{"internalType":"uint256","name":"oldTime","type":"uint256"}],"internalType":"struct Structs.ShiftData","name":"thresholdShift","type":"tuple"},{"components":[{"internalType":"uint256","name":"shiftPercentage","type":"uint256"},{"internalType":"uint256","name":"duration","type":"uint256"},{"internalType":"uint256","name":"startTimestamp","type":"uint256"}],"internalType":"struct Structs.CenterPriceShift","name":"centerPriceShift","type":"tuple"}],"internalType":"struct Structs.ShiftChanges","name":"shifts","type":"tuple"},{"internalType":"uint256","name":"token0PerSupplyShare","type":"uint256"},{"internalType":"uint256","name":"token1PerSupplyShare","type":"uint256"},{"internalType":"uint256","name":"token0PerBorrowShare","type":"uint256"},{"internalType":"uint256","name":"token1PerBorrowShare","type":"uint256"}],"internalType":"struct Structs.DexState","name":"state_","type":"tuple"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"dex_","type":"address"}],"name":"getDexSwapLimitsAndAvailability","outputs":[{"components":[{"internalType":"uint256","name":"liquiditySupplyToken0","type":"uint256"},{"internalType":"uint256","name":"liquiditySupplyToken1","type":"uint256"},{"internalType":"uint256","name":"liquidityBorrowToken0","type":"uint256"},{"internalType":"uint256","name":"liquidityBorrowToken1","type":"uint256"},{"internalType":"uint256","name":"liquidityWithdrawableToken0","type":"uint256"},{"internalType":"uint256","name":"liquidityWithdrawableToken1","type":"uint256"},{"internalType":"uint256","name":"liquidityBorrowableToken0","type":"uint256"},{"internalType":"uint256","name":"liquidityBorrowableToken1","type":"uint256"},{"internalType":"uint256","name":"utilizationLimitToken0","type":"uint256"},{"internalType":"uint256","name":"utilizationLimitToken1","type":"uint256"},{"internalType":"uint256","name":"withdrawableUntilUtilizationLimitToken0","type":"uint256"},{"internalType":"uint256","name":"withdrawableUntilUtilizationLimitToken1","type":"uint256"},{"internalType":"uint256","name":"borrowableUntilUtilizationLimitToken0","type":"uint256"},{"internalType":"uint256","name":"borrowableUntilUtilizationLimitToken1","type":"uint256"},{"components":[{"internalType":"bool","name":"modeWithInterest","type":"bool"},{"internalType":"uint256","name":"supply","type":"uint256"},{"internalType":"uint256","name":"withdrawalLimit","type":"uint256"},{"internalType":"uint256","name":"lastUpdateTimestamp","type":"uint256"},{"internalType":"uint256","name":"expandPercent","type":"uint256"},{"internalType":"uint256","name":"expandDuration","type":"uint256"},{"internalType":"uint256","name":"baseWithdrawalLimit","type":"uint256"},{"internalType":"uint256","name":"withdrawableUntilLimit","type":"uint256"},{"internalType":"uint256","name":"withdrawable","type":"uint256"}],"internalType":"struct Structs.UserSupplyData","name":"liquidityUserSupplyDataToken0","type":"tuple"},{"components":[{"internalType":"bool","name":"modeWithInterest","type":"bool"},{"internalType":"uint256","name":"supply","type":"uint256"},{"internalType":"uint256","name":"withdrawalLimit","type":"uint256"},{"internalType":"uint256","name":"lastUpdateTimestamp","type":"uint256"},{"internalType":"uint256","name":"expandPercent","type":"uint256"},{"internalType":"uint256","name":"expandDuration","type":"uint256"},{"internalType":"uint256","name":"baseWithdrawalLimit","type":"uint256"},{"internalType":"uint256","name":"withdrawableUntilLimit","type":"uint256"},{"internalType":"uint256","name":"withdrawable","type":"uint256"}],"internalType":"struct Structs.UserSupplyData","name":"liquidityUserSupplyDataToken1","type":"tuple"},{"components":[{"internalType":"bool","name":"modeWithInterest","type":"bool"},{"internalType":"uint256","name":"borrow","type":"uint256"},{"internalType":"uint256","name":"borrowLimit","type":"uint256"},{"internalType":"uint256","name":"lastUpdateTimestamp","type":"uint256"},{"internalType":"uint256","name":"expandPercent","type":"uint256"},{"internalType":"uint256","name":"expandDuration","type":"uint256"},{"internalType":"uint256","name":"baseBorrowLimit","type":"uint256"},{"internalType":"uint256","name":"maxBorrowLimit","type":"uint256"},{"internalType":"uint256","name":"borrowableUntilLimit","type":"uint256"},{"internalType":"uint256","name":"borrowable","type":"uint256"},{"internalType":"uint256","name":"borrowLimitUtilization","type":"uint256"}],"internalType":"struct Structs.UserBorrowData","name":"liquidityUserBorrowDataToken0","type":"tuple"},{"components":[{"internalType":"bool","name":"modeWithInterest","type":"bool"},{"internalType":"uint256","name":"borrow","type":"uint256"},{"internalType":"uint256","name":"borrowLimit","type":"uint256"},{"internalType":"uint256","name":"lastUpdateTimestamp","type":"uint256"},{"internalType":"uint256","name":"expandPercent","type":"uint256"},{"internalType":"uint256","name":"expandDuration","type":"uint256"},{"internalType":"uint256","name":"baseBorrowLimit","type":"uint256"},{"internalType":"uint256","name":"maxBorrowLimit","type":"uint256"},{"internalType":"uint256","name":"borrowableUntilLimit","type":"uint256"},{"internalType":"uint256","name":"borrowable","type":"uint256"},{"internalType":"uint256","name":"borrowLimitUtilization","type":"uint256"}],"internalType":"struct Structs.UserBorrowData","name":"liquidityUserBorrowDataToken1","type":"tuple"}],"internalType":"struct Structs.SwapLimitsAndAvailability","name":"limitsAndAvailability_","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"dex_","type":"address"}],"name":"getDexTokens","outputs":[{"internalType":"address","name":"token0_","type":"address"},{"internalType":"address","name":"token1_","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"dex_","type":"address"}],"name":"getDexVariables2Raw","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"dex_","type":"address"}],"name":"getDexVariablesRaw","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"dex_","type":"address"},{"internalType":"uint256","name":"index_","type":"uint256"}],"name":"getOracleRaw","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"dex_","type":"address"}],"name":"getRangeShiftRaw","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"dex_","type":"address"}],"name":"getThresholdShiftRaw","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"dex_","type":"address"}],"name":"getTotalBorrowSharesRaw","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTotalDexes","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"dex_","type":"address"}],"name":"getTotalSupplySharesRaw","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"dex_","type":"address"},{"internalType":"address","name":"user_","type":"address"}],"name":"getUserBorrowData","outputs":[{"components":[{"internalType":"bool","name":"isAllowed","type":"bool"},{"internalType":"uint256","name":"borrow","type":"uint256"},{"internalType":"uint256","name":"borrowLimit","type":"uint256"},{"internalType":"uint256","name":"lastUpdateTimestamp","type":"uint256"},{"internalType":"uint256","name":"expandPercent","type":"uint256"},{"internalType":"uint256","name":"expandDuration","type":"uint256"},{"internalType":"uint256","name":"baseBorrowLimit","type":"uint256"},{"internalType":"uint256","name":"maxBorrowLimit","type":"uint256"},{"internalType":"uint256","name":"borrowableUntilLimit","type":"uint256"},{"internalType":"uint256","name":"borrowable","type":"uint256"},{"components":[{"internalType":"bool","name":"modeWithInterest","type":"bool"},{"internalType":"uint256","name":"borrow","type":"uint256"},{"internalType":"uint256","name":"borrowLimit","type":"uint256"},{"internalType":"uint256","name":"lastUpdateTimestamp","type":"uint256"},{"internalType":"uint256","name":"expandPercent","type":"uint256"},{"internalType":"uint256","name":"expandDuration","type":"uint256"},{"internalType":"uint256","name":"baseBorrowLimit","type":"uint256"},{"internalType":"uint256","name":"maxBorrowLimit","type":"uint256"},{"internalType":"uint256","name":"borrowableUntilLimit","type":"uint256"},{"internalType":"uint256","name":"borrowable","type":"uint256"},{"internalType":"uint256","name":"borrowLimitUtilization","type":"uint256"}],"internalType":"struct Structs.UserBorrowData","name":"liquidityUserBorrowDataToken0","type":"tuple"},{"components":[{"internalType":"bool","name":"modeWithInterest","type":"bool"},{"internalType":"uint256","name":"borrow","type":"uint256"},{"internalType":"uint256","name":"borrowLimit","type":"uint256"},{"internalType":"uint256","name":"lastUpdateTimestamp","type":"uint256"},{"internalType":"uint256","name":"expandPercent","type":"uint256"},{"internalType":"uint256","name":"expandDuration","type":"uint256"},{"internalType":"uint256","name":"baseBorrowLimit","type":"uint256"},{"internalType":"uint256","name":"maxBorrowLimit","type":"uint256"},{"internalType":"uint256","name":"borrowableUntilLimit","type":"uint256"},{"internalType":"uint256","name":"borrowable","type":"uint256"},{"internalType":"uint256","name":"borrowLimitUtilization","type":"uint256"}],"internalType":"struct Structs.UserBorrowData","name":"liquidityUserBorrowDataToken1","type":"tuple"}],"internalType":"struct Structs.UserBorrowData","name":"userBorrowData_","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"dex_","type":"address"},{"internalType":"address","name":"user_","type":"address"}],"name":"getUserBorrowDataRaw","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"dex_","type":"address"},{"internalType":"address[]","name":"users_","type":"address[]"}],"name":"getUserBorrowDatas","outputs":[{"components":[{"internalType":"bool","name":"isAllowed","type":"bool"},{"internalType":"uint256","name":"borrow","type":"uint256"},{"internalType":"uint256","name":"borrowLimit","type":"uint256"},{"internalType":"uint256","name":"lastUpdateTimestamp","type":"uint256"},{"internalType":"uint256","name":"expandPercent","type":"uint256"},{"internalType":"uint256","name":"expandDuration","type":"uint256"},{"internalType":"uint256","name":"baseBorrowLimit","type":"uint256"},{"internalType":"uint256","name":"maxBorrowLimit","type":"uint256"},{"internalType":"uint256","name":"borrowableUntilLimit","type":"uint256"},{"internalType":"uint256","name":"borrowable","type":"uint256"},{"components":[{"internalType":"bool","name":"modeWithInterest","type":"bool"},{"internalType":"uint256","name":"borrow","type":"uint256"},{"internalType":"uint256","name":"borrowLimit","type":"uint256"},{"internalType":"uint256","name":"lastUpdateTimestamp","type":"uint256"},{"internalType":"uint256","name":"expandPercent","type":"uint256"},{"internalType":"uint256","name":"expandDuration","type":"uint256"},{"internalType":"uint256","name":"baseBorrowLimit","type":"uint256"},{"internalType":"uint256","name":"maxBorrowLimit","type":"uint256"},{"internalType":"uint256","name":"borrowableUntilLimit","type":"uint256"},{"internalType":"uint256","name":"borrowable","type":"uint256"},{"internalType":"uint256","name":"borrowLimitUtilization","type":"uint256"}],"internalType":"struct Structs.UserBorrowData","name":"liquidityUserBorrowDataToken0","type":"tuple"},{"components":[{"internalType":"bool","name":"modeWithInterest","type":"bool"},{"internalType":"uint256","name":"borrow","type":"uint256"},{"internalType":"uint256","name":"borrowLimit","type":"uint256"},{"internalType":"uint256","name":"lastUpdateTimestamp","type":"uint256"},{"internalType":"uint256","name":"expandPercent","type":"uint256"},{"internalType":"uint256","name":"expandDuration","type":"uint256"},{"internalType":"uint256","name":"baseBorrowLimit","type":"uint256"},{"internalType":"uint256","name":"maxBorrowLimit","type":"uint256"},{"internalType":"uint256","name":"borrowableUntilLimit","type":"uint256"},{"internalType":"uint256","name":"borrowable","type":"uint256"},{"internalType":"uint256","name":"borrowLimitUtilization","type":"uint256"}],"internalType":"struct Structs.UserBorrowData","name":"liquidityUserBorrowDataToken1","type":"tuple"}],"internalType":"struct Structs.UserBorrowData[]","name":"userBorrowingsData_","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"dex_","type":"address"},{"internalType":"address[]","name":"users_","type":"address[]"}],"name":"getUserBorrowSupplyDatas","outputs":[{"components":[{"internalType":"bool","name":"isAllowed","type":"bool"},{"internalType":"uint256","name":"supply","type":"uint256"},{"internalType":"uint256","name":"withdrawalLimit","type":"uint256"},{"internalType":"uint256","name":"lastUpdateTimestamp","type":"uint256"},{"internalType":"uint256","name":"expandPercent","type":"uint256"},{"internalType":"uint256","name":"expandDuration","type":"uint256"},{"internalType":"uint256","name":"baseWithdrawalLimit","type":"uint256"},{"internalType":"uint256","name":"withdrawableUntilLimit","type":"uint256"},{"internalType":"uint256","name":"withdrawable","type":"uint256"},{"components":[{"internalType":"bool","name":"modeWithInterest","type":"bool"},{"internalType":"uint256","name":"supply","type":"uint256"},{"internalType":"uint256","name":"withdrawalLimit","type":"uint256"},{"internalType":"uint256","name":"lastUpdateTimestamp","type":"uint256"},{"internalType":"uint256","name":"expandPercent","type":"uint256"},{"internalType":"uint256","name":"expandDuration","type":"uint256"},{"internalType":"uint256","name":"baseWithdrawalLimit","type":"uint256"},{"internalType":"uint256","name":"withdrawableUntilLimit","type":"uint256"},{"internalType":"uint256","name":"withdrawable","type":"uint256"}],"internalType":"struct Structs.UserSupplyData","name":"liquidityUserSupplyDataToken0","type":"tuple"},{"components":[{"internalType":"bool","name":"modeWithInterest","type":"bool"},{"internalType":"uint256","name":"supply","type":"uint256"},{"internalType":"uint256","name":"withdrawalLimit","type":"uint256"},{"internalType":"uint256","name":"lastUpdateTimestamp","type":"uint256"},{"internalType":"uint256","name":"expandPercent","type":"uint256"},{"internalType":"uint256","name":"expandDuration","type":"uint256"},{"internalType":"uint256","name":"baseWithdrawalLimit","type":"uint256"},{"internalType":"uint256","name":"withdrawableUntilLimit","type":"uint256"},{"internalType":"uint256","name":"withdrawable","type":"uint256"}],"internalType":"struct Structs.UserSupplyData","name":"liquidityUserSupplyDataToken1","type":"tuple"}],"internalType":"struct Structs.UserSupplyData[]","name":"userSuppliesData_","type":"tuple[]"},{"components":[{"internalType":"bool","name":"isAllowed","type":"bool"},{"internalType":"uint256","name":"borrow","type":"uint256"},{"internalType":"uint256","name":"borrowLimit","type":"uint256"},{"internalType":"uint256","name":"lastUpdateTimestamp","type":"uint256"},{"internalType":"uint256","name":"expandPercent","type":"uint256"},{"internalType":"uint256","name":"expandDuration","type":"uint256"},{"internalType":"uint256","name":"baseBorrowLimit","type":"uint256"},{"internalType":"uint256","name":"maxBorrowLimit","type":"uint256"},{"internalType":"uint256","name":"borrowableUntilLimit","type":"uint256"},{"internalType":"uint256","name":"borrowable","type":"uint256"},{"components":[{"internalType":"bool","name":"modeWithInterest","type":"bool"},{"internalType":"uint256","name":"borrow","type":"uint256"},{"internalType":"uint256","name":"borrowLimit","type":"uint256"},{"internalType":"uint256","name":"lastUpdateTimestamp","type":"uint256"},{"internalType":"uint256","name":"expandPercent","type":"uint256"},{"internalType":"uint256","name":"expandDuration","type":"uint256"},{"internalType":"uint256","name":"baseBorrowLimit","type":"uint256"},{"internalType":"uint256","name":"maxBorrowLimit","type":"uint256"},{"internalType":"uint256","name":"borrowableUntilLimit","type":"uint256"},{"internalType":"uint256","name":"borrowable","type":"uint256"},{"internalType":"uint256","name":"borrowLimitUtilization","type":"uint256"}],"internalType":"struct Structs.UserBorrowData","name":"liquidityUserBorrowDataToken0","type":"tuple"},{"components":[{"internalType":"bool","name":"modeWithInterest","type":"bool"},{"internalType":"uint256","name":"borrow","type":"uint256"},{"internalType":"uint256","name":"borrowLimit","type":"uint256"},{"internalType":"uint256","name":"lastUpdateTimestamp","type":"uint256"},{"internalType":"uint256","name":"expandPercent","type":"uint256"},{"internalType":"uint256","name":"expandDuration","type":"uint256"},{"internalType":"uint256","name":"baseBorrowLimit","type":"uint256"},{"internalType":"uint256","name":"maxBorrowLimit","type":"uint256"},{"internalType":"uint256","name":"borrowableUntilLimit","type":"uint256"},{"internalType":"uint256","name":"borrowable","type":"uint256"},{"internalType":"uint256","name":"borrowLimitUtilization","type":"uint256"}],"internalType":"struct Structs.UserBorrowData","name":"liquidityUserBorrowDataToken1","type":"tuple"}],"internalType":"struct Structs.UserBorrowData[]","name":"userBorrowingsData_","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"dex_","type":"address"},{"internalType":"address","name":"user_","type":"address"}],"name":"getUserSupplyData","outputs":[{"components":[{"internalType":"bool","name":"isAllowed","type":"bool"},{"internalType":"uint256","name":"supply","type":"uint256"},{"internalType":"uint256","name":"withdrawalLimit","type":"uint256"},{"internalType":"uint256","name":"lastUpdateTimestamp","type":"uint256"},{"internalType":"uint256","name":"expandPercent","type":"uint256"},{"internalType":"uint256","name":"expandDuration","type":"uint256"},{"internalType":"uint256","name":"baseWithdrawalLimit","type":"uint256"},{"internalType":"uint256","name":"withdrawableUntilLimit","type":"uint256"},{"internalType":"uint256","name":"withdrawable","type":"uint256"},{"components":[{"internalType":"bool","name":"modeWithInterest","type":"bool"},{"internalType":"uint256","name":"supply","type":"uint256"},{"internalType":"uint256","name":"withdrawalLimit","type":"uint256"},{"internalType":"uint256","name":"lastUpdateTimestamp","type":"uint256"},{"internalType":"uint256","name":"expandPercent","type":"uint256"},{"internalType":"uint256","name":"expandDuration","type":"uint256"},{"internalType":"uint256","name":"baseWithdrawalLimit","type":"uint256"},{"internalType":"uint256","name":"withdrawableUntilLimit","type":"uint256"},{"internalType":"uint256","name":"withdrawable","type":"uint256"}],"internalType":"struct Structs.UserSupplyData","name":"liquidityUserSupplyDataToken0","type":"tuple"},{"components":[{"internalType":"bool","name":"modeWithInterest","type":"bool"},{"internalType":"uint256","name":"supply","type":"uint256"},{"internalType":"uint256","name":"withdrawalLimit","type":"uint256"},{"internalType":"uint256","name":"lastUpdateTimestamp","type":"uint256"},{"internalType":"uint256","name":"expandPercent","type":"uint256"},{"internalType":"uint256","name":"expandDuration","type":"uint256"},{"internalType":"uint256","name":"baseWithdrawalLimit","type":"uint256"},{"internalType":"uint256","name":"withdrawableUntilLimit","type":"uint256"},{"internalType":"uint256","name":"withdrawable","type":"uint256"}],"internalType":"struct Structs.UserSupplyData","name":"liquidityUserSupplyDataToken1","type":"tuple"}],"internalType":"struct Structs.UserSupplyData","name":"userSupplyData_","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"dex_","type":"address"},{"internalType":"address","name":"user_","type":"address"}],"name":"getUserSupplyDataRaw","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"dex_","type":"address"},{"internalType":"address[]","name":"users_","type":"address[]"}],"name":"getUserSupplyDatas","outputs":[{"components":[{"internalType":"bool","name":"isAllowed","type":"bool"},{"internalType":"uint256","name":"supply","type":"uint256"},{"internalType":"uint256","name":"withdrawalLimit","type":"uint256"},{"internalType":"uint256","name":"lastUpdateTimestamp","type":"uint256"},{"internalType":"uint256","name":"expandPercent","type":"uint256"},{"internalType":"uint256","name":"expandDuration","type":"uint256"},{"internalType":"uint256","name":"baseWithdrawalLimit","type":"uint256"},{"internalType":"uint256","name":"withdrawableUntilLimit","type":"uint256"},{"internalType":"uint256","name":"withdrawable","type":"uint256"},{"components":[{"internalType":"bool","name":"modeWithInterest","type":"bool"},{"internalType":"uint256","name":"supply","type":"uint256"},{"internalType":"uint256","name":"withdrawalLimit","type":"uint256"},{"internalType":"uint256","name":"lastUpdateTimestamp","type":"uint256"},{"internalType":"uint256","name":"expandPercent","type":"uint256"},{"internalType":"uint256","name":"expandDuration","type":"uint256"},{"internalType":"uint256","name":"baseWithdrawalLimit","type":"uint256"},{"internalType":"uint256","name":"withdrawableUntilLimit","type":"uint256"},{"internalType":"uint256","name":"withdrawable","type":"uint256"}],"internalType":"struct Structs.UserSupplyData","name":"liquidityUserSupplyDataToken0","type":"tuple"},{"components":[{"internalType":"bool","name":"modeWithInterest","type":"bool"},{"internalType":"uint256","name":"supply","type":"uint256"},{"internalType":"uint256","name":"withdrawalLimit","type":"uint256"},{"internalType":"uint256","name":"lastUpdateTimestamp","type":"uint256"},{"internalType":"uint256","name":"expandPercent","type":"uint256"},{"internalType":"uint256","name":"expandDuration","type":"uint256"},{"internalType":"uint256","name":"baseWithdrawalLimit","type":"uint256"},{"internalType":"uint256","name":"withdrawableUntilLimit","type":"uint256"},{"internalType":"uint256","name":"withdrawable","type":"uint256"}],"internalType":"struct Structs.UserSupplyData","name":"liquidityUserSupplyDataToken1","type":"tuple"}],"internalType":"struct Structs.UserSupplyData[]","name":"userSuppliesData_","type":"tuple[]"}],"stateMutability":"view","type":"function"}]

6101006040523480156200001257600080fd5b506040516200613038038062006130833981016040819052620000359162000075565b6001600160a01b0393841660805291831660a052821660c0521660e052620000d2565b80516001600160a01b03811681146200007057600080fd5b919050565b600080600080608085870312156200008c57600080fd5b620000978562000058565b9350620000a76020860162000058565b9250620000b76040860162000058565b9150620000c76060860162000058565b905092959194509250565b60805160a05160c05160e051615fd062000160600039600081816108be015281816121a201526121ee01526000818161068d01528181611b0801528181611bbd0152818161239e01528181612453015281816130b0015281816131680152818161322201526132d7015260006104c20152600081816104f601528181610dcc01526124d30152615fd06000f3fe6080604052600436106103135760003560e01c80637b05c2001161019a578063cdaf7f22116100e1578063e72ef91b1161008a578063eeb9baeb11610064578063eeb9baeb146109cf578063eee99670146109ef578063f44dfe5014610a0f57600080fd5b8063e72ef91b1461096d578063ebf11ce41461099a578063ee221c08146109af57600080fd5b8063d91a0633116100bb578063d91a0633146108f3578063e1a25ab914610913578063e5c458431461094057600080fd5b8063cdaf7f221461088c578063d1d32444146108ac578063d82ae0fa146108e057600080fd5b8063957755e6116101435780639bb65fc71161011d5780639bb65fc7146108465780639c1b042314610866578063bb39e3a11461087957600080fd5b8063957755e6146107d9578063967915d6146107f957806396cc6dbf1461082657600080fd5b80638ad1fe82116101745780638ad1fe82146107695780638bfe3db21461079757806395430c41146107ac57600080fd5b80637b05c200146106ef5780637f51d07f1461070f57806384502d951461073c57600080fd5b80633a490e6f1161025e5780634f8666a0116102075780636902f79f116101e15780636902f79f1461067b5780636dd5fd85146106af578063741c0b5c146106cf57600080fd5b80634f8666a01461060e578063546b08cd1461062e57806355181f111461064e57600080fd5b8063425711371161023857806342571137146105bb578063472f2d09146105ce5780634dd3a4e0146105ee57600080fd5b80633a490e6f146105455780633cb84b11146105655780633f7256611461059357600080fd5b80631cba0023116102c05780632861c7d11161029a5780632861c7d1146104b05780632dd31000146104e4578063345df8df1461051857600080fd5b80631cba0023146104345780632516d94014610461578063266398ef1461048e57600080fd5b80631272e9ac116102f15780631272e9ac146103bb57806312e366aa146103dc57806318e172d91461041457600080fd5b8063015f6cfa146103185780630208dbb01461034e578063030a68101461037b575b600080fd5b34801561032457600080fd5b50610338610333366004614398565b610a22565b60405161034591906143b5565b60405180910390f35b34801561035a57600080fd5b5061036e610369366004614398565b610b75565b6040516103459190614b5c565b34801561038757600080fd5b5061039b610396366004614398565b610c40565b604080516001600160a01b03938416815292909116602083015201610345565b6103ce6103c9366004614b6b565b610cbe565b604051908152602001610345565b3480156103e857600080fd5b506103fc6103f7366004614ba6565b610dc5565b6040516001600160a01b039091168152602001610345565b34801561042057600080fd5b506103ce61042f366004614398565b610df7565b34801561044057600080fd5b5061045461044f366004614398565b610e64565b6040516103459190614bbf565b34801561046d57600080fd5b5061048161047c366004614398565b610e87565b6040516103459190614bce565b34801561049a57600080fd5b506104a3610ed5565b6040516103459190614bdd565b3480156104bc57600080fd5b506103fc7f000000000000000000000000000000000000000000000000000000000000000081565b3480156104f057600080fd5b506103fc7f000000000000000000000000000000000000000000000000000000000000000081565b34801561052457600080fd5b50610538610533366004614d8a565b610f82565b6040516103459190614e1e565b34801561055157600080fd5b506103ce610560366004614398565b611039565b34801561057157600080fd5b50610585610580366004614e61565b611068565b6040516103459291906151d6565b6105a66105a1366004614b6b565b6111ce565b60408051928352602083019190915201610345565b6103ce6105c9366004615212565b6112dc565b3480156105da57600080fd5b506103ce6105e9366004615258565b6113d3565b3480156105fa57600080fd5b506103ce610609366004615284565b611455565b34801561061a57600080fd5b506103ce610629366004614398565b611471565b34801561063a57600080fd5b506103ce610649366004614398565b6114e8565b34801561065a57600080fd5b5061066e610669366004614398565b61156d565b60405161034591906152bd565b34801561068757600080fd5b506103fc7f000000000000000000000000000000000000000000000000000000000000000081565b3480156106bb57600080fd5b506103ce6106ca366004614398565b6115b8565b3480156106db57600080fd5b506103ce6106ea366004614b6b565b6115e8565b3480156106fb57600080fd5b506105a661070a366004614b6b565b61167b565b34801561071b57600080fd5b5061072f61072a366004614398565b61170f565b6040516103459190615300565b34801561074857600080fd5b5061075c610757366004614e61565b61179c565b604051610345919061532b565b34801561077557600080fd5b5061078961078436600461533e565b61184e565b6040516103459291906153e4565b3480156107a357600080fd5b506105386118cf565b3480156107b857600080fd5b506107cc6107c7366004614e61565b6118e1565b604051610345919061546b565b3480156107e557600080fd5b5061072f6107f4366004614398565b61198a565b34801561080557600080fd5b50610819610814366004615284565b6119c7565b604051610345919061547e565b34801561083257600080fd5b506105a6610841366004614b6b565b611c3a565b34801561085257600080fd5b506103ce610861366004614b6b565b611c9b565b6103ce610874366004614b6b565b611d8e565b6103ce610887366004615212565b611e21565b34801561089857600080fd5b506103ce6108a7366004614398565b611e83565b3480156108b857600080fd5b506103fc7f000000000000000000000000000000000000000000000000000000000000000081565b6103ce6108ee366004614b6b565b611eb3565b3480156108ff57600080fd5b506103ce61090e366004614398565b611f13565b34801561091f57600080fd5b5061093361092e366004614398565b611f43565b60405161034591906155cc565b34801561094c57600080fd5b5061096061095b366004614398565b612043565b60405161034591906155db565b34801561097957600080fd5b5061098d610988366004615284565b612278565b60405161034591906155ea565b3480156109a657600080fd5b506103ce6124cf565b3480156109bb57600080fd5b506103ce6109ca366004615284565b612553565b3480156109db57600080fd5b506103ce6109ea366004614398565b61256f565b3480156109fb57600080fd5b506103ce610a0a366004614b6b565b6125af565b6105a6610a1d366004614b6b565b61260e565b610a716040518061012001604052806000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b816001600160a01b031663916cef4e6040518163ffffffff1660e01b8152600401600060405180830381600087803b158015610aac57600080fd5b505af1925050508015610abd575060015b610b70573d808015610aeb576040519150601f19603f3d011682016040523d82523d6000602084013e610af0565b606091505b5060208101517fdc4022c5000000000000000000000000000000000000000000000000000000007fffffffff00000000000000000000000000000000000000000000000000000000821601610b6d57610b57826004808551610b529190615743565b612670565b806020019051810190610b6a9190615756565b92505b50505b919050565b610b7d613b50565b6001600160a01b0382168152610b9282611f43565b6020820152610ba08261170f565b6040820152610bae82612043565b6060820152610bbc82610a22565b60808201526040810151610bd19083906127ce565b60a08201526040810151610be6908390612a65565b60c0820181905260a0820151610bfe91849190612d83565b8160e00181905250610c3582826020015160a00151836020015160c0015184606001516101a0015185606001516101c00151613058565b610100820152919050565b6000806000836001600160a01b031663b7791bf26040518163ffffffff1660e01b815260040161024060405180830381865afa158015610c84573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ca89190615857565b90508060a001518160c001519250925050915091565b6040517fe980e1eb000000000000000000000000000000000000000000000000000000008152600481018490526024810183905260448101829052600160648201526000906001600160a01b0386169063e980e1eb9034906084015b60206040518083038185885af193505050508015610d55575060408051601f3d908101601f19168201909252610d529181019061593e565b60015b610dbb573d808015610d83576040519150601f19603f3d011682016040523d82523d6000602084013e610d88565b606091505b50610db3817fe8d35d06000000000000000000000000000000000000000000000000000000006134f1565b915050610dbd565b505b949350505050565b6000610df17f000000000000000000000000000000000000000000000000000000000000000083613540565b92915050565b604051632d71cdb960e21b8152600260048201526000906001600160a01b0383169063b5c736e4906024015b602060405180830381865afa158015610e40573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610df1919061593e565b610e6c613da7565b610df182610e798461198a565b610e828561156d565b612d83565b610e8f613e25565b600080610e9b84610c40565b915091506000610eaa856115b8565b90506103ff60e482901c81169060ee83901c16610eca8786868585613058565b979650505050505050565b60606000610ee16124cf565b90508067ffffffffffffffff811115610efc57610efc614c2a565b604051908082528060200260200182016040528015610f25578160200160208202803683370190505b50915060005b81811015610f7d57610f416103f7826001615957565b838281518110610f5357610f5361596a565b6001600160a01b039092166020928302919091019091015280610f7581615999565b915050610f2b565b505090565b80516060908067ffffffffffffffff811115610fa057610fa0614c2a565b604051908082528060200260200182016040528015610fd957816020015b610fc6613b50565b815260200190600190039081610fbe5790505b50915060005b81811015610b6d57611009848281518110610ffc57610ffc61596a565b6020026020010151610b75565b83828151811061101b5761101b61596a565b6020026020010181905250808061103190615999565b915050610fdf565b604051632d71cdb960e21b81526004808201526000906001600160a01b0383169063b5c736e490602401610e23565b606080828067ffffffffffffffff81111561108557611085614c2a565b6040519080825280602002602001820160405280156110be57816020015b6110ab614002565b8152602001906001900390816110a35790505b5092508067ffffffffffffffff8111156110da576110da614c2a565b60405190808252806020026020018201604052801561111357816020015b6111006140f6565b8152602001906001900390816110f85790505b50915060005b818110156111c45761114c878787848181106111375761113761596a565b90506020020160208101906109889190614398565b84828151811061115e5761115e61596a565b60200260200101819052506111948787878481811061117f5761117f61596a565b90506020020160208101906108149190614398565b8382815181106111a6576111a661596a565b602002602001018190525080806111bc90615999565b915050611119565b5050935093915050565b6040517f4d9036de0000000000000000000000000000000000000000000000000000000081526004810184905260248101839052604481018290526001606482015260009081906001600160a01b03871690634d9036de9034906084015b604080518083038185885af193505050508015611266575060408051601f3d908101601f19168201909252611263918101906159d1565b60015b6112d0573d808015611294576040519150601f19603f3d011682016040523d82523d6000602084013e611299565b606091505b506112c4817f1458577f0000000000000000000000000000000000000000000000000000000061394b565b90935091506112d39050565b50505b94509492505050565b6040517f286f0e610000000000000000000000000000000000000000000000000000000081528315156004820152602481018390526044810182905261dead60648201526000906001600160a01b0386169063286f0e619034906084015b60206040518083038185885af193505050508015611375575060408051601f3d908101601f191682019092526113729181019061593e565b60015b610dbb573d8080156113a3576040519150601f19603f3d011682016040523d82523d6000602084013e6113a8565b606091505b50610db3817fb3bfda99000000000000000000000000000000000000000000000000000000006134f1565b6000826001600160a01b031663b5c736e46113ef6006856139ab565b6040518263ffffffff1660e01b815260040161140d91815260200190565b602060405180830381865afa15801561142a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061144e919061593e565b9392505050565b6000826001600160a01b031663b5c736e46113ef6005856139e1565b604051632d71cdb960e21b8152600760048201526000906080906001600160a01b0384169063b5c736e490602401602060405180830381865afa1580156114bc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114e0919061593e565b901c92915050565b604051632d71cdb960e21b8152600760048201526000906fffffffffffffffffffffffffffffffff906001600160a01b0384169063b5c736e490602401602060405180830381865afa158015611542573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611566919061593e565b1692915050565b6115a66040518060c001604052806000815260200160008152602001600081526020016000815260200160008152602001600081525090565b610df1826115b38461170f565b612a65565b604051632d71cdb960e21b8152600160048201526000906001600160a01b0383169063b5c736e490602401610e23565b6040517fd331bef700000000000000000000000000000000000000000000000000000000815260048101849052602481018390526044810182905261dead60648201526000906001600160a01b0386169063d331bef7906084015b6020604051808303816000875af1925050508015610d55575060408051601f3d908101601f19168201909252610d529181019061593e565b6040517fe27203cd00000000000000000000000000000000000000000000000000000000815260048101849052602481018390526044810182905261dead606482015260009081906001600160a01b0387169063e27203cd906084015b60408051808303816000875af1925050508015611266575060408051601f3d908101601f19168201909252611263918101906159d1565b61173a6040518060800160405280600081526020016000815260200160008152602001600081525090565b816001600160a01b0316631595cbd36040518163ffffffff1660e01b8152600401608060405180830381865afa158015611778573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610df19190615a5b565b6060818067ffffffffffffffff8111156117b8576117b8614c2a565b6040519080825280602002602001820160405280156117f157816020015b6117de614002565b8152602001906001900390816117d65790505b50915060005b8181101561184557611815868686848181106111375761113761596a565b8382815181106118275761182761596a565b6020026020010181905250808061183d90615999565b9150506117f7565b50509392505050565b60606000836001600160a01b031663d811b2ce846040518263ffffffff1660e01b815260040161187e9190615a77565b600060405180830381865afa15801561189b573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526118c39190810190615b29565b915091505b9250929050565b60606118dc610533610ed5565b905090565b6060818067ffffffffffffffff8111156118fd576118fd614c2a565b60405190808252806020026020018201604052801561193657816020015b6119236140f6565b81526020019060019003908161191b5790505b50915060005b818110156118455761195a8686868481811061117f5761117f61596a565b83828151811061196c5761196c61596a565b6020026020010181905250808061198290615999565b91505061193c565b6119b56040518060800160405280600081526020016000815260200160008152602001600081525090565b610df1826119c28461170f565b6127ce565b6119cf6140f6565b60006119db8484611455565b90508015611c3357600180821681148352611a0b9082901c67ffffffffffffffff16600860ff9082901c91161b90565b60208301819052611a1d908290613a05565b60408301526401ffffffff608182901c166060830152613fff60a282901c16608083015262ffffff60b082901c1660a08301526103ff60d082901c1660ff60c883901c161b60c08301526103ff60e282901c1660ff60da83901c161b60e08301526020820151604083015111611a94576000611aa8565b81602001518260400151611aa89190615743565b6101008301819052610120830152600080611ac286610c40565b6040517f967915d60000000000000000000000000000000000000000000000000000000081526001600160a01b03898116600483015280841660248301529294509092507f00000000000000000000000000000000000000000000000000000000000000009091169063967915d69060440161050060405180830381865afa158015611b52573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b769190615dd3565b506101408501526040517f967915d60000000000000000000000000000000000000000000000000000000081526001600160a01b03878116600483015282811660248301527f0000000000000000000000000000000000000000000000000000000000000000169063967915d69060440161050060405180830381865afa158015611c05573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c299190615dd3565b5061016085015250505b5092915050565b6040517f35f0df9800000000000000000000000000000000000000000000000000000000815260048101849052602481018390526044810182905261dead606482015260009081906001600160a01b038716906335f0df98906084016116d8565b6040517f4c89bfd400000000000000000000000000000000000000000000000000000000815260048101849052602481018390526044810182905261dead60648201526000906001600160a01b03861690634c89bfd4906084016020604051808303816000875af1925050508015611d30575060408051601f3d908101601f19168201909252611d2d9181019061593e565b60015b610dbb573d808015611d5e576040519150601f19603f3d011682016040523d82523d6000602084013e611d63565b606091505b50610db3817f73999506000000000000000000000000000000000000000000000000000000006134f1565b6040517f30acd6fd000000000000000000000000000000000000000000000000000000008152600481018490526024810183905260448101829052600160648201526000906001600160a01b038616906330acd6fd90349060840160206040518083038185885af193505050508015611d30575060408051601f3d908101601f19168201909252611d2d9181019061593e565b6040517f2668dfaa0000000000000000000000000000000000000000000000000000000081528315156004820152602481018390526044810182905261dead60648201526000906001600160a01b03861690632668dfaa90349060840161133a565b604051632d71cdb960e21b8152600060048201819052906001600160a01b0383169063b5c736e490602401610e23565b6040517f68766981000000000000000000000000000000000000000000000000000000008152600481018490526024810183905260448101829052600160648201526000906001600160a01b038616906368766981903490608401610d1a565b604051632d71cdb960e21b8152600860048201526000906001600160a01b0383169063b5c736e490602401610e23565b611fe0604080516101c08101825260008082526020808301829052828401829052835160a08101855282815290810182905292830181905260608381018290526080840191909152909190820190815260006020820181905260408201819052606082018190526080820181905260a0820181905260c0820181905260e08201819052610100820181905261012082018190526101409091015290565b816001600160a01b031663b7791bf26040518163ffffffff1660e01b815260040161024060405180830381865afa15801561201f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610df19190615857565b6120e06040518061022001604052806000151581526020016000151581526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160006001600160a01b0316815260200160006001600160a01b031681526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b60006120eb836115b8565b60018181161483526002808216811460208501526201ffff9082901c166040840152607f601382901c166060840152620fffff601b82901c8116608080860191909152602f83901c90911660a08501526103ff604483901c811660c0860152604e83901c1660e085015262ffffff605883901c1661010085015290915061217184610df7565b901c6101e0830152608061218484611039565b901c610200830152607081901c633fffffff1680156121d7576121c77f000000000000000000000000000000000000000000000000000000000000000082613540565b6001600160a01b03166101208401525b50608e81901c633fffffff168015612223576122137f000000000000000000000000000000000000000000000000000000000000000082613540565b6001600160a01b03166101408401525b620fffff60b483901c1660ff60ac84901c161b610160840152620fffff60d083901c1660ff60c884901c161b610180840152506103ff60e482901c81166101a084015260ee9190911c166101c0820152919050565b612280614002565b600061228c8484612553565b90508015611c33576001808216811483526122bc9082901c67ffffffffffffffff16600860ff9082901c91161b90565b602083018190526122ce908290613ac0565b60408301819052608182901c6401ffffffff16606084015260a282901c613fff16608084015260b082901c62ffffff1660a084015260d082901c6103ff1660c883901c60ff161b60c084015260208301511161232b57600061233f565b8160400151826020015161233f9190615743565b60e0830181905261010083015260008061235886610c40565b6040517fe72ef91b0000000000000000000000000000000000000000000000000000000081526001600160a01b03898116600483015280841660248301529294509092507f00000000000000000000000000000000000000000000000000000000000000009091169063e72ef91b906044016104c060405180830381865afa1580156123e8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061240c9190615e91565b506101208501526040517fe72ef91b0000000000000000000000000000000000000000000000000000000081526001600160a01b03878116600483015282811660248301527f0000000000000000000000000000000000000000000000000000000000000000169063e72ef91b906044016104c060405180830381865afa15801561249b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124bf9190615e91565b5061014085015250505092915050565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166393656c176040518163ffffffff1660e01b8152600401602060405180830381865afa15801561252f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118dc919061593e565b6000826001600160a01b031663b5c736e46113ef6003856139e1565b6000816001600160a01b031663f4b9a3fb6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610e40573d6000803e3d6000fd5b6040517f242011d500000000000000000000000000000000000000000000000000000000815260048101849052602481018390526044810182905261dead60648201526000906001600160a01b0386169063242011d590608401611643565b6040517f5b3d38d70000000000000000000000000000000000000000000000000000000081526004810184905260248101839052604481018290526001606482015260009081906001600160a01b03871690635b3d38d790349060840161122c565b60608161267e81601f615957565b10156126eb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f7700000000000000000000000000000000000060448201526064015b60405180910390fd5b6126f58284615957565b8451101561275f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f736c6963655f6f75744f66426f756e647300000000000000000000000000000060448201526064016126e2565b8115801561277c57604051915060008252602082016040526127c6565b6040519150601f8316801560200281840101848101868315602002848a0101015b818310156127b557805183526020928301920161279d565b5050848452601f01601f1916604052505b509392505050565b6127f96040518060800160405280600081526020016000815260200160008152602001600081525090565b6000612804846115b8565b90508060011660011461283e5760405180608001604052806000815260200160008152602001600081526020016000815250915050610df1565b6040517f015f6cfa0000000000000000000000000000000000000000000000000000000081526001600160a01b0385166004820152309063015f6cfa90602401610120604051808303816000875af19250505080156128ba575060408051601f3d908101601f191682019092526128b791810190615756565b60015b6128ea57604051806080016040528060008152602001600081526020016000815260200160008152509150611c33565b6080810151604080830151606084015160a085015160e086015193517f6560abaa000000000000000000000000000000000000000000000000000000008152600481019590955260248501929092526044840152606483015260848201526001600160a01b03861690636560abaa9060a401608060405180830381865afa925050508015612995575060408051601f3d908101601f1916820190925261299291810190615a5b565b60015b6129c557604051806080016040528060008152602001600081526020016000815260200160008152509250612a5d565b8451602086015182516129d89190615f2c565b6129e29190615f43565b84528451602086015160408301516129fa9190615f2c565b612a049190615f43565b60408086019190915285015160608601516020830151612a249190615f2c565b612a2e9190615f43565b6020850152604085015160608087015190830151612a4c9190615f2c565b612a569190615f43565b6060850152505b505092915050565b612a9e6040518060c001604052806000815260200160008152602001600081526020016000815260200160008152602001600081525090565b6000612aa9846115b8565b905080600216600214612af1576040518060c0016040528060008152602001600081526020016000815260200160008152602001600081526020016000815250915050610df1565b6040517f015f6cfa0000000000000000000000000000000000000000000000000000000081526001600160a01b0385166004820152309063015f6cfa90602401610120604051808303816000875af1925050508015612b6d575060408051601f3d908101601f19168201909252612b6a91810190615756565b60015b612bab576040518060c00160405280600081526020016000815260200160008152602001600081526020016000815260200160008152509150611c33565b6080810151604080830151606084015160c085015161010086015193517f05d455a9000000000000000000000000000000000000000000000000000000008152600481019590955260248501929092526044840152606483015260848201526001600160a01b038616906305d455a99060a40160c060405180830381865afa925050508015612c57575060408051601f3d908101601f19168201909252612c5491810190615f7e565b60015b612c95576040518060c00160405280600081526020016000815260200160008152602001600081526020016000815260200160008152509250612a5d565b845160208601518251612ca89190615f2c565b612cb29190615f43565b8452845160208601516040830151612cca9190615f2c565b612cd49190615f43565b6040850152845160208601516080830151612cef9190615f2c565b612cf99190615f43565b6080850152604085015160608601516020830151612d179190615f2c565b612d219190615f43565b6020850152604085015160608087015190830151612d3f9190615f2c565b612d499190615f43565b846060018181525050846040015185606001518260a00151612d6b9190615f2c565b612d759190615f43565b60a085015250505092915050565b612d8b613da7565b6000612d9685611e83565b64ffffffffff600182901c81168452602982901c81166020850152605182901c1660408401526401ffffffff607982901c166060840152623fffff609a82901c166080840152600760b082901c1660a084015261ffff60b382901c1660c084015290506fffffffffffffffffffffffffffffffff612e1386610df7565b1660e08301526fffffffffffffffffffffffffffffffff612e3386611039565b16610100830152612e43856115b8565b600160ff82901c811461012085015261014084018051601a84901c8316831490528051604384901c831683146020909101525160f883901c82169091146040909101529050612e91856114e8565b61014083018051606090810151620fffff8085169091528251820151601485901c82166020909101528251820151602885901c909116604091909101529051810151603c83901c6401ffffffff169101529050612eed85611471565b610140830180516080908101516103ff8085169091528251820151601485901c9091166020909101528151810151602884901c620fffff166040909101528151810151603c84901c6401ffffffff16606091909101529051810151605d83901c62ffffff169101529050612f6085611f13565b6101408301805160a0908101516401ffffffff84166040909101528151810151620fffff602185901c811690915291510151603583901c90911660209091015260e0830151855191925090612fbd90670de0b6b3a7640000615f2c565b612fc79190615f43565b61016083015260e08201516020850151612fe990670de0b6b3a7640000615f2c565b612ff39190615f43565b610180830152610100820151835161301390670de0b6b3a7640000615f2c565b61301d9190615f43565b6101a0830152610100820151602084015161304090670de0b6b3a7640000615f2c565b61304a9190615f43565b6101c0830152509392505050565b613060613e25565b6130686141a9565b6130706141a9565b6040517fe72ef91b0000000000000000000000000000000000000000000000000000000081526001600160a01b03898116600483015288811660248301527f0000000000000000000000000000000000000000000000000000000000000000169063e72ef91b906044016104c060405180830381865afa1580156130f8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061311c9190615e91565b6101c08501919091526040517fe72ef91b0000000000000000000000000000000000000000000000000000000081526001600160a01b038a8116600483015288811660248301529193507f00000000000000000000000000000000000000000000000000000000000000009091169063e72ef91b906044016104c060405180830381865afa1580156131b2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131d69190615e91565b6101e08501919091526040517f967915d60000000000000000000000000000000000000000000000000000000081526001600160a01b038a8116600483015289811660248301529192507f00000000000000000000000000000000000000000000000000000000000000009091169063967915d69060440161050060405180830381865afa15801561326c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132909190615dd3565b506102008401526040517f967915d60000000000000000000000000000000000000000000000000000000081526001600160a01b03898116600483015287811660248301527f0000000000000000000000000000000000000000000000000000000000000000169063967915d69060440161050060405180830381865afa15801561331f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133439190615dd3565b506102208401819052610180808401518086529083015160208601526101a080850151604087015283015160608601526101c08501516101009081015160808701526101e0860151015160a08601526102008501516101209081015160c08701529091015160e08501526103e8906133bc908790615f2c565b6133c69190615f43565b61010084015260208301516103e8906133e0908690615f2c565b6133ea9190615f43565b61012084015261010083015160408401511015613468578483604001516103e86134149190615f2c565b61341e9190615f43565b6101408401819052835111613434576000613446565b61014083015183516134469190615743565b61014084015260408301516101008401516134619190615743565b6101808401525b826101200151836060015110156134e6578383606001516103e861348c9190615f2c565b6134969190615f43565b61016084018190526020840151116134af5760006134c4565b82610160015183602001516134c49190615743565b61016084015260608301516101208401516134df9190615743565b6101a08401525b505095945050505050565b600060248351101561350557506000610df1565b60208301517fffffffff0000000000000000000000000000000000000000000000000000000080841690821603611c33575050506024015190565b6000606082600003613556576000915050610df1565b607f831161360c576040517fd60000000000000000000000000000000000000000000000000000000000000060208201527f940000000000000000000000000000000000000000000000000000000000000060218201526bffffffffffffffffffffffff19606086901b16602282015260f884901b7fff000000000000000000000000000000000000000000000000000000000000001660368201526037015b604051602081830303815290604052905061393c565b60ff83116136d6576040517fd70000000000000000000000000000000000000000000000000000000000000060208201527f940000000000000000000000000000000000000000000000000000000000000060218201526bffffffffffffffffffffffff19606086901b1660228201527f8100000000000000000000000000000000000000000000000000000000000000603682015260f884901b7fff000000000000000000000000000000000000000000000000000000000000001660378201526038016135f6565b61ffff83116137a1576040517fd80000000000000000000000000000000000000000000000000000000000000060208201527f940000000000000000000000000000000000000000000000000000000000000060218201526bffffffffffffffffffffffff19606086901b1660228201527f820000000000000000000000000000000000000000000000000000000000000060368201527fffff00000000000000000000000000000000000000000000000000000000000060f085901b1660378201526039016135f6565b62ffffff831161386d576040517fd90000000000000000000000000000000000000000000000000000000000000060208201527f940000000000000000000000000000000000000000000000000000000000000060218201526bffffffffffffffffffffffff19606086901b1660228201527f830000000000000000000000000000000000000000000000000000000000000060368201527fffffff000000000000000000000000000000000000000000000000000000000060e885901b166037820152603a016135f6565b6040517fda0000000000000000000000000000000000000000000000000000000000000060208201527f940000000000000000000000000000000000000000000000000000000000000060218201526bffffffffffffffffffffffff19606086901b1660228201527f840000000000000000000000000000000000000000000000000000000000000060368201527fffffffff0000000000000000000000000000000000000000000000000000000060e085901b166037820152603b0160405160208183030381529060405290505b80516020909101209392505050565b600080604484511015613963575060009050806118c8565b60208401517fffffffff00000000000000000000000000000000000000000000000000000000808516908216036139a35760248501519250604485015191505b509250929050565b60408051602081018390529081018390526000906060015b60405160208183030381529060405280519060200120905092915050565b604080516001600160a01b03831660208201529081018390526000906060016139c3565b60d082901c6103ff1660c883901c60ff161b613fff60a284901c166127108382020480840183811015613a3a57505050610df1565b608186901c6401ffffffff164203925066ffffffffffffff604987901c1660ff604188901c161b60b087901c62ffffff16613a758585615f2c565b613a7f9190615f43565b613a899190615957565b935080841115613a97578093505b6103ff60e287901c1660ff60da88901c161b925082841115613ab7578293505b50505092915050565b600066ffffffffffffff604984901c1660ff604185901c161b808203613aea576000915050610df1565b612710613fff60a286901c168402046401ffffffff608186901c16420362ffffff60b087901c16613b1b8284615f2c565b613b259190615f43565b9050808311613b35576000613b39565b8083035b93505080840383811115613ab75795945050505050565b604080516101208082018352600080835283516101c0810185528181526020818101839052818601839052855160a080820188528482528183018590529681018490526060808201859052608080830186905290840191909152820183905294810182905260c0810182905260e0810182905261010081018290529182018190526101408201819052610160820181905261018082018190526101a082015290918201908152602001613c246040518060800160405280600081526020016000815260200160008152602001600081525090565b8152602001613cc66040518061022001604052806000151581526020016000151581526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160006001600160a01b0316815260200160006001600160a01b031681526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b8152602001613d1a6040518061012001604052806000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b8152602001613d4a6040518060800160405280600081526020016000815260200160008152602001600081525090565b8152602001613d886040518060c001604052806000815260200160008152602001600081526020016000815260200160008152602001600081525090565b8152602001613d95613da7565b8152602001613da2613e25565b905290565b604051806101e00160405280600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600015158152602001613e0361422d565b8152602001600081526020016000815260200160008152602001600081525090565b6040518061024001604052806000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001613ee460405180610120016040528060001515815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b8152602001613f3a60405180610120016040528060001515815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b8152602001613f9e604051806101600160405280600015158152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b8152602001613da2604051806101600160405280600015158152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b60405180610160016040528060001515815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016140a060405180610120016040528060001515815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b8152602001613da260405180610120016040528060001515815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b604051806101800160405280600015158152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001613f9e604051806101600160405280600015158152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b60405180610220016040528060008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001613da26142e5565b6040518060c001604052806000151581526020016000151581526020016000151581526020016142856040518060a0016040528060008152602001600081526020016000815260200160008152602001600081525090565b81526020016142bc6040518060a0016040528060008152602001600081526020016000815260200160008152602001600081525090565b8152602001613da260405180606001604052806000815260200160008152602001600081525090565b6040518060600160405280600081526020016143326040518060a0016040528060006001600160a01b03168152602001600081526020016000815260200160008152602001600081525090565b8152602001613da26040518060e0016040528060006001600160a01b031681526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b6001600160a01b038116811461439557600080fd5b50565b6000602082840312156143aa57600080fd5b813561144e81614380565b6101208101610df18284805182526020810151602083015260408101516040830152606081015160608301526080810151608083015260a081015160a083015260c081015160c083015260e081015160e08301526101008082015181840152505050565b80518252602081015161443760208401826001600160a01b03169052565b50604081015161445260408401826001600160a01b03169052565b5060608101516144a360608401826001600160a01b03808251168352806020830151166020840152806040830151166040840152806060830151166060840152806080830151166080840152505050565b5060808101516101006144c0818501836001600160a01b03169052565b60a083015191506101206144de818601846001600160a01b03169052565b60c084015192506101406144fc818701856001600160a01b03169052565b60e0850151610160878101919091529285015161018080880191909152918501516101a080880191909152908501516101c0870152918401516101e0860152830151610200850152909101516102209092019190915250565b805115158252602081015161456e602084018215159052565b5060408101516040830152606081015160608301526080810151608083015260a081015160a083015260c081015160c083015260e081015160e0830152610100808201518184015250610120808201516145d2828501826001600160a01b03169052565b5050610140818101516001600160a01b031690830152610160808201519083015261018080820151908301526101a080820151908301526101c080820151908301526101e0808201519083015261020090810151910152565b8051151582526020810151151560208301526040810151151560408301526060810151614686606084018280518252602081015160208301526040810151604083015260608101516060830152608081015160808301525050565b506080818101518051610100850152602081015161012085015260408101516101408501526060810151610160850152908101516101808401525060a0015180516101a083015260208101516101c0830152604001516101e090910152565b805182526020810151602083015260408101516040830152606081015160608301526080810151608083015260a081015160a083015260c081015160c083015260e081015160e08301526101008082015181840152506101208082015161474f8285018215159052565b5050610140808201516147648285018261462b565b50506101608101516103408301526101808101516103608301526101a08101516103808301526101c001516103a090910152565b805182526020808201518184015260408083015181850152606080840151818601526080808501518187015260a0808601518188015260c0808701518189015260e080880151818a015261010080890151818b0152610120808a0151908b0152610140808a0151908b0152610160808a0151908b0152610180808a0151908b01526101a0808a0151908b01526101c0808a015180511515828d0152988901516101e08c0152968801516102008b0152948701516102208a015292860151610240890152908501516102608801528401516102808701528301516102a08601528201516102c08501529050506101e0810151805115156102e0840152602081015161030084015260408101516103208401526060810151610340840152608081015161036084015260a081015161038084015260c08101516103a084015260e08101516103c08401526101008101516103e0840152506102008101516149706104008401828051151582526020810151602083015260408101516040830152606081015160608301526080810151608083015260a081015160a083015260c081015160c083015260e081015160e08301526101008082015181840152506101208082015181840152506101408082015181840152505050565b50610220015180511515610560830152602081015161058083015260408101516105a083015260608101516105c083015260808101516105e083015260a081015161060083015260c081015161062083015260e081015161064083015261010081015161066083015261012081015161068083015261014001516106a090910152565b505050565b80516001600160a01b031682526020810151614a176020840182614419565b5060408181015180516102608501526020810151610280850152908101516102a08401526060908101516102c0840152810151614a586102e0840182614555565b5060808181015180516105008501526020810151610520850152604081015161054085015260608101516105608501529081015161058084015260a08101516105a084015260c08101516105c084015260e08101516105e08401526101008101516106008401525060a081015180516106208401526020810151610640840152604081015161066084015260608101516106808401525060c081015180516106a084015260208101516106c084015260408101516106e08401526060810151610700840152608081015161072084015260a08101516107408401525060e0810151614b476107608401826146e5565b506101008101516149f3610b20840182614798565b6111e08101610df182846149f8565b60008060008060808587031215614b8157600080fd5b8435614b8c81614380565b966020860135965060408601359560600135945092505050565b600060208284031215614bb857600080fd5b5035919050565b6103c08101610df182846146e5565b6106c08101610df18284614798565b6020808252825182820181905260009190848201906040850190845b81811015614c1e5783516001600160a01b031683529284019291840191600101614bf9565b50909695505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610120810167ffffffffffffffff81118282101715614c7d57614c7d614c2a565b60405290565b60405160a0810167ffffffffffffffff81118282101715614c7d57614c7d614c2a565b6040516101c0810167ffffffffffffffff81118282101715614c7d57614c7d614c2a565b6040516060810167ffffffffffffffff81118282101715614c7d57614c7d614c2a565b604051610220810167ffffffffffffffff81118282101715614c7d57614c7d614c2a565b604051610160810167ffffffffffffffff81118282101715614c7d57614c7d614c2a565b604051601f8201601f1916810167ffffffffffffffff81118282101715614d5e57614d5e614c2a565b604052919050565b600067ffffffffffffffff821115614d8057614d80614c2a565b5060051b60200190565b60006020808385031215614d9d57600080fd5b823567ffffffffffffffff811115614db457600080fd5b8301601f81018513614dc557600080fd5b8035614dd8614dd382614d66565b614d35565b81815260059190911b82018301908381019087831115614df757600080fd5b928401925b82841015610eca578335614e0f81614380565b82529284019290840190614dfc565b6020808252825182820181905260009190848201906040850190845b81811015614c1e57614e4d8385516149f8565b928401926111e09290920191600101614e3a565b600080600060408486031215614e7657600080fd5b8335614e8181614380565b9250602084013567ffffffffffffffff80821115614e9e57600080fd5b818601915086601f830112614eb257600080fd5b813581811115614ec157600080fd5b8760208260051b8501011115614ed657600080fd5b6020830194508093505050509250925092565b600081518084526020808501945080840160005b8381101561503f5761502b8783518051151582526020818101518382015260408083015181850152606080840151818601526080808501518187015260a0808601518188015260c0808701518189015260e080880151818a015261010080890151818b0152610120808a015180511515828d0152988901516101408c0152968801516101608b0152948701516101808a0152928601516101a0890152908501516101c08801528401516101e08701528301516102008601528201516102208501529050506101400151805115156102408301526020810151610260830152604081015161028083015260608101516102a083015260808101516102c083015260a08101516102e083015260c081015161030083015260e0810151610320830152610100015161034090910152565b610360969096019590820190600101614efd565b509495945050505050565b600081518084526020808501945080840160005b8381101561503f576151c28783518051151582526020808201518184015260408083015181850152606080840151818601526080808501518187015260a0808601518188015260c0808701518189015260e080880151818a015261010080890151818b0152610120808a0151818c0152610140808b015180511515828e0152998a01516101608d0152978901516101808c0152958801516101a08b0152938701516101c08a0152918601516101e0890152850151610200880152840151610220870152830151610240860152820151610260850152818101516102808501529050506101600151805115156102a083015260208101516102c083015260408101516102e08301526060810151610300830152608081015161032083015260a081015161034083015260c081015161036083015260e08101516103808301526101008101516103a08301526101208101516103c083015261014001516103e090910152565b61040096909601959082019060010161505e565b6040815260006151e96040830185614ee9565b82810360208401526151fb818561504a565b95945050505050565b801515811461439557600080fd5b6000806000806080858703121561522857600080fd5b843561523381614380565b9350602085013561524381615204565b93969395505050506040820135916060013590565b6000806040838503121561526b57600080fd5b823561527681614380565b946020939093013593505050565b6000806040838503121561529757600080fd5b82356152a281614380565b915060208301356152b281614380565b809150509250929050565b60c08101610df18284805182526020810151602083015260408101516040830152606081015160608301526080810151608083015260a081015160a08301525050565b8151815260208083015190820152604080830151908201526060808301519082015260808101610df1565b60208152600061144e6020830184614ee9565b6000806040838503121561535157600080fd5b823561535c81614380565b915060208381013567ffffffffffffffff81111561537957600080fd5b8401601f8101861361538a57600080fd5b8035615398614dd382614d66565b81815260059190911b820183019083810190888311156153b757600080fd5b928401925b828410156153d5578335825292840192908401906153bc565b80955050505050509250929050565b604080825283519082018190526000906020906060840190828701845b8281101561545c57615449848351805182526020810151602083015260408101516040830152606081015160608301526080810151608083015260a081015160a08301525050565b60c0939093019290840190600101615401565b50505092019290925292915050565b60208152600061144e602083018461504a565b8151151581526020808301518183015260408084015181840152606080850151818501526080808601518186015260a0808701518187015260c0808801518188015260e08089015181890152610100808a0151818a0152610120808b0151818b0152610140808c015180511515828d0152808b0151610160808e0191909152818b01516101808e0152818a01516101a08e0152818901516101c08e0152818801516101e08e0152818701516102008e0152818601516102208e0152818501516102408e0152818401516102608e0152908201516102808d01528c0151805115156102a08d0152998a01516102c08c0152978901516102e08b0152958801516103008a015293870151610320890152918601516103408801528501516103608701528401516103808601528301516103a08501528201516103c084015201516103e08201526104008101610df1565b6102408101610df18284614419565b6102208101610df18284614555565b6103608101610df182848051151582526020818101518382015260408083015181850152606080840151818601526080808501518187015260a0808601518188015260c0808701518189015260e080880151818a015261010080890151818b0152610120808a015180511515828d0152988901516101408c0152968801516101608b0152948701516101808a0152928601516101a0890152908501516101c08801528401516101e08701528301516102008601528201516102208501529050506101400151805115156102408301526020810151610260830152604081015161028083015260608101516102a083015260808101516102c083015260a08101516102e083015260c081015161030083015260e0810151610320830152610100015161034090910152565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b81810381811115610df157610df1615714565b6000610120828403121561576957600080fd5b615771614c59565b825181526020830151602082015260408301516040820152606083015160608201526080830151608082015260a083015160a082015260c083015160c082015260e083015160e08201526101008084015181830152508091505092915050565b8051610b7081614380565b600060a082840312156157ee57600080fd5b6157f6614c83565b9050815161580381614380565b8152602082015161581381614380565b6020820152604082015161582681614380565b6040820152606082015161583981614380565b6060820152608082015161584c81614380565b608082015292915050565b6000610240828403121561586a57600080fd5b615872614ca6565b82518152615882602084016157d1565b6020820152615893604084016157d1565b60408201526158a584606085016157dc565b60608201526101006158b88185016157d1565b60808301526101206158cb8186016157d1565b60a08401526101406158de8187016157d1565b60c08501526101608087015160e086015261018080880151858701526101a0945084880151848701526101c0880151838701526101e088015182870152610200880151818701525050505061022084015181830152508091505092915050565b60006020828403121561595057600080fd5b5051919050565b80820180821115610df157610df1615714565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036159ca576159ca615714565b5060010190565b600080604083850312156159e457600080fd5b505080516020909101519092909150565b600060808284031215615a0757600080fd5b6040516080810181811067ffffffffffffffff82111715615a2a57615a2a614c2a565b8060405250809150825181526020830151602082015260408301516040820152606083015160608201525092915050565b600060808284031215615a6d57600080fd5b61144e83836159f5565b6020808252825182820181905260009190848201906040850190845b81811015614c1e57835183529284019291840191600101615a93565b600060c08284031215615ac157600080fd5b60405160c0810181811067ffffffffffffffff82111715615ae457615ae4614c2a565b8060405250809150825181526020830151602082015260408301516040820152606083015160608201526080830151608082015260a083015160a08201525092915050565b60008060408385031215615b3c57600080fd5b825167ffffffffffffffff811115615b5357600080fd5b8301601f81018513615b6457600080fd5b80516020615b74614dd383614d66565b82815260c09283028401820192828201919089851115615b9357600080fd5b948301945b84861015615bb957615baa8a87615aaf565b83529485019491830191615b98565b50969091015195979596505050505050565b8051610b7081615204565b600060e08284031215615be857600080fd5b60405160e0810181811067ffffffffffffffff82111715615c0b57615c0b614c2a565b80604052508091508251615c1e81614380565b808252506020830151602082015260408301516040820152606083015160608201526080830151608082015260a083015160a082015260c083015160c08201525092915050565b60008183036101a0811215615c7957600080fd5b615c81614cca565b91508251825260a0601f1982011215615c9957600080fd5b50615ca2614c83565b6020830151615cb081614380565b8082525060408301516020820152606083015160408201526080830151606082015260a0830151608082015280602083015250615cf08360c08401615bd6565b604082015292915050565b60006103a08284031215615d0e57600080fd5b615d16614ced565b825181526020808401519082015260408084015190820152606080840151908201526080808401519082015260a0808401519082015260c0808401519082015260e08084015190820152610100808401519082015261012080840151908201526101408084015190820152610160808401519082015261018080840151908201526101a080840151908201526101c080840151908201526101e080840151908201529050610200615dc984828501615c65565b9082015292915050565b600080828403610500811215615de857600080fd5b61016080821215615df857600080fd5b615e00614d11565b9150615e0b85615bcb565b82526020850151602083015260408501516040830152606085015160608301526080850151608083015260a085015160a083015260c085015160c083015260e085015160e0830152610100808601518184015250610120808601518184015250610140808601518184015250819350615e8686828701615cfb565b925050509250929050565b6000808284036104c0811215615ea657600080fd5b61012080821215615eb657600080fd5b615ebe614c59565b9150615ec985615bcb565b82526020850151602083015260408501516040830152606085015160608301526080850151608083015260a085015160a083015260c085015160c083015260e085015160e0830152610100808601518184015250819350615e8686828701615cfb565b8082028115828204841417610df157610df1615714565b600082615f79577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b600060c08284031215615f9057600080fd5b61144e8383615aaf56fea2646970667358221220fcd2a27edbe8111b023753c985ea3195013405e481ece49117ff5de0cc48808164736f6c6343000815003300000000000000000000000091716c4eda1fb55e84bf8b4c7085f84285c1908500000000000000000000000052aa899454998be5b000ad077a46bbe360f4e497000000000000000000000000f82111c4354622ab12b9803cd3f6164fce52e8470000000000000000000000004ec7b668baf70d4a4b0fc7941a7708a07b6d45be

Deployed Bytecode

0x6080604052600436106103135760003560e01c80637b05c2001161019a578063cdaf7f22116100e1578063e72ef91b1161008a578063eeb9baeb11610064578063eeb9baeb146109cf578063eee99670146109ef578063f44dfe5014610a0f57600080fd5b8063e72ef91b1461096d578063ebf11ce41461099a578063ee221c08146109af57600080fd5b8063d91a0633116100bb578063d91a0633146108f3578063e1a25ab914610913578063e5c458431461094057600080fd5b8063cdaf7f221461088c578063d1d32444146108ac578063d82ae0fa146108e057600080fd5b8063957755e6116101435780639bb65fc71161011d5780639bb65fc7146108465780639c1b042314610866578063bb39e3a11461087957600080fd5b8063957755e6146107d9578063967915d6146107f957806396cc6dbf1461082657600080fd5b80638ad1fe82116101745780638ad1fe82146107695780638bfe3db21461079757806395430c41146107ac57600080fd5b80637b05c200146106ef5780637f51d07f1461070f57806384502d951461073c57600080fd5b80633a490e6f1161025e5780634f8666a0116102075780636902f79f116101e15780636902f79f1461067b5780636dd5fd85146106af578063741c0b5c146106cf57600080fd5b80634f8666a01461060e578063546b08cd1461062e57806355181f111461064e57600080fd5b8063425711371161023857806342571137146105bb578063472f2d09146105ce5780634dd3a4e0146105ee57600080fd5b80633a490e6f146105455780633cb84b11146105655780633f7256611461059357600080fd5b80631cba0023116102c05780632861c7d11161029a5780632861c7d1146104b05780632dd31000146104e4578063345df8df1461051857600080fd5b80631cba0023146104345780632516d94014610461578063266398ef1461048e57600080fd5b80631272e9ac116102f15780631272e9ac146103bb57806312e366aa146103dc57806318e172d91461041457600080fd5b8063015f6cfa146103185780630208dbb01461034e578063030a68101461037b575b600080fd5b34801561032457600080fd5b50610338610333366004614398565b610a22565b60405161034591906143b5565b60405180910390f35b34801561035a57600080fd5b5061036e610369366004614398565b610b75565b6040516103459190614b5c565b34801561038757600080fd5b5061039b610396366004614398565b610c40565b604080516001600160a01b03938416815292909116602083015201610345565b6103ce6103c9366004614b6b565b610cbe565b604051908152602001610345565b3480156103e857600080fd5b506103fc6103f7366004614ba6565b610dc5565b6040516001600160a01b039091168152602001610345565b34801561042057600080fd5b506103ce61042f366004614398565b610df7565b34801561044057600080fd5b5061045461044f366004614398565b610e64565b6040516103459190614bbf565b34801561046d57600080fd5b5061048161047c366004614398565b610e87565b6040516103459190614bce565b34801561049a57600080fd5b506104a3610ed5565b6040516103459190614bdd565b3480156104bc57600080fd5b506103fc7f00000000000000000000000052aa899454998be5b000ad077a46bbe360f4e49781565b3480156104f057600080fd5b506103fc7f00000000000000000000000091716c4eda1fb55e84bf8b4c7085f84285c1908581565b34801561052457600080fd5b50610538610533366004614d8a565b610f82565b6040516103459190614e1e565b34801561055157600080fd5b506103ce610560366004614398565b611039565b34801561057157600080fd5b50610585610580366004614e61565b611068565b6040516103459291906151d6565b6105a66105a1366004614b6b565b6111ce565b60408051928352602083019190915201610345565b6103ce6105c9366004615212565b6112dc565b3480156105da57600080fd5b506103ce6105e9366004615258565b6113d3565b3480156105fa57600080fd5b506103ce610609366004615284565b611455565b34801561061a57600080fd5b506103ce610629366004614398565b611471565b34801561063a57600080fd5b506103ce610649366004614398565b6114e8565b34801561065a57600080fd5b5061066e610669366004614398565b61156d565b60405161034591906152bd565b34801561068757600080fd5b506103fc7f000000000000000000000000f82111c4354622ab12b9803cd3f6164fce52e84781565b3480156106bb57600080fd5b506103ce6106ca366004614398565b6115b8565b3480156106db57600080fd5b506103ce6106ea366004614b6b565b6115e8565b3480156106fb57600080fd5b506105a661070a366004614b6b565b61167b565b34801561071b57600080fd5b5061072f61072a366004614398565b61170f565b6040516103459190615300565b34801561074857600080fd5b5061075c610757366004614e61565b61179c565b604051610345919061532b565b34801561077557600080fd5b5061078961078436600461533e565b61184e565b6040516103459291906153e4565b3480156107a357600080fd5b506105386118cf565b3480156107b857600080fd5b506107cc6107c7366004614e61565b6118e1565b604051610345919061546b565b3480156107e557600080fd5b5061072f6107f4366004614398565b61198a565b34801561080557600080fd5b50610819610814366004615284565b6119c7565b604051610345919061547e565b34801561083257600080fd5b506105a6610841366004614b6b565b611c3a565b34801561085257600080fd5b506103ce610861366004614b6b565b611c9b565b6103ce610874366004614b6b565b611d8e565b6103ce610887366004615212565b611e21565b34801561089857600080fd5b506103ce6108a7366004614398565b611e83565b3480156108b857600080fd5b506103fc7f0000000000000000000000004ec7b668baf70d4a4b0fc7941a7708a07b6d45be81565b6103ce6108ee366004614b6b565b611eb3565b3480156108ff57600080fd5b506103ce61090e366004614398565b611f13565b34801561091f57600080fd5b5061093361092e366004614398565b611f43565b60405161034591906155cc565b34801561094c57600080fd5b5061096061095b366004614398565b612043565b60405161034591906155db565b34801561097957600080fd5b5061098d610988366004615284565b612278565b60405161034591906155ea565b3480156109a657600080fd5b506103ce6124cf565b3480156109bb57600080fd5b506103ce6109ca366004615284565b612553565b3480156109db57600080fd5b506103ce6109ea366004614398565b61256f565b3480156109fb57600080fd5b506103ce610a0a366004614b6b565b6125af565b6105a6610a1d366004614b6b565b61260e565b610a716040518061012001604052806000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b816001600160a01b031663916cef4e6040518163ffffffff1660e01b8152600401600060405180830381600087803b158015610aac57600080fd5b505af1925050508015610abd575060015b610b70573d808015610aeb576040519150601f19603f3d011682016040523d82523d6000602084013e610af0565b606091505b5060208101517fdc4022c5000000000000000000000000000000000000000000000000000000007fffffffff00000000000000000000000000000000000000000000000000000000821601610b6d57610b57826004808551610b529190615743565b612670565b806020019051810190610b6a9190615756565b92505b50505b919050565b610b7d613b50565b6001600160a01b0382168152610b9282611f43565b6020820152610ba08261170f565b6040820152610bae82612043565b6060820152610bbc82610a22565b60808201526040810151610bd19083906127ce565b60a08201526040810151610be6908390612a65565b60c0820181905260a0820151610bfe91849190612d83565b8160e00181905250610c3582826020015160a00151836020015160c0015184606001516101a0015185606001516101c00151613058565b610100820152919050565b6000806000836001600160a01b031663b7791bf26040518163ffffffff1660e01b815260040161024060405180830381865afa158015610c84573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ca89190615857565b90508060a001518160c001519250925050915091565b6040517fe980e1eb000000000000000000000000000000000000000000000000000000008152600481018490526024810183905260448101829052600160648201526000906001600160a01b0386169063e980e1eb9034906084015b60206040518083038185885af193505050508015610d55575060408051601f3d908101601f19168201909252610d529181019061593e565b60015b610dbb573d808015610d83576040519150601f19603f3d011682016040523d82523d6000602084013e610d88565b606091505b50610db3817fe8d35d06000000000000000000000000000000000000000000000000000000006134f1565b915050610dbd565b505b949350505050565b6000610df17f00000000000000000000000091716c4eda1fb55e84bf8b4c7085f84285c1908583613540565b92915050565b604051632d71cdb960e21b8152600260048201526000906001600160a01b0383169063b5c736e4906024015b602060405180830381865afa158015610e40573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610df1919061593e565b610e6c613da7565b610df182610e798461198a565b610e828561156d565b612d83565b610e8f613e25565b600080610e9b84610c40565b915091506000610eaa856115b8565b90506103ff60e482901c81169060ee83901c16610eca8786868585613058565b979650505050505050565b60606000610ee16124cf565b90508067ffffffffffffffff811115610efc57610efc614c2a565b604051908082528060200260200182016040528015610f25578160200160208202803683370190505b50915060005b81811015610f7d57610f416103f7826001615957565b838281518110610f5357610f5361596a565b6001600160a01b039092166020928302919091019091015280610f7581615999565b915050610f2b565b505090565b80516060908067ffffffffffffffff811115610fa057610fa0614c2a565b604051908082528060200260200182016040528015610fd957816020015b610fc6613b50565b815260200190600190039081610fbe5790505b50915060005b81811015610b6d57611009848281518110610ffc57610ffc61596a565b6020026020010151610b75565b83828151811061101b5761101b61596a565b6020026020010181905250808061103190615999565b915050610fdf565b604051632d71cdb960e21b81526004808201526000906001600160a01b0383169063b5c736e490602401610e23565b606080828067ffffffffffffffff81111561108557611085614c2a565b6040519080825280602002602001820160405280156110be57816020015b6110ab614002565b8152602001906001900390816110a35790505b5092508067ffffffffffffffff8111156110da576110da614c2a565b60405190808252806020026020018201604052801561111357816020015b6111006140f6565b8152602001906001900390816110f85790505b50915060005b818110156111c45761114c878787848181106111375761113761596a565b90506020020160208101906109889190614398565b84828151811061115e5761115e61596a565b60200260200101819052506111948787878481811061117f5761117f61596a565b90506020020160208101906108149190614398565b8382815181106111a6576111a661596a565b602002602001018190525080806111bc90615999565b915050611119565b5050935093915050565b6040517f4d9036de0000000000000000000000000000000000000000000000000000000081526004810184905260248101839052604481018290526001606482015260009081906001600160a01b03871690634d9036de9034906084015b604080518083038185885af193505050508015611266575060408051601f3d908101601f19168201909252611263918101906159d1565b60015b6112d0573d808015611294576040519150601f19603f3d011682016040523d82523d6000602084013e611299565b606091505b506112c4817f1458577f0000000000000000000000000000000000000000000000000000000061394b565b90935091506112d39050565b50505b94509492505050565b6040517f286f0e610000000000000000000000000000000000000000000000000000000081528315156004820152602481018390526044810182905261dead60648201526000906001600160a01b0386169063286f0e619034906084015b60206040518083038185885af193505050508015611375575060408051601f3d908101601f191682019092526113729181019061593e565b60015b610dbb573d8080156113a3576040519150601f19603f3d011682016040523d82523d6000602084013e6113a8565b606091505b50610db3817fb3bfda99000000000000000000000000000000000000000000000000000000006134f1565b6000826001600160a01b031663b5c736e46113ef6006856139ab565b6040518263ffffffff1660e01b815260040161140d91815260200190565b602060405180830381865afa15801561142a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061144e919061593e565b9392505050565b6000826001600160a01b031663b5c736e46113ef6005856139e1565b604051632d71cdb960e21b8152600760048201526000906080906001600160a01b0384169063b5c736e490602401602060405180830381865afa1580156114bc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114e0919061593e565b901c92915050565b604051632d71cdb960e21b8152600760048201526000906fffffffffffffffffffffffffffffffff906001600160a01b0384169063b5c736e490602401602060405180830381865afa158015611542573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611566919061593e565b1692915050565b6115a66040518060c001604052806000815260200160008152602001600081526020016000815260200160008152602001600081525090565b610df1826115b38461170f565b612a65565b604051632d71cdb960e21b8152600160048201526000906001600160a01b0383169063b5c736e490602401610e23565b6040517fd331bef700000000000000000000000000000000000000000000000000000000815260048101849052602481018390526044810182905261dead60648201526000906001600160a01b0386169063d331bef7906084015b6020604051808303816000875af1925050508015610d55575060408051601f3d908101601f19168201909252610d529181019061593e565b6040517fe27203cd00000000000000000000000000000000000000000000000000000000815260048101849052602481018390526044810182905261dead606482015260009081906001600160a01b0387169063e27203cd906084015b60408051808303816000875af1925050508015611266575060408051601f3d908101601f19168201909252611263918101906159d1565b61173a6040518060800160405280600081526020016000815260200160008152602001600081525090565b816001600160a01b0316631595cbd36040518163ffffffff1660e01b8152600401608060405180830381865afa158015611778573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610df19190615a5b565b6060818067ffffffffffffffff8111156117b8576117b8614c2a565b6040519080825280602002602001820160405280156117f157816020015b6117de614002565b8152602001906001900390816117d65790505b50915060005b8181101561184557611815868686848181106111375761113761596a565b8382815181106118275761182761596a565b6020026020010181905250808061183d90615999565b9150506117f7565b50509392505050565b60606000836001600160a01b031663d811b2ce846040518263ffffffff1660e01b815260040161187e9190615a77565b600060405180830381865afa15801561189b573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526118c39190810190615b29565b915091505b9250929050565b60606118dc610533610ed5565b905090565b6060818067ffffffffffffffff8111156118fd576118fd614c2a565b60405190808252806020026020018201604052801561193657816020015b6119236140f6565b81526020019060019003908161191b5790505b50915060005b818110156118455761195a8686868481811061117f5761117f61596a565b83828151811061196c5761196c61596a565b6020026020010181905250808061198290615999565b91505061193c565b6119b56040518060800160405280600081526020016000815260200160008152602001600081525090565b610df1826119c28461170f565b6127ce565b6119cf6140f6565b60006119db8484611455565b90508015611c3357600180821681148352611a0b9082901c67ffffffffffffffff16600860ff9082901c91161b90565b60208301819052611a1d908290613a05565b60408301526401ffffffff608182901c166060830152613fff60a282901c16608083015262ffffff60b082901c1660a08301526103ff60d082901c1660ff60c883901c161b60c08301526103ff60e282901c1660ff60da83901c161b60e08301526020820151604083015111611a94576000611aa8565b81602001518260400151611aa89190615743565b6101008301819052610120830152600080611ac286610c40565b6040517f967915d60000000000000000000000000000000000000000000000000000000081526001600160a01b03898116600483015280841660248301529294509092507f000000000000000000000000f82111c4354622ab12b9803cd3f6164fce52e8479091169063967915d69060440161050060405180830381865afa158015611b52573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b769190615dd3565b506101408501526040517f967915d60000000000000000000000000000000000000000000000000000000081526001600160a01b03878116600483015282811660248301527f000000000000000000000000f82111c4354622ab12b9803cd3f6164fce52e847169063967915d69060440161050060405180830381865afa158015611c05573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c299190615dd3565b5061016085015250505b5092915050565b6040517f35f0df9800000000000000000000000000000000000000000000000000000000815260048101849052602481018390526044810182905261dead606482015260009081906001600160a01b038716906335f0df98906084016116d8565b6040517f4c89bfd400000000000000000000000000000000000000000000000000000000815260048101849052602481018390526044810182905261dead60648201526000906001600160a01b03861690634c89bfd4906084016020604051808303816000875af1925050508015611d30575060408051601f3d908101601f19168201909252611d2d9181019061593e565b60015b610dbb573d808015611d5e576040519150601f19603f3d011682016040523d82523d6000602084013e611d63565b606091505b50610db3817f73999506000000000000000000000000000000000000000000000000000000006134f1565b6040517f30acd6fd000000000000000000000000000000000000000000000000000000008152600481018490526024810183905260448101829052600160648201526000906001600160a01b038616906330acd6fd90349060840160206040518083038185885af193505050508015611d30575060408051601f3d908101601f19168201909252611d2d9181019061593e565b6040517f2668dfaa0000000000000000000000000000000000000000000000000000000081528315156004820152602481018390526044810182905261dead60648201526000906001600160a01b03861690632668dfaa90349060840161133a565b604051632d71cdb960e21b8152600060048201819052906001600160a01b0383169063b5c736e490602401610e23565b6040517f68766981000000000000000000000000000000000000000000000000000000008152600481018490526024810183905260448101829052600160648201526000906001600160a01b038616906368766981903490608401610d1a565b604051632d71cdb960e21b8152600860048201526000906001600160a01b0383169063b5c736e490602401610e23565b611fe0604080516101c08101825260008082526020808301829052828401829052835160a08101855282815290810182905292830181905260608381018290526080840191909152909190820190815260006020820181905260408201819052606082018190526080820181905260a0820181905260c0820181905260e08201819052610100820181905261012082018190526101409091015290565b816001600160a01b031663b7791bf26040518163ffffffff1660e01b815260040161024060405180830381865afa15801561201f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610df19190615857565b6120e06040518061022001604052806000151581526020016000151581526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160006001600160a01b0316815260200160006001600160a01b031681526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b60006120eb836115b8565b60018181161483526002808216811460208501526201ffff9082901c166040840152607f601382901c166060840152620fffff601b82901c8116608080860191909152602f83901c90911660a08501526103ff604483901c811660c0860152604e83901c1660e085015262ffffff605883901c1661010085015290915061217184610df7565b901c6101e0830152608061218484611039565b901c610200830152607081901c633fffffff1680156121d7576121c77f0000000000000000000000004ec7b668baf70d4a4b0fc7941a7708a07b6d45be82613540565b6001600160a01b03166101208401525b50608e81901c633fffffff168015612223576122137f0000000000000000000000004ec7b668baf70d4a4b0fc7941a7708a07b6d45be82613540565b6001600160a01b03166101408401525b620fffff60b483901c1660ff60ac84901c161b610160840152620fffff60d083901c1660ff60c884901c161b610180840152506103ff60e482901c81166101a084015260ee9190911c166101c0820152919050565b612280614002565b600061228c8484612553565b90508015611c33576001808216811483526122bc9082901c67ffffffffffffffff16600860ff9082901c91161b90565b602083018190526122ce908290613ac0565b60408301819052608182901c6401ffffffff16606084015260a282901c613fff16608084015260b082901c62ffffff1660a084015260d082901c6103ff1660c883901c60ff161b60c084015260208301511161232b57600061233f565b8160400151826020015161233f9190615743565b60e0830181905261010083015260008061235886610c40565b6040517fe72ef91b0000000000000000000000000000000000000000000000000000000081526001600160a01b03898116600483015280841660248301529294509092507f000000000000000000000000f82111c4354622ab12b9803cd3f6164fce52e8479091169063e72ef91b906044016104c060405180830381865afa1580156123e8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061240c9190615e91565b506101208501526040517fe72ef91b0000000000000000000000000000000000000000000000000000000081526001600160a01b03878116600483015282811660248301527f000000000000000000000000f82111c4354622ab12b9803cd3f6164fce52e847169063e72ef91b906044016104c060405180830381865afa15801561249b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124bf9190615e91565b5061014085015250505092915050565b60007f00000000000000000000000091716c4eda1fb55e84bf8b4c7085f84285c190856001600160a01b03166393656c176040518163ffffffff1660e01b8152600401602060405180830381865afa15801561252f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118dc919061593e565b6000826001600160a01b031663b5c736e46113ef6003856139e1565b6000816001600160a01b031663f4b9a3fb6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610e40573d6000803e3d6000fd5b6040517f242011d500000000000000000000000000000000000000000000000000000000815260048101849052602481018390526044810182905261dead60648201526000906001600160a01b0386169063242011d590608401611643565b6040517f5b3d38d70000000000000000000000000000000000000000000000000000000081526004810184905260248101839052604481018290526001606482015260009081906001600160a01b03871690635b3d38d790349060840161122c565b60608161267e81601f615957565b10156126eb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f7700000000000000000000000000000000000060448201526064015b60405180910390fd5b6126f58284615957565b8451101561275f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f736c6963655f6f75744f66426f756e647300000000000000000000000000000060448201526064016126e2565b8115801561277c57604051915060008252602082016040526127c6565b6040519150601f8316801560200281840101848101868315602002848a0101015b818310156127b557805183526020928301920161279d565b5050848452601f01601f1916604052505b509392505050565b6127f96040518060800160405280600081526020016000815260200160008152602001600081525090565b6000612804846115b8565b90508060011660011461283e5760405180608001604052806000815260200160008152602001600081526020016000815250915050610df1565b6040517f015f6cfa0000000000000000000000000000000000000000000000000000000081526001600160a01b0385166004820152309063015f6cfa90602401610120604051808303816000875af19250505080156128ba575060408051601f3d908101601f191682019092526128b791810190615756565b60015b6128ea57604051806080016040528060008152602001600081526020016000815260200160008152509150611c33565b6080810151604080830151606084015160a085015160e086015193517f6560abaa000000000000000000000000000000000000000000000000000000008152600481019590955260248501929092526044840152606483015260848201526001600160a01b03861690636560abaa9060a401608060405180830381865afa925050508015612995575060408051601f3d908101601f1916820190925261299291810190615a5b565b60015b6129c557604051806080016040528060008152602001600081526020016000815260200160008152509250612a5d565b8451602086015182516129d89190615f2c565b6129e29190615f43565b84528451602086015160408301516129fa9190615f2c565b612a049190615f43565b60408086019190915285015160608601516020830151612a249190615f2c565b612a2e9190615f43565b6020850152604085015160608087015190830151612a4c9190615f2c565b612a569190615f43565b6060850152505b505092915050565b612a9e6040518060c001604052806000815260200160008152602001600081526020016000815260200160008152602001600081525090565b6000612aa9846115b8565b905080600216600214612af1576040518060c0016040528060008152602001600081526020016000815260200160008152602001600081526020016000815250915050610df1565b6040517f015f6cfa0000000000000000000000000000000000000000000000000000000081526001600160a01b0385166004820152309063015f6cfa90602401610120604051808303816000875af1925050508015612b6d575060408051601f3d908101601f19168201909252612b6a91810190615756565b60015b612bab576040518060c00160405280600081526020016000815260200160008152602001600081526020016000815260200160008152509150611c33565b6080810151604080830151606084015160c085015161010086015193517f05d455a9000000000000000000000000000000000000000000000000000000008152600481019590955260248501929092526044840152606483015260848201526001600160a01b038616906305d455a99060a40160c060405180830381865afa925050508015612c57575060408051601f3d908101601f19168201909252612c5491810190615f7e565b60015b612c95576040518060c00160405280600081526020016000815260200160008152602001600081526020016000815260200160008152509250612a5d565b845160208601518251612ca89190615f2c565b612cb29190615f43565b8452845160208601516040830151612cca9190615f2c565b612cd49190615f43565b6040850152845160208601516080830151612cef9190615f2c565b612cf99190615f43565b6080850152604085015160608601516020830151612d179190615f2c565b612d219190615f43565b6020850152604085015160608087015190830151612d3f9190615f2c565b612d499190615f43565b846060018181525050846040015185606001518260a00151612d6b9190615f2c565b612d759190615f43565b60a085015250505092915050565b612d8b613da7565b6000612d9685611e83565b64ffffffffff600182901c81168452602982901c81166020850152605182901c1660408401526401ffffffff607982901c166060840152623fffff609a82901c166080840152600760b082901c1660a084015261ffff60b382901c1660c084015290506fffffffffffffffffffffffffffffffff612e1386610df7565b1660e08301526fffffffffffffffffffffffffffffffff612e3386611039565b16610100830152612e43856115b8565b600160ff82901c811461012085015261014084018051601a84901c8316831490528051604384901c831683146020909101525160f883901c82169091146040909101529050612e91856114e8565b61014083018051606090810151620fffff8085169091528251820151601485901c82166020909101528251820151602885901c909116604091909101529051810151603c83901c6401ffffffff169101529050612eed85611471565b610140830180516080908101516103ff8085169091528251820151601485901c9091166020909101528151810151602884901c620fffff166040909101528151810151603c84901c6401ffffffff16606091909101529051810151605d83901c62ffffff169101529050612f6085611f13565b6101408301805160a0908101516401ffffffff84166040909101528151810151620fffff602185901c811690915291510151603583901c90911660209091015260e0830151855191925090612fbd90670de0b6b3a7640000615f2c565b612fc79190615f43565b61016083015260e08201516020850151612fe990670de0b6b3a7640000615f2c565b612ff39190615f43565b610180830152610100820151835161301390670de0b6b3a7640000615f2c565b61301d9190615f43565b6101a0830152610100820151602084015161304090670de0b6b3a7640000615f2c565b61304a9190615f43565b6101c0830152509392505050565b613060613e25565b6130686141a9565b6130706141a9565b6040517fe72ef91b0000000000000000000000000000000000000000000000000000000081526001600160a01b03898116600483015288811660248301527f000000000000000000000000f82111c4354622ab12b9803cd3f6164fce52e847169063e72ef91b906044016104c060405180830381865afa1580156130f8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061311c9190615e91565b6101c08501919091526040517fe72ef91b0000000000000000000000000000000000000000000000000000000081526001600160a01b038a8116600483015288811660248301529193507f000000000000000000000000f82111c4354622ab12b9803cd3f6164fce52e8479091169063e72ef91b906044016104c060405180830381865afa1580156131b2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131d69190615e91565b6101e08501919091526040517f967915d60000000000000000000000000000000000000000000000000000000081526001600160a01b038a8116600483015289811660248301529192507f000000000000000000000000f82111c4354622ab12b9803cd3f6164fce52e8479091169063967915d69060440161050060405180830381865afa15801561326c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132909190615dd3565b506102008401526040517f967915d60000000000000000000000000000000000000000000000000000000081526001600160a01b03898116600483015287811660248301527f000000000000000000000000f82111c4354622ab12b9803cd3f6164fce52e847169063967915d69060440161050060405180830381865afa15801561331f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133439190615dd3565b506102208401819052610180808401518086529083015160208601526101a080850151604087015283015160608601526101c08501516101009081015160808701526101e0860151015160a08601526102008501516101209081015160c08701529091015160e08501526103e8906133bc908790615f2c565b6133c69190615f43565b61010084015260208301516103e8906133e0908690615f2c565b6133ea9190615f43565b61012084015261010083015160408401511015613468578483604001516103e86134149190615f2c565b61341e9190615f43565b6101408401819052835111613434576000613446565b61014083015183516134469190615743565b61014084015260408301516101008401516134619190615743565b6101808401525b826101200151836060015110156134e6578383606001516103e861348c9190615f2c565b6134969190615f43565b61016084018190526020840151116134af5760006134c4565b82610160015183602001516134c49190615743565b61016084015260608301516101208401516134df9190615743565b6101a08401525b505095945050505050565b600060248351101561350557506000610df1565b60208301517fffffffff0000000000000000000000000000000000000000000000000000000080841690821603611c33575050506024015190565b6000606082600003613556576000915050610df1565b607f831161360c576040517fd60000000000000000000000000000000000000000000000000000000000000060208201527f940000000000000000000000000000000000000000000000000000000000000060218201526bffffffffffffffffffffffff19606086901b16602282015260f884901b7fff000000000000000000000000000000000000000000000000000000000000001660368201526037015b604051602081830303815290604052905061393c565b60ff83116136d6576040517fd70000000000000000000000000000000000000000000000000000000000000060208201527f940000000000000000000000000000000000000000000000000000000000000060218201526bffffffffffffffffffffffff19606086901b1660228201527f8100000000000000000000000000000000000000000000000000000000000000603682015260f884901b7fff000000000000000000000000000000000000000000000000000000000000001660378201526038016135f6565b61ffff83116137a1576040517fd80000000000000000000000000000000000000000000000000000000000000060208201527f940000000000000000000000000000000000000000000000000000000000000060218201526bffffffffffffffffffffffff19606086901b1660228201527f820000000000000000000000000000000000000000000000000000000000000060368201527fffff00000000000000000000000000000000000000000000000000000000000060f085901b1660378201526039016135f6565b62ffffff831161386d576040517fd90000000000000000000000000000000000000000000000000000000000000060208201527f940000000000000000000000000000000000000000000000000000000000000060218201526bffffffffffffffffffffffff19606086901b1660228201527f830000000000000000000000000000000000000000000000000000000000000060368201527fffffff000000000000000000000000000000000000000000000000000000000060e885901b166037820152603a016135f6565b6040517fda0000000000000000000000000000000000000000000000000000000000000060208201527f940000000000000000000000000000000000000000000000000000000000000060218201526bffffffffffffffffffffffff19606086901b1660228201527f840000000000000000000000000000000000000000000000000000000000000060368201527fffffffff0000000000000000000000000000000000000000000000000000000060e085901b166037820152603b0160405160208183030381529060405290505b80516020909101209392505050565b600080604484511015613963575060009050806118c8565b60208401517fffffffff00000000000000000000000000000000000000000000000000000000808516908216036139a35760248501519250604485015191505b509250929050565b60408051602081018390529081018390526000906060015b60405160208183030381529060405280519060200120905092915050565b604080516001600160a01b03831660208201529081018390526000906060016139c3565b60d082901c6103ff1660c883901c60ff161b613fff60a284901c166127108382020480840183811015613a3a57505050610df1565b608186901c6401ffffffff164203925066ffffffffffffff604987901c1660ff604188901c161b60b087901c62ffffff16613a758585615f2c565b613a7f9190615f43565b613a899190615957565b935080841115613a97578093505b6103ff60e287901c1660ff60da88901c161b925082841115613ab7578293505b50505092915050565b600066ffffffffffffff604984901c1660ff604185901c161b808203613aea576000915050610df1565b612710613fff60a286901c168402046401ffffffff608186901c16420362ffffff60b087901c16613b1b8284615f2c565b613b259190615f43565b9050808311613b35576000613b39565b8083035b93505080840383811115613ab75795945050505050565b604080516101208082018352600080835283516101c0810185528181526020818101839052818601839052855160a080820188528482528183018590529681018490526060808201859052608080830186905290840191909152820183905294810182905260c0810182905260e0810182905261010081018290529182018190526101408201819052610160820181905261018082018190526101a082015290918201908152602001613c246040518060800160405280600081526020016000815260200160008152602001600081525090565b8152602001613cc66040518061022001604052806000151581526020016000151581526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160006001600160a01b0316815260200160006001600160a01b031681526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b8152602001613d1a6040518061012001604052806000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b8152602001613d4a6040518060800160405280600081526020016000815260200160008152602001600081525090565b8152602001613d886040518060c001604052806000815260200160008152602001600081526020016000815260200160008152602001600081525090565b8152602001613d95613da7565b8152602001613da2613e25565b905290565b604051806101e00160405280600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600015158152602001613e0361422d565b8152602001600081526020016000815260200160008152602001600081525090565b6040518061024001604052806000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001613ee460405180610120016040528060001515815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b8152602001613f3a60405180610120016040528060001515815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b8152602001613f9e604051806101600160405280600015158152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b8152602001613da2604051806101600160405280600015158152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b60405180610160016040528060001515815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016140a060405180610120016040528060001515815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b8152602001613da260405180610120016040528060001515815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b604051806101800160405280600015158152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001613f9e604051806101600160405280600015158152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b60405180610220016040528060008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001613da26142e5565b6040518060c001604052806000151581526020016000151581526020016000151581526020016142856040518060a0016040528060008152602001600081526020016000815260200160008152602001600081525090565b81526020016142bc6040518060a0016040528060008152602001600081526020016000815260200160008152602001600081525090565b8152602001613da260405180606001604052806000815260200160008152602001600081525090565b6040518060600160405280600081526020016143326040518060a0016040528060006001600160a01b03168152602001600081526020016000815260200160008152602001600081525090565b8152602001613da26040518060e0016040528060006001600160a01b031681526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b6001600160a01b038116811461439557600080fd5b50565b6000602082840312156143aa57600080fd5b813561144e81614380565b6101208101610df18284805182526020810151602083015260408101516040830152606081015160608301526080810151608083015260a081015160a083015260c081015160c083015260e081015160e08301526101008082015181840152505050565b80518252602081015161443760208401826001600160a01b03169052565b50604081015161445260408401826001600160a01b03169052565b5060608101516144a360608401826001600160a01b03808251168352806020830151166020840152806040830151166040840152806060830151166060840152806080830151166080840152505050565b5060808101516101006144c0818501836001600160a01b03169052565b60a083015191506101206144de818601846001600160a01b03169052565b60c084015192506101406144fc818701856001600160a01b03169052565b60e0850151610160878101919091529285015161018080880191909152918501516101a080880191909152908501516101c0870152918401516101e0860152830151610200850152909101516102209092019190915250565b805115158252602081015161456e602084018215159052565b5060408101516040830152606081015160608301526080810151608083015260a081015160a083015260c081015160c083015260e081015160e0830152610100808201518184015250610120808201516145d2828501826001600160a01b03169052565b5050610140818101516001600160a01b031690830152610160808201519083015261018080820151908301526101a080820151908301526101c080820151908301526101e0808201519083015261020090810151910152565b8051151582526020810151151560208301526040810151151560408301526060810151614686606084018280518252602081015160208301526040810151604083015260608101516060830152608081015160808301525050565b506080818101518051610100850152602081015161012085015260408101516101408501526060810151610160850152908101516101808401525060a0015180516101a083015260208101516101c0830152604001516101e090910152565b805182526020810151602083015260408101516040830152606081015160608301526080810151608083015260a081015160a083015260c081015160c083015260e081015160e08301526101008082015181840152506101208082015161474f8285018215159052565b5050610140808201516147648285018261462b565b50506101608101516103408301526101808101516103608301526101a08101516103808301526101c001516103a090910152565b805182526020808201518184015260408083015181850152606080840151818601526080808501518187015260a0808601518188015260c0808701518189015260e080880151818a015261010080890151818b0152610120808a0151908b0152610140808a0151908b0152610160808a0151908b0152610180808a0151908b01526101a0808a0151908b01526101c0808a015180511515828d0152988901516101e08c0152968801516102008b0152948701516102208a015292860151610240890152908501516102608801528401516102808701528301516102a08601528201516102c08501529050506101e0810151805115156102e0840152602081015161030084015260408101516103208401526060810151610340840152608081015161036084015260a081015161038084015260c08101516103a084015260e08101516103c08401526101008101516103e0840152506102008101516149706104008401828051151582526020810151602083015260408101516040830152606081015160608301526080810151608083015260a081015160a083015260c081015160c083015260e081015160e08301526101008082015181840152506101208082015181840152506101408082015181840152505050565b50610220015180511515610560830152602081015161058083015260408101516105a083015260608101516105c083015260808101516105e083015260a081015161060083015260c081015161062083015260e081015161064083015261010081015161066083015261012081015161068083015261014001516106a090910152565b505050565b80516001600160a01b031682526020810151614a176020840182614419565b5060408181015180516102608501526020810151610280850152908101516102a08401526060908101516102c0840152810151614a586102e0840182614555565b5060808181015180516105008501526020810151610520850152604081015161054085015260608101516105608501529081015161058084015260a08101516105a084015260c08101516105c084015260e08101516105e08401526101008101516106008401525060a081015180516106208401526020810151610640840152604081015161066084015260608101516106808401525060c081015180516106a084015260208101516106c084015260408101516106e08401526060810151610700840152608081015161072084015260a08101516107408401525060e0810151614b476107608401826146e5565b506101008101516149f3610b20840182614798565b6111e08101610df182846149f8565b60008060008060808587031215614b8157600080fd5b8435614b8c81614380565b966020860135965060408601359560600135945092505050565b600060208284031215614bb857600080fd5b5035919050565b6103c08101610df182846146e5565b6106c08101610df18284614798565b6020808252825182820181905260009190848201906040850190845b81811015614c1e5783516001600160a01b031683529284019291840191600101614bf9565b50909695505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610120810167ffffffffffffffff81118282101715614c7d57614c7d614c2a565b60405290565b60405160a0810167ffffffffffffffff81118282101715614c7d57614c7d614c2a565b6040516101c0810167ffffffffffffffff81118282101715614c7d57614c7d614c2a565b6040516060810167ffffffffffffffff81118282101715614c7d57614c7d614c2a565b604051610220810167ffffffffffffffff81118282101715614c7d57614c7d614c2a565b604051610160810167ffffffffffffffff81118282101715614c7d57614c7d614c2a565b604051601f8201601f1916810167ffffffffffffffff81118282101715614d5e57614d5e614c2a565b604052919050565b600067ffffffffffffffff821115614d8057614d80614c2a565b5060051b60200190565b60006020808385031215614d9d57600080fd5b823567ffffffffffffffff811115614db457600080fd5b8301601f81018513614dc557600080fd5b8035614dd8614dd382614d66565b614d35565b81815260059190911b82018301908381019087831115614df757600080fd5b928401925b82841015610eca578335614e0f81614380565b82529284019290840190614dfc565b6020808252825182820181905260009190848201906040850190845b81811015614c1e57614e4d8385516149f8565b928401926111e09290920191600101614e3a565b600080600060408486031215614e7657600080fd5b8335614e8181614380565b9250602084013567ffffffffffffffff80821115614e9e57600080fd5b818601915086601f830112614eb257600080fd5b813581811115614ec157600080fd5b8760208260051b8501011115614ed657600080fd5b6020830194508093505050509250925092565b600081518084526020808501945080840160005b8381101561503f5761502b8783518051151582526020818101518382015260408083015181850152606080840151818601526080808501518187015260a0808601518188015260c0808701518189015260e080880151818a015261010080890151818b0152610120808a015180511515828d0152988901516101408c0152968801516101608b0152948701516101808a0152928601516101a0890152908501516101c08801528401516101e08701528301516102008601528201516102208501529050506101400151805115156102408301526020810151610260830152604081015161028083015260608101516102a083015260808101516102c083015260a08101516102e083015260c081015161030083015260e0810151610320830152610100015161034090910152565b610360969096019590820190600101614efd565b509495945050505050565b600081518084526020808501945080840160005b8381101561503f576151c28783518051151582526020808201518184015260408083015181850152606080840151818601526080808501518187015260a0808601518188015260c0808701518189015260e080880151818a015261010080890151818b0152610120808a0151818c0152610140808b015180511515828e0152998a01516101608d0152978901516101808c0152958801516101a08b0152938701516101c08a0152918601516101e0890152850151610200880152840151610220870152830151610240860152820151610260850152818101516102808501529050506101600151805115156102a083015260208101516102c083015260408101516102e08301526060810151610300830152608081015161032083015260a081015161034083015260c081015161036083015260e08101516103808301526101008101516103a08301526101208101516103c083015261014001516103e090910152565b61040096909601959082019060010161505e565b6040815260006151e96040830185614ee9565b82810360208401526151fb818561504a565b95945050505050565b801515811461439557600080fd5b6000806000806080858703121561522857600080fd5b843561523381614380565b9350602085013561524381615204565b93969395505050506040820135916060013590565b6000806040838503121561526b57600080fd5b823561527681614380565b946020939093013593505050565b6000806040838503121561529757600080fd5b82356152a281614380565b915060208301356152b281614380565b809150509250929050565b60c08101610df18284805182526020810151602083015260408101516040830152606081015160608301526080810151608083015260a081015160a08301525050565b8151815260208083015190820152604080830151908201526060808301519082015260808101610df1565b60208152600061144e6020830184614ee9565b6000806040838503121561535157600080fd5b823561535c81614380565b915060208381013567ffffffffffffffff81111561537957600080fd5b8401601f8101861361538a57600080fd5b8035615398614dd382614d66565b81815260059190911b820183019083810190888311156153b757600080fd5b928401925b828410156153d5578335825292840192908401906153bc565b80955050505050509250929050565b604080825283519082018190526000906020906060840190828701845b8281101561545c57615449848351805182526020810151602083015260408101516040830152606081015160608301526080810151608083015260a081015160a08301525050565b60c0939093019290840190600101615401565b50505092019290925292915050565b60208152600061144e602083018461504a565b8151151581526020808301518183015260408084015181840152606080850151818501526080808601518186015260a0808701518187015260c0808801518188015260e08089015181890152610100808a0151818a0152610120808b0151818b0152610140808c015180511515828d0152808b0151610160808e0191909152818b01516101808e0152818a01516101a08e0152818901516101c08e0152818801516101e08e0152818701516102008e0152818601516102208e0152818501516102408e0152818401516102608e0152908201516102808d01528c0151805115156102a08d0152998a01516102c08c0152978901516102e08b0152958801516103008a015293870151610320890152918601516103408801528501516103608701528401516103808601528301516103a08501528201516103c084015201516103e08201526104008101610df1565b6102408101610df18284614419565b6102208101610df18284614555565b6103608101610df182848051151582526020818101518382015260408083015181850152606080840151818601526080808501518187015260a0808601518188015260c0808701518189015260e080880151818a015261010080890151818b0152610120808a015180511515828d0152988901516101408c0152968801516101608b0152948701516101808a0152928601516101a0890152908501516101c08801528401516101e08701528301516102008601528201516102208501529050506101400151805115156102408301526020810151610260830152604081015161028083015260608101516102a083015260808101516102c083015260a08101516102e083015260c081015161030083015260e0810151610320830152610100015161034090910152565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b81810381811115610df157610df1615714565b6000610120828403121561576957600080fd5b615771614c59565b825181526020830151602082015260408301516040820152606083015160608201526080830151608082015260a083015160a082015260c083015160c082015260e083015160e08201526101008084015181830152508091505092915050565b8051610b7081614380565b600060a082840312156157ee57600080fd5b6157f6614c83565b9050815161580381614380565b8152602082015161581381614380565b6020820152604082015161582681614380565b6040820152606082015161583981614380565b6060820152608082015161584c81614380565b608082015292915050565b6000610240828403121561586a57600080fd5b615872614ca6565b82518152615882602084016157d1565b6020820152615893604084016157d1565b60408201526158a584606085016157dc565b60608201526101006158b88185016157d1565b60808301526101206158cb8186016157d1565b60a08401526101406158de8187016157d1565b60c08501526101608087015160e086015261018080880151858701526101a0945084880151848701526101c0880151838701526101e088015182870152610200880151818701525050505061022084015181830152508091505092915050565b60006020828403121561595057600080fd5b5051919050565b80820180821115610df157610df1615714565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036159ca576159ca615714565b5060010190565b600080604083850312156159e457600080fd5b505080516020909101519092909150565b600060808284031215615a0757600080fd5b6040516080810181811067ffffffffffffffff82111715615a2a57615a2a614c2a565b8060405250809150825181526020830151602082015260408301516040820152606083015160608201525092915050565b600060808284031215615a6d57600080fd5b61144e83836159f5565b6020808252825182820181905260009190848201906040850190845b81811015614c1e57835183529284019291840191600101615a93565b600060c08284031215615ac157600080fd5b60405160c0810181811067ffffffffffffffff82111715615ae457615ae4614c2a565b8060405250809150825181526020830151602082015260408301516040820152606083015160608201526080830151608082015260a083015160a08201525092915050565b60008060408385031215615b3c57600080fd5b825167ffffffffffffffff811115615b5357600080fd5b8301601f81018513615b6457600080fd5b80516020615b74614dd383614d66565b82815260c09283028401820192828201919089851115615b9357600080fd5b948301945b84861015615bb957615baa8a87615aaf565b83529485019491830191615b98565b50969091015195979596505050505050565b8051610b7081615204565b600060e08284031215615be857600080fd5b60405160e0810181811067ffffffffffffffff82111715615c0b57615c0b614c2a565b80604052508091508251615c1e81614380565b808252506020830151602082015260408301516040820152606083015160608201526080830151608082015260a083015160a082015260c083015160c08201525092915050565b60008183036101a0811215615c7957600080fd5b615c81614cca565b91508251825260a0601f1982011215615c9957600080fd5b50615ca2614c83565b6020830151615cb081614380565b8082525060408301516020820152606083015160408201526080830151606082015260a0830151608082015280602083015250615cf08360c08401615bd6565b604082015292915050565b60006103a08284031215615d0e57600080fd5b615d16614ced565b825181526020808401519082015260408084015190820152606080840151908201526080808401519082015260a0808401519082015260c0808401519082015260e08084015190820152610100808401519082015261012080840151908201526101408084015190820152610160808401519082015261018080840151908201526101a080840151908201526101c080840151908201526101e080840151908201529050610200615dc984828501615c65565b9082015292915050565b600080828403610500811215615de857600080fd5b61016080821215615df857600080fd5b615e00614d11565b9150615e0b85615bcb565b82526020850151602083015260408501516040830152606085015160608301526080850151608083015260a085015160a083015260c085015160c083015260e085015160e0830152610100808601518184015250610120808601518184015250610140808601518184015250819350615e8686828701615cfb565b925050509250929050565b6000808284036104c0811215615ea657600080fd5b61012080821215615eb657600080fd5b615ebe614c59565b9150615ec985615bcb565b82526020850151602083015260408501516040830152606085015160608301526080850151608083015260a085015160a083015260c085015160c083015260e085015160e0830152610100808601518184015250819350615e8686828701615cfb565b8082028115828204841417610df157610df1615714565b600082615f79577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b600060c08284031215615f9057600080fd5b61144e8383615aaf56fea2646970667358221220fcd2a27edbe8111b023753c985ea3195013405e481ece49117ff5de0cc48808164736f6c63430008150033

Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)

00000000000000000000000091716c4eda1fb55e84bf8b4c7085f84285c1908500000000000000000000000052aa899454998be5b000ad077a46bbe360f4e497000000000000000000000000f82111c4354622ab12b9803cd3f6164fce52e8470000000000000000000000004ec7b668baf70d4a4b0fc7941a7708a07b6d45be

-----Decoded View---------------
Arg [0] : factory_ (address): 0x91716C4EDA1Fb55e84Bf8b4c7085f84285c19085
Arg [1] : liquidity_ (address): 0x52Aa899454998Be5b000Ad077a46Bbe360F4e497
Arg [2] : liquidityResolver_ (address): 0xF82111c4354622AB12b9803cD3F6164FCE52e847
Arg [3] : deployer_ (address): 0x4EC7b668BAF70d4A4b0FC7941a7708A07b6d45Be

-----Encoded View---------------
4 Constructor Arguments found :
Arg [0] : 00000000000000000000000091716c4eda1fb55e84bf8b4c7085f84285c19085
Arg [1] : 00000000000000000000000052aa899454998be5b000ad077a46bbe360f4e497
Arg [2] : 000000000000000000000000f82111c4354622ab12b9803cd3f6164fce52e847
Arg [3] : 0000000000000000000000004ec7b668baf70d4a4b0fc7941a7708a07b6d45be


Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading
[ Download: CSV Export  ]

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.