Overview
S Balance
0 S
S Value
-More Info
Private Name Tags
ContractCreator
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Latest 1 internal transaction
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
434338 | 20 days ago | Contract Creation | 0 S |
Loading...
Loading
Contract Name:
FluidVaultTicksBranchesResolver
Compiler Version
v0.8.21+commit.d9974bed
Optimization Enabled:
Yes with 10000000 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 { TickMath } from "../../../libraries/tickMath.sol"; import { BigMathMinified } from "../../../libraries/bigMathMinified.sol"; import { IFluidVaultResolver } from "../vault/iVaultResolver.sol"; import { IFluidVault } from "../../../protocols/vault/interfaces/iVault.sol"; import { Structs } from "./structs.sol"; import { Variables } from "./variables.sol"; /// @notice Fluid Vault protocol ticks & branches resolver for all vault types. contract FluidVaultTicksBranchesResolver is Variables, Structs { /// @notice thrown if an input param address is zero error FluidVaultTicksBranchesResolver__AddressZero(); /// @notice constructor sets the immutable vault resolver address constructor(IFluidVaultResolver vaultResolver_) Variables(vaultResolver_) { if (address(vaultResolver_) == address(0)) { revert FluidVaultTicksBranchesResolver__AddressZero(); } } function getTicksDebt( address vault_, int fromTick_, uint totalTicks_ ) public view returns (TickDebt[] memory ticksDebt_, int toTick_) { int topTick_ = _tickHelper(((VAULT_RESOLVER.getVaultVariablesRaw(vault_) >> 2) & X20)); fromTick_ = topTick_ < fromTick_ ? topTick_ : fromTick_; if (fromTick_ > type(int).min) { // if fromTick_ == tpye(int).min means top tick is not set, meaning no positions exist int startMapId_ = fromTick_ < 0 ? ((fromTick_ + 1) / 256) - 1 : fromTick_ / 256; // Removing all other after fromTick uint tickHasDebt_; { uint tickHasDebtRaw_ = VAULT_RESOLVER.getTickHasDebtRaw(vault_, startMapId_); uint bitsToRemove_ = uint(-fromTick_ + (startMapId_ * 256 + 255)); tickHasDebt_ = (tickHasDebtRaw_ << bitsToRemove_) >> bitsToRemove_; } // Adding 1 here as toTick_ is inclusive in the data so if totalTicks_ = 400 then it'll only check 400 toTick_ = fromTick_ - int(totalTicks_) + 1; uint count_ = _countTicksWithDebt(vault_, toTick_, startMapId_, tickHasDebt_); (, , uint vaultSupplyExchangePrice_, uint vaultBorrowExchangePrice_) = IFluidVault(vault_) .updateExchangePrices(VAULT_RESOLVER.getVaultVariables2Raw(vault_)); ticksDebt_ = _populateTicksDebt( vault_, toTick_, startMapId_, tickHasDebt_, count_, vaultSupplyExchangePrice_, vaultBorrowExchangePrice_ ); } } function getMultipleVaultsTicksDebt( address[] memory vaults_, int[] memory fromTicks_, uint[] memory totalTicks_ ) public view returns (VaultsTickDebt[] memory vaultsTickDebt_) { uint length_ = vaults_.length; vaultsTickDebt_ = new VaultsTickDebt[](length_); for (uint i = 0; i < length_; i++) { (vaultsTickDebt_[i].tickDebt, vaultsTickDebt_[i].toTick) = getTicksDebt( vaults_[i], fromTicks_[i], totalTicks_[i] ); } } function getAllVaultsTicksDebt(uint totalTicks_) public view returns (VaultsTickDebt[] memory vaultsTickDebt_) { address[] memory vaults_ = VAULT_RESOLVER.getAllVaultsAddresses(); uint length_ = vaults_.length; vaultsTickDebt_ = new VaultsTickDebt[](length_); for (uint i = 0; i < length_; i++) { (vaultsTickDebt_[i].tickDebt, vaultsTickDebt_[i].toTick) = getTicksDebt( vaults_[i], type(int).max, totalTicks_ ); } } function getBranchesDebt( address vault_, uint fromBranchId_, uint toBranchId_ ) public view returns (BranchDebt[] memory branchesDebt_) { uint vaultVariables_ = VAULT_RESOLVER.getVaultVariablesRaw(vault_); uint totalBranch_ = (vaultVariables_ >> 52) & X30; toBranchId_ = (toBranchId_ == 0 ? 1 : toBranchId_); fromBranchId_ = (totalBranch_ < fromBranchId_ ? totalBranch_ : fromBranchId_); require(fromBranchId_ >= toBranchId_, "fromBranchId_ must be greater than or equal to toBranchId_"); branchesDebt_ = new BranchDebt[](fromBranchId_ - toBranchId_ + 1); uint index_; for (uint i = fromBranchId_; i >= toBranchId_; i--) { branchesDebt_[index_++] = _getBranchDebt(vault_, vaultVariables_, i); } } function getMultipleVaultsBranchesDebt( address[] memory vaults_, uint[] memory fromBranchIds_, uint[] memory toBranchIds_ ) external view returns (BranchesDebt[] memory branchesDebt_) { uint length_ = vaults_.length; branchesDebt_ = new BranchesDebt[](length_); for (uint i = 0; i < length_; i++) { branchesDebt_[i].branchDebt = getBranchesDebt(vaults_[i], fromBranchIds_[i], toBranchIds_[i]); } } function getAllVaultsBranchesDebt() external view returns (BranchesDebt[] memory branchesDebt_) { address[] memory vaults_ = VAULT_RESOLVER.getAllVaultsAddresses(); uint length_ = vaults_.length; branchesDebt_ = new BranchesDebt[](length_); for (uint i = 0; i < length_; i++) { branchesDebt_[i].branchDebt = getBranchesDebt(vaults_[i], type(uint).max, 0); } } function _populateTicksDebt( address vault_, int toTick_, int mapId_, uint tickHasDebt_, uint count_, uint vaultSupplyExchangePrice_, uint vaultBorrowExchangePrice_ ) internal view returns (TickDebt[] memory ticksDebt_) { ticksDebt_ = new TickDebt[](count_); count_ = 0; // reuse var for loop index counter int nextTick_; uint tickExistingRawDebt_; uint ratio_; uint collateralRaw_; while (true) { while (tickHasDebt_ > 0) { { uint msb_ = BigMathMinified.mostSignificantBit(tickHasDebt_); // removing next tick from tickHasDebt tickHasDebt_ = (tickHasDebt_ << (257 - msb_)) >> (257 - msb_); nextTick_ = mapId_ * 256 + int(msb_ - 1); } if (nextTick_ < toTick_) { return ticksDebt_; } tickExistingRawDebt_ = (VAULT_RESOLVER.getTickDataRaw(vault_, nextTick_) >> 25) & X64; tickExistingRawDebt_ = (tickExistingRawDebt_ >> 8) << (tickExistingRawDebt_ & X8); ratio_ = TickMath.getRatioAtTick(nextTick_); collateralRaw_ = (tickExistingRawDebt_ * (1 << 96)) / ratio_; ticksDebt_[count_++] = TickDebt({ debtRaw: tickExistingRawDebt_, collateralRaw: collateralRaw_, debtNormal: (tickExistingRawDebt_ * vaultBorrowExchangePrice_) / 1e12, collateralNormal: (collateralRaw_ * vaultSupplyExchangePrice_) / 1e12, ratio: ratio_, tick: nextTick_ }); } if (--mapId_ == -129) { break; } tickHasDebt_ = VAULT_RESOLVER.getTickHasDebtRaw(vault_, mapId_); } } function _tickHelper(uint tickRaw_) internal pure returns (int tick) { require(tickRaw_ < X20, "invalid-number"); if (tickRaw_ > 0) { tick = tickRaw_ & 1 == 1 ? int((tickRaw_ >> 1) & X19) : -int((tickRaw_ >> 1) & X19); } else { tick = type(int).min; } } function _countTicksWithDebt( address vault_, int toTick_, int mapId_, uint tickHasDebt_ ) internal view returns (uint count_) { uint msb_; int nextTick_; while (true) { while (tickHasDebt_ > 0) { msb_ = BigMathMinified.mostSignificantBit(tickHasDebt_); // removing next tick from tickHasDebt tickHasDebt_ = (tickHasDebt_ << (257 - msb_)) >> (257 - msb_); nextTick_ = mapId_ * 256 + int(msb_ - 1); if (nextTick_ < toTick_) { return count_; } count_++; } if (--mapId_ == -129) { break; } tickHasDebt_ = VAULT_RESOLVER.getTickHasDebtRaw(vault_, mapId_); } return count_; } function _getBranchDebt( address vault_, uint vaultVariables_, uint branchId_ ) internal view returns (BranchDebt memory) { uint currentBranchData_ = VAULT_RESOLVER.getBranchDataRaw(vault_, branchId_); int minimaTick_ = _tickHelper((currentBranchData_ >> 2) & X20); uint status_ = currentBranchData_ & 3; if (status_ == 0) { // not liquidated status == 0 // only current branch can be non-liquidated branch return _getActiveBranchDebt(vaultVariables_, currentBranchData_, branchId_, status_); } else if (status_ == 1) { // liquidated status == 1 return _getLiquidatedBranchDebt(vault_, currentBranchData_, branchId_, status_, minimaTick_); } else { // merged status == 2 // absorbed status == 3 return _getClosedOrMergedBranchDebt(currentBranchData_, branchId_, status_); } } function _getActiveBranchDebt( uint vaultVariables_, uint currentBranchData_, uint branchId_, uint status_ ) internal pure returns (BranchDebt memory branchDebt_) { int topTick_ = _tickHelper((vaultVariables_ >> 2) & X20); uint ratio_ = topTick_ > type(int).min ? TickMath.getRatioAtTick(topTick_) : 0; branchDebt_ = BranchDebt({ debtRaw: 0, collateralRaw: 0, debtNormal: 0, collateralNormal: 0, branchId: branchId_, status: status_, // active status tick: topTick_, // as branch is not liquidated, just returning topTick for now, as whenever liquidation starts it'll start from topTick partials: 0, ratio: ratio_, debtFactor: (currentBranchData_ >> 116) & X50, baseBranchId: ((currentBranchData_ >> 166) & X30), baseBranchTick: _tickHelper((currentBranchData_ >> 196) & X20) // if == type(int).min, then current branch is master branch }); } function _getClosedOrMergedBranchDebt( uint currentBranchData_, uint branchId_, uint status_ ) internal pure returns (BranchDebt memory branchDebt_) { int baseBranchTick_ = _tickHelper((currentBranchData_ >> 196) & X20); uint ratio_ = baseBranchTick_ > type(int).min ? TickMath.getRatioAtTick(baseBranchTick_) : 0; branchDebt_ = BranchDebt({ debtRaw: 0, collateralRaw: 0, debtNormal: 0, collateralNormal: 0, branchId: branchId_, status: status_, tick: baseBranchTick_, // as branch is merged/closed, so adding baseBranchTick_ as this is where it went out of existance partials: 0, ratio: ratio_, debtFactor: (currentBranchData_ >> 116) & X50, baseBranchId: ((currentBranchData_ >> 166) & X30), baseBranchTick: baseBranchTick_ // if == type(int).min, then current branch is master branch }); } function _getLiquidatedBranchDebt( address vault_, uint currentBranchData_, uint branchId_, uint status_, int minimaTick_ ) internal view returns (BranchDebt memory branchDebt_) { uint debtLiquidity_ = BigMathMinified.fromBigNumber((currentBranchData_ >> 52) & X64, 8, X8); (uint collateralRaw_, uint ratio_) = _getCollateralRaw(currentBranchData_, debtLiquidity_, minimaTick_); (, , uint256 vaultSupplyExchangePrice_, uint256 vaultBorrowExchangePrice_) = IFluidVault(vault_) .updateExchangePrices(VAULT_RESOLVER.getVaultVariables2Raw(vault_)); branchDebt_ = BranchDebt({ debtRaw: debtLiquidity_, collateralRaw: collateralRaw_, debtNormal: (debtLiquidity_ * vaultBorrowExchangePrice_) / 1e12, collateralNormal: (collateralRaw_ * vaultSupplyExchangePrice_) / 1e12, branchId: branchId_, status: status_, tick: minimaTick_, // as branch is merged/closed, so adding baseBranchTick_ as this is where it went out of existance partials: 0, ratio: ratio_, debtFactor: (currentBranchData_ >> 116) & X50, baseBranchId: ((currentBranchData_ >> 166) & X30), baseBranchTick: _tickHelper((currentBranchData_ >> 196) & X20) // if == type(int).min, then current branch is master branch }); } function _getCollateralRaw( uint currentBranchData_, uint debtLiquidity_, int minimaTick_ ) internal pure returns (uint collateralRaw_, uint ratio_) { ratio_ = TickMath.getRatioAtTick(int24(minimaTick_)); uint ratioOneLess_ = (ratio_ * 10000) / 10015; uint length_ = ratio_ - ratioOneLess_; uint partials_ = (currentBranchData_ >> 22) & X30; uint currentRatio_ = ratioOneLess_ + ((length_ * partials_) / X30); collateralRaw_ = (debtLiquidity_ * TickMath.ZERO_TICK_SCALED_RATIO) / currentRatio_; } }
// 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; /// @title library that calculates number "tick" and "ratioX96" from this: ratioX96 = (1.0015^tick) * 2^96 /// @notice this library is used in Fluid Vault protocol for optimiziation. /// @dev "tick" supports between -32767 and 32767. "ratioX96" supports between 37075072 and 169307877264527972847801929085841449095838922544595 library TickMath { /// The minimum tick that can be passed in getRatioAtTick. 1.0015**-32767 int24 internal constant MIN_TICK = -32767; /// The maximum tick that can be passed in getRatioAtTick. 1.0015**32767 int24 internal constant MAX_TICK = 32767; uint256 internal constant FACTOR00 = 0x100000000000000000000000000000000; uint256 internal constant FACTOR01 = 0xff9dd7de423466c20352b1246ce4856f; // 2^128/1.0015**1 = 339772707859149738855091969477551883631 uint256 internal constant FACTOR02 = 0xff3bd55f4488ad277531fa1c725a66d0; // 2^128/1.0015**2 = 339263812140938331358054887146831636176 uint256 internal constant FACTOR03 = 0xfe78410fd6498b73cb96a6917f853259; // 2^128/1.0015**4 = 338248306163758188337119769319392490073 uint256 internal constant FACTOR04 = 0xfcf2d9987c9be178ad5bfeffaa123273; // 2^128/1.0015**8 = 336226404141693512316971918999264834163 uint256 internal constant FACTOR05 = 0xf9ef02c4529258b057769680fc6601b3; // 2^128/1.0015**16 = 332218786018727629051611634067491389875 uint256 internal constant FACTOR06 = 0xf402d288133a85a17784a411f7aba082; // 2^128/1.0015**32 = 324346285652234375371948336458280706178 uint256 internal constant FACTOR07 = 0xe895615b5beb6386553757b0352bda90; // 2^128/1.0015**64 = 309156521885964218294057947947195947664 uint256 internal constant FACTOR08 = 0xd34f17a00ffa00a8309940a15930391a; // 2^128/1.0015**128 = 280877777739312896540849703637713172762 uint256 internal constant FACTOR09 = 0xae6b7961714e20548d88ea5123f9a0ff; // 2^128/1.0015**256 = 231843708922198649176471782639349113087 uint256 internal constant FACTOR10 = 0x76d6461f27082d74e0feed3b388c0ca1; // 2^128/1.0015**512 = 157961477267171621126394973980180876449 uint256 internal constant FACTOR11 = 0x372a3bfe0745d8b6b19d985d9a8b85bb; // 2^128/1.0015**1024 = 73326833024599564193373530205717235131 uint256 internal constant FACTOR12 = 0x0be32cbee48979763cf7247dd7bb539d; // 2^128/1.0015**2048 = 15801066890623697521348224657638773661 uint256 internal constant FACTOR13 = 0x8d4f70c9ff4924dac37612d1e2921e; // 2^128/1.0015**4096 = 733725103481409245883800626999235102 uint256 internal constant FACTOR14 = 0x4e009ae5519380809a02ca7aec77; // 2^128/1.0015**8192 = 1582075887005588088019997442108535 uint256 internal constant FACTOR15 = 0x17c45e641b6e95dee056ff10; // 2^128/1.0015**16384 = 7355550435635883087458926352 /// The minimum value that can be returned from getRatioAtTick. Equivalent to getRatioAtTick(MIN_TICK). ~ Equivalent to `(1 << 96) * (1.0015**-32767)` uint256 internal constant MIN_RATIOX96 = 37075072; /// The maximum value that can be returned from getRatioAtTick. Equivalent to getRatioAtTick(MAX_TICK). /// ~ Equivalent to `(1 << 96) * (1.0015**32767)`, rounding etc. leading to minor difference uint256 internal constant MAX_RATIOX96 = 169307877264527972847801929085841449095838922544595; uint256 internal constant ZERO_TICK_SCALED_RATIO = 0x1000000000000000000000000; // 1 << 96 // 79228162514264337593543950336 uint256 internal constant _1E26 = 1e26; /// @notice ratioX96 = (1.0015^tick) * 2^96 /// @dev Throws if |tick| > max tick /// @param tick The input tick for the above formula /// @return ratioX96 ratio = (debt amount/collateral amount) function getRatioAtTick(int tick) internal pure returns (uint256 ratioX96) { assembly { let absTick_ := sub(xor(tick, sar(255, tick)), sar(255, tick)) if gt(absTick_, MAX_TICK) { revert(0, 0) } let factor_ := FACTOR00 if and(absTick_, 0x1) { factor_ := FACTOR01 } if and(absTick_, 0x2) { factor_ := shr(128, mul(factor_, FACTOR02)) } if and(absTick_, 0x4) { factor_ := shr(128, mul(factor_, FACTOR03)) } if and(absTick_, 0x8) { factor_ := shr(128, mul(factor_, FACTOR04)) } if and(absTick_, 0x10) { factor_ := shr(128, mul(factor_, FACTOR05)) } if and(absTick_, 0x20) { factor_ := shr(128, mul(factor_, FACTOR06)) } if and(absTick_, 0x40) { factor_ := shr(128, mul(factor_, FACTOR07)) } if and(absTick_, 0x80) { factor_ := shr(128, mul(factor_, FACTOR08)) } if and(absTick_, 0x100) { factor_ := shr(128, mul(factor_, FACTOR09)) } if and(absTick_, 0x200) { factor_ := shr(128, mul(factor_, FACTOR10)) } if and(absTick_, 0x400) { factor_ := shr(128, mul(factor_, FACTOR11)) } if and(absTick_, 0x800) { factor_ := shr(128, mul(factor_, FACTOR12)) } if and(absTick_, 0x1000) { factor_ := shr(128, mul(factor_, FACTOR13)) } if and(absTick_, 0x2000) { factor_ := shr(128, mul(factor_, FACTOR14)) } if and(absTick_, 0x4000) { factor_ := shr(128, mul(factor_, FACTOR15)) } let precision_ := 0 if iszero(and(tick, 0x8000000000000000000000000000000000000000000000000000000000000000)) { factor_ := div(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, factor_) // we round up in the division so getTickAtRatio of the output price is always consistent if mod(factor_, 0x100000000) { precision_ := 1 } } ratioX96 := add(shr(32, factor_), precision_) } } /// @notice ratioX96 = (1.0015^tick) * 2^96 /// @dev Throws if ratioX96 > max ratio || ratioX96 < min ratio /// @param ratioX96 The input ratio; ratio = (debt amount/collateral amount) /// @return tick The output tick for the above formula. Returns in round down form. if tick is 123.23 then 123, if tick is -123.23 then returns -124 /// @return perfectRatioX96 perfect ratio for the above tick function getTickAtRatio(uint256 ratioX96) internal pure returns (int tick, uint perfectRatioX96) { assembly { if or(gt(ratioX96, MAX_RATIOX96), lt(ratioX96, MIN_RATIOX96)) { revert(0, 0) } let cond := lt(ratioX96, ZERO_TICK_SCALED_RATIO) let factor_ if iszero(cond) { // if ratioX96 >= ZERO_TICK_SCALED_RATIO factor_ := div(mul(ratioX96, _1E26), ZERO_TICK_SCALED_RATIO) } if cond { // ratioX96 < ZERO_TICK_SCALED_RATIO factor_ := div(mul(ZERO_TICK_SCALED_RATIO, _1E26), ratioX96) } // put in https://www.wolframalpha.com/ whole equation: (1.0015^tick) * 2^96 * 10^26 / 79228162514264337593543950336 // for tick = 16384 // ratioX96 = (1.0015^16384) * 2^96 = 3665252098134783297721995888537077351735 // 3665252098134783297721995888537077351735 * 10^26 / 79228162514264337593543950336 = // 4626198540796508716348404308345255985.06131964639489434655721 if iszero(lt(factor_, 4626198540796508716348404308345255985)) { tick := or(tick, 0x4000) factor_ := div(mul(factor_, _1E26), 4626198540796508716348404308345255985) } // for tick = 8192 // ratioX96 = (1.0015^8192) * 2^96 = 17040868196391020479062776466509865 // 17040868196391020479062776466509865 * 10^26 / 79228162514264337593543950336 = // 21508599537851153911767490449162.3037648642153898377655505172 if iszero(lt(factor_, 21508599537851153911767490449162)) { tick := or(tick, 0x2000) factor_ := div(mul(factor_, _1E26), 21508599537851153911767490449162) } // for tick = 4096 // ratioX96 = (1.0015^4096) * 2^96 = 36743933851015821532611831851150 // 36743933851015821532611831851150 * 10^26 / 79228162514264337593543950336 = // 46377364670549310883002866648.9777607649742626173648716941385 if iszero(lt(factor_, 46377364670549310883002866649)) { tick := or(tick, 0x1000) factor_ := div(mul(factor_, _1E26), 46377364670549310883002866649) } // for tick = 2048 // ratioX96 = (1.0015^2048) * 2^96 = 1706210527034005899209104452335 // 1706210527034005899209104452335 * 10^26 / 79228162514264337593543950336 = // 2153540449365864845468344760.06357108484096046743300420319322 if iszero(lt(factor_, 2153540449365864845468344760)) { tick := or(tick, 0x800) factor_ := div(mul(factor_, _1E26), 2153540449365864845468344760) } // for tick = 1024 // ratioX96 = (1.0015^1024) * 2^96 = 367668226692760093024536487236 // 367668226692760093024536487236 * 10^26 / 79228162514264337593543950336 = // 464062544207767844008185024.950588990554136265212906454481127 if iszero(lt(factor_, 464062544207767844008185025)) { tick := or(tick, 0x400) factor_ := div(mul(factor_, _1E26), 464062544207767844008185025) } // for tick = 512 // ratioX96 = (1.0015^512) * 2^96 = 170674186729409605620119663668 // 170674186729409605620119663668 * 10^26 / 79228162514264337593543950336 = // 215421109505955298802281577.031879604792139232258508172947569 if iszero(lt(factor_, 215421109505955298802281577)) { tick := or(tick, 0x200) factor_ := div(mul(factor_, _1E26), 215421109505955298802281577) } // for tick = 256 // ratioX96 = (1.0015^256) * 2^96 = 116285004205991934861656513301 // 116285004205991934861656513301 * 10^26 / 79228162514264337593543950336 = // 146772309890508740607270614.667650899656438875541505058062410 if iszero(lt(factor_, 146772309890508740607270615)) { tick := or(tick, 0x100) factor_ := div(mul(factor_, _1E26), 146772309890508740607270615) } // for tick = 128 // ratioX96 = (1.0015^128) * 2^96 = 95984619659632141743747099590 // 95984619659632141743747099590 * 10^26 / 79228162514264337593543950336 = // 121149622323187099817270416.157248837742741760456796835775887 if iszero(lt(factor_, 121149622323187099817270416)) { tick := or(tick, 0x80) factor_ := div(mul(factor_, _1E26), 121149622323187099817270416) } // for tick = 64 // ratioX96 = (1.0015^64) * 2^96 = 87204845308406958006717891124 // 87204845308406958006717891124 * 10^26 / 79228162514264337593543950336 = // 110067989135437147685980801.568068573422377364214113968609839 if iszero(lt(factor_, 110067989135437147685980801)) { tick := or(tick, 0x40) factor_ := div(mul(factor_, _1E26), 110067989135437147685980801) } // for tick = 32 // ratioX96 = (1.0015^32) * 2^96 = 83120873769022354029916374475 // 83120873769022354029916374475 * 10^26 / 79228162514264337593543950336 = // 104913292358707887270979599.831816586773651266562785765558183 if iszero(lt(factor_, 104913292358707887270979600)) { tick := or(tick, 0x20) factor_ := div(mul(factor_, _1E26), 104913292358707887270979600) } // for tick = 16 // ratioX96 = (1.0015^16) * 2^96 = 81151180492336368327184716176 // 81151180492336368327184716176 * 10^26 / 79228162514264337593543950336 = // 102427189924701091191840927.762844039579442328381455567932128 if iszero(lt(factor_, 102427189924701091191840928)) { tick := or(tick, 0x10) factor_ := div(mul(factor_, _1E26), 102427189924701091191840928) } // for tick = 8 // ratioX96 = (1.0015^8) * 2^96 = 80183906840906820640659903620 // 80183906840906820640659903620 * 10^26 / 79228162514264337593543950336 = // 101206318935480056907421312.890625 if iszero(lt(factor_, 101206318935480056907421313)) { tick := or(tick, 0x8) factor_ := div(mul(factor_, _1E26), 101206318935480056907421313) } // for tick = 4 // ratioX96 = (1.0015^4) * 2^96 = 79704602139525152702959747603 // 79704602139525152702959747603 * 10^26 / 79228162514264337593543950336 = // 100601351350506250000000000 if iszero(lt(factor_, 100601351350506250000000000)) { tick := or(tick, 0x4) factor_ := div(mul(factor_, _1E26), 100601351350506250000000000) } // for tick = 2 // ratioX96 = (1.0015^2) * 2^96 = 79466025265172787701084167660 // 79466025265172787701084167660 * 10^26 / 79228162514264337593543950336 = // 100300225000000000000000000 if iszero(lt(factor_, 100300225000000000000000000)) { tick := or(tick, 0x2) factor_ := div(mul(factor_, _1E26), 100300225000000000000000000) } // for tick = 1 // ratioX96 = (1.0015^1) * 2^96 = 79347004758035734099934266261 // 79347004758035734099934266261 * 10^26 / 79228162514264337593543950336 = // 100150000000000000000000000 if iszero(lt(factor_, 100150000000000000000000000)) { tick := or(tick, 0x1) factor_ := div(mul(factor_, _1E26), 100150000000000000000000000) } if iszero(cond) { // if ratioX96 >= ZERO_TICK_SCALED_RATIO perfectRatioX96 := div(mul(ratioX96, _1E26), factor_) } if cond { // ratioX96 < ZERO_TICK_SCALED_RATIO tick := not(tick) perfectRatioX96 := div(mul(ratioX96, factor_), 100150000000000000000000000) } // perfect ratio should always be <= ratioX96 // not sure if it can ever be bigger but better to have extra checks if gt(perfectRatioX96, ratioX96) { revert(0, 0) } } } }
// 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 { 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; import { Structs } from "./structs.sol"; interface IFluidVaultResolver { function vaultByNftId(uint nftId_) external view returns (address vault_); function positionByNftId( uint nftId_ ) external view returns (Structs.UserPosition memory userPosition_, Structs.VaultEntireData memory vaultData_); function getVaultVariablesRaw(address vault_) external view returns (uint); function getVaultVariables2Raw(address vault_) external view returns (uint); function getTickHasDebtRaw(address vault_, int key_) external view returns (uint); function getTickDataRaw(address vault_, int tick_) external view returns (uint); function getBranchDataRaw(address vault_, uint branch_) external view returns (uint); function getPositionDataRaw(address vault_, uint positionId_) external view returns (uint); function getAllVaultsAddresses() external view returns (address[] memory vaults_); function getVaultLiquidation( address vault_, uint tokenInAmt_ ) external returns (Structs.LiquidationStruct memory liquidationData_); function getVaultEntireData(address vault_) external view returns (Structs.VaultEntireData memory vaultData_); }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.21; import { IFluidVault } from "../../../protocols/vault/interfaces/iVault.sol"; import { Structs as FluidLiquidityResolverStructs } from "../liquidity/structs.sol"; // @dev Amounts are always in token amount for normal col / normal debt or in // shares for Dex smart col / smart debt. contract Structs { struct Configs { // can be supplyRate instead if Vault Type is smart col. in that case if 1st bit == 1 then positive else negative uint16 supplyRateMagnifier; // can be borrowRate instead if Vault Type is smart debt. in that case if 1st bit == 1 then positive else negative uint16 borrowRateMagnifier; uint16 collateralFactor; uint16 liquidationThreshold; uint16 liquidationMaxLimit; uint16 withdrawalGap; uint16 liquidationPenalty; uint16 borrowFee; address oracle; // Oracle price is always debt per col, i.e. amount of debt for 1 col. // In case of Dex this price can be used to resolve shares values w.r.t. token0 or token1: // - T2: debt token per 1 col share // - T3: debt shares per 1 col token // - T4: debt shares per 1 col share uint oraclePriceOperate; uint oraclePriceLiquidate; address rebalancer; uint lastUpdateTimestamp; } struct ExchangePricesAndRates { uint lastStoredLiquiditySupplyExchangePrice; // 0 in case of smart col uint lastStoredLiquidityBorrowExchangePrice; // 0 in case of smart debt uint lastStoredVaultSupplyExchangePrice; uint lastStoredVaultBorrowExchangePrice; uint liquiditySupplyExchangePrice; // set to 1e12 in case of smart col uint liquidityBorrowExchangePrice; // set to 1e12 in case of smart debt uint vaultSupplyExchangePrice; uint vaultBorrowExchangePrice; uint supplyRateLiquidity; // set to 0 in case of smart col. Must get per token through DexEntireData uint borrowRateLiquidity; // set to 0 in case of smart debt. Must get per token through DexEntireData // supplyRateVault or borrowRateVault: // - when normal col / debt: rate at liquidity + diff rewards or fee through magnifier (rewardsOrFeeRate below) // - when smart col / debt: rewards or fee rate at the vault itself. always == rewardsOrFeeRate below. // to get the full rates for vault when smart col / debt, combine with data from DexResolver: // - rateAtLiquidity for token0 or token1 (DexResolver) // - the rewards or fee rate at the vault (VaultResolver) // - the Dex APR (currently off-chain compiled through tracking swap events at the DEX) int supplyRateVault; // can be negative in case of smart col (meaning pay to supply) int borrowRateVault; // can be negative in case of smart debt (meaning get paid to borrow) // rewardsOrFeeRateSupply: rewards or fee rate in percent 1e2 precision (1% = 100, 100% = 10000). // positive rewards, negative fee. // for smart col vaults: supplyRateVault == supplyRateLiquidity. // for normal col vaults: relative percent to supplyRateLiquidity, e.g.: // when rewards: supplyRateLiquidity = 4%, rewardsOrFeeRateSupply = 20%, supplyRateVault = 4.8%. // when fee: supplyRateLiquidity = 4%, rewardsOrFeeRateSupply = -30%, supplyRateVault = 2.8%. int rewardsOrFeeRateSupply; // rewardsOrFeeRateBorrow: rewards or fee rate in percent 1e2 precision (1% = 100, 100% = 10000). // negative rewards, positive fee. // for smart debt vaults: borrowRateVault == borrowRateLiquidity. // for normal debt vaults: relative percent to borrowRateLiquidity, e.g.: // when rewards: borrowRateLiquidity = 4%, rewardsOrFeeRateBorrow = -20%, borrowRateVault = 3.2%. // when fee: borrowRateLiquidity = 4%, rewardsOrFeeRateBorrow = 30%, borrowRateVault = 5.2%. int rewardsOrFeeRateBorrow; } struct TotalSupplyAndBorrow { uint totalSupplyVault; uint totalBorrowVault; uint totalSupplyLiquidityOrDex; uint totalBorrowLiquidityOrDex; uint absorbedSupply; uint absorbedBorrow; } struct LimitsAndAvailability { // in case of DEX: withdrawable / borrowable amount of vault at DEX, BUT there could be that DEX can not withdraw // that much at Liquidity! So for DEX this must be combined with returned data in DexResolver. uint withdrawLimit; uint withdrawableUntilLimit; uint withdrawable; uint borrowLimit; uint borrowableUntilLimit; // borrowable amount until any borrow limit (incl. max utilization limit) uint borrowable; // actual currently borrowable amount (borrow limit - already borrowed) & considering balance, max utilization uint borrowLimitUtilization; // borrow limit for `maxUtilization` config at Liquidity uint minimumBorrowing; } struct CurrentBranchState { uint status; // if 0 then not liquidated, if 1 then liquidated, if 2 then merged, if 3 then closed int minimaTick; uint debtFactor; uint partials; uint debtLiquidity; uint baseBranchId; int baseBranchMinima; } struct VaultState { uint totalPositions; int topTick; uint currentBranch; uint totalBranch; uint totalBorrow; uint totalSupply; CurrentBranchState currentBranchState; } struct VaultEntireData { address vault; bool isSmartCol; // true if col token is a Fluid Dex bool isSmartDebt; // true if debt token is a Fluid Dex IFluidVault.ConstantViews constantVariables; Configs configs; ExchangePricesAndRates exchangePricesAndRates; TotalSupplyAndBorrow totalSupplyAndBorrow; LimitsAndAvailability limitsAndAvailability; VaultState vaultState; // liquidity related data such as supply amount, limits, expansion etc. // Also set for Dex, limits are in shares and same things apply as noted for LimitsAndAvailability above! FluidLiquidityResolverStructs.UserSupplyData liquidityUserSupplyData; // liquidity related data such as borrow amount, limits, expansion etc. // Also set for Dex, limits are in shares and same things apply as noted for LimitsAndAvailability above! FluidLiquidityResolverStructs.UserBorrowData liquidityUserBorrowData; } struct UserPosition { uint nftId; address owner; bool isLiquidated; bool isSupplyPosition; // if true that means borrowing is 0 int tick; uint tickId; uint beforeSupply; uint beforeBorrow; uint beforeDustBorrow; uint supply; uint borrow; uint dustBorrow; } /// @dev liquidation related data /// @param vault address of vault /// @param token0In address of token in /// @param token0Out address of token out /// @param token1In address of token in (if smart debt) /// @param token1Out address of token out (if smart col) /// @param inAmt (without absorb liquidity) minimum of available liquidation /// @param outAmt (without absorb liquidity) expected token out, collateral to withdraw /// @param inAmtWithAbsorb (absorb liquidity included) minimum of available liquidation. In most cases it'll be same as inAmt but sometimes can be bigger. /// @param outAmtWithAbsorb (absorb liquidity included) expected token out, collateral to withdraw. In most cases it'll be same as outAmt but sometimes can be bigger. /// @param absorbAvailable true if absorb is available /// @dev Liquidity in with absirb will always be >= without asborb. Sometimes without asborb can provide better swaps, /// sometimes with absirb can provide better swaps. But available in with absirb will always be >= One struct LiquidationStruct { address vault; address token0In; address token0Out; address token1In; address token1Out; // amounts in case of smart debt are in shares, otherwise token amounts. // smart col can not be liquidated so to exchange inAmt always use DexResolver DexState.tokenPerDebtShare // and tokenPerColShare for outAmt when Vault is smart col. uint inAmt; uint outAmt; uint inAmtWithAbsorb; uint outAmtWithAbsorb; bool absorbAvailable; } struct AbsorbStruct { address vault; bool absorbAvailable; } }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.21; contract Structs { struct TickDebt { uint256 debtRaw; uint256 collateralRaw; uint256 debtNormal; // debtRaw * exchange price uint256 collateralNormal; // collateralRaw * exchange price uint256 ratio; int256 tick; } struct VaultsTickDebt { TickDebt[] tickDebt; int toTick; } struct BranchDebt { uint256 debtRaw; uint256 collateralRaw; uint256 debtNormal; // debtRaw * exchange price uint256 collateralNormal; // collateralRaw * exchange price uint256 branchId; uint256 status; // if 0 then not liquidated, if 1 then liquidated, if 2 then merged, if 3 then closed int256 tick; uint256 partials; uint256 ratio; uint debtFactor; // debt factor or connection factor uint baseBranchId; int baseBranchTick; } struct BranchesDebt { BranchDebt[] branchDebt; } }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.21; import { IFluidVaultResolver } from "../vault/iVaultResolver.sol"; contract Variables { IFluidVaultResolver public immutable VAULT_RESOLVER; uint internal constant X8 = 0xff; uint internal constant X19 = 0x7ffff; uint internal constant X20 = 0xfffff; uint internal constant X30 = 0x3fffffff; uint internal constant X50 = 0x3ffffffffffff; uint internal constant X64 = 0xffffffffffffffff; constructor(IFluidVaultResolver vaultResolver_) { VAULT_RESOLVER = vaultResolver_; } }
//SPDX-License-Identifier: MIT pragma solidity 0.8.21; /// @notice common Fluid vaults interface, some methods only available for vaults > T1 (type, simulateLiquidate, rebalance is different) interface IFluidVault { /// @notice returns the vault id function VAULT_ID() external view returns (uint256); /// @notice returns the vault id function TYPE() 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 Tokens { address token0; address token1; } struct ConstantViews { address liquidity; address factory; address operateImplementation; address adminImplementation; address secondaryImplementation; address deployer; // address which deploys oracle address supply; // either liquidity layer or DEX protocol address borrow; // either liquidity layer or DEX protocol Tokens supplyToken; // if smart collateral then address of token0 & token1 else just supply token address at token0 and token1 as empty Tokens borrowToken; // if smart debt then address of token0 & token1 else just borrow token address at token0 and token1 as empty uint256 vaultId; uint256 vaultType; bytes32 supplyExchangePriceSlot; // if smart collateral then slot is from DEX protocol else from liquidity layer bytes32 borrowExchangePriceSlot; // if smart debt then slot is from DEX protocol else from liquidity layer bytes32 userSupplySlot; // if smart collateral then slot is from DEX protocol else from liquidity layer bytes32 userBorrowSlot; // if smart debt then slot is from DEX protocol else from liquidity layer } /// @notice returns all Vault constants function constantsView() external view returns (ConstantViews memory constantsView_); /// @notice fetches the latest user position after a liquidation function fetchLatestPosition( int256 positionTick_, uint256 positionTickId_, uint256 positionRawDebt_, uint256 tickData_ ) external view returns ( int256, // tick uint256, // raw debt uint256, // raw collateral uint256, // branchID_ uint256 // branchData_ ); /// @notice calculates the updated vault exchange prices function updateExchangePrices( uint256 vaultVariables2_ ) external view returns ( uint256 liqSupplyExPrice_, uint256 liqBorrowExPrice_, uint256 vaultSupplyExPrice_, uint256 vaultBorrowExPrice_ ); /// @notice calculates the updated vault exchange prices and writes them to storage function updateExchangePricesOnStorage() external returns ( uint256 liqSupplyExPrice_, uint256 liqBorrowExPrice_, uint256 vaultSupplyExPrice_, uint256 vaultBorrowExPrice_ ); /// @notice returns the liquidity contract address function LIQUIDITY() external view returns (address); error FluidLiquidateResult(uint256 colLiquidated, uint256 debtLiquidated); function rebalance( int colToken0MinMax_, int colToken1MinMax_, int debtToken0MinMax_, int debtToken1MinMax_ ) external payable returns (int supplyAmt_, int borrowAmt_); /// @notice reverts with FluidLiquidateResult function simulateLiquidate(uint debtAmt_, bool absorb_) external; }
{ "optimizer": { "enabled": true, "runs": 10000000 }, "evmVersion": "paris", "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "metadata": { "useLiteralContent": true }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"contract IFluidVaultResolver","name":"vaultResolver_","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"FluidVaultTicksBranchesResolver__AddressZero","type":"error"},{"inputs":[],"name":"VAULT_RESOLVER","outputs":[{"internalType":"contract IFluidVaultResolver","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getAllVaultsBranchesDebt","outputs":[{"components":[{"components":[{"internalType":"uint256","name":"debtRaw","type":"uint256"},{"internalType":"uint256","name":"collateralRaw","type":"uint256"},{"internalType":"uint256","name":"debtNormal","type":"uint256"},{"internalType":"uint256","name":"collateralNormal","type":"uint256"},{"internalType":"uint256","name":"branchId","type":"uint256"},{"internalType":"uint256","name":"status","type":"uint256"},{"internalType":"int256","name":"tick","type":"int256"},{"internalType":"uint256","name":"partials","type":"uint256"},{"internalType":"uint256","name":"ratio","type":"uint256"},{"internalType":"uint256","name":"debtFactor","type":"uint256"},{"internalType":"uint256","name":"baseBranchId","type":"uint256"},{"internalType":"int256","name":"baseBranchTick","type":"int256"}],"internalType":"struct Structs.BranchDebt[]","name":"branchDebt","type":"tuple[]"}],"internalType":"struct Structs.BranchesDebt[]","name":"branchesDebt_","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"totalTicks_","type":"uint256"}],"name":"getAllVaultsTicksDebt","outputs":[{"components":[{"components":[{"internalType":"uint256","name":"debtRaw","type":"uint256"},{"internalType":"uint256","name":"collateralRaw","type":"uint256"},{"internalType":"uint256","name":"debtNormal","type":"uint256"},{"internalType":"uint256","name":"collateralNormal","type":"uint256"},{"internalType":"uint256","name":"ratio","type":"uint256"},{"internalType":"int256","name":"tick","type":"int256"}],"internalType":"struct Structs.TickDebt[]","name":"tickDebt","type":"tuple[]"},{"internalType":"int256","name":"toTick","type":"int256"}],"internalType":"struct Structs.VaultsTickDebt[]","name":"vaultsTickDebt_","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"vault_","type":"address"},{"internalType":"uint256","name":"fromBranchId_","type":"uint256"},{"internalType":"uint256","name":"toBranchId_","type":"uint256"}],"name":"getBranchesDebt","outputs":[{"components":[{"internalType":"uint256","name":"debtRaw","type":"uint256"},{"internalType":"uint256","name":"collateralRaw","type":"uint256"},{"internalType":"uint256","name":"debtNormal","type":"uint256"},{"internalType":"uint256","name":"collateralNormal","type":"uint256"},{"internalType":"uint256","name":"branchId","type":"uint256"},{"internalType":"uint256","name":"status","type":"uint256"},{"internalType":"int256","name":"tick","type":"int256"},{"internalType":"uint256","name":"partials","type":"uint256"},{"internalType":"uint256","name":"ratio","type":"uint256"},{"internalType":"uint256","name":"debtFactor","type":"uint256"},{"internalType":"uint256","name":"baseBranchId","type":"uint256"},{"internalType":"int256","name":"baseBranchTick","type":"int256"}],"internalType":"struct Structs.BranchDebt[]","name":"branchesDebt_","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"vaults_","type":"address[]"},{"internalType":"uint256[]","name":"fromBranchIds_","type":"uint256[]"},{"internalType":"uint256[]","name":"toBranchIds_","type":"uint256[]"}],"name":"getMultipleVaultsBranchesDebt","outputs":[{"components":[{"components":[{"internalType":"uint256","name":"debtRaw","type":"uint256"},{"internalType":"uint256","name":"collateralRaw","type":"uint256"},{"internalType":"uint256","name":"debtNormal","type":"uint256"},{"internalType":"uint256","name":"collateralNormal","type":"uint256"},{"internalType":"uint256","name":"branchId","type":"uint256"},{"internalType":"uint256","name":"status","type":"uint256"},{"internalType":"int256","name":"tick","type":"int256"},{"internalType":"uint256","name":"partials","type":"uint256"},{"internalType":"uint256","name":"ratio","type":"uint256"},{"internalType":"uint256","name":"debtFactor","type":"uint256"},{"internalType":"uint256","name":"baseBranchId","type":"uint256"},{"internalType":"int256","name":"baseBranchTick","type":"int256"}],"internalType":"struct Structs.BranchDebt[]","name":"branchDebt","type":"tuple[]"}],"internalType":"struct Structs.BranchesDebt[]","name":"branchesDebt_","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"vaults_","type":"address[]"},{"internalType":"int256[]","name":"fromTicks_","type":"int256[]"},{"internalType":"uint256[]","name":"totalTicks_","type":"uint256[]"}],"name":"getMultipleVaultsTicksDebt","outputs":[{"components":[{"components":[{"internalType":"uint256","name":"debtRaw","type":"uint256"},{"internalType":"uint256","name":"collateralRaw","type":"uint256"},{"internalType":"uint256","name":"debtNormal","type":"uint256"},{"internalType":"uint256","name":"collateralNormal","type":"uint256"},{"internalType":"uint256","name":"ratio","type":"uint256"},{"internalType":"int256","name":"tick","type":"int256"}],"internalType":"struct Structs.TickDebt[]","name":"tickDebt","type":"tuple[]"},{"internalType":"int256","name":"toTick","type":"int256"}],"internalType":"struct Structs.VaultsTickDebt[]","name":"vaultsTickDebt_","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"vault_","type":"address"},{"internalType":"int256","name":"fromTick_","type":"int256"},{"internalType":"uint256","name":"totalTicks_","type":"uint256"}],"name":"getTicksDebt","outputs":[{"components":[{"internalType":"uint256","name":"debtRaw","type":"uint256"},{"internalType":"uint256","name":"collateralRaw","type":"uint256"},{"internalType":"uint256","name":"debtNormal","type":"uint256"},{"internalType":"uint256","name":"collateralNormal","type":"uint256"},{"internalType":"uint256","name":"ratio","type":"uint256"},{"internalType":"int256","name":"tick","type":"int256"}],"internalType":"struct Structs.TickDebt[]","name":"ticksDebt_","type":"tuple[]"},{"internalType":"int256","name":"toTick_","type":"int256"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
60a06040523480156200001157600080fd5b50604051620027d0380380620027d0833981016040819052620000349162000068565b6001600160a01b038116608081905262000061576040516365b1d2ef60e11b815260040160405180910390fd5b506200009a565b6000602082840312156200007b57600080fd5b81516001600160a01b03811681146200009357600080fd5b9392505050565b6080516126ce620001026000396000818160e40152818161029d015281816104b6015281816105f5015281816107160152818161094501528181610b9b01528181610ef8015281816110c90152818161127f015281816113b401526119bc01526126ce6000f3fe608060405234801561001057600080fd5b506004361061007d5760003560e01c80637f3e2b481161005b5780637f3e2b48146100df578063a12a377a1461012b578063d17ac4a81461014b578063f2c8e5421461016b57600080fd5b80633009c6ba146100825780636791522f146100ab5780637cec0866146100be575b600080fd5b610095610090366004611ea9565b610173565b6040516100a29190611f85565b60405180910390f35b6100956100b936600461207b565b610297565b6100d16100cc366004612094565b61045d565b6040516100a29291906120c9565b6101067f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100a2565b61013e610139366004612147565b610808565b6040516100a29190612268565b61015e610159366004612094565b6108fa565b6040516100a291906122f0565b61013e610b95565b82516060908067ffffffffffffffff81111561019157610191611d13565b6040519080825280602002602001820160405280156101d757816020015b6040805180820190915260608152600060208201528152602001906001900390816101af5790505b50915060005b8181101561028e5761023b8682815181106101fa576101fa612303565b602002602001015186838151811061021457610214612303565b602002602001015186848151811061022e5761022e612303565b602002602001015161045d565b84838151811061024d5761024d612303565b602002602001015160000185848151811061026a5761026a612303565b6020908102919091018101510191909152528061028681612361565b9150506101dd565b50509392505050565b606060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663a8d9f4936040518163ffffffff1660e01b8152600401600060405180830381865afa158015610306573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405261034c9190810190612399565b80519091508067ffffffffffffffff81111561036a5761036a611d13565b6040519080825280602002602001820160405280156103b057816020015b6040805180820190915260608152600060208201528152602001906001900390816103885790505b50925060005b81811015610455576104028382815181106103d3576103d3612303565b60200260200101517f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8761045d565b85838151811061041457610414612303565b602002602001015160000186848151811061043157610431612303565b6020908102919091018101510191909152528061044d81612361565b9150506103b6565b505050919050565b6040517f03e883e000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8481166004830152606091600091829161052991620fffff916002917f000000000000000000000000000000000000000000000000000000000000000016906303e883e090602401602060405180830381865afa1580156104fd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105219190612428565b901c16610d31565b9050848112610538578461053a565b805b94507f80000000000000000000000000000000000000000000000000000000000000008513156107ff57600080861261057e5761057961010087612470565b6105a1565b600161010061058d88836124d8565b6105979190612470565b6105a19190612500565b6040517fa8bc069300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff89811660048301526024820183905291925060009182917f00000000000000000000000000000000000000000000000000000000000000009091169063a8bc069390604401602060405180830381865afa15801561063e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106629190612428565b9050600061067284610100612527565b61067d9060ff6124d8565b6106868a612573565b61069091906124d8565b91821b90911c91506106a490508688612500565b6106af9060016124d8565b935060006106bf89868585610dff565b6040517feb1db01800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff808c1660048301819052929350600092839290916309f0d8cb917f00000000000000000000000000000000000000000000000000000000000000009091169063eb1db01890602401602060405180830381865afa15801561075f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107839190612428565b6040518263ffffffff1660e01b81526004016107a191815260200190565b608060405180830381865afa1580156107be573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107e291906125ab565b9350935050506107f78b888787878787610f75565b975050505050505b50935093915050565b82516060908067ffffffffffffffff81111561082657610826611d13565b60405190808252806020026020018201604052801561086657816020015b6040805160208101909152606081528152602001906001900390816108445790505b50915060005b8181101561028e576108ca86828151811061088957610889612303565b60200260200101518683815181106108a3576108a3612303565b60200260200101518684815181106108bd576108bd612303565b60200260200101516108fa565b8382815181106108dc576108dc612303565b602090810291909101015152806108f281612361565b91505061086c565b6040517f03e883e000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff84811660048301526060916000917f000000000000000000000000000000000000000000000000000000000000000016906303e883e090602401602060405180830381865afa15801561098c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109b09190612428565b9050603481901c633fffffff1683156109c957836109cc565b60015b93508481106109db57846109dd565b805b945083851015610a74576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f66726f6d4272616e636849645f206d757374206265206772656174657220746860448201527f616e206f7220657175616c20746f20746f4272616e636849645f00000000000060648201526084015b60405180910390fd5b610a7e84866125e1565b610a899060016125f4565b67ffffffffffffffff811115610aa157610aa1611d13565b604051908082528060200260200182016040528015610b3657816020015b610b236040518061018001604052806000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b815260200190600190039081610abf5790505b5092506000855b858110610b8a57610b4f888583611301565b8583610b5a81612361565b945081518110610b6c57610b6c612303565b60200260200101819052508080610b8290612607565b915050610b3d565b505050509392505050565b606060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663a8d9f4936040518163ffffffff1660e01b8152600401600060405180830381865afa158015610c04573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052610c4a9190810190612399565b80519091508067ffffffffffffffff811115610c6857610c68611d13565b604051908082528060200260200182016040528015610ca857816020015b604080516020810190915260608152815260200190600190039081610c865790505b50925060005b81811015610d2b57610cfb838281518110610ccb57610ccb612303565b60200260200101517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60006108fa565b848281518110610d0d57610d0d612303565b60209081029190910101515280610d2381612361565b915050610cae565b50505090565b6000620fffff8210610d9f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f696e76616c69642d6e756d6265720000000000000000000000000000000000006044820152606401610a6b565b8115610dd85781600116600114610dc757610dc2600183901c6207ffff16612573565b610dd2565b6207ffff600183901c165b92915050565b507f8000000000000000000000000000000000000000000000000000000000000000919050565b60008060005b8315610e7a57610e1484611483565b9150610e22826101016125e1565b610e2e836101016125e1565b9490941b90931c92610e416001836125e1565b610e4d86610100612527565b610e5791906124d8565b905085811215610e68575050610f6d565b82610e7281612361565b935050610e05565b610e838561263c565b94507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f8514610f6a576040517fa8bc069300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8881166004830152602482018790527f0000000000000000000000000000000000000000000000000000000000000000169063a8bc069390604401602060405180830381865afa158015610f3f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f639190612428565b9350610e05565b50505b949350505050565b60608367ffffffffffffffff811115610f9057610f90611d13565b604051908082528060200260200182016040528015610ffa57816020015b610fe76040518060c001604052806000815260200160008152602001600081526020016000815260200160008152602001600081525090565b815260200190600190039081610fae5790505b509050600093506000806000805b88156112015760006110198a611483565b9050611027816101016125e1565b611033826101016125e1565b9a909a1b90991c986110466001826125e1565b6110528c610100612527565b61105c91906124d8565b9450508a84121561107057505050506112f6565b6040517f168a11c200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8d811660048301526024820186905267ffffffffffffffff916019917f0000000000000000000000000000000000000000000000000000000000000000169063168a11c290604401602060405180830381865afa158015611110573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111349190612428565b901c16600881901c60ff9091161b925061114d84611539565b915081611167846c0100000000000000000000000061266d565b6111719190612684565b90506040518060c0016040528084815260200182815260200164e8d4a51000888661119c919061266d565b6111a69190612684565b815260200164e8d4a510006111bb8a8561266d565b6111c59190612684565b81526020810184905260400185905285896111df81612361565b9a50815181106111f1576111f1612303565b6020026020010181905250611008565b61120a8a61263c565b99507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f8a146112f1576040517fa8bc069300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8d81166004830152602482018c90527f0000000000000000000000000000000000000000000000000000000000000000169063a8bc069390604401602060405180830381865afa1580156112c6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112ea9190612428565b9850611008565b505050505b979650505050505050565b6113656040518061018001604052806000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b6040517fbf518f5f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8581166004830152602482018490526000917f00000000000000000000000000000000000000000000000000000000000000009091169063bf518f5f90604401602060405180830381865afa1580156113fd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114219190612428565b90506000611437620fffff600284901c16610d31565b905060038216600081900361145c576114528684878461179b565b935050505061147c565b806001036114715761145287848784866118d9565b611452838683611b49565b9392505050565b6000816fffffffffffffffffffffffffffffffff8311156114a55760809150811c5b67ffffffffffffffff8111156114bd576040918201911c5b63ffffffff8111156114d1576020918201911c5b61ffff8111156114e3576010918201911c5b60ff8111156114f4576008918201911c5b600f811115611505576004918201911c5b6003811115611516576002918201911c5b6001811115611526576001820191505b8015611533576001820191505b50919050565b600060ff82901d80831803617fff81111561155357600080fd5b700100000000000000000000000000000000600182161561158157506fff9dd7de423466c20352b1246ce4856f5b60028216156115a0576fff3bd55f4488ad277531fa1c725a66d00260801c5b60048216156115bf576ffe78410fd6498b73cb96a6917f8532590260801c5b60088216156115de576ffcf2d9987c9be178ad5bfeffaa1232730260801c5b60108216156115fd576ff9ef02c4529258b057769680fc6601b30260801c5b602082161561161c576ff402d288133a85a17784a411f7aba0820260801c5b604082161561163b576fe895615b5beb6386553757b0352bda900260801c5b608082161561165a576fd34f17a00ffa00a8309940a15930391a0260801c5b61010082161561167a576fae6b7961714e20548d88ea5123f9a0ff0260801c5b61020082161561169a576f76d6461f27082d74e0feed3b388c0ca10260801c5b6104008216156116ba576f372a3bfe0745d8b6b19d985d9a8b85bb0260801c5b6108008216156116da576f0be32cbee48979763cf7247dd7bb539d0260801c5b6110008216156116f9576e8d4f70c9ff4924dac37612d1e2921e0260801c5b612000821615611717576d4e009ae5519380809a02ca7aec770260801c5b614000821615611733576b17c45e641b6e95dee056ff100260801c5b600091507f80000000000000000000000000000000000000000000000000000000000000008416611791577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0463ffffffff81161561179157600191505b60201c0192915050565b6117ff6040518061018001604052806000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b6000611813620fffff600288901c16610d31565b905060007f8000000000000000000000000000000000000000000000000000000000000000821361184557600061184e565b61184e82611539565b905060405180610180016040528060008152602001600081526020016000815260200160008152602001868152602001858152602001838152602001600081526020018281526020016603ffffffffffff607489901c168152602001633fffffff60a689901c1681526020016118cc620fffff60c48a901c16610d31565b9052979650505050505050565b61193d6040518061018001604052806000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b603c85901c66ffffffffffffff16603486901c60ff161b600080611962888487611c77565b6040517feb1db01800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff808d1660048301819052939550919350600092839290916309f0d8cb917f0000000000000000000000000000000000000000000000000000000000000000169063eb1db01890602401602060405180830381865afa158015611a03573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a279190612428565b6040518263ffffffff1660e01b8152600401611a4591815260200190565b608060405180830381865afa158015611a62573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a8691906125ab565b93509350505060405180610180016040528086815260200185815260200164e8d4a510008388611ab6919061266d565b611ac09190612684565b815260200164e8d4a51000611ad5858861266d565b611adf9190612684565b81526020018a8152602001898152602001888152602001600081526020018481526020016603ffffffffffff60748d901c168152602001633fffffff60a68d901c168152602001611b38620fffff60c48e901c16610d31565b90529b9a5050505050505050505050565b611bad6040518061018001604052806000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b6000611bc1620fffff60c487901c16610d31565b905060007f80000000000000000000000000000000000000000000000000000000000000008213611bf3576000611bfc565b611bfc82611539565b905060405180610180016040528060008152602001600081526020016000815260200160008152602001868152602001858152602001838152602001600081526020018281526020016603ffffffffffff607489901c168152602001633fffffff60a689901c16815260200183815250925050509392505050565b600080611c868360020b611539565b9050600061271f611c998361271061266d565b611ca39190612684565b90506000611cb182846125e1565b9050633fffffff601688901c811690600090611ccd838561266d565b611cd79190612684565b611ce190856125f4565b905080611cfb6c010000000000000000000000008a61266d565b611d059190612684565b955050505050935093915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715611d8957611d89611d13565b604052919050565b600067ffffffffffffffff821115611dab57611dab611d13565b5060051b60200190565b73ffffffffffffffffffffffffffffffffffffffff81168114611dd757600080fd5b50565b600082601f830112611deb57600080fd5b81356020611e00611dfb83611d91565b611d42565b82815260059290921b84018101918181019086841115611e1f57600080fd5b8286015b84811015611e43578035611e3681611db5565b8352918301918301611e23565b509695505050505050565b600082601f830112611e5f57600080fd5b81356020611e6f611dfb83611d91565b82815260059290921b84018101918181019086841115611e8e57600080fd5b8286015b84811015611e435780358352918301918301611e92565b600080600060608486031215611ebe57600080fd5b833567ffffffffffffffff80821115611ed657600080fd5b611ee287838801611dda565b9450602091508186013581811115611ef957600080fd5b8601601f81018813611f0a57600080fd5b8035611f18611dfb82611d91565b81815260059190911b8201840190848101908a831115611f3757600080fd5b928501925b82841015611f5557833582529285019290850190611f3c565b96505050506040860135915080821115611f6e57600080fd5b50611f7b86828701611e4e565b9150509250925092565b60006020808301818452808551808352604092508286019150828160051b8701018488016000805b8481101561206c578984037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0018652825180518886528051898701819052908a0190849060608801905b8083101561204d578351805183526020808201519084015260408082015190840152606080820151908401526080808201519084015260a0908101519083015260c0820191508c84019350600183019250611ff7565b50928b0151968b01969096525095880195935091870191600101611fad565b50919998505050505050505050565b60006020828403121561208d57600080fd5b5035919050565b6000806000606084860312156120a957600080fd5b83356120b481611db5565b95602085013595506040909401359392505050565b604080825283519082018190526000906020906060840190828701845b82811015612138578151805185526020808201519086015260408082015190860152606080820151908601526080808201519086015260a0908101519085015260c084019350908401906001016120e6565b50505092019290925292915050565b60008060006060848603121561215c57600080fd5b833567ffffffffffffffff8082111561217457600080fd5b61218087838801611dda565b9450602086013591508082111561219657600080fd5b6121a287838801611e4e565b93506040860135915080821115611f6e57600080fd5b600081518084526020808501945080840160005b8381101561225d57815180518852838101518489015260408082015190890152606080820151908901526080808201519089015260a0808201519089015260c0808201519089015260e08082015190890152610100808201519089015261012080820151908901526101408082015190890152610160908101519088015261018090960195908201906001016121cc565b509495945050505050565b6000602080830181845280855180835260408601915060408160051b870101925083870160005b828110156122e3577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08886030184528151518686526122d0878701826121b8565b955050928501929085019060010161228f565b5092979650505050505050565b60208152600061147c60208301846121b8565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361239257612392612332565b5060010190565b600060208083850312156123ac57600080fd5b825167ffffffffffffffff8111156123c357600080fd5b8301601f810185136123d457600080fd5b80516123e2611dfb82611d91565b81815260059190911b8201830190838101908783111561240157600080fd5b928401925b828410156112f657835161241981611db5565b82529284019290840190612406565b60006020828403121561243a57600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60008261247f5761247f612441565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83147f8000000000000000000000000000000000000000000000000000000000000000831416156124d3576124d3612332565b500590565b80820182811260008312801582168215821617156124f8576124f8612332565b505092915050565b818103600083128015838313168383128216171561252057612520612332565b5092915050565b808202600082127f80000000000000000000000000000000000000000000000000000000000000008414161561255f5761255f612332565b8181058314821517610dd257610dd2612332565b60007f800000000000000000000000000000000000000000000000000000000000000082036125a4576125a4612332565b5060000390565b600080600080608085870312156125c157600080fd5b505082516020840151604085015160609095015191969095509092509050565b81810381811115610dd257610dd2612332565b80820180821115610dd257610dd2612332565b60008161261657612616612332565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b60007f8000000000000000000000000000000000000000000000000000000000000000820361261657612616612332565b8082028115828204841417610dd257610dd2612332565b60008261269357612693612441565b50049056fea26469706673582212208701324d348fcb8b848363e1d0ed7d2920058c437e7fe09f90f34c3262e5b2fc64736f6c63430008150033000000000000000000000000d6c90a7b61f3e0ac04e2f4b0359ab0ac09035507
Deployed Bytecode
0x608060405234801561001057600080fd5b506004361061007d5760003560e01c80637f3e2b481161005b5780637f3e2b48146100df578063a12a377a1461012b578063d17ac4a81461014b578063f2c8e5421461016b57600080fd5b80633009c6ba146100825780636791522f146100ab5780637cec0866146100be575b600080fd5b610095610090366004611ea9565b610173565b6040516100a29190611f85565b60405180910390f35b6100956100b936600461207b565b610297565b6100d16100cc366004612094565b61045d565b6040516100a29291906120c9565b6101067f000000000000000000000000d6c90a7b61f3e0ac04e2f4b0359ab0ac0903550781565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100a2565b61013e610139366004612147565b610808565b6040516100a29190612268565b61015e610159366004612094565b6108fa565b6040516100a291906122f0565b61013e610b95565b82516060908067ffffffffffffffff81111561019157610191611d13565b6040519080825280602002602001820160405280156101d757816020015b6040805180820190915260608152600060208201528152602001906001900390816101af5790505b50915060005b8181101561028e5761023b8682815181106101fa576101fa612303565b602002602001015186838151811061021457610214612303565b602002602001015186848151811061022e5761022e612303565b602002602001015161045d565b84838151811061024d5761024d612303565b602002602001015160000185848151811061026a5761026a612303565b6020908102919091018101510191909152528061028681612361565b9150506101dd565b50509392505050565b606060007f000000000000000000000000d6c90a7b61f3e0ac04e2f4b0359ab0ac0903550773ffffffffffffffffffffffffffffffffffffffff1663a8d9f4936040518163ffffffff1660e01b8152600401600060405180830381865afa158015610306573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405261034c9190810190612399565b80519091508067ffffffffffffffff81111561036a5761036a611d13565b6040519080825280602002602001820160405280156103b057816020015b6040805180820190915260608152600060208201528152602001906001900390816103885790505b50925060005b81811015610455576104028382815181106103d3576103d3612303565b60200260200101517f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8761045d565b85838151811061041457610414612303565b602002602001015160000186848151811061043157610431612303565b6020908102919091018101510191909152528061044d81612361565b9150506103b6565b505050919050565b6040517f03e883e000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8481166004830152606091600091829161052991620fffff916002917f000000000000000000000000d6c90a7b61f3e0ac04e2f4b0359ab0ac0903550716906303e883e090602401602060405180830381865afa1580156104fd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105219190612428565b901c16610d31565b9050848112610538578461053a565b805b94507f80000000000000000000000000000000000000000000000000000000000000008513156107ff57600080861261057e5761057961010087612470565b6105a1565b600161010061058d88836124d8565b6105979190612470565b6105a19190612500565b6040517fa8bc069300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff89811660048301526024820183905291925060009182917f000000000000000000000000d6c90a7b61f3e0ac04e2f4b0359ab0ac090355079091169063a8bc069390604401602060405180830381865afa15801561063e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106629190612428565b9050600061067284610100612527565b61067d9060ff6124d8565b6106868a612573565b61069091906124d8565b91821b90911c91506106a490508688612500565b6106af9060016124d8565b935060006106bf89868585610dff565b6040517feb1db01800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff808c1660048301819052929350600092839290916309f0d8cb917f000000000000000000000000d6c90a7b61f3e0ac04e2f4b0359ab0ac090355079091169063eb1db01890602401602060405180830381865afa15801561075f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107839190612428565b6040518263ffffffff1660e01b81526004016107a191815260200190565b608060405180830381865afa1580156107be573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107e291906125ab565b9350935050506107f78b888787878787610f75565b975050505050505b50935093915050565b82516060908067ffffffffffffffff81111561082657610826611d13565b60405190808252806020026020018201604052801561086657816020015b6040805160208101909152606081528152602001906001900390816108445790505b50915060005b8181101561028e576108ca86828151811061088957610889612303565b60200260200101518683815181106108a3576108a3612303565b60200260200101518684815181106108bd576108bd612303565b60200260200101516108fa565b8382815181106108dc576108dc612303565b602090810291909101015152806108f281612361565b91505061086c565b6040517f03e883e000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff84811660048301526060916000917f000000000000000000000000d6c90a7b61f3e0ac04e2f4b0359ab0ac0903550716906303e883e090602401602060405180830381865afa15801561098c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109b09190612428565b9050603481901c633fffffff1683156109c957836109cc565b60015b93508481106109db57846109dd565b805b945083851015610a74576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f66726f6d4272616e636849645f206d757374206265206772656174657220746860448201527f616e206f7220657175616c20746f20746f4272616e636849645f00000000000060648201526084015b60405180910390fd5b610a7e84866125e1565b610a899060016125f4565b67ffffffffffffffff811115610aa157610aa1611d13565b604051908082528060200260200182016040528015610b3657816020015b610b236040518061018001604052806000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b815260200190600190039081610abf5790505b5092506000855b858110610b8a57610b4f888583611301565b8583610b5a81612361565b945081518110610b6c57610b6c612303565b60200260200101819052508080610b8290612607565b915050610b3d565b505050509392505050565b606060007f000000000000000000000000d6c90a7b61f3e0ac04e2f4b0359ab0ac0903550773ffffffffffffffffffffffffffffffffffffffff1663a8d9f4936040518163ffffffff1660e01b8152600401600060405180830381865afa158015610c04573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052610c4a9190810190612399565b80519091508067ffffffffffffffff811115610c6857610c68611d13565b604051908082528060200260200182016040528015610ca857816020015b604080516020810190915260608152815260200190600190039081610c865790505b50925060005b81811015610d2b57610cfb838281518110610ccb57610ccb612303565b60200260200101517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60006108fa565b848281518110610d0d57610d0d612303565b60209081029190910101515280610d2381612361565b915050610cae565b50505090565b6000620fffff8210610d9f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f696e76616c69642d6e756d6265720000000000000000000000000000000000006044820152606401610a6b565b8115610dd85781600116600114610dc757610dc2600183901c6207ffff16612573565b610dd2565b6207ffff600183901c165b92915050565b507f8000000000000000000000000000000000000000000000000000000000000000919050565b60008060005b8315610e7a57610e1484611483565b9150610e22826101016125e1565b610e2e836101016125e1565b9490941b90931c92610e416001836125e1565b610e4d86610100612527565b610e5791906124d8565b905085811215610e68575050610f6d565b82610e7281612361565b935050610e05565b610e838561263c565b94507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f8514610f6a576040517fa8bc069300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8881166004830152602482018790527f000000000000000000000000d6c90a7b61f3e0ac04e2f4b0359ab0ac09035507169063a8bc069390604401602060405180830381865afa158015610f3f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f639190612428565b9350610e05565b50505b949350505050565b60608367ffffffffffffffff811115610f9057610f90611d13565b604051908082528060200260200182016040528015610ffa57816020015b610fe76040518060c001604052806000815260200160008152602001600081526020016000815260200160008152602001600081525090565b815260200190600190039081610fae5790505b509050600093506000806000805b88156112015760006110198a611483565b9050611027816101016125e1565b611033826101016125e1565b9a909a1b90991c986110466001826125e1565b6110528c610100612527565b61105c91906124d8565b9450508a84121561107057505050506112f6565b6040517f168a11c200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8d811660048301526024820186905267ffffffffffffffff916019917f000000000000000000000000d6c90a7b61f3e0ac04e2f4b0359ab0ac09035507169063168a11c290604401602060405180830381865afa158015611110573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111349190612428565b901c16600881901c60ff9091161b925061114d84611539565b915081611167846c0100000000000000000000000061266d565b6111719190612684565b90506040518060c0016040528084815260200182815260200164e8d4a51000888661119c919061266d565b6111a69190612684565b815260200164e8d4a510006111bb8a8561266d565b6111c59190612684565b81526020810184905260400185905285896111df81612361565b9a50815181106111f1576111f1612303565b6020026020010181905250611008565b61120a8a61263c565b99507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f8a146112f1576040517fa8bc069300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8d81166004830152602482018c90527f000000000000000000000000d6c90a7b61f3e0ac04e2f4b0359ab0ac09035507169063a8bc069390604401602060405180830381865afa1580156112c6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112ea9190612428565b9850611008565b505050505b979650505050505050565b6113656040518061018001604052806000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b6040517fbf518f5f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8581166004830152602482018490526000917f000000000000000000000000d6c90a7b61f3e0ac04e2f4b0359ab0ac090355079091169063bf518f5f90604401602060405180830381865afa1580156113fd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114219190612428565b90506000611437620fffff600284901c16610d31565b905060038216600081900361145c576114528684878461179b565b935050505061147c565b806001036114715761145287848784866118d9565b611452838683611b49565b9392505050565b6000816fffffffffffffffffffffffffffffffff8311156114a55760809150811c5b67ffffffffffffffff8111156114bd576040918201911c5b63ffffffff8111156114d1576020918201911c5b61ffff8111156114e3576010918201911c5b60ff8111156114f4576008918201911c5b600f811115611505576004918201911c5b6003811115611516576002918201911c5b6001811115611526576001820191505b8015611533576001820191505b50919050565b600060ff82901d80831803617fff81111561155357600080fd5b700100000000000000000000000000000000600182161561158157506fff9dd7de423466c20352b1246ce4856f5b60028216156115a0576fff3bd55f4488ad277531fa1c725a66d00260801c5b60048216156115bf576ffe78410fd6498b73cb96a6917f8532590260801c5b60088216156115de576ffcf2d9987c9be178ad5bfeffaa1232730260801c5b60108216156115fd576ff9ef02c4529258b057769680fc6601b30260801c5b602082161561161c576ff402d288133a85a17784a411f7aba0820260801c5b604082161561163b576fe895615b5beb6386553757b0352bda900260801c5b608082161561165a576fd34f17a00ffa00a8309940a15930391a0260801c5b61010082161561167a576fae6b7961714e20548d88ea5123f9a0ff0260801c5b61020082161561169a576f76d6461f27082d74e0feed3b388c0ca10260801c5b6104008216156116ba576f372a3bfe0745d8b6b19d985d9a8b85bb0260801c5b6108008216156116da576f0be32cbee48979763cf7247dd7bb539d0260801c5b6110008216156116f9576e8d4f70c9ff4924dac37612d1e2921e0260801c5b612000821615611717576d4e009ae5519380809a02ca7aec770260801c5b614000821615611733576b17c45e641b6e95dee056ff100260801c5b600091507f80000000000000000000000000000000000000000000000000000000000000008416611791577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0463ffffffff81161561179157600191505b60201c0192915050565b6117ff6040518061018001604052806000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b6000611813620fffff600288901c16610d31565b905060007f8000000000000000000000000000000000000000000000000000000000000000821361184557600061184e565b61184e82611539565b905060405180610180016040528060008152602001600081526020016000815260200160008152602001868152602001858152602001838152602001600081526020018281526020016603ffffffffffff607489901c168152602001633fffffff60a689901c1681526020016118cc620fffff60c48a901c16610d31565b9052979650505050505050565b61193d6040518061018001604052806000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b603c85901c66ffffffffffffff16603486901c60ff161b600080611962888487611c77565b6040517feb1db01800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff808d1660048301819052939550919350600092839290916309f0d8cb917f000000000000000000000000d6c90a7b61f3e0ac04e2f4b0359ab0ac09035507169063eb1db01890602401602060405180830381865afa158015611a03573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a279190612428565b6040518263ffffffff1660e01b8152600401611a4591815260200190565b608060405180830381865afa158015611a62573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a8691906125ab565b93509350505060405180610180016040528086815260200185815260200164e8d4a510008388611ab6919061266d565b611ac09190612684565b815260200164e8d4a51000611ad5858861266d565b611adf9190612684565b81526020018a8152602001898152602001888152602001600081526020018481526020016603ffffffffffff60748d901c168152602001633fffffff60a68d901c168152602001611b38620fffff60c48e901c16610d31565b90529b9a5050505050505050505050565b611bad6040518061018001604052806000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b6000611bc1620fffff60c487901c16610d31565b905060007f80000000000000000000000000000000000000000000000000000000000000008213611bf3576000611bfc565b611bfc82611539565b905060405180610180016040528060008152602001600081526020016000815260200160008152602001868152602001858152602001838152602001600081526020018281526020016603ffffffffffff607489901c168152602001633fffffff60a689901c16815260200183815250925050509392505050565b600080611c868360020b611539565b9050600061271f611c998361271061266d565b611ca39190612684565b90506000611cb182846125e1565b9050633fffffff601688901c811690600090611ccd838561266d565b611cd79190612684565b611ce190856125f4565b905080611cfb6c010000000000000000000000008a61266d565b611d059190612684565b955050505050935093915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715611d8957611d89611d13565b604052919050565b600067ffffffffffffffff821115611dab57611dab611d13565b5060051b60200190565b73ffffffffffffffffffffffffffffffffffffffff81168114611dd757600080fd5b50565b600082601f830112611deb57600080fd5b81356020611e00611dfb83611d91565b611d42565b82815260059290921b84018101918181019086841115611e1f57600080fd5b8286015b84811015611e43578035611e3681611db5565b8352918301918301611e23565b509695505050505050565b600082601f830112611e5f57600080fd5b81356020611e6f611dfb83611d91565b82815260059290921b84018101918181019086841115611e8e57600080fd5b8286015b84811015611e435780358352918301918301611e92565b600080600060608486031215611ebe57600080fd5b833567ffffffffffffffff80821115611ed657600080fd5b611ee287838801611dda565b9450602091508186013581811115611ef957600080fd5b8601601f81018813611f0a57600080fd5b8035611f18611dfb82611d91565b81815260059190911b8201840190848101908a831115611f3757600080fd5b928501925b82841015611f5557833582529285019290850190611f3c565b96505050506040860135915080821115611f6e57600080fd5b50611f7b86828701611e4e565b9150509250925092565b60006020808301818452808551808352604092508286019150828160051b8701018488016000805b8481101561206c578984037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0018652825180518886528051898701819052908a0190849060608801905b8083101561204d578351805183526020808201519084015260408082015190840152606080820151908401526080808201519084015260a0908101519083015260c0820191508c84019350600183019250611ff7565b50928b0151968b01969096525095880195935091870191600101611fad565b50919998505050505050505050565b60006020828403121561208d57600080fd5b5035919050565b6000806000606084860312156120a957600080fd5b83356120b481611db5565b95602085013595506040909401359392505050565b604080825283519082018190526000906020906060840190828701845b82811015612138578151805185526020808201519086015260408082015190860152606080820151908601526080808201519086015260a0908101519085015260c084019350908401906001016120e6565b50505092019290925292915050565b60008060006060848603121561215c57600080fd5b833567ffffffffffffffff8082111561217457600080fd5b61218087838801611dda565b9450602086013591508082111561219657600080fd5b6121a287838801611e4e565b93506040860135915080821115611f6e57600080fd5b600081518084526020808501945080840160005b8381101561225d57815180518852838101518489015260408082015190890152606080820151908901526080808201519089015260a0808201519089015260c0808201519089015260e08082015190890152610100808201519089015261012080820151908901526101408082015190890152610160908101519088015261018090960195908201906001016121cc565b509495945050505050565b6000602080830181845280855180835260408601915060408160051b870101925083870160005b828110156122e3577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08886030184528151518686526122d0878701826121b8565b955050928501929085019060010161228f565b5092979650505050505050565b60208152600061147c60208301846121b8565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361239257612392612332565b5060010190565b600060208083850312156123ac57600080fd5b825167ffffffffffffffff8111156123c357600080fd5b8301601f810185136123d457600080fd5b80516123e2611dfb82611d91565b81815260059190911b8201830190838101908783111561240157600080fd5b928401925b828410156112f657835161241981611db5565b82529284019290840190612406565b60006020828403121561243a57600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60008261247f5761247f612441565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83147f8000000000000000000000000000000000000000000000000000000000000000831416156124d3576124d3612332565b500590565b80820182811260008312801582168215821617156124f8576124f8612332565b505092915050565b818103600083128015838313168383128216171561252057612520612332565b5092915050565b808202600082127f80000000000000000000000000000000000000000000000000000000000000008414161561255f5761255f612332565b8181058314821517610dd257610dd2612332565b60007f800000000000000000000000000000000000000000000000000000000000000082036125a4576125a4612332565b5060000390565b600080600080608085870312156125c157600080fd5b505082516020840151604085015160609095015191969095509092509050565b81810381811115610dd257610dd2612332565b80820180821115610dd257610dd2612332565b60008161261657612616612332565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b60007f8000000000000000000000000000000000000000000000000000000000000000820361261657612616612332565b8082028115828204841417610dd257610dd2612332565b60008261269357612693612441565b50049056fea26469706673582212208701324d348fcb8b848363e1d0ed7d2920058c437e7fe09f90f34c3262e5b2fc64736f6c63430008150033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000d6c90a7b61f3e0ac04e2f4b0359ab0ac09035507
-----Decoded View---------------
Arg [0] : vaultResolver_ (address): 0xd6C90A7B61F3e0Ac04e2F4B0359aB0ac09035507
-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 000000000000000000000000d6c90a7b61f3e0ac04e2f4b0359ab0ac09035507
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
[ 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.