Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 1 internal transaction
Advanced mode:
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
21033819 | 21 days ago | Contract Creation | 0 ETH |
Loading...
Loading
Contract Name:
FluidDexResolver
Compiler Version
v0.8.21+commit.d9974bed
Optimization Enabled:
Yes with 5000 runs
Other Settings:
paris EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// 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; } }
// 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)))); } }
// 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) } } } }
// 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; } }
// 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_; } }
// 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_)); } }
// 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; } }
// 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; } }
// 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_; } }
//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_ ); }
// 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` } }
// 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_); }
// 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_ ); }
{ "optimizer": { "enabled": true, "runs": 5000 }, "evmVersion": "paris", "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"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"}]
Contract Creation Code
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
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
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.