{ "address": "0x2Cc710218F2e3a82CcC77Cc4B3B93Ee6Ba9451CD", "abi": [ { "inputs": [ { "internalType": "address", "name": "liquidity_", "type": "address" }, { "internalType": "address", "name": "vaultAdminImplementation_", "type": "address" }, { "internalType": "address", "name": "vaultSecondaryImplementation_", "type": "address" } ], "stateMutability": "nonpayable", "type": "constructor" }, { "inputs": [ { "internalType": "uint256", "name": "colLiquidated", "type": "uint256" }, { "internalType": "uint256", "name": "debtLiquidated", "type": "uint256" } ], "name": "FluidLiquidateResult", "type": "error" }, { "inputs": [ { "internalType": "uint256", "name": "errorId_", "type": "uint256" } ], "name": "FluidVaultError", "type": "error" }, { "anonymous": false, "inputs": [ { "indexed": true, "internalType": "address", "name": "vault", "type": "address" }, { "indexed": false, "internalType": "uint256", "name": "vaultId", "type": "uint256" }, { "indexed": true, "internalType": "address", "name": "supplyToken", "type": "address" }, { "indexed": true, "internalType": "address", "name": "borrowToken", "type": "address" } ], "name": "VaultT1Deployed", "type": "event" }, { "inputs": [], "name": "ADDRESS_THIS", "outputs": [ { "internalType": "address", "name": "", "type": "address" } ], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "ADMIN_IMPLEMENTATION", "outputs": [ { "internalType": "address", "name": "", "type": "address" } ], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "LIQUIDITY", "outputs": [ { "internalType": "address", "name": "", "type": "address" } ], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "SECONDARY_IMPLEMENTATION", "outputs": [ { "internalType": "address", "name": "", "type": "address" } ], "stateMutability": "view", "type": "function" }, { "inputs": [ { "internalType": "address", "name": "supplyToken_", "type": "address" }, { "internalType": "address", "name": "borrowToken_", "type": "address" } ], "name": "vaultT1", "outputs": [ { "internalType": "bytes", "name": "vaultCreationBytecode_", "type": "bytes" } ], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [], "name": "vaultT1CreationBytecode", "outputs": [ { "internalType": "bytes", "name": "", "type": "bytes" } ], "stateMutability": "view", "type": "function" } ], "transactionHash": "0xcbe3ede36a2dd9a39430b8ce0af180e7c1ce0ee0f8a86ca11025776fabcc8fdc", "receipt": { "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", "from": "0x0Ed35B1609Ec45c7079E80d11149a52717e4859A", "contractAddress": null, "transactionIndex": 0, "gasUsed": "6475871", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "blockHash": "0x3321fe38ae7095132653b3ef3fd09c89bcadb49c1ff886962186e0a88585bc6b", "transactionHash": "0xcbe3ede36a2dd9a39430b8ce0af180e7c1ce0ee0f8a86ca11025776fabcc8fdc", "logs": [], "blockNumber": 19959877, "cumulativeGasUsed": "6475871", "status": 1, "byzantium": true }, "args": [ "0x52Aa899454998Be5b000Ad077a46Bbe360F4e497", "0x5dDf07980ADD152D518AE463269e1A97e93EE1a9", "0xbd6C8ee7CB9a13333e043C4d5fCf3ac125f7f890" ], "numDeployments": 6, "solcInputHash": "033d84042c3fe6a1afa58a71e8e52d69", "metadata": "{\"compiler\":{\"version\":\"0.8.21+commit.d9974bed\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"liquidity_\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"vaultAdminImplementation_\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"vaultSecondaryImplementation_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"colLiquidated\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"debtLiquidated\",\"type\":\"uint256\"}],\"name\":\"FluidLiquidateResult\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"errorId_\",\"type\":\"uint256\"}],\"name\":\"FluidVaultError\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"vault\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"vaultId\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"supplyToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"borrowToken\",\"type\":\"address\"}],\"name\":\"VaultT1Deployed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"ADDRESS_THIS\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"ADMIN_IMPLEMENTATION\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"LIQUIDITY\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"SECONDARY_IMPLEMENTATION\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"supplyToken_\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"borrowToken_\",\"type\":\"address\"}],\"name\":\"vaultT1\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"vaultCreationBytecode_\",\"type\":\"bytes\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"vaultT1CreationBytecode\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"events\":{\"VaultT1Deployed(address,uint256,address,address)\":{\"params\":{\"borrowToken\":\"The address of the borrow token.\",\"supplyToken\":\"The address of the supply token.\",\"vault\":\"The address of the newly deployed vault.\",\"vaultId\":\"The id of the newly deployed vault.\"}}},\"kind\":\"dev\",\"methods\":{\"vaultT1(address,address)\":{\"params\":{\"borrowToken_\":\"The address of the borrow token.\",\"supplyToken_\":\"The address of the supply token.\"},\"returns\":{\"vaultCreationBytecode_\":\" Returns the bytecode of the new vault to deploy.\"}}},\"stateVariables\":{\"VAULT_T1_CREATIONCODE_ADDRESS_1\":{\"details\":\"SSTORE2 pointer for the VaultT1 creation code. Stored externally to reduce factory bytecode (in 2 parts)\"}},\"version\":1},\"userdoc\":{\"errors\":{\"FluidLiquidateResult(uint256,uint256)\":[{\"notice\":\"used to simulate liquidation to find the maximum liquidatable amounts\"}]},\"events\":{\"VaultT1Deployed(address,uint256,address,address)\":{\"notice\":\"Emitted when a new vaultT1 is deployed.\"}},\"kind\":\"user\",\"methods\":{\"ADDRESS_THIS()\":{\"notice\":\"address of this contract\"},\"ADMIN_IMPLEMENTATION()\":{\"notice\":\"address of Admin implementation\"},\"LIQUIDITY()\":{\"notice\":\"address of liquidity contract\"},\"SECONDARY_IMPLEMENTATION()\":{\"notice\":\"address of Secondary implementation\"},\"vaultT1(address,address)\":{\"notice\":\"Computes vaultT1 bytecode for the given supply token (`supplyToken_`) and borrow token (`borrowToken_`). This will be called by the VaultFactory via .delegateCall\"},\"vaultT1CreationBytecode()\":{\"notice\":\"returns the stored VaultT1 creation bytecode\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/protocols/vault/factory/deploymentLogics/vaultT1Logic.sol\":\"FluidVaultT1DeploymentLogic\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":10000000},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/token/ERC721/IERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/IERC721.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../../utils/introspection/IERC165.sol\\\";\\n\\n/**\\n * @dev Required interface of an ERC721 compliant contract.\\n */\\ninterface IERC721 is IERC165 {\\n /**\\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\\n\\n /**\\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\\n */\\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\\n\\n /**\\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\\n */\\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\\n\\n /**\\n * @dev Returns the number of tokens in ``owner``'s account.\\n */\\n function balanceOf(address owner) external view returns (uint256 balance);\\n\\n /**\\n * @dev Returns the owner of the `tokenId` token.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n */\\n function ownerOf(uint256 tokenId) external view returns (address owner);\\n\\n /**\\n * @dev Safely transfers `tokenId` token from `from` to `to`.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must exist and be owned by `from`.\\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes calldata data\\n ) external;\\n\\n /**\\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must exist and be owned by `from`.\\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 tokenId\\n ) external;\\n\\n /**\\n * @dev Transfers `tokenId` token from `from` to `to`.\\n *\\n * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721\\n * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must\\n * understand this adds an external call which potentially creates a reentrancy vulnerability.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must be owned by `from`.\\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 tokenId\\n ) external;\\n\\n /**\\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\\n * The approval is cleared when the token is transferred.\\n *\\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\\n *\\n * Requirements:\\n *\\n * - The caller must own the token or be an approved operator.\\n * - `tokenId` must exist.\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address to, uint256 tokenId) external;\\n\\n /**\\n * @dev Approve or remove `operator` as an operator for the caller.\\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\\n *\\n * Requirements:\\n *\\n * - The `operator` cannot be the caller.\\n *\\n * Emits an {ApprovalForAll} event.\\n */\\n function setApprovalForAll(address operator, bool _approved) external;\\n\\n /**\\n * @dev Returns the account approved for `tokenId` token.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n */\\n function getApproved(uint256 tokenId) external view returns (address operator);\\n\\n /**\\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\\n *\\n * See {setApprovalForAll}\\n */\\n function isApprovedForAll(address owner, address operator) external view returns (bool);\\n}\\n\",\"keccak256\":\"0xab28a56179c1db258c9bf5235b382698cb650debecb51b23d12be9e241374b68\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC721/extensions/IERC721Enumerable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC721.sol\\\";\\n\\n/**\\n * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension\\n * @dev See https://eips.ethereum.org/EIPS/eip-721\\n */\\ninterface IERC721Enumerable is IERC721 {\\n /**\\n * @dev Returns the total amount of tokens stored by the contract.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns a token ID owned by `owner` at a given `index` of its token list.\\n * Use along with {balanceOf} to enumerate all of ``owner``'s tokens.\\n */\\n function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256);\\n\\n /**\\n * @dev Returns a token ID at a given `index` of all the tokens stored by the contract.\\n * Use along with {totalSupply} to enumerate all tokens.\\n */\\n function tokenByIndex(uint256 index) external view returns (uint256);\\n}\\n\",\"keccak256\":\"0xd1556954440b31c97a142c6ba07d5cade45f96fafd52091d33a14ebe365aecbf\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/introspection/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC165 standard, as defined in the\\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\\n *\\n * Implementers can declare support of contract interfaces, which can then be\\n * queried by others ({ERC165Checker}).\\n *\\n * For an implementation, see {ERC165}.\\n */\\ninterface IERC165 {\\n /**\\n * @dev Returns true if this contract implements the interface defined by\\n * `interfaceId`. See the corresponding\\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\\n * to learn more about how these ids are created.\\n *\\n * This function call must use less than 30 000 gas.\\n */\\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1\",\"license\":\"MIT\"},\"contracts/infiniteProxy/interfaces/iProxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.21;\\n\\ninterface IProxy {\\n function setAdmin(address newAdmin_) external;\\n\\n function setDummyImplementation(address newDummyImplementation_) external;\\n\\n function addImplementation(address implementation_, bytes4[] calldata sigs_) external;\\n\\n function removeImplementation(address implementation_) external;\\n\\n function getAdmin() external view returns (address);\\n\\n function getDummyImplementation() external view returns (address);\\n\\n function getImplementationSigs(address impl_) external view returns (bytes4[] memory);\\n\\n function getSigsImplementation(bytes4 sig_) external view returns (address);\\n\\n function readFromStorage(bytes32 slot_) external view returns (uint256 result_);\\n}\\n\",\"keccak256\":\"0xbb605491d4bac08e816248feecae7dd17cfc1877c88b2e555abece2970f5ea00\",\"license\":\"MIT\"},\"contracts/libraries/bigMathMinified.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\npragma solidity 0.8.21;\\n\\n/// @title library that represents a number in BigNumber(coefficient and exponent) format to store in smaller bits.\\n/// @notice the number is divided into two parts: a coefficient and an exponent. This comes at a cost of losing some precision\\n/// at the end of the number because the exponent simply fills it with zeroes. This precision is oftentimes negligible and can\\n/// result in significant gas cost reduction due to storage space reduction.\\n/// 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.\\n/// @dev roundUp is more like a increase 1, which happens everytime for the same number.\\n/// roundDown simply sets trailing digits after coefficientSize to zero (floor), only once for the same number.\\nlibrary BigMathMinified {\\n /// @dev constants to use for `roundUp` input param to increase readability\\n bool internal constant ROUND_DOWN = false;\\n bool internal constant ROUND_UP = true;\\n\\n /// @dev converts `normal` number to BigNumber with `exponent` and `coefficient` (or precision).\\n /// e.g.:\\n /// 5035703444687813576399599 (normal) = (coefficient[32bits], exponent[8bits])[40bits]\\n /// 5035703444687813576399599 (decimal) => 10000101010010110100000011111011110010100110100000000011100101001101001101011101111 (binary)\\n /// => 10000101010010110100000011111011000000000000000000000000000000000000000000000000000\\n /// ^-------------------- 51(exponent) -------------- ^\\n /// coefficient = 1000,0101,0100,1011,0100,0000,1111,1011 (2236301563)\\n /// exponent = 0011,0011 (51)\\n /// bigNumber = 1000,0101,0100,1011,0100,0000,1111,1011,0011,0011 (572493200179)\\n ///\\n /// @param normal number which needs to be converted into Big Number\\n /// @param coefficientSize at max how many bits of precision there should be (64 = uint64 (64 bits precision))\\n /// @param exponentSize at max how many bits of exponent there should be (8 = uint8 (8 bits exponent))\\n /// @param roundUp signals if result should be rounded down or up\\n /// @return bigNumber converted bigNumber (coefficient << exponent)\\n function toBigNumber(\\n uint256 normal,\\n uint256 coefficientSize,\\n uint256 exponentSize,\\n bool roundUp\\n ) internal pure returns (uint256 bigNumber) {\\n assembly {\\n let lastBit_\\n let number_ := normal\\n if gt(number_, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) {\\n number_ := shr(0x80, number_)\\n lastBit_ := 0x80\\n }\\n if gt(number_, 0xFFFFFFFFFFFFFFFF) {\\n number_ := shr(0x40, number_)\\n lastBit_ := add(lastBit_, 0x40)\\n }\\n if gt(number_, 0xFFFFFFFF) {\\n number_ := shr(0x20, number_)\\n lastBit_ := add(lastBit_, 0x20)\\n }\\n if gt(number_, 0xFFFF) {\\n number_ := shr(0x10, number_)\\n lastBit_ := add(lastBit_, 0x10)\\n }\\n if gt(number_, 0xFF) {\\n number_ := shr(0x8, number_)\\n lastBit_ := add(lastBit_, 0x8)\\n }\\n if gt(number_, 0xF) {\\n number_ := shr(0x4, number_)\\n lastBit_ := add(lastBit_, 0x4)\\n }\\n if gt(number_, 0x3) {\\n number_ := shr(0x2, number_)\\n lastBit_ := add(lastBit_, 0x2)\\n }\\n if gt(number_, 0x1) {\\n lastBit_ := add(lastBit_, 1)\\n }\\n if gt(number_, 0) {\\n lastBit_ := add(lastBit_, 1)\\n }\\n if lt(lastBit_, coefficientSize) {\\n // for throw exception\\n lastBit_ := coefficientSize\\n }\\n let exponent := sub(lastBit_, coefficientSize)\\n let coefficient := shr(exponent, normal)\\n if and(roundUp, gt(exponent, 0)) {\\n // rounding up is only needed if exponent is > 0, as otherwise the coefficient fully holds the original number\\n coefficient := add(coefficient, 1)\\n if eq(shl(coefficientSize, 1), coefficient) {\\n // case were coefficient was e.g. 111, with adding 1 it became 1000 (in binary) and coefficientSize 3 bits\\n // final coefficient would exceed it's size. -> reduce coefficent to 100 and increase exponent by 1.\\n coefficient := shl(sub(coefficientSize, 1), 1)\\n exponent := add(exponent, 1)\\n }\\n }\\n if iszero(lt(exponent, shl(exponentSize, 1))) {\\n // if exponent is >= exponentSize, the normal number is too big to fit within\\n // BigNumber with too small sizes for coefficient and exponent\\n revert(0, 0)\\n }\\n bigNumber := shl(exponentSize, coefficient)\\n bigNumber := add(bigNumber, exponent)\\n }\\n }\\n\\n /// @dev get `normal` number from `bigNumber`, `exponentSize` and `exponentMask`\\n function fromBigNumber(\\n uint256 bigNumber,\\n uint256 exponentSize,\\n uint256 exponentMask\\n ) internal pure returns (uint256 normal) {\\n assembly {\\n let coefficient := shr(exponentSize, bigNumber)\\n let exponent := and(bigNumber, exponentMask)\\n normal := shl(exponent, coefficient)\\n }\\n }\\n\\n /// @dev gets the most significant bit `lastBit` of a `normal` number (length of given number of binary format).\\n /// e.g.\\n /// 5035703444687813576399599 = 10000101010010110100000011111011110010100110100000000011100101001101001101011101111\\n /// lastBit = ^--------------------------------- 83 ----------------------------------------^\\n function mostSignificantBit(uint256 normal) internal pure returns (uint lastBit) {\\n assembly {\\n let number_ := normal\\n if gt(normal, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) {\\n number_ := shr(0x80, number_)\\n lastBit := 0x80\\n }\\n if gt(number_, 0xFFFFFFFFFFFFFFFF) {\\n number_ := shr(0x40, number_)\\n lastBit := add(lastBit, 0x40)\\n }\\n if gt(number_, 0xFFFFFFFF) {\\n number_ := shr(0x20, number_)\\n lastBit := add(lastBit, 0x20)\\n }\\n if gt(number_, 0xFFFF) {\\n number_ := shr(0x10, number_)\\n lastBit := add(lastBit, 0x10)\\n }\\n if gt(number_, 0xFF) {\\n number_ := shr(0x8, number_)\\n lastBit := add(lastBit, 0x8)\\n }\\n if gt(number_, 0xF) {\\n number_ := shr(0x4, number_)\\n lastBit := add(lastBit, 0x4)\\n }\\n if gt(number_, 0x3) {\\n number_ := shr(0x2, number_)\\n lastBit := add(lastBit, 0x2)\\n }\\n if gt(number_, 0x1) {\\n lastBit := add(lastBit, 1)\\n }\\n if gt(number_, 0) {\\n lastBit := add(lastBit, 1)\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xf0be1002909edf30aec3dc6623c2bd2407ed94064b62674c01032b844dec206a\",\"license\":\"BUSL-1.1\"},\"contracts/libraries/bigMathVault.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\npragma solidity 0.8.21;\\n\\nimport { BigMathMinified } from \\\"./bigMathMinified.sol\\\";\\n\\n/// @title Extended version of BigMathMinified. Implements functions for normal operators (*, /, etc) modified to interact with big numbers.\\n/// @notice this is an optimized version mainly created by taking Fluid vault's codebase into consideration so it's use is limited for other cases.\\n// \\n// @dev IMPORTANT: for any change here, make sure to uncomment and run the fuzz tests in bigMathVault.t.sol\\nlibrary BigMathVault {\\n uint private constant COEFFICIENT_SIZE_DEBT_FACTOR = 35;\\n uint private constant EXPONENT_SIZE_DEBT_FACTOR = 15;\\n uint private constant COEFFICIENT_MAX_DEBT_FACTOR = (1 << COEFFICIENT_SIZE_DEBT_FACTOR) - 1;\\n uint private constant EXPONENT_MAX_DEBT_FACTOR = (1 << EXPONENT_SIZE_DEBT_FACTOR) - 1;\\n uint private constant DECIMALS_DEBT_FACTOR = 16384;\\n uint internal constant MAX_MASK_DEBT_FACTOR = (1 << (COEFFICIENT_SIZE_DEBT_FACTOR + EXPONENT_SIZE_DEBT_FACTOR)) - 1;\\n\\n // Having precision as 2**64 on vault\\n uint internal constant PRECISION = 64;\\n uint internal constant TWO_POWER_64 = 1 << PRECISION;\\n // Max bit for 35 bits * 35 bits number will be 70\\n // why do we use 69 then here instead of 70\\n uint internal constant TWO_POWER_69_MINUS_1 = (1 << 69) - 1;\\n\\n uint private constant COEFFICIENT_PLUS_PRECISION = COEFFICIENT_SIZE_DEBT_FACTOR + PRECISION; // 99\\n uint private constant COEFFICIENT_PLUS_PRECISION_MINUS_1 = COEFFICIENT_PLUS_PRECISION - 1; // 98\\n uint private constant TWO_POWER_COEFFICIENT_PLUS_PRECISION_MINUS_1 = (1 << COEFFICIENT_PLUS_PRECISION_MINUS_1) - 1; // (1 << 98) - 1;\\n uint private constant TWO_POWER_COEFFICIENT_PLUS_PRECISION_MINUS_1_MINUS_1 =\\n (1 << (COEFFICIENT_PLUS_PRECISION_MINUS_1 - 1)) - 1; // (1 << 97) - 1;\\n\\n /// @dev multiplies a `normal` number with a `bigNumber1` and then divides by `bigNumber2`.\\n /// @dev For vault's use case MUST always:\\n /// - bigNumbers have exponent size 15 bits\\n /// - bigNumbers have coefficient size 35 bits and have 35th bit always 1 (when exponent > 0 BigMath numbers have max precision)\\n /// so coefficients must always be in range 17179869184 <= coefficient <= 34359738367.\\n /// - bigNumber1 (debt factor) always have exponent >= 1 & <= 16384\\n /// - bigNumber2 (connection factor) always have exponent >= 1 & <= 32767 (15 bits)\\n /// - bigNumber2 always >= bigNumber1 (connection factor can never be < base branch debt factor)\\n /// - as a result of previous points, numbers must never be 0\\n /// - normal is positionRawDebt and is always within 10000 and type(int128).max\\n /// @return normal * bigNumber1 / bigNumber2\\n function mulDivNormal(uint256 normal, uint256 bigNumber1, uint256 bigNumber2) internal pure returns (uint256) {\\n unchecked {\\n // exponent2_ - exponent1_\\n uint netExponent_ = (bigNumber2 & EXPONENT_MAX_DEBT_FACTOR) - (bigNumber1 & EXPONENT_MAX_DEBT_FACTOR);\\n if (netExponent_ < 129) {\\n // (normal * coefficient1_) / (coefficient2_ << netExponent_);\\n return ((normal * (bigNumber1 >> EXPONENT_SIZE_DEBT_FACTOR)) /\\n ((bigNumber2 >> EXPONENT_SIZE_DEBT_FACTOR) << netExponent_));\\n }\\n // else:\\n // biggest possible nominator: type(int128).max * 35bits max = 5846006549323611672814739330865132078589370433536\\n // smallest possible denominator: 17179869184 << 129 (= 1 << 163) = 11692013098647223345629478661730264157247460343808\\n // -> can only ever be 0\\n return 0;\\n }\\n }\\n\\n /// @dev multiplies a `bigNumber` with normal `number1` and then divides by `TWO_POWER_64`.\\n /// @dev For vault's use case (calculating new branch debt factor after liquidation):\\n /// - number1 is debtFactor, intialized as TWO_POWER_64 and reduced from there, hence it's always <= TWO_POWER_64 and always > 0.\\n /// - bigNumber is branch debt factor, which starts as ((X35 << 15) | (1 << 14)) and reduces from there.\\n /// - bigNumber must have have exponent size 15 bits and be >= 1 & <= 16384\\n /// - bigNumber must have coefficient size 35 bits and have 35th bit always 1 (when exponent > 0 BigMath numbers have max precision)\\n /// so coefficients must always be in range 17179869184 <= coefficient <= 34359738367.\\n /// @param bigNumber Coefficient | Exponent.\\n /// @param number1 normal number.\\n /// @return result bigNumber * number1 / TWO_POWER_64.\\n function mulDivBigNumber(uint256 bigNumber, uint256 number1) internal pure returns (uint256 result) {\\n // using unchecked as we are only at 1 place in Vault and it won't overflow there.\\n unchecked {\\n uint256 _resultNumerator = (bigNumber >> EXPONENT_SIZE_DEBT_FACTOR) * number1; // bigNumber coefficient * normal number\\n // 99% chances are that most sig bit should be 64 + 35 - 1 or 64 + 35 - 2\\n // diff = mostSigBit. Can only ever be >= 35 and <= 98\\n uint256 diff = (_resultNumerator > TWO_POWER_COEFFICIENT_PLUS_PRECISION_MINUS_1)\\n ? COEFFICIENT_PLUS_PRECISION\\n : (_resultNumerator > TWO_POWER_COEFFICIENT_PLUS_PRECISION_MINUS_1_MINUS_1)\\n ? COEFFICIENT_PLUS_PRECISION_MINUS_1\\n : BigMathMinified.mostSignificantBit(_resultNumerator);\\n\\n // diff = difference in bits to make the _resultNumerator 35 bits again\\n diff = diff - COEFFICIENT_SIZE_DEBT_FACTOR;\\n _resultNumerator = _resultNumerator >> diff;\\n // starting exponent is 16384, so exponent should never get 0 here\\n result = (bigNumber & EXPONENT_MAX_DEBT_FACTOR) + diff;\\n if (result > PRECISION) {\\n result = (_resultNumerator << EXPONENT_SIZE_DEBT_FACTOR) + result - PRECISION; // divides by TWO_POWER_64 by reducing exponent by 64\\n } else {\\n // if number1 is small, e.g. 1e4 and bigNumber is also small e.g. coefficient = 17179869184 & exponent is at 50\\n // then: resultNumerator = 171798691840000, diff most significant bit = 48, ending up with diff = 13\\n // for exponent in result we end up doing: 50 + 13 - 64 -> underflowing exponent.\\n // this should never happen anyway, but if it does better to revert than to continue with unknown effects.\\n revert(); // debt factor should never become a BigNumber with exponent <= 0\\n }\\n }\\n }\\n\\n /// @dev multiplies a `bigNumber1` with another `bigNumber2`.\\n /// @dev For vault's use case (calculating connection factor of merged branches userTickDebtFactor * connectionDebtFactor *... connectionDebtFactor):\\n /// - bigNumbers must have have exponent size 15 bits and be >= 1 & <= 32767\\n /// - bigNumber must have coefficient size 35 bits and have 35th bit always 1 (when exponent > 0 BigMath numbers have max precision)\\n /// so coefficients must always be in range 17179869184 <= coefficient <= 34359738367.\\n /// @dev sum of exponents from `bigNumber1` `bigNumber2` should be > 16384.\\n /// e.g. res = bigNumber1 * bigNumber2 = [(coe1, exp1) * (coe2, exp2)] >> decimal\\n /// = (coe1*coe2>>overflow, exp1+exp2+overflow-decimal)\\n /// @param bigNumber1 BigNumber format with coefficient and exponent.\\n /// @param bigNumber2 BigNumber format with coefficient and exponent.\\n /// @return BigNumber format with coefficient and exponent\\n function mulBigNumber(uint256 bigNumber1, uint256 bigNumber2) internal pure returns (uint256) {\\n unchecked {\\n // coefficient1_ * coefficient2_\\n uint resCoefficient_ = (bigNumber1 >> EXPONENT_SIZE_DEBT_FACTOR) *\\n (bigNumber2 >> EXPONENT_SIZE_DEBT_FACTOR);\\n // res coefficient at min can be 17179869184 * 17179869184 = 295147905179352825856 (= 1 << 68; 69th bit as 1)\\n // res coefficient at max can be 34359738367 * 34359738367 = 1180591620648691826689 (X35 * X35 fits in 70 bits)\\n uint overflowLen_ = resCoefficient_ > TWO_POWER_69_MINUS_1\\n ? COEFFICIENT_SIZE_DEBT_FACTOR\\n : COEFFICIENT_SIZE_DEBT_FACTOR - 1;\\n // overflowLen_ is either 34 or 35\\n resCoefficient_ = resCoefficient_ >> overflowLen_;\\n\\n // bigNumber2 is connection factor\\n // exponent1_ + exponent2_ + overflowLen_ - decimals\\n uint resExponent_ = ((bigNumber1 & EXPONENT_MAX_DEBT_FACTOR) +\\n (bigNumber2 & EXPONENT_MAX_DEBT_FACTOR) +\\n overflowLen_);\\n if (resExponent_ < DECIMALS_DEBT_FACTOR) {\\n // for this ever to happen, the debt factors used to calculate connection factors would have to be at extremely\\n // unrealistic values. Like e.g.\\n // branch3 (debt factor X35 << 15 | 16383) got merged into branch2 (debt factor X35 << 15 | 8190)\\n // -> connection factor (divBigNumber): ((coe1<>overflowLen, exp1+decimal+overflowLen-exp2-precision_) so:\\n // coefficient: (X35<<64)/X35 >> 30 = 17179869184\\n // exponent: 8190+16384+30-16383-64 = 8157.\\n // result: 17179869184 << 15 | 8157\\n // and then branch2 into branch1 (debt factor X35 << 15 | 22). -> connection factor:\\n // coefficient: (X35<<64)/X35 >> 30 = 17179869184\\n // exponent: 22+16384+30-8190-64 = 8182.\\n // result: 17179869184 << 15 | 8182\\n // connection factors sum up (mulBigNumber): (coe1*coe2>>overflow, exp1+exp2+overflow-decimal)\\n // exponent: 8182+8157+35-16384=16374-16384=-10. underflow.\\n // this should never happen anyway, but if it does better to revert than to continue with unknown effects.\\n revert();\\n }\\n resExponent_ = resExponent_ - DECIMALS_DEBT_FACTOR;\\n\\n if (resExponent_ > EXPONENT_MAX_DEBT_FACTOR) {\\n // if resExponent_ is not within limits that means user's got ~100% (something like 99.999999999999...)\\n // this situation will probably never happen and this basically means user's position is ~100% liquidated\\n return MAX_MASK_DEBT_FACTOR;\\n }\\n\\n return ((resCoefficient_ << EXPONENT_SIZE_DEBT_FACTOR) | resExponent_);\\n }\\n }\\n\\n /// @dev divides a `bigNumber1` by `bigNumber2`.\\n /// @dev For vault's use case (calculating connectionFactor_ = baseBranchDebtFactor / currentBranchDebtFactor) bigNumbers MUST always:\\n /// - have exponent size 15 bits and be >= 1 & <= 16384\\n /// - have coefficient size 35 bits and have 35th bit always 1 (when exponent > 0 BigMath numbers have max precision)\\n /// so coefficients must always be in range 17179869184 <= coefficient <= 34359738367.\\n /// - as a result of previous points, numbers must never be 0\\n /// e.g. res = bigNumber1 / bigNumber2 = [(coe1, exp1) / (coe2, exp2)] << decimal\\n /// = ((coe1<= baseBranchDebtFactor (c = x*100/y with both x,y > 0 & x,y <= 100: c can only ever be >= x)\\n function divBigNumber(uint256 bigNumber1, uint256 bigNumber2) internal pure returns (uint256) {\\n unchecked {\\n // (coefficient1_ << PRECISION) / coefficient2_\\n uint256 resCoefficient_ = ((bigNumber1 >> EXPONENT_SIZE_DEBT_FACTOR) << PRECISION) /\\n (bigNumber2 >> EXPONENT_SIZE_DEBT_FACTOR);\\n // nominator at min 17179869184 << 64 = 316912650057057350374175801344. at max 34359738367 << 64 = 633825300095667956674642051072.\\n // so min value resCoefficient_ 9223372037123211264 (64 bits) vs max 36893488146345361408 (fits in 65 bits)\\n\\n // mostSigBit will be PRECISION + 1 or PRECISION\\n uint256 overflowLen_ = ((resCoefficient_ >> PRECISION) == 1) ? (PRECISION + 1) : PRECISION;\\n // Overflow will be PRECISION - COEFFICIENT_SIZE_DEBT_FACTOR or (PRECISION + 1) - COEFFICIENT_SIZE_DEBT_FACTOR\\n // Meaning 64 - 35 = 29 or 65 - 35 = 30\\n overflowLen_ = overflowLen_ - COEFFICIENT_SIZE_DEBT_FACTOR;\\n resCoefficient_ = resCoefficient_ >> overflowLen_;\\n\\n // exponent1_ will always be less than or equal to 16384\\n // exponent2_ will always be less than or equal to 16384\\n // Even if exponent2_ is 0 (not possible) & resExponent_ = DECIMALS_DEBT_FACTOR then also resExponent_ will be less than max limit, so no overflow\\n // result exponent = (exponent1_ + DECIMALS_DEBT_FACTOR + overflowLen_) - (exponent2_ + PRECISION);\\n uint256 resExponent_ = ((bigNumber1 & EXPONENT_MAX_DEBT_FACTOR) + // exponent1_\\n DECIMALS_DEBT_FACTOR + // DECIMALS_DEBT_FACTOR is 100% as it is percentage value\\n overflowLen_); // addition part resExponent_ here min 16414, max 32798\\n // reuse overFlowLen_ variable for subtraction sum of exponent\\n overflowLen_ = (bigNumber2 & EXPONENT_MAX_DEBT_FACTOR) + PRECISION; // subtraction part overflowLen_ here: min 65, max 16448\\n if (resExponent_ > overflowLen_) {\\n resExponent_ = resExponent_ - overflowLen_;\\n\\n return ((resCoefficient_ << EXPONENT_SIZE_DEBT_FACTOR) | resExponent_);\\n }\\n\\n // Can happen if bigNumber1 exponent is < 35 (35+16384+29 = 16448) and bigNumber2 exponent is e.g. max 16384.\\n // this would mean a branch with a normal big debt factor (bigNumber2) is merged into a base branch with an extremely small\\n // debt factor (bigNumber1).\\n // this should never happen anyway, but if it does better to revert than to continue with unknown effects.\\n revert(); // connection factor should never become a BigNumber with exponent <= 0\\n }\\n }\\n}\\n\",\"keccak256\":\"0xae1aa0a4f28f1b1a0accf2beb8a1e4f5bcab01d9432fff0494fbbe3ddf3ab348\",\"license\":\"BUSL-1.1\"},\"contracts/libraries/errorTypes.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\npragma solidity 0.8.21;\\n\\nlibrary LibsErrorTypes {\\n /***********************************|\\n | LiquidityCalcs | \\n |__________________________________*/\\n\\n /// @notice thrown when supply or borrow exchange price is zero at calc token data (token not configured yet)\\n uint256 internal constant LiquidityCalcs__ExchangePriceZero = 70001;\\n\\n /// @notice thrown when rate data is set to a version that is not implemented\\n uint256 internal constant LiquidityCalcs__UnsupportedRateVersion = 70002;\\n\\n /// @notice thrown when the calculated borrow rate turns negative. This should never happen.\\n uint256 internal constant LiquidityCalcs__BorrowRateNegative = 70003;\\n\\n /***********************************|\\n | SafeTransfer | \\n |__________________________________*/\\n\\n /// @notice thrown when safe transfer from for an ERC20 fails\\n uint256 internal constant SafeTransfer__TransferFromFailed = 71001;\\n\\n /// @notice thrown when safe transfer for an ERC20 fails\\n uint256 internal constant SafeTransfer__TransferFailed = 71002;\\n}\\n\",\"keccak256\":\"0xaf7732f30d00dd38082d37aa37887be485fc94b0c76ff302aff615d03381674f\",\"license\":\"BUSL-1.1\"},\"contracts/libraries/liquidityCalcs.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\npragma solidity 0.8.21;\\n\\nimport { LibsErrorTypes as ErrorTypes } from \\\"./errorTypes.sol\\\";\\nimport { LiquiditySlotsLink } from \\\"./liquiditySlotsLink.sol\\\";\\nimport { BigMathMinified } from \\\"./bigMathMinified.sol\\\";\\n\\n/// @notice implements calculation methods used for Fluid liquidity such as updated exchange prices,\\n/// borrow rate, withdrawal / borrow limits, revenue amount.\\nlibrary LiquidityCalcs {\\n error FluidLiquidityCalcsError(uint256 errorId_);\\n\\n /// @notice emitted if the calculated borrow rate surpassed max borrow rate (16 bits) and was capped at maximum value 65535\\n event BorrowRateMaxCap();\\n\\n /// @dev constants as from Liquidity variables.sol\\n uint256 internal constant EXCHANGE_PRICES_PRECISION = 1e12;\\n\\n /// @dev Ignoring leap years\\n uint256 internal constant SECONDS_PER_YEAR = 365 days;\\n // constants used for BigMath conversion from and to storage\\n uint256 internal constant DEFAULT_EXPONENT_SIZE = 8;\\n uint256 internal constant DEFAULT_EXPONENT_MASK = 0xFF;\\n\\n uint256 internal constant FOUR_DECIMALS = 1e4;\\n uint256 internal constant TWELVE_DECIMALS = 1e12;\\n uint256 internal constant X14 = 0x3fff;\\n uint256 internal constant X15 = 0x7fff;\\n uint256 internal constant X16 = 0xffff;\\n uint256 internal constant X18 = 0x3ffff;\\n uint256 internal constant X24 = 0xffffff;\\n uint256 internal constant X33 = 0x1ffffffff;\\n uint256 internal constant X64 = 0xffffffffffffffff;\\n\\n ///////////////////////////////////////////////////////////////////////////\\n ////////// CALC EXCHANGE PRICES /////////\\n ///////////////////////////////////////////////////////////////////////////\\n\\n /// @dev calculates interest (exchange prices) for a token given its' exchangePricesAndConfig from storage.\\n /// @param exchangePricesAndConfig_ exchange prices and config packed uint256 read from storage\\n /// @return supplyExchangePrice_ updated supplyExchangePrice\\n /// @return borrowExchangePrice_ updated borrowExchangePrice\\n function calcExchangePrices(\\n uint256 exchangePricesAndConfig_\\n ) internal view returns (uint256 supplyExchangePrice_, uint256 borrowExchangePrice_) {\\n // Extracting exchange prices\\n supplyExchangePrice_ =\\n (exchangePricesAndConfig_ >> LiquiditySlotsLink.BITS_EXCHANGE_PRICES_SUPPLY_EXCHANGE_PRICE) &\\n X64;\\n borrowExchangePrice_ =\\n (exchangePricesAndConfig_ >> LiquiditySlotsLink.BITS_EXCHANGE_PRICES_BORROW_EXCHANGE_PRICE) &\\n X64;\\n\\n if (supplyExchangePrice_ == 0 || borrowExchangePrice_ == 0) {\\n revert FluidLiquidityCalcsError(ErrorTypes.LiquidityCalcs__ExchangePriceZero);\\n }\\n\\n uint256 temp_ = exchangePricesAndConfig_ & X16; // temp_ = borrowRate\\n\\n unchecked {\\n // last timestamp can not be > current timestamp\\n uint256 secondsSinceLastUpdate_ = block.timestamp -\\n ((exchangePricesAndConfig_ >> LiquiditySlotsLink.BITS_EXCHANGE_PRICES_LAST_TIMESTAMP) & X33);\\n\\n uint256 borrowRatio_ = (exchangePricesAndConfig_ >> LiquiditySlotsLink.BITS_EXCHANGE_PRICES_BORROW_RATIO) &\\n X15;\\n if (secondsSinceLastUpdate_ == 0 || temp_ == 0 || borrowRatio_ == 1) {\\n // if no time passed, borrow rate is 0, or no raw borrowings: no exchange price update needed\\n // (if borrowRatio_ == 1 means there is only borrowInterestFree, as first bit is 1 and rest is 0)\\n return (supplyExchangePrice_, borrowExchangePrice_);\\n }\\n\\n // calculate new borrow exchange price.\\n // formula borrowExchangePriceIncrease: previous price * borrow rate * secondsSinceLastUpdate_.\\n // nominator is max uint112 (uint64 * uint16 * uint32). Divisor can not be 0.\\n borrowExchangePrice_ +=\\n (borrowExchangePrice_ * temp_ * secondsSinceLastUpdate_) /\\n (SECONDS_PER_YEAR * FOUR_DECIMALS);\\n\\n // FOR SUPPLY EXCHANGE PRICE:\\n // all yield paid by borrowers (in mode with interest) goes to suppliers in mode with interest.\\n // formula: previous price * supply rate * secondsSinceLastUpdate_.\\n // where supply rate = (borrow rate - revenueFee%) * ratioSupplyYield. And\\n // ratioSupplyYield = utilization * supplyRatio * borrowRatio\\n //\\n // Example:\\n // supplyRawInterest is 80, supplyInterestFree is 20. totalSupply is 100. BorrowedRawInterest is 50.\\n // BorrowInterestFree is 10. TotalBorrow is 60. borrow rate 40%, revenueFee 10%.\\n // yield is 10 (so half a year must have passed).\\n // supplyRawInterest must become worth 89. totalSupply must become 109. BorrowedRawInterest must become 60.\\n // borrowInterestFree must still be 10. supplyInterestFree still 20. totalBorrow 70.\\n // supplyExchangePrice would have to go from 1 to 1,125 (+ 0.125). borrowExchangePrice from 1 to 1,2 (+0.2).\\n // utilization is 60%. supplyRatio = 20 / 80 = 25% (only 80% of lenders receiving yield).\\n // borrowRatio = 10 / 50 = 20% (only 83,333% of borrowers paying yield):\\n // x of borrowers paying yield = 100% - (20 / (100 + 20)) = 100% - 16.6666666% = 83,333%.\\n // ratioSupplyYield = 60% * 83,33333% * (100% + 20%) = 62,5%\\n // supplyRate = (40% * (100% - 10%)) * = 36% * 62,5% = 22.5%\\n // increase in supplyExchangePrice, assuming 100 as previous price.\\n // 100 * 22,5% * 1/2 (half a year) = 0,1125.\\n // cross-check supplyRawInterest worth = 80 * 1.1125 = 89. totalSupply worth = 89 + 20.\\n\\n // -------------- 1. calculate ratioSupplyYield --------------------------------\\n // step1: utilization * supplyRatio (or actually part of lenders receiving yield)\\n\\n // temp_ => supplyRatio (in 1e2: 100% = 10_000; 1% = 100 -> max value 16_383)\\n // if first bit 0 then ratio is supplyInterestFree / supplyWithInterest (supplyWithInterest is bigger)\\n // else ratio is supplyWithInterest / supplyInterestFree (supplyInterestFree is bigger)\\n temp_ = (exchangePricesAndConfig_ >> LiquiditySlotsLink.BITS_EXCHANGE_PRICES_SUPPLY_RATIO) & X15;\\n\\n if (temp_ == 1) {\\n // if no raw supply: no exchange price update needed\\n // (if supplyRatio_ == 1 means there is only supplyInterestFree, as first bit is 1 and rest is 0)\\n return (supplyExchangePrice_, borrowExchangePrice_);\\n }\\n\\n // ratioSupplyYield precision is 1e27 as 100% for increased precision when supplyInterestFree > supplyWithInterest\\n if (temp_ & 1 == 1) {\\n // ratio is supplyWithInterest / supplyInterestFree (supplyInterestFree is bigger)\\n temp_ = temp_ >> 1;\\n\\n // Note: case where temp_ == 0 (only supplyInterestFree, no yield) already covered by early return\\n // in the if statement a little above.\\n\\n // based on above example but supplyRawInterest is 20, supplyInterestFree is 80. no fee.\\n // supplyRawInterest must become worth 30. totalSupply must become 110.\\n // supplyExchangePrice would have to go from 1 to 1,5. borrowExchangePrice from 1 to 1,2.\\n // so ratioSupplyYield must come out as 2.5 (250%).\\n // supplyRatio would be (20 * 10_000 / 80) = 2500. but must be inverted.\\n temp_ = (1e27 * FOUR_DECIMALS) / temp_; // e.g. 1e31 / 2500 = 4e27. (* 1e27 for precision)\\n // e.g. 5_000 * (1e27 + 4e27) / 1e27 = 25_000 (=250%).\\n temp_ =\\n // utilization * (100% + 100% / supplyRatio)\\n (((exchangePricesAndConfig_ >> LiquiditySlotsLink.BITS_EXCHANGE_PRICES_UTILIZATION) & X14) *\\n (1e27 + temp_)) / // extract utilization (max 16_383 so there is no way this can overflow).\\n (FOUR_DECIMALS);\\n // max possible value of temp_ here is 16383 * (1e27 + 1e31) / 1e4 = ~1.64e31\\n } else {\\n // ratio is supplyInterestFree / supplyWithInterest (supplyWithInterest is bigger)\\n temp_ = temp_ >> 1;\\n // if temp_ == 0 then only supplyWithInterest => full yield. temp_ is already 0\\n\\n // e.g. 5_000 * 10_000 + (20 * 10_000 / 80) / 10_000 = 5000 * 12500 / 10000 = 6250 (=62.5%).\\n temp_ =\\n // 1e27 * utilization * (100% + supplyRatio) / 100%\\n (1e27 *\\n ((exchangePricesAndConfig_ >> LiquiditySlotsLink.BITS_EXCHANGE_PRICES_UTILIZATION) & X14) * // extract utilization (max 16_383 so there is no way this can overflow).\\n (FOUR_DECIMALS + temp_)) /\\n (FOUR_DECIMALS * FOUR_DECIMALS);\\n // max possible temp_ value: 1e27 * 16383 * 2e4 / 1e8 = 3.2766e27\\n }\\n // from here temp_ => ratioSupplyYield (utilization * supplyRatio part) scaled by 1e27. max possible value ~1.64e31\\n\\n // step2 of ratioSupplyYield: add borrowRatio (only x% of borrowers paying yield)\\n if (borrowRatio_ & 1 == 1) {\\n // ratio is borrowWithInterest / borrowInterestFree (borrowInterestFree is bigger)\\n borrowRatio_ = borrowRatio_ >> 1;\\n // borrowRatio_ => x of total bororwers paying yield. scale to 1e27.\\n\\n // Note: case where borrowRatio_ == 0 (only borrowInterestFree, no yield) already covered\\n // at the beginning of the method by early return if `borrowRatio_ == 1`.\\n\\n // based on above example but borrowRawInterest is 10, borrowInterestFree is 50. no fee. borrowRatio = 20%.\\n // so only 16.66% of borrowers are paying yield. so the 100% - part of the formula is not needed.\\n // x of borrowers paying yield = (borrowRatio / (100 + borrowRatio)) = 16.6666666%\\n // borrowRatio_ => x of total bororwers paying yield. scale to 1e27.\\n borrowRatio_ = (borrowRatio_ * 1e27) / (FOUR_DECIMALS + borrowRatio_);\\n // max value here for borrowRatio_ is (1e31 / (1e4 + 1e4))= 5e26 (= 50% of borrowers paying yield).\\n } else {\\n // ratio is borrowInterestFree / borrowWithInterest (borrowWithInterest is bigger)\\n borrowRatio_ = borrowRatio_ >> 1;\\n\\n // borrowRatio_ => x of total bororwers paying yield. scale to 1e27.\\n // x of borrowers paying yield = 100% - (borrowRatio / (100 + borrowRatio)) = 100% - 16.6666666% = 83,333%.\\n borrowRatio_ = (1e27 - ((borrowRatio_ * 1e27) / (FOUR_DECIMALS + borrowRatio_)));\\n // borrowRatio can never be > 100%. so max subtraction can be 100% - 100% / 200%.\\n // or if borrowRatio_ is 0 -> 100% - 0. or if borrowRatio_ is 1 -> 100% - 1 / 101.\\n // max value here for borrowRatio_ is 1e27 - 0 = 1e27 (= 100% of borrowers paying yield).\\n }\\n\\n // temp_ => ratioSupplyYield. scaled down from 1e25 = 1% each to normal percent precision 1e2 = 1%.\\n // max nominator value is ~1.64e31 * 1e27 = 1.64e58. max result = 1.64e8\\n temp_ = (FOUR_DECIMALS * temp_ * borrowRatio_) / 1e54;\\n\\n // 2. calculate supply rate\\n // temp_ => supply rate (borrow rate - revenueFee%) * ratioSupplyYield.\\n // division part is done in next step to increase precision. (divided by 2x FOUR_DECIMALS, fee + borrowRate)\\n // Note that all calculation divisions for supplyExchangePrice are rounded down.\\n // Note supply rate can be bigger than the borrowRate, e.g. if there are only few lenders with interest\\n // but more suppliers not earning interest.\\n temp_ = ((exchangePricesAndConfig_ & X16) * // borrow rate\\n temp_ * // ratioSupplyYield\\n (FOUR_DECIMALS - ((exchangePricesAndConfig_ >> LiquiditySlotsLink.BITS_EXCHANGE_PRICES_FEE) & X14))); // revenueFee\\n // fee can not be > 100%. max possible = 65535 * ~1.64e8 * 1e4 =~1.074774e17.\\n\\n // 3. calculate increase in supply exchange price\\n supplyExchangePrice_ += ((supplyExchangePrice_ * temp_ * secondsSinceLastUpdate_) /\\n (SECONDS_PER_YEAR * FOUR_DECIMALS * FOUR_DECIMALS * FOUR_DECIMALS));\\n // max possible nominator = max uint 64 * 1.074774e17 * max uint32 = ~8.52e45. Denominator can not be 0.\\n }\\n }\\n\\n ///////////////////////////////////////////////////////////////////////////\\n ////////// CALC REVENUE /////////\\n ///////////////////////////////////////////////////////////////////////////\\n\\n /// @dev gets the `revenueAmount_` for a token given its' totalAmounts and exchangePricesAndConfig from storage\\n /// and the current balance of the Fluid liquidity contract for the token.\\n /// @param totalAmounts_ total amounts packed uint256 read from storage\\n /// @param exchangePricesAndConfig_ exchange prices and config packed uint256 read from storage\\n /// @param liquidityTokenBalance_ current balance of Liquidity contract (IERC20(token_).balanceOf(address(this)))\\n /// @return revenueAmount_ collectable revenue amount\\n function calcRevenue(\\n uint256 totalAmounts_,\\n uint256 exchangePricesAndConfig_,\\n uint256 liquidityTokenBalance_\\n ) internal view returns (uint256 revenueAmount_) {\\n // @dev no need to super-optimize this method as it is only used by admin\\n\\n // calculate the new exchange prices based on earned interest\\n (uint256 supplyExchangePrice_, uint256 borrowExchangePrice_) = calcExchangePrices(exchangePricesAndConfig_);\\n\\n // total supply = interest free + with interest converted from raw\\n uint256 totalSupply_ = getTotalSupply(totalAmounts_, supplyExchangePrice_);\\n\\n if (totalSupply_ > 0) {\\n // available revenue: balanceOf(token) + totalBorrowings - totalLendings.\\n revenueAmount_ = liquidityTokenBalance_ + getTotalBorrow(totalAmounts_, borrowExchangePrice_);\\n // ensure there is no possible case because of rounding etc. where this would revert,\\n // explicitly check if >\\n revenueAmount_ = revenueAmount_ > totalSupply_ ? revenueAmount_ - totalSupply_ : 0;\\n // Note: if utilization > 100% (totalSupply < totalBorrow), then all the amount above 100% utilization\\n // can only be revenue.\\n } else {\\n // if supply is 0, then rest of balance can be withdrawn as revenue so that no amounts get stuck\\n revenueAmount_ = liquidityTokenBalance_;\\n }\\n }\\n\\n ///////////////////////////////////////////////////////////////////////////\\n ////////// CALC LIMITS /////////\\n ///////////////////////////////////////////////////////////////////////////\\n\\n /// @dev calculates withdrawal limit before an operate execution:\\n /// amount of user supply that must stay supplied (not amount that can be withdrawn).\\n /// i.e. if user has supplied 100m and can withdraw 5M, this method returns the 95M, not the withdrawable amount 5M\\n /// @param userSupplyData_ user supply data packed uint256 from storage\\n /// @param userSupply_ current user supply amount already extracted from `userSupplyData_` and converted from BigMath\\n /// @return currentWithdrawalLimit_ current withdrawal limit updated for expansion since last interaction.\\n /// returned value is in raw for with interest mode, normal amount for interest free mode!\\n function calcWithdrawalLimitBeforeOperate(\\n uint256 userSupplyData_,\\n uint256 userSupply_\\n ) internal view returns (uint256 currentWithdrawalLimit_) {\\n // @dev must support handling the case where timestamp is 0 (config is set but no interactions yet).\\n // first tx where timestamp is 0 will enter `if (lastWithdrawalLimit_ == 0)` because lastWithdrawalLimit_ is not set yet.\\n // returning max withdrawal allowed, which is not exactly right but doesn't matter because the first interaction must be\\n // a deposit anyway. Important is that it would not revert.\\n\\n // Note the first time a deposit brings the user supply amount to above the base withdrawal limit, the active limit\\n // is the fully expanded limit immediately.\\n\\n // extract last set withdrawal limit\\n uint256 lastWithdrawalLimit_ = (userSupplyData_ >>\\n LiquiditySlotsLink.BITS_USER_SUPPLY_PREVIOUS_WITHDRAWAL_LIMIT) & X64;\\n lastWithdrawalLimit_ =\\n (lastWithdrawalLimit_ >> DEFAULT_EXPONENT_SIZE) <<\\n (lastWithdrawalLimit_ & DEFAULT_EXPONENT_MASK);\\n if (lastWithdrawalLimit_ == 0) {\\n // withdrawal limit is not activated. Max withdrawal allowed\\n return 0;\\n }\\n\\n uint256 maxWithdrawableLimit_;\\n uint256 temp_;\\n unchecked {\\n // extract max withdrawable percent of user supply and\\n // calculate maximum withdrawable amount expandPercentage of user supply at full expansion duration elapsed\\n // e.g.: if 10% expandPercentage, meaning 10% is withdrawable after full expandDuration has elapsed.\\n\\n // userSupply_ needs to be atleast 1e73 to overflow max limit of ~1e77 in uint256 (no token in existence where this is possible).\\n maxWithdrawableLimit_ =\\n (((userSupplyData_ >> LiquiditySlotsLink.BITS_USER_SUPPLY_EXPAND_PERCENT) & X14) * userSupply_) /\\n FOUR_DECIMALS;\\n\\n // time elapsed since last withdrawal limit was set (in seconds)\\n // @dev last process timestamp is guaranteed to exist for withdrawal, as a supply must have happened before.\\n // last timestamp can not be > current timestamp\\n temp_ =\\n block.timestamp -\\n ((userSupplyData_ >> LiquiditySlotsLink.BITS_USER_SUPPLY_LAST_UPDATE_TIMESTAMP) & X33);\\n }\\n // calculate withdrawable amount of expandPercent that is elapsed of expandDuration.\\n // e.g. if 60% of expandDuration has elapsed, then user should be able to withdraw 6% of user supply, down to 94%.\\n // Note: no explicit check for this needed, it is covered by setting minWithdrawalLimit_ if needed.\\n temp_ =\\n (maxWithdrawableLimit_ * temp_) /\\n // extract expand duration: After this, decrement won't happen (user can withdraw 100% of withdraw limit)\\n ((userSupplyData_ >> LiquiditySlotsLink.BITS_USER_SUPPLY_EXPAND_DURATION) & X24); // expand duration can never be 0\\n // calculate expanded withdrawal limit: last withdrawal limit - withdrawable amount.\\n // Note: withdrawable amount here can grow bigger than userSupply if timeElapsed is a lot bigger than expandDuration,\\n // which would cause the subtraction `lastWithdrawalLimit_ - withdrawableAmount_` to revert. In that case, set 0\\n // which will cause minimum (fully expanded) withdrawal limit to be set in lines below.\\n unchecked {\\n // underflow explicitly checked & handled\\n currentWithdrawalLimit_ = lastWithdrawalLimit_ > temp_ ? lastWithdrawalLimit_ - temp_ : 0;\\n // calculate minimum withdrawal limit: minimum amount of user supply that must stay supplied at full expansion.\\n // subtraction can not underflow as maxWithdrawableLimit_ is a percentage amount (<=100%) of userSupply_\\n temp_ = userSupply_ - maxWithdrawableLimit_;\\n }\\n // if withdrawal limit is decreased below minimum then set minimum\\n // (e.g. when more than expandDuration time has elapsed)\\n if (temp_ > currentWithdrawalLimit_) {\\n currentWithdrawalLimit_ = temp_;\\n }\\n }\\n\\n /// @dev calculates withdrawal limit after an operate execution:\\n /// amount of user supply that must stay supplied (not amount that can be withdrawn).\\n /// i.e. if user has supplied 100m and can withdraw 5M, this method returns the 95M, not the withdrawable amount 5M\\n /// @param userSupplyData_ user supply data packed uint256 from storage\\n /// @param userSupply_ current user supply amount already extracted from `userSupplyData_` and added / subtracted with the executed operate amount\\n /// @param newWithdrawalLimit_ current withdrawal limit updated for expansion since last interaction, result from `calcWithdrawalLimitBeforeOperate`\\n /// @return withdrawalLimit_ updated withdrawal limit that should be written to storage. returned value is in\\n /// raw for with interest mode, normal amount for interest free mode!\\n function calcWithdrawalLimitAfterOperate(\\n uint256 userSupplyData_,\\n uint256 userSupply_,\\n uint256 newWithdrawalLimit_\\n ) internal pure returns (uint256) {\\n // temp_ => base withdrawal limit. below this, maximum withdrawals are allowed\\n uint256 temp_ = (userSupplyData_ >> LiquiditySlotsLink.BITS_USER_SUPPLY_BASE_WITHDRAWAL_LIMIT) & X18;\\n temp_ = (temp_ >> DEFAULT_EXPONENT_SIZE) << (temp_ & DEFAULT_EXPONENT_MASK);\\n\\n // if user supply is below base limit then max withdrawals are allowed\\n if (userSupply_ < temp_) {\\n return 0;\\n }\\n // temp_ => withdrawal limit expandPercent (is in 1e2 decimals)\\n temp_ = (userSupplyData_ >> LiquiditySlotsLink.BITS_USER_SUPPLY_EXPAND_PERCENT) & X14;\\n unchecked {\\n // temp_ => minimum withdrawal limit: userSupply - max withdrawable limit (userSupply * expandPercent))\\n // userSupply_ needs to be atleast 1e73 to overflow max limit of ~1e77 in uint256 (no token in existence where this is possible).\\n // subtraction can not underflow as maxWithdrawableLimit_ is a percentage amount (<=100%) of userSupply_\\n temp_ = userSupply_ - ((userSupply_ * temp_) / FOUR_DECIMALS);\\n }\\n // if new (before operation) withdrawal limit is less than minimum limit then set minimum limit.\\n // e.g. can happen on new deposits. withdrawal limit is instantly fully expanded in a scenario where\\n // increased deposit amount outpaces withrawals.\\n if (temp_ > newWithdrawalLimit_) {\\n return temp_;\\n }\\n return newWithdrawalLimit_;\\n }\\n\\n /// @dev calculates borrow limit before an operate execution:\\n /// total amount user borrow can reach (not borrowable amount in current operation).\\n /// i.e. if user has borrowed 50M and can still borrow 5M, this method returns the total 55M, not the borrowable amount 5M\\n /// @param userBorrowData_ user borrow data packed uint256 from storage\\n /// @param userBorrow_ current user borrow amount already extracted from `userBorrowData_`\\n /// @return currentBorrowLimit_ current borrow limit updated for expansion since last interaction. returned value is in\\n /// raw for with interest mode, normal amount for interest free mode!\\n function calcBorrowLimitBeforeOperate(\\n uint256 userBorrowData_,\\n uint256 userBorrow_\\n ) internal view returns (uint256 currentBorrowLimit_) {\\n // @dev must support handling the case where timestamp is 0 (config is set but no interactions yet) -> base limit.\\n // first tx where timestamp is 0 will enter `if (maxExpandedBorrowLimit_ < baseBorrowLimit_)` because `userBorrow_` and thus\\n // `maxExpansionLimit_` and thus `maxExpandedBorrowLimit_` is 0 and `baseBorrowLimit_` can not be 0.\\n\\n // temp_ = extract borrow expand percent (is in 1e2 decimals)\\n uint256 temp_ = (userBorrowData_ >> LiquiditySlotsLink.BITS_USER_BORROW_EXPAND_PERCENT) & X14;\\n\\n uint256 maxExpansionLimit_;\\n uint256 maxExpandedBorrowLimit_;\\n unchecked {\\n // calculate max expansion limit: Max amount limit can expand to since last interaction\\n // userBorrow_ needs to be atleast 1e73 to overflow max limit of ~1e77 in uint256 (no token in existence where this is possible).\\n maxExpansionLimit_ = ((userBorrow_ * temp_) / FOUR_DECIMALS);\\n\\n // calculate max borrow limit: Max point limit can increase to since last interaction\\n maxExpandedBorrowLimit_ = userBorrow_ + maxExpansionLimit_;\\n }\\n\\n // currentBorrowLimit_ = extract base borrow limit\\n currentBorrowLimit_ = (userBorrowData_ >> LiquiditySlotsLink.BITS_USER_BORROW_BASE_BORROW_LIMIT) & X18;\\n currentBorrowLimit_ =\\n (currentBorrowLimit_ >> DEFAULT_EXPONENT_SIZE) <<\\n (currentBorrowLimit_ & DEFAULT_EXPONENT_MASK);\\n\\n if (maxExpandedBorrowLimit_ < currentBorrowLimit_) {\\n return currentBorrowLimit_;\\n }\\n // time elapsed since last borrow limit was set (in seconds)\\n unchecked {\\n // temp_ = timeElapsed_ (last timestamp can not be > current timestamp)\\n temp_ =\\n block.timestamp -\\n ((userBorrowData_ >> LiquiditySlotsLink.BITS_USER_BORROW_LAST_UPDATE_TIMESTAMP) & X33); // extract last update timestamp\\n }\\n\\n // currentBorrowLimit_ = expandedBorrowableAmount + extract last set borrow limit\\n currentBorrowLimit_ =\\n // calculate borrow limit expansion since last interaction for `expandPercent` that is elapsed of `expandDuration`.\\n // divisor is extract expand duration (after this, full expansion to expandPercentage happened).\\n ((maxExpansionLimit_ * temp_) /\\n ((userBorrowData_ >> LiquiditySlotsLink.BITS_USER_BORROW_EXPAND_DURATION) & X24)) + // expand duration can never be 0\\n // extract last set borrow limit\\n BigMathMinified.fromBigNumber(\\n (userBorrowData_ >> LiquiditySlotsLink.BITS_USER_BORROW_PREVIOUS_BORROW_LIMIT) & X64,\\n DEFAULT_EXPONENT_SIZE,\\n DEFAULT_EXPONENT_MASK\\n );\\n\\n // if timeElapsed is bigger than expandDuration, new borrow limit would be > max expansion,\\n // so set to `maxExpandedBorrowLimit_` in that case.\\n // also covers the case where last process timestamp = 0 (timeElapsed would simply be very big)\\n if (currentBorrowLimit_ > maxExpandedBorrowLimit_) {\\n currentBorrowLimit_ = maxExpandedBorrowLimit_;\\n }\\n // temp_ = extract hard max borrow limit. Above this user can never borrow (not expandable above)\\n temp_ = (userBorrowData_ >> LiquiditySlotsLink.BITS_USER_BORROW_MAX_BORROW_LIMIT) & X18;\\n temp_ = (temp_ >> DEFAULT_EXPONENT_SIZE) << (temp_ & DEFAULT_EXPONENT_MASK);\\n\\n if (currentBorrowLimit_ > temp_) {\\n currentBorrowLimit_ = temp_;\\n }\\n }\\n\\n /// @dev calculates borrow limit after an operate execution:\\n /// total amount user borrow can reach (not borrowable amount in current operation).\\n /// i.e. if user has borrowed 50M and can still borrow 5M, this method returns the total 55M, not the borrowable amount 5M\\n /// @param userBorrowData_ user borrow data packed uint256 from storage\\n /// @param userBorrow_ current user borrow amount already extracted from `userBorrowData_` and added / subtracted with the executed operate amount\\n /// @param newBorrowLimit_ current borrow limit updated for expansion since last interaction, result from `calcBorrowLimitBeforeOperate`\\n /// @return borrowLimit_ updated borrow limit that should be written to storage.\\n /// returned value is in raw for with interest mode, normal amount for interest free mode!\\n function calcBorrowLimitAfterOperate(\\n uint256 userBorrowData_,\\n uint256 userBorrow_,\\n uint256 newBorrowLimit_\\n ) internal pure returns (uint256 borrowLimit_) {\\n // temp_ = extract borrow expand percent\\n uint256 temp_ = (userBorrowData_ >> LiquiditySlotsLink.BITS_USER_BORROW_EXPAND_PERCENT) & X14; // (is in 1e2 decimals)\\n\\n unchecked {\\n // borrowLimit_ = calculate maximum borrow limit at full expansion.\\n // userBorrow_ needs to be at least 1e73 to overflow max limit of ~1e77 in uint256 (no token in existence where this is possible).\\n borrowLimit_ = userBorrow_ + ((userBorrow_ * temp_) / FOUR_DECIMALS);\\n }\\n\\n // temp_ = extract base borrow limit\\n temp_ = (userBorrowData_ >> LiquiditySlotsLink.BITS_USER_BORROW_BASE_BORROW_LIMIT) & X18;\\n temp_ = (temp_ >> DEFAULT_EXPONENT_SIZE) << (temp_ & DEFAULT_EXPONENT_MASK);\\n\\n if (borrowLimit_ < temp_) {\\n // below base limit, borrow limit is always base limit\\n return temp_;\\n }\\n // temp_ = extract hard max borrow limit. Above this user can never borrow (not expandable above)\\n temp_ = (userBorrowData_ >> LiquiditySlotsLink.BITS_USER_BORROW_MAX_BORROW_LIMIT) & X18;\\n temp_ = (temp_ >> DEFAULT_EXPONENT_SIZE) << (temp_ & DEFAULT_EXPONENT_MASK);\\n\\n // make sure fully expanded borrow limit is not above hard max borrow limit\\n if (borrowLimit_ > temp_) {\\n borrowLimit_ = temp_;\\n }\\n // if new borrow limit (from before operate) is > max borrow limit, set max borrow limit.\\n // (e.g. on a repay shrinking instantly to fully expanded borrow limit from new borrow amount. shrinking is instant)\\n if (newBorrowLimit_ > borrowLimit_) {\\n return borrowLimit_;\\n }\\n return newBorrowLimit_;\\n }\\n\\n ///////////////////////////////////////////////////////////////////////////\\n ////////// CALC RATES /////////\\n ///////////////////////////////////////////////////////////////////////////\\n\\n /// @dev Calculates new borrow rate from utilization for a token\\n /// @param rateData_ rate data packed uint256 from storage for the token\\n /// @param utilization_ totalBorrow / totalSupply. 1e4 = 100% utilization\\n /// @return rate_ rate for that particular token in 1e2 precision (e.g. 5% rate = 500)\\n function calcBorrowRateFromUtilization(uint256 rateData_, uint256 utilization_) internal returns (uint256 rate_) {\\n // extract rate version: 4 bits (0xF) starting from bit 0\\n uint256 rateVersion_ = (rateData_ & 0xF);\\n\\n if (rateVersion_ == 1) {\\n rate_ = calcRateV1(rateData_, utilization_);\\n } else if (rateVersion_ == 2) {\\n rate_ = calcRateV2(rateData_, utilization_);\\n } else {\\n revert FluidLiquidityCalcsError(ErrorTypes.LiquidityCalcs__UnsupportedRateVersion);\\n }\\n\\n if (rate_ > X16) {\\n // hard cap for borrow rate at maximum value 16 bits (65535) to make sure it does not overflow storage space.\\n // this is unlikely to ever happen if configs stay within expected levels.\\n rate_ = X16;\\n // emit event to more easily become aware\\n emit BorrowRateMaxCap();\\n }\\n }\\n\\n /// @dev calculates the borrow rate based on utilization for rate data version 1 (with one kink) in 1e2 precision\\n /// @param rateData_ rate data packed uint256 from storage for the token\\n /// @param utilization_ in 1e2 (100% = 1e4)\\n /// @return rate_ rate in 1e2 precision\\n function calcRateV1(uint256 rateData_, uint256 utilization_) internal pure returns (uint256 rate_) {\\n /// For rate v1 (one kink) ------------------------------------------------------\\n /// Next 16 bits => 4 - 19 => Rate at utilization 0% (in 1e2: 100% = 10_000; 1% = 100 -> max value 65535)\\n /// Next 16 bits => 20- 35 => Utilization at kink1 (in 1e2: 100% = 10_000; 1% = 100 -> max value 65535)\\n /// Next 16 bits => 36- 51 => Rate at utilization kink1 (in 1e2: 100% = 10_000; 1% = 100 -> max value 65535)\\n /// Next 16 bits => 52- 67 => Rate at utilization 100% (in 1e2: 100% = 10_000; 1% = 100 -> max value 65535)\\n /// Last 188 bits => 68-255 => blank, might come in use in future\\n\\n // y = mx + c.\\n // y is borrow rate\\n // x is utilization\\n // m = slope (m can also be negative for declining rates)\\n // c is constant (c can be negative)\\n\\n uint256 y1_;\\n uint256 y2_;\\n uint256 x1_;\\n uint256 x2_;\\n\\n // extract kink1: 16 bits (0xFFFF) starting from bit 20\\n // kink is in 1e2, same as utilization, so no conversion needed for direct comparison of the two\\n uint256 kink1_ = (rateData_ >> LiquiditySlotsLink.BITS_RATE_DATA_V1_UTILIZATION_AT_KINK) & X16;\\n if (utilization_ < kink1_) {\\n // if utilization is less than kink\\n y1_ = (rateData_ >> LiquiditySlotsLink.BITS_RATE_DATA_V1_RATE_AT_UTILIZATION_ZERO) & X16;\\n y2_ = (rateData_ >> LiquiditySlotsLink.BITS_RATE_DATA_V1_RATE_AT_UTILIZATION_KINK) & X16;\\n x1_ = 0; // 0%\\n x2_ = kink1_;\\n } else {\\n // else utilization is greater than kink\\n y1_ = (rateData_ >> LiquiditySlotsLink.BITS_RATE_DATA_V1_RATE_AT_UTILIZATION_KINK) & X16;\\n y2_ = (rateData_ >> LiquiditySlotsLink.BITS_RATE_DATA_V1_RATE_AT_UTILIZATION_MAX) & X16;\\n x1_ = kink1_;\\n x2_ = FOUR_DECIMALS; // 100%\\n }\\n\\n int256 constant_;\\n int256 slope_;\\n unchecked {\\n // calculating slope with twelve decimal precision. m = (y2 - y1) / (x2 - x1).\\n // utilization of x2 can not be <= utilization of x1 (so no underflow or 0 divisor)\\n // y is in 1e2 so can not overflow when multiplied with TWELVE_DECIMALS\\n slope_ = (int256(y2_ - y1_) * int256(TWELVE_DECIMALS)) / int256((x2_ - x1_));\\n\\n // calculating constant at 12 decimal precision. slope is already in 12 decimal hence only multiple with y1. c = y - mx.\\n // maximum y1_ value is 65535. 65535 * 1e12 can not overflow int256\\n // maximum slope is 65535 - 0 * TWELVE_DECIMALS / 1 = 65535 * 1e12;\\n // maximum x1_ is 100% (9_999 actually) => slope_ * x1_ can not overflow int256\\n // subtraction most extreme case would be 0 - max value slope_ * x1_ => can not underflow int256\\n constant_ = int256(y1_ * TWELVE_DECIMALS) - (slope_ * int256(x1_));\\n\\n // calculating new borrow rate\\n // - slope_ max value is 65535 * 1e12,\\n // - utilization max value is let's say 500% (extreme case where borrow rate increases borrow amount without new supply)\\n // - constant max value is 65535 * 1e12\\n // so max values are 65535 * 1e12 * 50_000 + 65535 * 1e12 -> 3.2768*10^21, which easily fits int256\\n // divisor TWELVE_DECIMALS can not be 0\\n slope_ = (slope_ * int256(utilization_)) + constant_; // reusing `slope_` as variable for gas savings\\n if (slope_ < 0) {\\n revert FluidLiquidityCalcsError(ErrorTypes.LiquidityCalcs__BorrowRateNegative);\\n }\\n rate_ = uint256(slope_) / TWELVE_DECIMALS;\\n }\\n }\\n\\n /// @dev calculates the borrow rate based on utilization for rate data version 2 (with two kinks) in 1e4 precision\\n /// @param rateData_ rate data packed uint256 from storage for the token\\n /// @param utilization_ in 1e2 (100% = 1e4)\\n /// @return rate_ rate in 1e4 precision\\n function calcRateV2(uint256 rateData_, uint256 utilization_) internal pure returns (uint256 rate_) {\\n /// For rate v2 (two kinks) -----------------------------------------------------\\n /// Next 16 bits => 4 - 19 => Rate at utilization 0% (in 1e2: 100% = 10_000; 1% = 100 -> max value 65535)\\n /// Next 16 bits => 20- 35 => Utilization at kink1 (in 1e2: 100% = 10_000; 1% = 100 -> max value 65535)\\n /// Next 16 bits => 36- 51 => Rate at utilization kink1 (in 1e2: 100% = 10_000; 1% = 100 -> max value 65535)\\n /// Next 16 bits => 52- 67 => Utilization at kink2 (in 1e2: 100% = 10_000; 1% = 100 -> max value 65535)\\n /// Next 16 bits => 68- 83 => Rate at utilization kink2 (in 1e2: 100% = 10_000; 1% = 100 -> max value 65535)\\n /// Next 16 bits => 84- 99 => Rate at utilization 100% (in 1e2: 100% = 10_000; 1% = 100 -> max value 65535)\\n /// Last 156 bits => 100-255 => blank, might come in use in future\\n\\n // y = mx + c.\\n // y is borrow rate\\n // x is utilization\\n // m = slope (m can also be negative for declining rates)\\n // c is constant (c can be negative)\\n\\n uint256 y1_;\\n uint256 y2_;\\n uint256 x1_;\\n uint256 x2_;\\n\\n // extract kink1: 16 bits (0xFFFF) starting from bit 20\\n // kink is in 1e2, same as utilization, so no conversion needed for direct comparison of the two\\n uint256 kink1_ = (rateData_ >> LiquiditySlotsLink.BITS_RATE_DATA_V2_UTILIZATION_AT_KINK1) & X16;\\n if (utilization_ < kink1_) {\\n // if utilization is less than kink1\\n y1_ = (rateData_ >> LiquiditySlotsLink.BITS_RATE_DATA_V2_RATE_AT_UTILIZATION_ZERO) & X16;\\n y2_ = (rateData_ >> LiquiditySlotsLink.BITS_RATE_DATA_V2_RATE_AT_UTILIZATION_KINK1) & X16;\\n x1_ = 0; // 0%\\n x2_ = kink1_;\\n } else {\\n // extract kink2: 16 bits (0xFFFF) starting from bit 52\\n uint256 kink2_ = (rateData_ >> LiquiditySlotsLink.BITS_RATE_DATA_V2_UTILIZATION_AT_KINK2) & X16;\\n if (utilization_ < kink2_) {\\n // if utilization is less than kink2\\n y1_ = (rateData_ >> LiquiditySlotsLink.BITS_RATE_DATA_V2_RATE_AT_UTILIZATION_KINK1) & X16;\\n y2_ = (rateData_ >> LiquiditySlotsLink.BITS_RATE_DATA_V2_RATE_AT_UTILIZATION_KINK2) & X16;\\n x1_ = kink1_;\\n x2_ = kink2_;\\n } else {\\n // else utilization is greater than kink2\\n y1_ = (rateData_ >> LiquiditySlotsLink.BITS_RATE_DATA_V2_RATE_AT_UTILIZATION_KINK2) & X16;\\n y2_ = (rateData_ >> LiquiditySlotsLink.BITS_RATE_DATA_V2_RATE_AT_UTILIZATION_MAX) & X16;\\n x1_ = kink2_;\\n x2_ = FOUR_DECIMALS;\\n }\\n }\\n\\n int256 constant_;\\n int256 slope_;\\n unchecked {\\n // calculating slope with twelve decimal precision. m = (y2 - y1) / (x2 - x1).\\n // utilization of x2 can not be <= utilization of x1 (so no underflow or 0 divisor)\\n // y is in 1e2 so can not overflow when multiplied with TWELVE_DECIMALS\\n slope_ = (int256(y2_ - y1_) * int256(TWELVE_DECIMALS)) / int256((x2_ - x1_));\\n\\n // calculating constant at 12 decimal precision. slope is already in 12 decimal hence only multiple with y1. c = y - mx.\\n // maximum y1_ value is 65535. 65535 * 1e12 can not overflow int256\\n // maximum slope is 65535 - 0 * TWELVE_DECIMALS / 1 = 65535 * 1e12;\\n // maximum x1_ is 100% (9_999 actually) => slope_ * x1_ can not overflow int256\\n // subtraction most extreme case would be 0 - max value slope_ * x1_ => can not underflow int256\\n constant_ = int256(y1_ * TWELVE_DECIMALS) - (slope_ * int256(x1_));\\n\\n // calculating new borrow rate\\n // - slope_ max value is 65535 * 1e12,\\n // - utilization max value is let's say 500% (extreme case where borrow rate increases borrow amount without new supply)\\n // - constant max value is 65535 * 1e12\\n // so max values are 65535 * 1e12 * 50_000 + 65535 * 1e12 -> 3.2768*10^21, which easily fits int256\\n // divisor TWELVE_DECIMALS can not be 0\\n slope_ = (slope_ * int256(utilization_)) + constant_; // reusing `slope_` as variable for gas savings\\n if (slope_ < 0) {\\n revert FluidLiquidityCalcsError(ErrorTypes.LiquidityCalcs__BorrowRateNegative);\\n }\\n rate_ = uint256(slope_) / TWELVE_DECIMALS;\\n }\\n }\\n\\n /// @dev reads the total supply out of Liquidity packed storage `totalAmounts_` for `supplyExchangePrice_`\\n function getTotalSupply(\\n uint256 totalAmounts_,\\n uint256 supplyExchangePrice_\\n ) internal pure returns (uint256 totalSupply_) {\\n // totalSupply_ => supplyInterestFree\\n totalSupply_ = (totalAmounts_ >> LiquiditySlotsLink.BITS_TOTAL_AMOUNTS_SUPPLY_INTEREST_FREE) & X64;\\n totalSupply_ = (totalSupply_ >> DEFAULT_EXPONENT_SIZE) << (totalSupply_ & DEFAULT_EXPONENT_MASK);\\n\\n uint256 totalSupplyRaw_ = totalAmounts_ & X64; // no shifting as supplyRaw is first 64 bits\\n totalSupplyRaw_ = (totalSupplyRaw_ >> DEFAULT_EXPONENT_SIZE) << (totalSupplyRaw_ & DEFAULT_EXPONENT_MASK);\\n\\n // totalSupply = supplyInterestFree + supplyRawInterest normalized from raw\\n totalSupply_ += ((totalSupplyRaw_ * supplyExchangePrice_) / EXCHANGE_PRICES_PRECISION);\\n }\\n\\n /// @dev reads the total borrow out of Liquidity packed storage `totalAmounts_` for `borrowExchangePrice_`\\n function getTotalBorrow(\\n uint256 totalAmounts_,\\n uint256 borrowExchangePrice_\\n ) internal pure returns (uint256 totalBorrow_) {\\n // totalBorrow_ => borrowInterestFree\\n // no & mask needed for borrow interest free as it occupies the last bits in the storage slot\\n totalBorrow_ = (totalAmounts_ >> LiquiditySlotsLink.BITS_TOTAL_AMOUNTS_BORROW_INTEREST_FREE);\\n totalBorrow_ = (totalBorrow_ >> DEFAULT_EXPONENT_SIZE) << (totalBorrow_ & DEFAULT_EXPONENT_MASK);\\n\\n uint256 totalBorrowRaw_ = (totalAmounts_ >> LiquiditySlotsLink.BITS_TOTAL_AMOUNTS_BORROW_WITH_INTEREST) & X64;\\n totalBorrowRaw_ = (totalBorrowRaw_ >> DEFAULT_EXPONENT_SIZE) << (totalBorrowRaw_ & DEFAULT_EXPONENT_MASK);\\n\\n // totalBorrow = borrowInterestFree + borrowRawInterest normalized from raw\\n totalBorrow_ += ((totalBorrowRaw_ * borrowExchangePrice_) / EXCHANGE_PRICES_PRECISION);\\n }\\n}\\n\",\"keccak256\":\"0xa65e2f84b2c33769ceb6b28fbd3221be29da2f8ac96e4d8b8cea91948d81a707\",\"license\":\"BUSL-1.1\"},\"contracts/libraries/liquiditySlotsLink.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\npragma solidity 0.8.21;\\n\\n/// @notice library that helps in reading / working with storage slot data of Fluid Liquidity.\\n/// @dev as all data for Fluid Liquidity is internal, any data must be fetched directly through manual\\n/// slot reading through this library or, if gas usage is less important, through the FluidLiquidityResolver.\\nlibrary LiquiditySlotsLink {\\n /// @dev storage slot for status at Liquidity\\n uint256 internal constant LIQUIDITY_STATUS_SLOT = 1;\\n /// @dev storage slot for auths mapping at Liquidity\\n uint256 internal constant LIQUIDITY_AUTHS_MAPPING_SLOT = 2;\\n /// @dev storage slot for guardians mapping at Liquidity\\n uint256 internal constant LIQUIDITY_GUARDIANS_MAPPING_SLOT = 3;\\n /// @dev storage slot for user class mapping at Liquidity\\n uint256 internal constant LIQUIDITY_USER_CLASS_MAPPING_SLOT = 4;\\n /// @dev storage slot for exchangePricesAndConfig mapping at Liquidity\\n uint256 internal constant LIQUIDITY_EXCHANGE_PRICES_MAPPING_SLOT = 5;\\n /// @dev storage slot for rateData mapping at Liquidity\\n uint256 internal constant LIQUIDITY_RATE_DATA_MAPPING_SLOT = 6;\\n /// @dev storage slot for totalAmounts mapping at Liquidity\\n uint256 internal constant LIQUIDITY_TOTAL_AMOUNTS_MAPPING_SLOT = 7;\\n /// @dev storage slot for user supply double mapping at Liquidity\\n uint256 internal constant LIQUIDITY_USER_SUPPLY_DOUBLE_MAPPING_SLOT = 8;\\n /// @dev storage slot for user borrow double mapping at Liquidity\\n uint256 internal constant LIQUIDITY_USER_BORROW_DOUBLE_MAPPING_SLOT = 9;\\n /// @dev storage slot for listed tokens array at Liquidity\\n uint256 internal constant LIQUIDITY_LISTED_TOKENS_ARRAY_SLOT = 10;\\n /// @dev storage slot for listed tokens array at Liquidity\\n uint256 internal constant LIQUIDITY_CONFIGS2_MAPPING_SLOT = 11;\\n\\n // --------------------------------\\n // @dev stacked uint256 storage slots bits position data for each:\\n\\n // ExchangePricesAndConfig\\n uint256 internal constant BITS_EXCHANGE_PRICES_BORROW_RATE = 0;\\n uint256 internal constant BITS_EXCHANGE_PRICES_FEE = 16;\\n uint256 internal constant BITS_EXCHANGE_PRICES_UTILIZATION = 30;\\n uint256 internal constant BITS_EXCHANGE_PRICES_UPDATE_THRESHOLD = 44;\\n uint256 internal constant BITS_EXCHANGE_PRICES_LAST_TIMESTAMP = 58;\\n uint256 internal constant BITS_EXCHANGE_PRICES_SUPPLY_EXCHANGE_PRICE = 91;\\n uint256 internal constant BITS_EXCHANGE_PRICES_BORROW_EXCHANGE_PRICE = 155;\\n uint256 internal constant BITS_EXCHANGE_PRICES_SUPPLY_RATIO = 219;\\n uint256 internal constant BITS_EXCHANGE_PRICES_BORROW_RATIO = 234;\\n uint256 internal constant BITS_EXCHANGE_PRICES_USES_CONFIGS2 = 249;\\n\\n // RateData:\\n uint256 internal constant BITS_RATE_DATA_VERSION = 0;\\n // RateData: V1\\n uint256 internal constant BITS_RATE_DATA_V1_RATE_AT_UTILIZATION_ZERO = 4;\\n uint256 internal constant BITS_RATE_DATA_V1_UTILIZATION_AT_KINK = 20;\\n uint256 internal constant BITS_RATE_DATA_V1_RATE_AT_UTILIZATION_KINK = 36;\\n uint256 internal constant BITS_RATE_DATA_V1_RATE_AT_UTILIZATION_MAX = 52;\\n // RateData: V2\\n uint256 internal constant BITS_RATE_DATA_V2_RATE_AT_UTILIZATION_ZERO = 4;\\n uint256 internal constant BITS_RATE_DATA_V2_UTILIZATION_AT_KINK1 = 20;\\n uint256 internal constant BITS_RATE_DATA_V2_RATE_AT_UTILIZATION_KINK1 = 36;\\n uint256 internal constant BITS_RATE_DATA_V2_UTILIZATION_AT_KINK2 = 52;\\n uint256 internal constant BITS_RATE_DATA_V2_RATE_AT_UTILIZATION_KINK2 = 68;\\n uint256 internal constant BITS_RATE_DATA_V2_RATE_AT_UTILIZATION_MAX = 84;\\n\\n // TotalAmounts\\n uint256 internal constant BITS_TOTAL_AMOUNTS_SUPPLY_WITH_INTEREST = 0;\\n uint256 internal constant BITS_TOTAL_AMOUNTS_SUPPLY_INTEREST_FREE = 64;\\n uint256 internal constant BITS_TOTAL_AMOUNTS_BORROW_WITH_INTEREST = 128;\\n uint256 internal constant BITS_TOTAL_AMOUNTS_BORROW_INTEREST_FREE = 192;\\n\\n // UserSupplyData\\n uint256 internal constant BITS_USER_SUPPLY_MODE = 0;\\n uint256 internal constant BITS_USER_SUPPLY_AMOUNT = 1;\\n uint256 internal constant BITS_USER_SUPPLY_PREVIOUS_WITHDRAWAL_LIMIT = 65;\\n uint256 internal constant BITS_USER_SUPPLY_LAST_UPDATE_TIMESTAMP = 129;\\n uint256 internal constant BITS_USER_SUPPLY_EXPAND_PERCENT = 162;\\n uint256 internal constant BITS_USER_SUPPLY_EXPAND_DURATION = 176;\\n uint256 internal constant BITS_USER_SUPPLY_BASE_WITHDRAWAL_LIMIT = 200;\\n uint256 internal constant BITS_USER_SUPPLY_IS_PAUSED = 255;\\n\\n // UserBorrowData\\n uint256 internal constant BITS_USER_BORROW_MODE = 0;\\n uint256 internal constant BITS_USER_BORROW_AMOUNT = 1;\\n uint256 internal constant BITS_USER_BORROW_PREVIOUS_BORROW_LIMIT = 65;\\n uint256 internal constant BITS_USER_BORROW_LAST_UPDATE_TIMESTAMP = 129;\\n uint256 internal constant BITS_USER_BORROW_EXPAND_PERCENT = 162;\\n uint256 internal constant BITS_USER_BORROW_EXPAND_DURATION = 176;\\n uint256 internal constant BITS_USER_BORROW_BASE_BORROW_LIMIT = 200;\\n uint256 internal constant BITS_USER_BORROW_MAX_BORROW_LIMIT = 218;\\n uint256 internal constant BITS_USER_BORROW_IS_PAUSED = 255;\\n\\n // Configs2\\n uint256 internal constant BITS_CONFIGS2_MAX_UTILIZATION = 0;\\n\\n // --------------------------------\\n\\n /// @notice Calculating the slot ID for Liquidity contract for single mapping at `slot_` for `key_`\\n function calculateMappingStorageSlot(uint256 slot_, address key_) internal pure returns (bytes32) {\\n return keccak256(abi.encode(key_, slot_));\\n }\\n\\n /// @notice Calculating the slot ID for Liquidity contract for double mapping at `slot_` for `key1_` and `key2_`\\n function calculateDoubleMappingStorageSlot(\\n uint256 slot_,\\n address key1_,\\n address key2_\\n ) internal pure returns (bytes32) {\\n bytes32 intermediateSlot_ = keccak256(abi.encode(key1_, slot_));\\n return keccak256(abi.encode(key2_, intermediateSlot_));\\n }\\n}\\n\",\"keccak256\":\"0x0ae3e1d231bb6c14b54fc1f5ffa306edc0ac827a6a92279c77c0c09627fe08ae\",\"license\":\"BUSL-1.1\"},\"contracts/libraries/safeTransfer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT OR Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport { LibsErrorTypes as ErrorTypes } from \\\"./errorTypes.sol\\\";\\n\\n/// @notice provides minimalistic methods for safe transfers, e.g. ERC20 safeTransferFrom\\nlibrary SafeTransfer {\\n error FluidSafeTransferError(uint256 errorId_);\\n\\n /// @dev Transfer `amount_` of `token_` from `from_` to `to_`, spending the approval given by `from_` to the\\n /// calling contract. If `token_` returns no value, non-reverting calls are assumed to be successful.\\n /// Minimally modified from Solmate SafeTransferLib (address as input param for token, Custom Error):\\n /// https://github.com/transmissions11/solmate/blob/50e15bb566f98b7174da9b0066126a4c3e75e0fd/src/utils/SafeTransferLib.sol#L31-L63\\n function safeTransferFrom(address token_, address from_, address to_, uint256 amount_) internal {\\n bool success_;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n // Get a pointer to some free memory.\\n let freeMemoryPointer := mload(0x40)\\n\\n // Write the abi-encoded calldata into memory, beginning with the function selector.\\n mstore(freeMemoryPointer, 0x23b872dd00000000000000000000000000000000000000000000000000000000)\\n mstore(add(freeMemoryPointer, 4), and(from_, 0xffffffffffffffffffffffffffffffffffffffff)) // Append and mask the \\\"from_\\\" argument.\\n mstore(add(freeMemoryPointer, 36), and(to_, 0xffffffffffffffffffffffffffffffffffffffff)) // Append and mask the \\\"to_\\\" argument.\\n mstore(add(freeMemoryPointer, 68), amount_) // Append the \\\"amount_\\\" argument. Masking not required as it's a full 32 byte type.\\n\\n success_ := and(\\n // Set success to whether the call reverted, if not we check it either\\n // returned exactly 1 (can't just be non-zero data), or had no return data.\\n or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())),\\n // We use 100 because the length of our calldata totals up like so: 4 + 32 * 3.\\n // We use 0 and 32 to copy up to 32 bytes of return data into the scratch space.\\n // Counterintuitively, this call must be positioned second to the or() call in the\\n // surrounding and() call or else returndatasize() will be zero during the computation.\\n call(gas(), token_, 0, freeMemoryPointer, 100, 0, 32)\\n )\\n }\\n\\n if (!success_) {\\n revert FluidSafeTransferError(ErrorTypes.SafeTransfer__TransferFromFailed);\\n }\\n }\\n\\n /// @dev Transfer `amount_` of `token_` to `to_`.\\n /// If `token_` returns no value, non-reverting calls are assumed to be successful.\\n /// Minimally modified from Solmate SafeTransferLib (address as input param for token, Custom Error):\\n /// https://github.com/transmissions11/solmate/blob/50e15bb566f98b7174da9b0066126a4c3e75e0fd/src/utils/SafeTransferLib.sol#L65-L95\\n function safeTransfer(address token_, address to_, uint256 amount_) internal {\\n bool success_;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n // Get a pointer to some free memory.\\n let freeMemoryPointer := mload(0x40)\\n\\n // Write the abi-encoded calldata into memory, beginning with the function selector.\\n mstore(freeMemoryPointer, 0xa9059cbb00000000000000000000000000000000000000000000000000000000)\\n mstore(add(freeMemoryPointer, 4), and(to_, 0xffffffffffffffffffffffffffffffffffffffff)) // Append and mask the \\\"to_\\\" argument.\\n mstore(add(freeMemoryPointer, 36), amount_) // Append the \\\"amount_\\\" argument. Masking not required as it's a full 32 byte type.\\n\\n success_ := and(\\n // Set success to whether the call reverted, if not we check it either\\n // returned exactly 1 (can't just be non-zero data), or had no return data.\\n or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())),\\n // We use 68 because the length of our calldata totals up like so: 4 + 32 * 2.\\n // We use 0 and 32 to copy up to 32 bytes of return data into the scratch space.\\n // Counterintuitively, this call must be positioned second to the or() call in the\\n // surrounding and() call or else returndatasize() will be zero during the computation.\\n call(gas(), token_, 0, freeMemoryPointer, 68, 0, 32)\\n )\\n }\\n\\n if (!success_) {\\n revert FluidSafeTransferError(ErrorTypes.SafeTransfer__TransferFailed);\\n }\\n }\\n\\n /// @dev Transfer `amount_` of ` native token to `to_`.\\n /// Minimally modified from Solmate SafeTransferLib (Custom Error):\\n /// https://github.com/transmissions11/solmate/blob/50e15bb566f98b7174da9b0066126a4c3e75e0fd/src/utils/SafeTransferLib.sol#L15-L25\\n function safeTransferNative(address to_, uint256 amount_) internal {\\n bool success_;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n // Transfer the ETH and store if it succeeded or not.\\n success_ := call(gas(), to_, amount_, 0, 0, 0, 0)\\n }\\n\\n if (!success_) {\\n revert FluidSafeTransferError(ErrorTypes.SafeTransfer__TransferFailed);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x7069d5801ef91035c666e05f11ccccdad310bbfc8f75b390cf44f69ff39d180d\",\"license\":\"MIT OR Apache-2.0\"},\"contracts/libraries/storageRead.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\npragma solidity 0.8.21;\\n\\n/// @notice implements a method to read uint256 data from storage at a bytes32 storage slot key.\\ncontract StorageRead {\\n function readFromStorage(bytes32 slot_) public view returns (uint256 result_) {\\n assembly {\\n result_ := sload(slot_) // read value from the storage slot\\n }\\n }\\n}\\n\",\"keccak256\":\"0x1b03dfe294c2f0376f7e34c3960fe7088d7ff44bb2ffd9cb2ac940486bfba8c9\",\"license\":\"BUSL-1.1\"},\"contracts/libraries/tickMath.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\npragma solidity 0.8.21;\\n\\n/// @title library that calculates number \\\"tick\\\" and \\\"ratioX96\\\" from this: ratioX96 = (1.0015^tick) * 2^96\\n/// @notice this library is used in Fluid Vault protocol for optimiziation.\\n/// @dev \\\"tick\\\" supports between -32767 and 32767. \\\"ratioX96\\\" supports between 37075072 and 169307877264527972847801929085841449095838922544595\\nlibrary TickMath {\\n /// The minimum tick that can be passed in getRatioAtTick. 1.0015**-32767\\n int24 internal constant MIN_TICK = -32767;\\n /// The maximum tick that can be passed in getRatioAtTick. 1.0015**32767\\n int24 internal constant MAX_TICK = 32767;\\n\\n uint256 internal constant FACTOR00 = 0x100000000000000000000000000000000;\\n uint256 internal constant FACTOR01 = 0xff9dd7de423466c20352b1246ce4856f; // 2^128/1.0015**1 = 339772707859149738855091969477551883631\\n uint256 internal constant FACTOR02 = 0xff3bd55f4488ad277531fa1c725a66d0; // 2^128/1.0015**2 = 339263812140938331358054887146831636176\\n uint256 internal constant FACTOR03 = 0xfe78410fd6498b73cb96a6917f853259; // 2^128/1.0015**4 = 338248306163758188337119769319392490073\\n uint256 internal constant FACTOR04 = 0xfcf2d9987c9be178ad5bfeffaa123273; // 2^128/1.0015**8 = 336226404141693512316971918999264834163\\n uint256 internal constant FACTOR05 = 0xf9ef02c4529258b057769680fc6601b3; // 2^128/1.0015**16 = 332218786018727629051611634067491389875\\n uint256 internal constant FACTOR06 = 0xf402d288133a85a17784a411f7aba082; // 2^128/1.0015**32 = 324346285652234375371948336458280706178\\n uint256 internal constant FACTOR07 = 0xe895615b5beb6386553757b0352bda90; // 2^128/1.0015**64 = 309156521885964218294057947947195947664\\n uint256 internal constant FACTOR08 = 0xd34f17a00ffa00a8309940a15930391a; // 2^128/1.0015**128 = 280877777739312896540849703637713172762 \\n uint256 internal constant FACTOR09 = 0xae6b7961714e20548d88ea5123f9a0ff; // 2^128/1.0015**256 = 231843708922198649176471782639349113087\\n uint256 internal constant FACTOR10 = 0x76d6461f27082d74e0feed3b388c0ca1; // 2^128/1.0015**512 = 157961477267171621126394973980180876449\\n uint256 internal constant FACTOR11 = 0x372a3bfe0745d8b6b19d985d9a8b85bb; // 2^128/1.0015**1024 = 73326833024599564193373530205717235131\\n uint256 internal constant FACTOR12 = 0x0be32cbee48979763cf7247dd7bb539d; // 2^128/1.0015**2048 = 15801066890623697521348224657638773661\\n uint256 internal constant FACTOR13 = 0x8d4f70c9ff4924dac37612d1e2921e; // 2^128/1.0015**4096 = 733725103481409245883800626999235102\\n uint256 internal constant FACTOR14 = 0x4e009ae5519380809a02ca7aec77; // 2^128/1.0015**8192 = 1582075887005588088019997442108535\\n uint256 internal constant FACTOR15 = 0x17c45e641b6e95dee056ff10; // 2^128/1.0015**16384 = 7355550435635883087458926352\\n\\n /// The minimum value that can be returned from getRatioAtTick. Equivalent to getRatioAtTick(MIN_TICK). ~ Equivalent to `(1 << 96) * (1.0015**-32767)`\\n uint256 internal constant MIN_RATIOX96 = 37075072;\\n /// The maximum value that can be returned from getRatioAtTick. Equivalent to getRatioAtTick(MAX_TICK).\\n /// ~ Equivalent to `(1 << 96) * (1.0015**32767)`, rounding etc. leading to minor difference\\n uint256 internal constant MAX_RATIOX96 = 169307877264527972847801929085841449095838922544595;\\n\\n uint256 internal constant ZERO_TICK_SCALED_RATIO = 0x1000000000000000000000000; // 1 << 96 // 79228162514264337593543950336\\n uint256 internal constant _1E26 = 1e26;\\n\\n /// @notice ratioX96 = (1.0015^tick) * 2^96\\n /// @dev Throws if |tick| > max tick\\n /// @param tick The input tick for the above formula\\n /// @return ratioX96 ratio = (debt amount/collateral amount)\\n function getRatioAtTick(int tick) internal pure returns (uint256 ratioX96) {\\n assembly {\\n let absTick_ := sub(xor(tick, sar(255, tick)), sar(255, tick))\\n\\n if gt(absTick_, MAX_TICK) {\\n revert(0, 0)\\n }\\n let factor_ := FACTOR00\\n if and(absTick_, 0x1) {\\n factor_ := FACTOR01\\n }\\n if and(absTick_, 0x2) {\\n factor_ := shr(128, mul(factor_, FACTOR02))\\n }\\n if and(absTick_, 0x4) {\\n factor_ := shr(128, mul(factor_, FACTOR03))\\n }\\n if and(absTick_, 0x8) {\\n factor_ := shr(128, mul(factor_, FACTOR04))\\n }\\n if and(absTick_, 0x10) {\\n factor_ := shr(128, mul(factor_, FACTOR05))\\n }\\n if and(absTick_, 0x20) {\\n factor_ := shr(128, mul(factor_, FACTOR06))\\n }\\n if and(absTick_, 0x40) {\\n factor_ := shr(128, mul(factor_, FACTOR07))\\n }\\n if and(absTick_, 0x80) {\\n factor_ := shr(128, mul(factor_, FACTOR08))\\n }\\n if and(absTick_, 0x100) {\\n factor_ := shr(128, mul(factor_, FACTOR09))\\n }\\n if and(absTick_, 0x200) {\\n factor_ := shr(128, mul(factor_, FACTOR10))\\n }\\n if and(absTick_, 0x400) {\\n factor_ := shr(128, mul(factor_, FACTOR11))\\n }\\n if and(absTick_, 0x800) {\\n factor_ := shr(128, mul(factor_, FACTOR12))\\n }\\n if and(absTick_, 0x1000) {\\n factor_ := shr(128, mul(factor_, FACTOR13))\\n }\\n if and(absTick_, 0x2000) {\\n factor_ := shr(128, mul(factor_, FACTOR14))\\n }\\n if and(absTick_, 0x4000) {\\n factor_ := shr(128, mul(factor_, FACTOR15))\\n }\\n\\n let precision_ := 0\\n if iszero(and(tick, 0x8000000000000000000000000000000000000000000000000000000000000000)) {\\n factor_ := div(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, factor_)\\n // we round up in the division so getTickAtRatio of the output price is always consistent\\n if mod(factor_, 0x100000000) {\\n precision_ := 1\\n }\\n }\\n ratioX96 := add(shr(32, factor_), precision_)\\n }\\n }\\n\\n /// @notice ratioX96 = (1.0015^tick) * 2^96\\n /// @dev Throws if ratioX96 > max ratio || ratioX96 < min ratio\\n /// @param ratioX96 The input ratio; ratio = (debt amount/collateral amount)\\n /// @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\\n /// @return perfectRatioX96 perfect ratio for the above tick\\n function getTickAtRatio(uint256 ratioX96) internal pure returns (int tick, uint perfectRatioX96) {\\n assembly {\\n if or(gt(ratioX96, MAX_RATIOX96), lt(ratioX96, MIN_RATIOX96)) {\\n revert(0, 0)\\n }\\n\\n let cond := lt(ratioX96, ZERO_TICK_SCALED_RATIO)\\n let factor_\\n\\n if iszero(cond) {\\n // if ratioX96 >= ZERO_TICK_SCALED_RATIO\\n factor_ := div(mul(ratioX96, _1E26), ZERO_TICK_SCALED_RATIO)\\n }\\n if cond {\\n // ratioX96 < ZERO_TICK_SCALED_RATIO\\n factor_ := div(mul(ZERO_TICK_SCALED_RATIO, _1E26), ratioX96)\\n }\\n\\n // put in https://www.wolframalpha.com/ whole equation: (1.0015^tick) * 2^96 * 10^26 / 79228162514264337593543950336\\n\\n // for tick = 16384\\n // ratioX96 = (1.0015^16384) * 2^96 = 3665252098134783297721995888537077351735\\n // 3665252098134783297721995888537077351735 * 10^26 / 79228162514264337593543950336 =\\n // 4626198540796508716348404308345255985.06131964639489434655721\\n if iszero(lt(factor_, 4626198540796508716348404308345255985)) {\\n tick := or(tick, 0x4000)\\n factor_ := div(mul(factor_, _1E26), 4626198540796508716348404308345255985)\\n }\\n // for tick = 8192\\n // ratioX96 = (1.0015^8192) * 2^96 = 17040868196391020479062776466509865\\n // 17040868196391020479062776466509865 * 10^26 / 79228162514264337593543950336 =\\n // 21508599537851153911767490449162.3037648642153898377655505172\\n if iszero(lt(factor_, 21508599537851153911767490449162)) {\\n tick := or(tick, 0x2000)\\n factor_ := div(mul(factor_, _1E26), 21508599537851153911767490449162)\\n }\\n // for tick = 4096\\n // ratioX96 = (1.0015^4096) * 2^96 = 36743933851015821532611831851150\\n // 36743933851015821532611831851150 * 10^26 / 79228162514264337593543950336 =\\n // 46377364670549310883002866648.9777607649742626173648716941385\\n if iszero(lt(factor_, 46377364670549310883002866649)) {\\n tick := or(tick, 0x1000)\\n factor_ := div(mul(factor_, _1E26), 46377364670549310883002866649)\\n }\\n // for tick = 2048\\n // ratioX96 = (1.0015^2048) * 2^96 = 1706210527034005899209104452335\\n // 1706210527034005899209104452335 * 10^26 / 79228162514264337593543950336 =\\n // 2153540449365864845468344760.06357108484096046743300420319322\\n if iszero(lt(factor_, 2153540449365864845468344760)) {\\n tick := or(tick, 0x800)\\n factor_ := div(mul(factor_, _1E26), 2153540449365864845468344760)\\n }\\n // for tick = 1024\\n // ratioX96 = (1.0015^1024) * 2^96 = 367668226692760093024536487236\\n // 367668226692760093024536487236 * 10^26 / 79228162514264337593543950336 =\\n // 464062544207767844008185024.950588990554136265212906454481127\\n if iszero(lt(factor_, 464062544207767844008185025)) {\\n tick := or(tick, 0x400)\\n factor_ := div(mul(factor_, _1E26), 464062544207767844008185025)\\n }\\n // for tick = 512\\n // ratioX96 = (1.0015^512) * 2^96 = 170674186729409605620119663668\\n // 170674186729409605620119663668 * 10^26 / 79228162514264337593543950336 =\\n // 215421109505955298802281577.031879604792139232258508172947569\\n if iszero(lt(factor_, 215421109505955298802281577)) {\\n tick := or(tick, 0x200)\\n factor_ := div(mul(factor_, _1E26), 215421109505955298802281577)\\n }\\n // for tick = 256\\n // ratioX96 = (1.0015^256) * 2^96 = 116285004205991934861656513301\\n // 116285004205991934861656513301 * 10^26 / 79228162514264337593543950336 =\\n // 146772309890508740607270614.667650899656438875541505058062410\\n if iszero(lt(factor_, 146772309890508740607270615)) {\\n tick := or(tick, 0x100)\\n factor_ := div(mul(factor_, _1E26), 146772309890508740607270615)\\n }\\n // for tick = 128\\n // ratioX96 = (1.0015^128) * 2^96 = 95984619659632141743747099590\\n // 95984619659632141743747099590 * 10^26 / 79228162514264337593543950336 =\\n // 121149622323187099817270416.157248837742741760456796835775887\\n if iszero(lt(factor_, 121149622323187099817270416)) {\\n tick := or(tick, 0x80)\\n factor_ := div(mul(factor_, _1E26), 121149622323187099817270416)\\n }\\n // for tick = 64\\n // ratioX96 = (1.0015^64) * 2^96 = 87204845308406958006717891124\\n // 87204845308406958006717891124 * 10^26 / 79228162514264337593543950336 =\\n // 110067989135437147685980801.568068573422377364214113968609839\\n if iszero(lt(factor_, 110067989135437147685980801)) {\\n tick := or(tick, 0x40)\\n factor_ := div(mul(factor_, _1E26), 110067989135437147685980801)\\n }\\n // for tick = 32\\n // ratioX96 = (1.0015^32) * 2^96 = 83120873769022354029916374475\\n // 83120873769022354029916374475 * 10^26 / 79228162514264337593543950336 =\\n // 104913292358707887270979599.831816586773651266562785765558183\\n if iszero(lt(factor_, 104913292358707887270979600)) {\\n tick := or(tick, 0x20)\\n factor_ := div(mul(factor_, _1E26), 104913292358707887270979600)\\n }\\n // for tick = 16\\n // ratioX96 = (1.0015^16) * 2^96 = 81151180492336368327184716176\\n // 81151180492336368327184716176 * 10^26 / 79228162514264337593543950336 =\\n // 102427189924701091191840927.762844039579442328381455567932128\\n if iszero(lt(factor_, 102427189924701091191840928)) {\\n tick := or(tick, 0x10)\\n factor_ := div(mul(factor_, _1E26), 102427189924701091191840928)\\n }\\n // for tick = 8\\n // ratioX96 = (1.0015^8) * 2^96 = 80183906840906820640659903620\\n // 80183906840906820640659903620 * 10^26 / 79228162514264337593543950336 =\\n // 101206318935480056907421312.890625\\n if iszero(lt(factor_, 101206318935480056907421313)) {\\n tick := or(tick, 0x8)\\n factor_ := div(mul(factor_, _1E26), 101206318935480056907421313)\\n }\\n // for tick = 4\\n // ratioX96 = (1.0015^4) * 2^96 = 79704602139525152702959747603\\n // 79704602139525152702959747603 * 10^26 / 79228162514264337593543950336 =\\n // 100601351350506250000000000\\n if iszero(lt(factor_, 100601351350506250000000000)) {\\n tick := or(tick, 0x4)\\n factor_ := div(mul(factor_, _1E26), 100601351350506250000000000)\\n }\\n // for tick = 2\\n // ratioX96 = (1.0015^2) * 2^96 = 79466025265172787701084167660\\n // 79466025265172787701084167660 * 10^26 / 79228162514264337593543950336 =\\n // 100300225000000000000000000\\n if iszero(lt(factor_, 100300225000000000000000000)) {\\n tick := or(tick, 0x2)\\n factor_ := div(mul(factor_, _1E26), 100300225000000000000000000)\\n }\\n // for tick = 1\\n // ratioX96 = (1.0015^1) * 2^96 = 79347004758035734099934266261\\n // 79347004758035734099934266261 * 10^26 / 79228162514264337593543950336 =\\n // 100150000000000000000000000\\n if iszero(lt(factor_, 100150000000000000000000000)) {\\n tick := or(tick, 0x1)\\n factor_ := div(mul(factor_, _1E26), 100150000000000000000000000)\\n }\\n if iszero(cond) {\\n // if ratioX96 >= ZERO_TICK_SCALED_RATIO\\n perfectRatioX96 := div(mul(ratioX96, _1E26), factor_)\\n }\\n if cond {\\n // ratioX96 < ZERO_TICK_SCALED_RATIO\\n tick := not(tick)\\n perfectRatioX96 := div(mul(ratioX96, factor_), 100150000000000000000000000)\\n }\\n // perfect ratio should always be <= ratioX96\\n // not sure if it can ever be bigger but better to have extra checks\\n if gt(perfectRatioX96, ratioX96) {\\n revert(0, 0)\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xc5c13deaa16bb036a4370c0e38c33445712e8e7da1c792018dd3dc4a641ea0c0\",\"license\":\"BUSL-1.1\"},\"contracts/liquidity/adminModule/structs.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\npragma solidity 0.8.21;\\n\\nabstract contract Structs {\\n struct AddressBool {\\n address addr;\\n bool value;\\n }\\n\\n struct AddressUint256 {\\n address addr;\\n uint256 value;\\n }\\n\\n /// @notice struct to set borrow rate data for version 1\\n struct RateDataV1Params {\\n ///\\n /// @param token for rate data\\n address token;\\n ///\\n /// @param kink in borrow rate. in 1e2: 100% = 10_000; 1% = 100\\n /// utilization below kink usually means slow increase in rate, once utilization is above kink borrow rate increases fast\\n uint256 kink;\\n ///\\n /// @param rateAtUtilizationZero desired borrow rate when utilization is zero. in 1e2: 100% = 10_000; 1% = 100\\n /// i.e. constant minimum borrow rate\\n /// e.g. at utilization = 0.01% rate could still be at least 4% (rateAtUtilizationZero would be 400 then)\\n uint256 rateAtUtilizationZero;\\n ///\\n /// @param rateAtUtilizationKink borrow rate when utilization is at kink. in 1e2: 100% = 10_000; 1% = 100\\n /// e.g. when rate should be 7% at kink then rateAtUtilizationKink would be 700\\n uint256 rateAtUtilizationKink;\\n ///\\n /// @param rateAtUtilizationMax borrow rate when utilization is maximum at 100%. in 1e2: 100% = 10_000; 1% = 100\\n /// e.g. when rate should be 125% at 100% then rateAtUtilizationMax would be 12_500\\n uint256 rateAtUtilizationMax;\\n }\\n\\n /// @notice struct to set borrow rate data for version 2\\n struct RateDataV2Params {\\n ///\\n /// @param token for rate data\\n address token;\\n ///\\n /// @param kink1 first kink in borrow rate. in 1e2: 100% = 10_000; 1% = 100\\n /// utilization below kink 1 usually means slow increase in rate, once utilization is above kink 1 borrow rate increases faster\\n uint256 kink1;\\n ///\\n /// @param kink2 second kink in borrow rate. in 1e2: 100% = 10_000; 1% = 100\\n /// utilization below kink 2 usually means slow / medium increase in rate, once utilization is above kink 2 borrow rate increases fast\\n uint256 kink2;\\n ///\\n /// @param rateAtUtilizationZero desired borrow rate when utilization is zero. in 1e2: 100% = 10_000; 1% = 100\\n /// i.e. constant minimum borrow rate\\n /// e.g. at utilization = 0.01% rate could still be at least 4% (rateAtUtilizationZero would be 400 then)\\n uint256 rateAtUtilizationZero;\\n ///\\n /// @param rateAtUtilizationKink1 desired borrow rate when utilization is at first kink. in 1e2: 100% = 10_000; 1% = 100\\n /// e.g. when rate should be 7% at first kink then rateAtUtilizationKink would be 700\\n uint256 rateAtUtilizationKink1;\\n ///\\n /// @param rateAtUtilizationKink2 desired borrow rate when utilization is at second kink. in 1e2: 100% = 10_000; 1% = 100\\n /// e.g. when rate should be 7% at second kink then rateAtUtilizationKink would be 1_200\\n uint256 rateAtUtilizationKink2;\\n ///\\n /// @param rateAtUtilizationMax desired borrow rate when utilization is maximum at 100%. in 1e2: 100% = 10_000; 1% = 100\\n /// e.g. when rate should be 125% at 100% then rateAtUtilizationMax would be 12_500\\n uint256 rateAtUtilizationMax;\\n }\\n\\n /// @notice struct to set token config\\n struct TokenConfig {\\n ///\\n /// @param token address\\n address token;\\n ///\\n /// @param fee charges on borrower's interest. in 1e2: 100% = 10_000; 1% = 100\\n uint256 fee;\\n ///\\n /// @param threshold on when to update the storage slot. in 1e2: 100% = 10_000; 1% = 100\\n uint256 threshold;\\n ///\\n /// @param maxUtilization maximum allowed utilization. in 1e2: 100% = 10_000; 1% = 100\\n /// set to 100% to disable and have default limit of 100% (avoiding SLOAD).\\n uint256 maxUtilization;\\n }\\n\\n /// @notice struct to set user supply & withdrawal config\\n struct UserSupplyConfig {\\n ///\\n /// @param user address\\n address user;\\n ///\\n /// @param token address\\n address token;\\n ///\\n /// @param mode: 0 = without interest. 1 = with interest\\n uint8 mode;\\n ///\\n /// @param expandPercent withdrawal limit expand percent. in 1e2: 100% = 10_000; 1% = 100\\n /// Also used to calculate rate at which withdrawal limit should decrease (instant).\\n uint256 expandPercent;\\n ///\\n /// @param expandDuration withdrawal limit expand duration in seconds.\\n /// used to calculate rate together with expandPercent\\n uint256 expandDuration;\\n ///\\n /// @param baseWithdrawalLimit base limit, below this, user can withdraw the entire amount.\\n /// amount in raw (to be multiplied with exchange price) or normal depends on configured mode in user config for the token:\\n /// with interest -> raw, without interest -> normal\\n uint256 baseWithdrawalLimit;\\n }\\n\\n /// @notice struct to set user borrow & payback config\\n struct UserBorrowConfig {\\n ///\\n /// @param user address\\n address user;\\n ///\\n /// @param token address\\n address token;\\n ///\\n /// @param mode: 0 = without interest. 1 = with interest\\n uint8 mode;\\n ///\\n /// @param expandPercent debt limit expand percent. in 1e2: 100% = 10_000; 1% = 100\\n /// Also used to calculate rate at which debt limit should decrease (instant).\\n uint256 expandPercent;\\n ///\\n /// @param expandDuration debt limit expand duration in seconds.\\n /// used to calculate rate together with expandPercent\\n uint256 expandDuration;\\n ///\\n /// @param baseDebtCeiling base borrow limit. until here, borrow limit remains as baseDebtCeiling\\n /// (user can borrow until this point at once without stepped expansion). Above this, automated limit comes in place.\\n /// amount in raw (to be multiplied with exchange price) or normal depends on configured mode in user config for the token:\\n /// with interest -> raw, without interest -> normal\\n uint256 baseDebtCeiling;\\n ///\\n /// @param maxDebtCeiling max borrow ceiling, maximum amount the user can borrow.\\n /// amount in raw (to be multiplied with exchange price) or normal depends on configured mode in user config for the token:\\n /// with interest -> raw, without interest -> normal\\n uint256 maxDebtCeiling;\\n }\\n}\\n\",\"keccak256\":\"0x10353c70015f27b880125cefab806dbed24a4458f187da66964f3ef60488f757\",\"license\":\"BUSL-1.1\"},\"contracts/liquidity/interfaces/iLiquidity.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\npragma solidity 0.8.21;\\n\\nimport { IProxy } from \\\"../../infiniteProxy/interfaces/iProxy.sol\\\";\\nimport { Structs as AdminModuleStructs } from \\\"../adminModule/structs.sol\\\";\\n\\ninterface IFluidLiquidityAdmin {\\n /// @notice adds/removes auths. Auths generally could be contracts which can have restricted actions defined on contract.\\n /// auths can be helpful in reducing governance overhead where it's not needed.\\n /// @param authsStatus_ array of structs setting allowed status for an address.\\n /// status true => add auth, false => remove auth\\n function updateAuths(AdminModuleStructs.AddressBool[] calldata authsStatus_) external;\\n\\n /// @notice adds/removes guardians. Only callable by Governance.\\n /// @param guardiansStatus_ array of structs setting allowed status for an address.\\n /// status true => add guardian, false => remove guardian\\n function updateGuardians(AdminModuleStructs.AddressBool[] calldata guardiansStatus_) external;\\n\\n /// @notice changes the revenue collector address (contract that is sent revenue). Only callable by Governance.\\n /// @param revenueCollector_ new revenue collector address\\n function updateRevenueCollector(address revenueCollector_) external;\\n\\n /// @notice changes current status, e.g. for pausing or unpausing all user operations. Only callable by Auths.\\n /// @param newStatus_ new status\\n /// status = 2 -> pause, status = 1 -> resume.\\n function changeStatus(uint256 newStatus_) external;\\n\\n /// @notice update tokens rate data version 1. Only callable by Auths.\\n /// @param tokensRateData_ array of RateDataV1Params with rate data to set for each token\\n function updateRateDataV1s(AdminModuleStructs.RateDataV1Params[] calldata tokensRateData_) external;\\n\\n /// @notice update tokens rate data version 2. Only callable by Auths.\\n /// @param tokensRateData_ array of RateDataV2Params with rate data to set for each token\\n function updateRateDataV2s(AdminModuleStructs.RateDataV2Params[] calldata tokensRateData_) external;\\n\\n /// @notice updates token configs: fee charge on borrowers interest & storage update utilization threshold.\\n /// Only callable by Auths.\\n /// @param tokenConfigs_ contains token address, fee & utilization threshold\\n function updateTokenConfigs(AdminModuleStructs.TokenConfig[] calldata tokenConfigs_) external;\\n\\n /// @notice updates user classes: 0 is for new protocols, 1 is for established protocols.\\n /// Only callable by Auths.\\n /// @param userClasses_ struct array of uint256 value to assign for each user address\\n function updateUserClasses(AdminModuleStructs.AddressUint256[] calldata userClasses_) external;\\n\\n /// @notice sets user supply configs per token basis. Eg: with interest or interest-free and automated limits.\\n /// Only callable by Auths.\\n /// @param userSupplyConfigs_ struct array containing user supply config, see `UserSupplyConfig` struct for more info\\n function updateUserSupplyConfigs(AdminModuleStructs.UserSupplyConfig[] memory userSupplyConfigs_) external;\\n\\n /// @notice setting user borrow configs per token basis. Eg: with interest or interest-free and automated limits.\\n /// Only callable by Auths.\\n /// @param userBorrowConfigs_ struct array containing user borrow config, see `UserBorrowConfig` struct for more info\\n function updateUserBorrowConfigs(AdminModuleStructs.UserBorrowConfig[] memory userBorrowConfigs_) external;\\n\\n /// @notice pause operations for a particular user in class 0 (class 1 users can't be paused by guardians).\\n /// Only callable by Guardians.\\n /// @param user_ address of user to pause operations for\\n /// @param supplyTokens_ token addresses to pause withdrawals for\\n /// @param borrowTokens_ token addresses to pause borrowings for\\n function pauseUser(address user_, address[] calldata supplyTokens_, address[] calldata borrowTokens_) external;\\n\\n /// @notice unpause operations for a particular user in class 0 (class 1 users can't be paused by guardians).\\n /// Only callable by Guardians.\\n /// @param user_ address of user to unpause operations for\\n /// @param supplyTokens_ token addresses to unpause withdrawals for\\n /// @param borrowTokens_ token addresses to unpause borrowings for\\n function unpauseUser(address user_, address[] calldata supplyTokens_, address[] calldata borrowTokens_) external;\\n\\n /// @notice collects revenue for tokens to configured revenueCollector address.\\n /// @param tokens_ array of tokens to collect revenue for\\n /// @dev Note that this can revert if token balance is < revenueAmount (utilization > 100%)\\n function collectRevenue(address[] calldata tokens_) external;\\n\\n /// @notice gets the current updated exchange prices for n tokens and updates all prices, rates related data in storage.\\n /// @param tokens_ tokens to update exchange prices for\\n /// @return supplyExchangePrices_ new supply rates of overall system for each token\\n /// @return borrowExchangePrices_ new borrow rates of overall system for each token\\n function updateExchangePrices(\\n address[] calldata tokens_\\n ) external returns (uint256[] memory supplyExchangePrices_, uint256[] memory borrowExchangePrices_);\\n}\\n\\ninterface IFluidLiquidityLogic is IFluidLiquidityAdmin {\\n /// @notice Single function which handles supply, withdraw, borrow & payback\\n /// @param token_ address of token (0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE for native)\\n /// @param supplyAmount_ if +ve then supply, if -ve then withdraw, if 0 then nothing\\n /// @param borrowAmount_ if +ve then borrow, if -ve then payback, if 0 then nothing\\n /// @param withdrawTo_ if withdrawal then to which address\\n /// @param borrowTo_ if borrow then to which address\\n /// @param callbackData_ callback data passed to `liquidityCallback` method of protocol\\n /// @return memVar3_ updated supplyExchangePrice\\n /// @return memVar4_ updated borrowExchangePrice\\n /// @dev to trigger skipping in / out transfers when in&out amounts balance themselves out (gas optimization):\\n /// - supply(+) == borrow(+), withdraw(-) == payback(-).\\n /// - `withdrawTo_` / `borrowTo_` must be msg.sender (protocol)\\n /// - `callbackData_` MUST be encoded so that \\\"from\\\" address is at last 20 bytes (if this optimization is desired),\\n /// also for native token operations where liquidityCallback is not triggered!\\n /// from address must come at last position if there is more data. I.e. encode like:\\n /// abi.encode(otherVar1, otherVar2, FROM_ADDRESS). Note dynamic types used with abi.encode come at the end\\n /// so if dynamic types are needed, you must use abi.encodePacked to ensure the from address is at the end.\\n function operate(\\n address token_,\\n int256 supplyAmount_,\\n int256 borrowAmount_,\\n address withdrawTo_,\\n address borrowTo_,\\n bytes calldata callbackData_\\n ) external payable returns (uint256 memVar3_, uint256 memVar4_);\\n}\\n\\ninterface IFluidLiquidity is IProxy, IFluidLiquidityLogic {}\\n\",\"keccak256\":\"0xc81ac0cfc8183ec57ec4e488b07a4f6d1ecd79787e0aaf0dcfdd0b9b7ac0fc84\",\"license\":\"MIT\"},\"contracts/oracle/fluidOracle.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\npragma solidity 0.8.21;\\n\\nimport { IFluidOracle } from \\\"./interfaces/iFluidOracle.sol\\\";\\n\\n/// @title FluidOracle\\n/// @notice Base contract that any Fluid Oracle must implement\\nabstract contract FluidOracle is IFluidOracle {\\n /// @inheritdoc IFluidOracle\\n function getExchangeRate() external view virtual returns (uint256 exchangeRate_);\\n\\n /// @inheritdoc IFluidOracle\\n function getExchangeRateOperate() external view virtual returns (uint256 exchangeRate_);\\n\\n /// @inheritdoc IFluidOracle\\n function getExchangeRateLiquidate() external view virtual returns (uint256 exchangeRate_);\\n}\\n\",\"keccak256\":\"0xd275b5b0ada86c81a4dc6c79a24b1cb8bcfc374f4856e08917bf1bae83574b37\",\"license\":\"BUSL-1.1\"},\"contracts/oracle/interfaces/iFluidOracle.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.21;\\n\\ninterface IFluidOracle {\\n /// @dev Deprecated. Use `getExchangeRateOperate()` and `getExchangeRateLiquidate()` instead. Only implemented for\\n /// backwards compatibility.\\n function getExchangeRate() external view returns (uint256 exchangeRate_);\\n\\n /// @notice Get the `exchangeRate_` between the underlying asset and the peg asset in 1e27 for operates\\n function getExchangeRateOperate() external view returns (uint256 exchangeRate_);\\n\\n /// @notice Get the `exchangeRate_` between the underlying asset and the peg asset in 1e27 for liquidations\\n function getExchangeRateLiquidate() external view returns (uint256 exchangeRate_);\\n}\\n\",\"keccak256\":\"0x410b5f85b64414df35131bbf322261e2a11956d58af3800d8b71b5befb9907d4\",\"license\":\"MIT\"},\"contracts/protocols/vault/error.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\npragma solidity 0.8.21;\\n\\ncontract Error {\\n error FluidVaultError(uint256 errorId_);\\n\\n /// @notice used to simulate liquidation to find the maximum liquidatable amounts\\n error FluidLiquidateResult(uint256 colLiquidated, uint256 debtLiquidated);\\n}\\n\",\"keccak256\":\"0x84d885c40fdca6828cb4cdc206c852fc4ad7e52f7621e2a63b151742123196f5\",\"license\":\"BUSL-1.1\"},\"contracts/protocols/vault/errorTypes.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\npragma solidity 0.8.21;\\n\\nlibrary ErrorTypes {\\n /***********************************|\\n | Vault Factory | \\n |__________________________________*/\\n\\n uint256 internal constant VaultFactory__InvalidOperation = 30001;\\n uint256 internal constant VaultFactory__Unauthorized = 30002;\\n uint256 internal constant VaultFactory__SameTokenNotAllowed = 30003;\\n uint256 internal constant VaultFactory__InvalidParams = 30004;\\n uint256 internal constant VaultFactory__InvalidVault = 30005;\\n uint256 internal constant VaultFactory__InvalidVaultAddress = 30006;\\n uint256 internal constant VaultFactory__OnlyDelegateCallAllowed = 30007;\\n\\n /***********************************|\\n | VaultT1 | \\n |__________________________________*/\\n\\n /// @notice thrown at reentrancy\\n uint256 internal constant VaultT1__AlreadyEntered = 31001;\\n\\n /// @notice thrown when user sends deposit & borrow amount as 0\\n uint256 internal constant VaultT1__InvalidOperateAmount = 31002;\\n\\n /// @notice thrown when msg.value is not in sync with native token deposit or payback\\n uint256 internal constant VaultT1__InvalidMsgValueOperate = 31003;\\n\\n /// @notice thrown when msg.sender is not the owner of the vault\\n uint256 internal constant VaultT1__NotAnOwner = 31004;\\n\\n /// @notice thrown when user's position does not exist. Sending the wrong index from the frontend\\n uint256 internal constant VaultT1__TickIsEmpty = 31005;\\n\\n /// @notice thrown when the user's position is above CF and the user tries to make it more risky by trying to withdraw or borrow\\n uint256 internal constant VaultT1__PositionAboveCF = 31006;\\n\\n /// @notice thrown when the top tick is not initialized. Happens if the vault is totally new or all the user's left\\n uint256 internal constant VaultT1__TopTickDoesNotExist = 31007;\\n\\n /// @notice thrown when msg.value in liquidate is not in sync payback\\n uint256 internal constant VaultT1__InvalidMsgValueLiquidate = 31008;\\n\\n /// @notice thrown when slippage is more on liquidation than what the liquidator sent\\n uint256 internal constant VaultT1__ExcessSlippageLiquidation = 31009;\\n\\n /// @notice thrown when msg.sender is not the rebalancer/reserve contract\\n uint256 internal constant VaultT1__NotRebalancer = 31010;\\n\\n /// @notice thrown when NFT of one vault interacts with the NFT of other vault\\n uint256 internal constant VaultT1__NftNotOfThisVault = 31011;\\n\\n /// @notice thrown when the token is not initialized on the liquidity contract\\n uint256 internal constant VaultT1__TokenNotInitialized = 31012;\\n\\n /// @notice thrown when admin updates fallback if a non-auth calls vault\\n uint256 internal constant VaultT1__NotAnAuth = 31013;\\n\\n /// @notice thrown in operate when user tries to witdhraw more collateral than deposited\\n uint256 internal constant VaultT1__ExcessCollateralWithdrawal = 31014;\\n\\n /// @notice thrown in operate when user tries to payback more debt than borrowed\\n uint256 internal constant VaultT1__ExcessDebtPayback = 31015;\\n\\n /// @notice thrown when user try to withdrawal more than operate's withdrawal limit\\n uint256 internal constant VaultT1__WithdrawMoreThanOperateLimit = 31016;\\n\\n /// @notice thrown when caller of liquidityCallback is not Liquidity\\n uint256 internal constant VaultT1__InvalidLiquidityCallbackAddress = 31017;\\n\\n /// @notice thrown when reentrancy is not already on\\n uint256 internal constant VaultT1__NotEntered = 31018;\\n\\n /// @notice thrown when someone directly calls secondary implementation contract\\n uint256 internal constant VaultT1__OnlyDelegateCallAllowed = 31019;\\n\\n /// @notice thrown when the safeTransferFrom for a token amount failed\\n uint256 internal constant VaultT1__TransferFromFailed = 31020;\\n\\n /// @notice thrown when exchange price overflows while updating on storage\\n uint256 internal constant VaultT1__ExchangePriceOverFlow = 31021;\\n\\n /// @notice thrown when debt to liquidate amt is sent wrong\\n uint256 internal constant VaultT1__InvalidLiquidationAmt = 31022;\\n\\n /// @notice thrown when user debt or collateral goes above 2**128 or below -2**128\\n uint256 internal constant VaultT1__UserCollateralDebtExceed = 31023;\\n\\n /// @notice thrown if on liquidation branch debt becomes lower than 100\\n uint256 internal constant VaultT1__BranchDebtTooLow = 31024;\\n\\n /// @notice thrown when tick's debt is less than 10000\\n uint256 internal constant VaultT1__TickDebtTooLow = 31025;\\n\\n /// @notice thrown when the received new liquidity exchange price is of unexpected value (< than the old one)\\n uint256 internal constant VaultT1__LiquidityExchangePriceUnexpected = 31026;\\n\\n /// @notice thrown when user's debt is less than 10000\\n uint256 internal constant VaultT1__UserDebtTooLow = 31027;\\n\\n /// @notice thrown when on only payback and only deposit the ratio of position increases\\n uint256 internal constant VaultT1__InvalidPaybackOrDeposit = 31028;\\n\\n /// @notice thrown when liquidation just happens of a single partial or when there's nothing to liquidate\\n uint256 internal constant VaultT1__InvalidLiquidation = 31029;\\n\\n /// @notice thrown when msg.value is sent wrong in rebalance\\n uint256 internal constant VaultT1__InvalidMsgValueInRebalance = 31030;\\n\\n /// @notice thrown when nothing rebalanced\\n uint256 internal constant VaultT1__NothingToRebalance = 31031;\\n\\n /// @notice thrown on unforseen liquidation scenarios. Might never come in use.\\n uint256 internal constant VaultT1__LiquidationReverts = 31032;\\n\\n /// @notice thrown when oracle price is > 1e54\\n uint256 internal constant VaultT1__InvalidOraclePrice = 31033;\\n\\n /***********************************|\\n | ERC721 | \\n |__________________________________*/\\n\\n uint256 internal constant ERC721__InvalidParams = 32001;\\n uint256 internal constant ERC721__Unauthorized = 32002;\\n uint256 internal constant ERC721__InvalidOperation = 32003;\\n uint256 internal constant ERC721__UnsafeRecipient = 32004;\\n uint256 internal constant ERC721__OutOfBoundsIndex = 32005;\\n\\n /***********************************|\\n | Vault Admin | \\n |__________________________________*/\\n\\n /// @notice thrown when admin tries to setup invalid value which are crossing limits\\n uint256 internal constant VaultT1Admin__ValueAboveLimit = 33001;\\n\\n /// @notice when someone directly calls admin implementation contract\\n uint256 internal constant VaultT1Admin__OnlyDelegateCallAllowed = 33002;\\n\\n /// @notice thrown when auth sends NFT ID as 0 while collecting dust debt\\n uint256 internal constant VaultT1Admin__NftIdShouldBeNonZero = 33003;\\n\\n /// @notice thrown when trying to collect dust debt of NFT which is not of this vault\\n uint256 internal constant VaultT1Admin__NftNotOfThisVault = 33004;\\n\\n /// @notice thrown when dust debt of NFT is 0, meaning nothing to collect\\n uint256 internal constant VaultT1Admin__DustDebtIsZero = 33005;\\n\\n /// @notice thrown when final debt after liquidation is not 0, meaning position 100% liquidated\\n uint256 internal constant VaultT1Admin__FinalDebtShouldBeZero = 33006;\\n\\n /// @notice thrown when NFT is not liquidated state\\n uint256 internal constant VaultT1Admin__NftNotLiquidated = 33007;\\n\\n /// @notice thrown when total absorbed dust debt is 0\\n uint256 internal constant VaultT1Admin__AbsorbedDustDebtIsZero = 33008;\\n\\n /// @notice thrown when address is set as 0\\n uint256 internal constant VaultT1Admin__AddressZeroNotAllowed = 33009;\\n\\n /***********************************|\\n | Vault Rewards | \\n |__________________________________*/\\n\\n uint256 internal constant VaultRewards__Unauthorized = 34001;\\n uint256 internal constant VaultRewards__AddressZero = 34002;\\n uint256 internal constant VaultRewards__InvalidParams = 34003;\\n uint256 internal constant VaultRewards__NewMagnifierSameAsOldMagnifier = 34004;\\n uint256 internal constant VaultRewards__NotTheInitiator = 34005;\\n uint256 internal constant VaultRewards__AlreadyStarted = 34006;\\n uint256 internal constant VaultRewards__RewardsNotStartedOrEnded = 34007;\\n}\\n\",\"keccak256\":\"0x0c6701ce11de6044d26e97782569d06ccec4297abfd2dab39a928bbed246ece7\",\"license\":\"BUSL-1.1\"},\"contracts/protocols/vault/factory/deploymentLogics/vaultT1Logic.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\npragma solidity 0.8.21;\\n\\nimport { SSTORE2 } from \\\"solmate/src/utils/SSTORE2.sol\\\";\\n\\nimport { ErrorTypes } from \\\"../../errorTypes.sol\\\";\\nimport { Error } from \\\"../../error.sol\\\";\\nimport { IFluidVaultFactory } from \\\"../../interfaces/iVaultFactory.sol\\\";\\n\\nimport { LiquiditySlotsLink } from \\\"../../../../libraries/liquiditySlotsLink.sol\\\";\\n\\nimport { IFluidVaultT1 } from \\\"../../interfaces/iVaultT1.sol\\\";\\nimport { FluidVaultT1 } from \\\"../../vaultT1/coreModule/main.sol\\\";\\n\\ninterface IERC20 {\\n function decimals() external view returns (uint8);\\n}\\n\\ncontract FluidVaultT1DeploymentLogic is Error {\\n address internal constant NATIVE_TOKEN = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;\\n\\n /// @dev SSTORE2 pointer for the VaultT1 creation code. Stored externally to reduce factory bytecode (in 2 parts)\\n address internal immutable VAULT_T1_CREATIONCODE_ADDRESS_1;\\n address internal immutable VAULT_T1_CREATIONCODE_ADDRESS_2;\\n\\n /// @notice address of liquidity contract\\n address public immutable LIQUIDITY;\\n\\n /// @notice address of Admin implementation\\n address public immutable ADMIN_IMPLEMENTATION;\\n\\n /// @notice address of Secondary implementation\\n address public immutable SECONDARY_IMPLEMENTATION;\\n\\n /// @notice address of this contract\\n address public immutable ADDRESS_THIS;\\n\\n /// @notice Emitted when a new vaultT1 is deployed.\\n /// @param vault The address of the newly deployed vault.\\n /// @param vaultId The id of the newly deployed vault.\\n /// @param supplyToken The address of the supply token.\\n /// @param borrowToken The address of the borrow token.\\n event VaultT1Deployed(\\n address indexed vault,\\n uint256 vaultId,\\n address indexed supplyToken,\\n address indexed borrowToken\\n );\\n\\n constructor(address liquidity_, address vaultAdminImplementation_, address vaultSecondaryImplementation_) {\\n LIQUIDITY = liquidity_;\\n ADMIN_IMPLEMENTATION = vaultAdminImplementation_;\\n SECONDARY_IMPLEMENTATION = vaultSecondaryImplementation_;\\n\\n // split storing creation code into two SSTORE2 pointers, because:\\n // due to contract code limits 24576 bytes is the maximum amount of data that can be written in a single pointer / key.\\n // Attempting to write more will result in failure.\\n // So by splitting in two parts we can make sure that the contract bytecode size can use up the full limit of 24576 bytes.\\n uint256 creationCodeLength_ = type(FluidVaultT1).creationCode.length;\\n VAULT_T1_CREATIONCODE_ADDRESS_1 = SSTORE2.write(\\n _bytesSlice(type(FluidVaultT1).creationCode, 0, creationCodeLength_ / 2)\\n );\\n // slice lengths:\\n // when even length, e.g. 250:\\n // part 1 = 0 -> 250 / 2, so 0 until 125 length, so 0 -> 125\\n // part 2 = 250 / 2 -> 250 - 250 / 2, so 125 until 125 length, so 125 -> 250\\n // when odd length: e.g. 251:\\n // part 1 = 0 -> 251 / 2, so 0 until 125 length, so 0 -> 125\\n // part 2 = 251 / 2 -> 251 - 251 / 2, so 125 until 126 length, so 125 -> 251\\n VAULT_T1_CREATIONCODE_ADDRESS_2 = SSTORE2.write(\\n _bytesSlice(\\n type(FluidVaultT1).creationCode,\\n creationCodeLength_ / 2,\\n creationCodeLength_ - creationCodeLength_ / 2\\n )\\n );\\n\\n ADDRESS_THIS = address(this);\\n }\\n\\n /// @notice Computes vaultT1 bytecode for the given supply token (`supplyToken_`) and borrow token (`borrowToken_`).\\n /// This will be called by the VaultFactory via .delegateCall\\n /// @param supplyToken_ The address of the supply token.\\n /// @param borrowToken_ The address of the borrow token.\\n /// @return vaultCreationBytecode_ Returns the bytecode of the new vault to deploy.\\n function vaultT1(\\n address supplyToken_,\\n address borrowToken_\\n ) external returns (bytes memory vaultCreationBytecode_) {\\n if (address(this) == ADDRESS_THIS) revert FluidVaultError(ErrorTypes.VaultFactory__OnlyDelegateCallAllowed);\\n\\n if (supplyToken_ == borrowToken_) revert FluidVaultError(ErrorTypes.VaultFactory__SameTokenNotAllowed);\\n\\n IFluidVaultT1.ConstantViews memory constants_;\\n constants_.liquidity = LIQUIDITY;\\n constants_.factory = address(this);\\n constants_.adminImplementation = ADMIN_IMPLEMENTATION;\\n constants_.secondaryImplementation = SECONDARY_IMPLEMENTATION;\\n constants_.supplyToken = supplyToken_;\\n constants_.supplyDecimals = supplyToken_ != NATIVE_TOKEN ? IERC20(supplyToken_).decimals() : 18;\\n constants_.borrowToken = borrowToken_;\\n constants_.borrowDecimals = borrowToken_ != NATIVE_TOKEN ? IERC20(borrowToken_).decimals() : 18;\\n constants_.vaultId = IFluidVaultFactory(address(this)).totalVaults();\\n\\n address vault_ = IFluidVaultFactory(address(this)).getVaultAddress(constants_.vaultId);\\n\\n constants_ = _calculateLiquidityVaultSlots(constants_, vault_);\\n\\n vaultCreationBytecode_ = abi.encodePacked(vaultT1CreationBytecode(), abi.encode(constants_));\\n\\n emit VaultT1Deployed(vault_, constants_.vaultId, supplyToken_, borrowToken_);\\n\\n return vaultCreationBytecode_;\\n }\\n\\n /// @notice returns the stored VaultT1 creation bytecode\\n function vaultT1CreationBytecode() public view returns (bytes memory) {\\n return\\n _bytesConcat(SSTORE2.read(VAULT_T1_CREATIONCODE_ADDRESS_1), SSTORE2.read(VAULT_T1_CREATIONCODE_ADDRESS_2));\\n }\\n\\n /// @dev Calculates the liquidity vault slots for the given supply token, borrow token, and vault (`vault_`).\\n /// @param constants_ Constants struct as used in Vault T1\\n /// @param vault_ The address of the vault.\\n /// @return liquidityVaultSlots_ Returns the calculated liquidity vault slots set in the `IFluidVaultT1.ConstantViews` struct.\\n function _calculateLiquidityVaultSlots(\\n IFluidVaultT1.ConstantViews memory constants_,\\n address vault_\\n ) private pure returns (IFluidVaultT1.ConstantViews memory) {\\n constants_.liquiditySupplyExchangePriceSlot = LiquiditySlotsLink.calculateMappingStorageSlot(\\n LiquiditySlotsLink.LIQUIDITY_EXCHANGE_PRICES_MAPPING_SLOT,\\n constants_.supplyToken\\n );\\n constants_.liquidityBorrowExchangePriceSlot = LiquiditySlotsLink.calculateMappingStorageSlot(\\n LiquiditySlotsLink.LIQUIDITY_EXCHANGE_PRICES_MAPPING_SLOT,\\n constants_.borrowToken\\n );\\n constants_.liquidityUserSupplySlot = LiquiditySlotsLink.calculateDoubleMappingStorageSlot(\\n LiquiditySlotsLink.LIQUIDITY_USER_SUPPLY_DOUBLE_MAPPING_SLOT,\\n vault_,\\n constants_.supplyToken\\n );\\n constants_.liquidityUserBorrowSlot = LiquiditySlotsLink.calculateDoubleMappingStorageSlot(\\n LiquiditySlotsLink.LIQUIDITY_USER_BORROW_DOUBLE_MAPPING_SLOT,\\n vault_,\\n constants_.borrowToken\\n );\\n return constants_;\\n }\\n\\n // @dev taken from https://github.com/GNSPS/solidity-bytes-utils/blob/master/contracts/BytesLib.sol\\n function _bytesConcat(bytes memory _preBytes, bytes memory _postBytes) private pure returns (bytes memory) {\\n bytes memory tempBytes;\\n\\n assembly {\\n // Get a location of some free memory and store it in tempBytes as\\n // Solidity does for memory variables.\\n tempBytes := mload(0x40)\\n\\n // Store the length of the first bytes array at the beginning of\\n // the memory for tempBytes.\\n let length := mload(_preBytes)\\n mstore(tempBytes, length)\\n\\n // Maintain a memory counter for the current write location in the\\n // temp bytes array by adding the 32 bytes for the array length to\\n // the starting location.\\n let mc := add(tempBytes, 0x20)\\n // Stop copying when the memory counter reaches the length of the\\n // first bytes array.\\n let end := add(mc, length)\\n\\n for {\\n // Initialize a copy counter to the start of the _preBytes data,\\n // 32 bytes into its memory.\\n let cc := add(_preBytes, 0x20)\\n } lt(mc, end) {\\n // Increase both counters by 32 bytes each iteration.\\n mc := add(mc, 0x20)\\n cc := add(cc, 0x20)\\n } {\\n // Write the _preBytes data into the tempBytes memory 32 bytes\\n // at a time.\\n mstore(mc, mload(cc))\\n }\\n\\n // Add the length of _postBytes to the current length of tempBytes\\n // and store it as the new length in the first 32 bytes of the\\n // tempBytes memory.\\n length := mload(_postBytes)\\n mstore(tempBytes, add(length, mload(tempBytes)))\\n\\n // Move the memory counter back from a multiple of 0x20 to the\\n // actual end of the _preBytes data.\\n mc := end\\n // Stop copying when the memory counter reaches the new combined\\n // length of the arrays.\\n end := add(mc, length)\\n\\n for {\\n let cc := add(_postBytes, 0x20)\\n } lt(mc, end) {\\n mc := add(mc, 0x20)\\n cc := add(cc, 0x20)\\n } {\\n mstore(mc, mload(cc))\\n }\\n\\n // Update the free-memory pointer by padding our last write location\\n // to 32 bytes: add 31 bytes to the end of tempBytes to move to the\\n // next 32 byte block, then round down to the nearest multiple of\\n // 32. If the sum of the length of the two arrays is zero then add\\n // one before rounding down to leave a blank 32 bytes (the length block with 0).\\n mstore(\\n 0x40,\\n and(\\n add(add(end, iszero(add(length, mload(_preBytes)))), 31),\\n not(31) // Round down to the nearest 32 bytes.\\n )\\n )\\n }\\n\\n return tempBytes;\\n }\\n\\n // @dev taken from https://github.com/GNSPS/solidity-bytes-utils/blob/master/contracts/BytesLib.sol\\n function _bytesSlice(bytes memory _bytes, uint256 _start, uint256 _length) private pure returns (bytes memory) {\\n require(_length + 31 >= _length, \\\"slice_overflow\\\");\\n require(_bytes.length >= _start + _length, \\\"slice_outOfBounds\\\");\\n\\n bytes memory tempBytes;\\n\\n assembly {\\n switch iszero(_length)\\n case 0 {\\n // Get a location of some free memory and store it in tempBytes as\\n // Solidity does for memory variables.\\n tempBytes := mload(0x40)\\n\\n // The first word of the slice result is potentially a partial\\n // word read from the original array. To read it, we calculate\\n // the length of that partial word and start copying that many\\n // bytes into the array. The first word we copy will start with\\n // data we don't care about, but the last `lengthmod` bytes will\\n // land at the beginning of the contents of the new array. When\\n // we're done copying, we overwrite the full first word with\\n // the actual length of the slice.\\n let lengthmod := and(_length, 31)\\n\\n // The multiplication in the next line is necessary\\n // because when slicing multiples of 32 bytes (lengthmod == 0)\\n // the following copy loop was copying the origin's length\\n // and then ending prematurely not copying everything it should.\\n let mc := add(add(tempBytes, lengthmod), mul(0x20, iszero(lengthmod)))\\n let end := add(mc, _length)\\n\\n for {\\n // The multiplication in the next line has the same exact purpose\\n // as the one above.\\n let cc := add(add(add(_bytes, lengthmod), mul(0x20, iszero(lengthmod))), _start)\\n } lt(mc, end) {\\n mc := add(mc, 0x20)\\n cc := add(cc, 0x20)\\n } {\\n mstore(mc, mload(cc))\\n }\\n\\n mstore(tempBytes, _length)\\n\\n //update free-memory pointer\\n //allocating the array padded to 32 bytes like the compiler does now\\n mstore(0x40, and(add(mc, 31), not(31)))\\n }\\n //if we want a zero-length slice let's just return a zero-length array\\n default {\\n tempBytes := mload(0x40)\\n //zero out the 32 bytes slice we are about to return\\n //we need to do it because Solidity does not garbage collect\\n mstore(tempBytes, 0)\\n\\n mstore(0x40, add(tempBytes, 0x20))\\n }\\n }\\n\\n return tempBytes;\\n }\\n}\\n\",\"keccak256\":\"0xdedc148d7879628d23f0ef752bfacfd5741b3d6955861c73f9280b7a7348eb18\",\"license\":\"BUSL-1.1\"},\"contracts/protocols/vault/interfaces/iVaultFactory.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\npragma solidity 0.8.21;\\n\\nimport { IERC721Enumerable } from \\\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol\\\";\\n\\ninterface IFluidVaultFactory is IERC721Enumerable {\\n /// @notice Minting an NFT Vault for the user\\n function mint(uint256 vaultId_, address user_) external returns (uint256 tokenId_);\\n\\n /// @notice returns owner of Vault which is also an NFT\\n function ownerOf(uint256 tokenId) external view returns (address owner);\\n\\n /// @notice Global auth is auth for all vaults\\n function isGlobalAuth(address auth_) external view returns (bool);\\n\\n /// @notice Vault auth is auth for a specific vault\\n function isVaultAuth(address vault_, address auth_) external view returns (bool);\\n\\n /// @notice Total vaults deployed.\\n function totalVaults() external view returns (uint256);\\n\\n /// @notice Compute vaultAddress\\n function getVaultAddress(uint256 vaultId) external view returns (address);\\n\\n /// @notice read uint256 `result_` for a storage `slot_` key\\n function readFromStorage(bytes32 slot_) external view returns (uint256 result_);\\n}\\n\",\"keccak256\":\"0xc4a0caed89a8670e1ccf159d03fa23bb29f69c579f522bb0e33b1b5cb106c40d\",\"license\":\"MIT\"},\"contracts/protocols/vault/interfaces/iVaultT1.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\npragma solidity 0.8.21;\\n\\ninterface IFluidVaultT1 {\\n /// @notice returns the vault id\\n function VAULT_ID() external view returns (uint256);\\n\\n /// @notice reads uint256 data `result_` from storage at a bytes32 storage `slot_` key.\\n function readFromStorage(bytes32 slot_) external view returns (uint256 result_);\\n\\n struct ConstantViews {\\n address liquidity;\\n address factory;\\n address adminImplementation;\\n address secondaryImplementation;\\n address supplyToken;\\n address borrowToken;\\n uint8 supplyDecimals;\\n uint8 borrowDecimals;\\n uint vaultId;\\n bytes32 liquiditySupplyExchangePriceSlot;\\n bytes32 liquidityBorrowExchangePriceSlot;\\n bytes32 liquidityUserSupplySlot;\\n bytes32 liquidityUserBorrowSlot;\\n }\\n\\n /// @notice returns all Vault constants\\n function constantsView() external view returns (ConstantViews memory constantsView_);\\n\\n /// @notice fetches the latest user position after a liquidation\\n function fetchLatestPosition(\\n int256 positionTick_,\\n uint256 positionTickId_,\\n uint256 positionRawDebt_,\\n uint256 tickData_\\n )\\n external\\n view\\n returns (\\n int256, // tick\\n uint256, // raw debt\\n uint256, // raw collateral\\n uint256, // branchID_\\n uint256 // branchData_\\n );\\n\\n /// @notice calculates the updated vault exchange prices\\n function updateExchangePrices(\\n uint256 vaultVariables2_\\n )\\n external\\n view\\n returns (\\n uint256 liqSupplyExPrice_,\\n uint256 liqBorrowExPrice_,\\n uint256 vaultSupplyExPrice_,\\n uint256 vaultBorrowExPrice_\\n );\\n\\n /// @notice calculates the updated vault exchange prices and writes them to storage\\n function updateExchangePricesOnStorage()\\n external\\n returns (\\n uint256 liqSupplyExPrice_,\\n uint256 liqBorrowExPrice_,\\n uint256 vaultSupplyExPrice_,\\n uint256 vaultBorrowExPrice_\\n );\\n\\n /// @notice returns the liquidity contract address\\n function LIQUIDITY() external view returns (address);\\n\\n function operate(\\n uint256 nftId_, // if 0 then new position\\n int256 newCol_, // if negative then withdraw\\n int256 newDebt_, // if negative then payback\\n address to_ // address at which the borrow & withdraw amount should go to. If address(0) then it'll go to msg.sender\\n )\\n external\\n payable\\n returns (\\n uint256, // nftId_\\n int256, // final supply amount. if - then withdraw\\n int256 // final borrow amount. if - then payback\\n );\\n \\n function liquidate(\\n uint256 debtAmt_,\\n uint256 colPerUnitDebt_, // min collateral needed per unit of debt in 1e18\\n address to_,\\n bool absorb_\\n ) external payable returns (uint actualDebtAmt_, uint actualColAmt_);\\n\\n function absorb() external;\\n\\n function rebalance() external payable returns (int supplyAmt_, int borrowAmt_);\\n\\n error FluidLiquidateResult(uint256 colLiquidated, uint256 debtLiquidated);\\n}\\n\",\"keccak256\":\"0xe0ec40a4531ecbcd7b8db25b4cd8529e0c284bb20eb40b7cf909fb8af0e3ca8b\",\"license\":\"MIT\"},\"contracts/protocols/vault/vaultT1/common/variables.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\npragma solidity 0.8.21;\\n\\ncontract Variables {\\n /***********************************|\\n | Storage Variables |\\n |__________________________________*/\\n\\n /// note: in all variables. For tick >= 0 are represented with bit as 1, tick < 0 are represented with bit as 0\\n /// note: read all the variables through storageRead.sol\\n\\n /// note: vaultVariables contains vault variables which need regular updates through transactions\\n /// First 1 bit => 0 => re-entrancy. If 0 then allow transaction to go, else throw.\\n /// Next 1 bit => 1 => Is the current active branch liquidated? If true then check the branch's minima tick before creating a new position\\n /// If the new tick is greater than minima tick then initialize a new branch, make that as current branch & do proper linking\\n /// Next 1 bit => 2 => sign of topmost tick (0 -> negative; 1 -> positive)\\n /// Next 19 bits => 3-21 => absolute value of topmost tick\\n /// Next 30 bits => 22-51 => current branch ID\\n /// Next 30 bits => 52-81 => total branch ID\\n /// Next 64 bits => 82-145 => Total supply\\n /// Next 64 bits => 146-209 => Total borrow\\n /// Next 32 bits => 210-241 => Total positions\\n uint256 internal vaultVariables;\\n\\n /// note: vaultVariables2 contains variables which do not update on every transaction. So mainly admin/auth set amount\\n /// First 16 bits => 0-15 => supply rate magnifier; 10000 = 1x (Here 16 bits should be more than enough)\\n /// Next 16 bits => 16-31 => borrow rate magnifier; 10000 = 1x (Here 16 bits should be more than enough)\\n /// Next 10 bits => 32-41 => collateral factor. 800 = 0.8 = 80% (max precision of 0.1%)\\n /// Next 10 bits => 42-51 => liquidation Threshold. 900 = 0.9 = 90% (max precision of 0.1%)\\n /// Next 10 bits => 52-61 => liquidation Max Limit. 950 = 0.95 = 95% (max precision of 0.1%) (above this 100% liquidation can happen)\\n /// Next 10 bits => 62-71 => withdraw gap. 100 = 0.1 = 10%. (max precision of 0.1%) (max 7 bits can also suffice for the requirement here of 0.1% to 10%). Needed to save some limits on withdrawals so liquidate can work seamlessly.\\n /// Next 10 bits => 72-81 => liquidation penalty. 100 = 0.01 = 1%. (max precision of 0.01%) (max liquidation penantly can be 10.23%). Applies when tick is in between liquidation Threshold & liquidation Max Limit.\\n /// Next 10 bits => 82-91 => borrow fee. 100 = 0.01 = 1%. (max precision of 0.01%) (max borrow fee can be 10.23%). Fees on borrow.\\n /// Next 4 bits => 92-95 => empty\\n /// Next 160 bits => 96-255 => Oracle address\\n uint256 internal vaultVariables2;\\n\\n /// note: stores absorbed liquidity\\n /// First 128 bits raw debt amount\\n /// last 128 bits raw col amount\\n uint256 internal absorbedLiquidity;\\n\\n /// position index => position data uint\\n /// if the entire variable is 0 (meaning not initialized) at the start that means no position at all\\n /// First 1 bit => 0 => position type (0 => borrow position; 1 => supply position)\\n /// Next 1 bit => 1 => sign of user's tick (0 => negative; 1 => positive)\\n /// Next 19 bits => 2-20 => absolute value of user's tick\\n /// Next 24 bits => 21-44 => user's tick's id\\n /// Below we are storing user's collateral & not debt, because the position can also be only collateral with no tick but it can never be only debt\\n /// Next 64 bits => 45-108 => user's supply amount. Debt will be calculated through supply & ratio.\\n /// Next 64 bits => 109-172 => user's dust debt amount. User's net debt = total debt - dust amount. Total debt is calculated through supply & ratio\\n /// User won't pay any extra interest on dust debt & hence we will not show it as a debt on UI. For user's there's no dust.\\n mapping(uint256 => uint256) internal positionData;\\n\\n /// Tick has debt only keeps data of non liquidated positions. liquidated tick's data stays in branch itself\\n /// tick parent => uint (represents bool for 256 children)\\n /// parent of (i)th tick:-\\n /// if (i>=0) (i / 256);\\n /// else ((i + 1) / 256) - 1\\n /// first bit of the variable is the smallest tick & last bit is the biggest tick of that slot\\n mapping(int256 => uint256) internal tickHasDebt;\\n\\n /// mapping tickId => tickData\\n /// Tick related data. Total debt & other things\\n /// First bit => 0 => If 1 then liquidated else not liquidated\\n /// Next 24 bits => 1-24 => Total IDs. ID should start from 1.\\n /// If not liquidated:\\n /// Next 64 bits => 25-88 => raw debt\\n /// If liquidated\\n /// The below 3 things are of last ID. This is to be updated when user creates a new position\\n /// Next 1 bit => 25 => Is 100% liquidated? If this is 1 meaning it was above max tick when it got liquidated (100% liquidated)\\n /// Next 30 bits => 26-55 => branch ID where this tick got liquidated\\n /// Next 50 bits => 56-105 => debt factor 50 bits (35 bits coefficient | 15 bits expansion)\\n mapping(int256 => uint256) internal tickData;\\n\\n /// tick id => previous tick id liquidation data. ID starts from 1\\n /// One tick ID contains 3 IDs of 80 bits in it, holding liquidation data of previously active but liquidated ticks\\n /// 81 bits data below\\n /// #### First 85 bits ####\\n /// 1st bit => 0 => Is 100% liquidated? If this is 1 meaning it was above max tick when it got liquidated\\n /// Next 30 bits => 1-30 => branch ID where this tick got liquidated\\n /// Next 50 bits => 31-80 => debt factor 50 bits (35 bits coefficient | 15 bits expansion)\\n /// #### Second 85 bits ####\\n /// 85th bit => 85 => Is 100% liquidated? If this is 1 meaning it was above max tick when it got liquidated\\n /// Next 30 bits => 86-115 => branch ID where this tick got liquidated\\n /// Next 50 bits => 116-165 => debt factor 50 bits (35 bits coefficient | 15 bits expansion)\\n /// #### Third 85 bits ####\\n /// 170th bit => 170 => Is 100% liquidated? If this is 1 meaning it was above max tick when it got liquidated\\n /// Next 30 bits => 171-200 => branch ID where this tick got liquidated\\n /// Next 50 bits => 201-250 => debt factor 50 bits (35 bits coefficient | 15 bits expansion)\\n mapping(int256 => mapping(uint256 => uint256)) internal tickId;\\n\\n /// mapping branchId => branchData\\n /// First 2 bits => 0-1 => if 0 then not liquidated, if 1 then liquidated, if 2 then merged, if 3 then closed\\n /// merged means the branch is merged into it's base branch\\n /// closed means all the users are 100% liquidated\\n /// Next 1 bit => 2 => minima tick sign of this branch. Will only be there if any liquidation happened.\\n /// Next 19 bits => 3-21 => minima tick of this branch. Will only be there if any liquidation happened.\\n /// Next 30 bits => 22-51 => Partials of minima tick of branch this is connected to. 0 if master branch.\\n /// Next 64 bits => 52-115 Debt liquidity at this branch. Similar to last's top tick data. Remaining debt will move here from tickData after first liquidation\\n /// If not merged\\n /// Next 50 bits => 116-165 => Debt factor or of this branch. (35 bits coefficient | 15 bits expansion)\\n /// If merged\\n /// Next 50 bits => 116-165 => Connection/adjustment debt factor of this branch with the next branch.\\n /// If closed\\n /// Next 50 bits => 116-165 => Debt factor as 0. As all the user's positions are now fully gone\\n /// following values are present always again (merged / not merged / closed)\\n /// Next 30 bits => 166-195 => Branch's ID with which this branch is connected. If 0 then that means this is the master branch\\n /// Next 1 bit => 196 => sign of minima tick of branch this is connected to. 0 if master branch.\\n /// Next 19 bits => 197-215 => minima tick of branch this is connected to. 0 if master branch.\\n mapping(uint256 => uint256) internal branchData;\\n\\n /// Exchange prices are in 1e12\\n /// First 64 bits => 0-63 => Liquidity's collateral token supply exchange price\\n /// First 64 bits => 64-127 => Liquidity's debt token borrow exchange price\\n /// First 64 bits => 128-191 => Vault's collateral token supply exchange price\\n /// First 64 bits => 192-255 => Vault's debt token borrow exchange price\\n uint256 internal rates;\\n\\n /// address of rebalancer\\n address internal rebalancer;\\n\\n uint256 internal absorbedDustDebt;\\n}\\n\",\"keccak256\":\"0x446a2d8d47d53d1584a1a1dd9aed247320ba04582e8bbcd7be60c979f908c52e\",\"license\":\"BUSL-1.1\"},\"contracts/protocols/vault/vaultT1/coreModule/constantVariables.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\npragma solidity 0.8.21;\\n\\nimport { IFluidVaultFactory } from \\\"../../interfaces/iVaultFactory.sol\\\";\\nimport { IFluidLiquidity } from \\\"../../../../liquidity/interfaces/iLiquidity.sol\\\";\\nimport { StorageRead } from \\\"../../../../libraries/storageRead.sol\\\";\\n\\nimport { Structs } from \\\"./structs.sol\\\";\\n\\ninterface TokenInterface {\\n function decimals() external view returns (uint8);\\n}\\n\\ncontract ConstantVariables is StorageRead, Structs {\\n /***********************************|\\n | Constant Variables |\\n |__________________________________*/\\n\\n address internal constant NATIVE_TOKEN = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;\\n /// @dev collateral token address\\n address internal immutable SUPPLY_TOKEN;\\n /// @dev borrow token address\\n address internal immutable BORROW_TOKEN;\\n\\n /// @dev Token decimals. For example wETH is 18 decimals\\n uint8 internal immutable SUPPLY_DECIMALS;\\n /// @dev Token decimals. For example USDC is 6 decimals\\n uint8 internal immutable BORROW_DECIMALS;\\n\\n /// @dev VaultT1 AdminModule implemenation address\\n address internal immutable ADMIN_IMPLEMENTATION;\\n\\n /// @dev VaultT1 Secondary implemenation (main2.sol) address\\n address internal immutable SECONDARY_IMPLEMENTATION;\\n\\n /// @dev liquidity proxy contract address\\n IFluidLiquidity public immutable LIQUIDITY;\\n\\n /// @dev vault factory contract address\\n IFluidVaultFactory public immutable VAULT_FACTORY;\\n\\n uint public immutable VAULT_ID;\\n\\n uint internal constant X8 = 0xff;\\n uint internal constant X10 = 0x3ff;\\n uint internal constant X16 = 0xffff;\\n uint internal constant X19 = 0x7ffff;\\n uint internal constant X20 = 0xfffff;\\n uint internal constant X24 = 0xffffff;\\n uint internal constant X25 = 0x1ffffff;\\n uint internal constant X30 = 0x3fffffff;\\n uint internal constant X35 = 0x7ffffffff;\\n uint internal constant X50 = 0x3ffffffffffff;\\n uint internal constant X64 = 0xffffffffffffffff;\\n uint internal constant X96 = 0xffffffffffffffffffffffff;\\n uint internal constant X128 = 0xffffffffffffffffffffffffffffffff;\\n\\n uint256 internal constant EXCHANGE_PRICES_PRECISION = 1e12;\\n\\n /// @dev slot ids in Liquidity contract. Helps in low gas fetch from liquidity contract by skipping delegate call\\n bytes32 internal immutable LIQUIDITY_SUPPLY_EXCHANGE_PRICE_SLOT;\\n bytes32 internal immutable LIQUIDITY_BORROW_EXCHANGE_PRICE_SLOT;\\n bytes32 internal immutable LIQUIDITY_USER_SUPPLY_SLOT;\\n bytes32 internal immutable LIQUIDITY_USER_BORROW_SLOT;\\n\\n /// @notice returns all Vault constants\\n function constantsView() external view returns (ConstantViews memory constantsView_) {\\n constantsView_.liquidity = address(LIQUIDITY);\\n constantsView_.factory = address(VAULT_FACTORY);\\n constantsView_.adminImplementation = ADMIN_IMPLEMENTATION;\\n constantsView_.secondaryImplementation = SECONDARY_IMPLEMENTATION;\\n constantsView_.supplyToken = SUPPLY_TOKEN;\\n constantsView_.borrowToken = BORROW_TOKEN;\\n constantsView_.supplyDecimals = SUPPLY_DECIMALS;\\n constantsView_.borrowDecimals = BORROW_DECIMALS;\\n constantsView_.vaultId = VAULT_ID;\\n constantsView_.liquiditySupplyExchangePriceSlot = LIQUIDITY_SUPPLY_EXCHANGE_PRICE_SLOT;\\n constantsView_.liquidityBorrowExchangePriceSlot = LIQUIDITY_BORROW_EXCHANGE_PRICE_SLOT;\\n constantsView_.liquidityUserSupplySlot = LIQUIDITY_USER_SUPPLY_SLOT;\\n constantsView_.liquidityUserBorrowSlot = LIQUIDITY_USER_BORROW_SLOT;\\n }\\n\\n constructor(ConstantViews memory constants_) {\\n LIQUIDITY = IFluidLiquidity(constants_.liquidity);\\n VAULT_FACTORY = IFluidVaultFactory(constants_.factory);\\n VAULT_ID = constants_.vaultId;\\n\\n SUPPLY_TOKEN = constants_.supplyToken;\\n BORROW_TOKEN = constants_.borrowToken;\\n SUPPLY_DECIMALS = constants_.supplyDecimals;\\n BORROW_DECIMALS = constants_.borrowDecimals;\\n\\n // @dev those slots are calculated in the deploymentLogics / VaultFactory\\n LIQUIDITY_SUPPLY_EXCHANGE_PRICE_SLOT = constants_.liquiditySupplyExchangePriceSlot;\\n LIQUIDITY_BORROW_EXCHANGE_PRICE_SLOT = constants_.liquidityBorrowExchangePriceSlot;\\n LIQUIDITY_USER_SUPPLY_SLOT = constants_.liquidityUserSupplySlot;\\n LIQUIDITY_USER_BORROW_SLOT = constants_.liquidityUserBorrowSlot;\\n\\n ADMIN_IMPLEMENTATION = constants_.adminImplementation;\\n SECONDARY_IMPLEMENTATION = constants_.secondaryImplementation;\\n }\\n}\\n\",\"keccak256\":\"0x30bb94d713254816c679c77ccaeef964608edf6cc3acdcd1f73eff0185fcd26e\",\"license\":\"BUSL-1.1\"},\"contracts/protocols/vault/vaultT1/coreModule/events.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\npragma solidity 0.8.21;\\n\\ncontract Events {\\n /// @notice emitted when an operate() method is executed that changes collateral (`colAmt_`) / debt (debtAmt_`)\\n /// amount for a `user_` position with `nftId_`. Receiver of any funds is the address `to_`.\\n event LogOperate(address user_, uint256 nftId_, int256 colAmt_, int256 debtAmt_, address to_);\\n\\n /// @notice emitted when the exchange prices are updated in storage.\\n event LogUpdateExchangePrice(uint256 supplyExPrice_, uint256 borrowExPrice_);\\n\\n /// @notice emitted when a liquidation has been executed.\\n event LogLiquidate(address liquidator_, uint256 colAmt_, uint256 debtAmt_, address to_);\\n\\n /// @notice emitted when `absorb()` was executed to absorb bad debt.\\n event LogAbsorb(uint colAbsorbedRaw_, uint debtAbsorbedRaw_);\\n\\n /// @notice emitted when a `rebalance()` has been executed, balancing out total supply / borrow between Vault\\n /// and Fluid Liquidity pools.\\n /// if `colAmt_` is positive then loss, meaning transfer from rebalancer address to vault and deposit.\\n /// if `colAmt_` is negative then profit, meaning withdrawn from vault and sent to rebalancer address.\\n /// if `debtAmt_` is positive then profit, meaning borrow from vault and sent to rebalancer address.\\n /// if `debtAmt_` is negative then loss, meaning transfer from rebalancer address to vault and payback.\\n event LogRebalance(int colAmt_, int debtAmt_);\\n}\\n\",\"keccak256\":\"0xf703ee56009b4a760e4d89d82d233c1cbf886393cb125de4e12ee16bfe2761f1\",\"license\":\"BUSL-1.1\"},\"contracts/protocols/vault/vaultT1/coreModule/helpers.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\npragma solidity 0.8.21;\\n\\nimport { Variables } from \\\"../common/variables.sol\\\";\\nimport { ConstantVariables } from \\\"./constantVariables.sol\\\";\\nimport { Events } from \\\"./events.sol\\\";\\nimport { TickMath } from \\\"../../../../libraries/tickMath.sol\\\";\\nimport { BigMathMinified } from \\\"../../../../libraries/bigMathMinified.sol\\\";\\nimport { BigMathVault } from \\\"../../../../libraries/bigMathVault.sol\\\";\\nimport { LiquidityCalcs } from \\\"../../../../libraries/liquidityCalcs.sol\\\";\\n\\nimport { ErrorTypes } from \\\"../../errorTypes.sol\\\";\\nimport { Error } from \\\"../../error.sol\\\";\\n\\n/// @dev Fluid vault protocol helper methods. Mostly used for `operate()` and `liquidate()` methods of CoreModule.\\nabstract contract Helpers is Variables, ConstantVariables, Events, Error {\\n using BigMathMinified for uint256;\\n using BigMathVault for uint256;\\n\\n /// @notice Calculates new vault exchange prices. Does not update values in storage.\\n /// @param vaultVariables2_ exactly same as vaultVariables2 from storage\\n /// @return liqSupplyExPrice_ latest liquidity's supply token supply exchange price\\n /// @return liqBorrowExPrice_ latest liquidity's borrow token borrow exchange price\\n /// @return vaultSupplyExPrice_ latest vault's supply token exchange price\\n /// @return vaultBorrowExPrice_ latest vault's borrow token exchange price\\n function updateExchangePrices(\\n uint256 vaultVariables2_\\n )\\n public\\n view\\n returns (\\n uint256 liqSupplyExPrice_,\\n uint256 liqBorrowExPrice_,\\n uint256 vaultSupplyExPrice_,\\n uint256 vaultBorrowExPrice_\\n )\\n {\\n // Fetching last stored rates\\n uint rates_ = rates;\\n\\n (liqSupplyExPrice_, ) = LiquidityCalcs.calcExchangePrices(\\n LIQUIDITY.readFromStorage(LIQUIDITY_SUPPLY_EXCHANGE_PRICE_SLOT)\\n );\\n (, liqBorrowExPrice_) = LiquidityCalcs.calcExchangePrices(\\n LIQUIDITY.readFromStorage(LIQUIDITY_BORROW_EXCHANGE_PRICE_SLOT)\\n );\\n\\n uint256 oldLiqSupplyExPrice_ = (rates_ & X64);\\n uint256 oldLiqBorrowExPrice_ = ((rates_ >> 64) & X64);\\n if (liqSupplyExPrice_ < oldLiqSupplyExPrice_ || liqBorrowExPrice_ < oldLiqBorrowExPrice_) {\\n // new liquidity exchange price is < than the old one. liquidity exchange price should only ever increase.\\n // If not, something went wrong and avoid proceeding with unknown outcome.\\n revert FluidVaultError(ErrorTypes.VaultT1__LiquidityExchangePriceUnexpected);\\n }\\n\\n // liquidity Exchange Prices always increases in next block. Hence substraction with old will never be negative\\n // uint64 * 1e18 is the max the number that could be\\n unchecked {\\n // Calculating increase in supply exchange price w.r.t last stored liquidity's exchange price\\n // vaultSupplyExPrice_ => supplyIncreaseInPercent_\\n vaultSupplyExPrice_ = ((((liqSupplyExPrice_ * 1e18) / oldLiqSupplyExPrice_) - 1e18) *\\n (vaultVariables2_ & X16)) / 10000; // supply rate magnifier\\n\\n // Calculating increase in borrow exchange price w.r.t last stored liquidity's exchange price\\n // vaultBorrowExPrice_ => borrowIncreaseInPercent_\\n vaultBorrowExPrice_ = ((((liqBorrowExPrice_ * 1e18) / oldLiqBorrowExPrice_) - 1e18) *\\n ((vaultVariables2_ >> 16) & X16)) / 10000; // borrow rate magnifier\\n\\n // It's extremely hard the exchange prices to overflow even in 100 years but if it does it's not an\\n // issue here as we are not updating on storage\\n // (rates_ >> 128) & X64) -> last stored vault's supply token exchange price\\n vaultSupplyExPrice_ = (((rates_ >> 128) & X64) * (1e18 + vaultSupplyExPrice_)) / 1e18;\\n // (rates_ >> 192) -> last stored vault's borrow token exchange price (no need to mask with & X64 as it is anyway max 64 bits)\\n vaultBorrowExPrice_ = ((rates_ >> 192) * (1e18 + vaultBorrowExPrice_)) / 1e18;\\n }\\n }\\n\\n /// note admin module is also calling this function self call\\n /// @dev updating exchange price on storage. Only need to update on storage when changing supply or borrow magnifier\\n function updateExchangePricesOnStorage()\\n public\\n returns (\\n uint256 liqSupplyExPrice_,\\n uint256 liqBorrowExPrice_,\\n uint256 vaultSupplyExPrice_,\\n uint256 vaultBorrowExPrice_\\n )\\n {\\n (liqSupplyExPrice_, liqBorrowExPrice_, vaultSupplyExPrice_, vaultBorrowExPrice_) = updateExchangePrices(\\n vaultVariables2\\n );\\n\\n if (\\n liqSupplyExPrice_ > X64 || liqBorrowExPrice_ > X64 || vaultSupplyExPrice_ > X64 || vaultBorrowExPrice_ > X64\\n ) {\\n revert FluidVaultError(ErrorTypes.VaultT1__ExchangePriceOverFlow);\\n }\\n\\n // Updating in storage\\n rates =\\n liqSupplyExPrice_ |\\n (liqBorrowExPrice_ << 64) |\\n (vaultSupplyExPrice_ << 128) |\\n (vaultBorrowExPrice_ << 192);\\n\\n emit LogUpdateExchangePrice(vaultSupplyExPrice_, vaultBorrowExPrice_);\\n }\\n\\n /// @dev fetches new user's position after liquidation. The new liquidated position's debt is decreased by 0.01%\\n /// to make sure that branch's liquidity never becomes 0 as if it would have gotten 0 then there will be multiple cases that we would need to tackle.\\n /// @param positionTick_ position's tick when it was last updated through operate\\n /// @param positionTickId_ position's tick Id. This stores the debt factor and branch to make the first connection\\n /// @param positionRawDebt_ position's raw debt when it was last updated through operate\\n /// @param tickData_ position's tick's tickData just for minor comparison to know if data is moved to tick Id or is still in tick data\\n /// @return final tick position after all the liquidation\\n /// @return final debt of position after all the liquidation\\n /// @return positionRawCol_ final collateral of position after all the liquidation\\n /// @return branchId_ final branch's ID where the position is at currently\\n /// @return branchData_ final branch's data where the position is at currently\\n function fetchLatestPosition(\\n int256 positionTick_,\\n uint256 positionTickId_,\\n uint256 positionRawDebt_,\\n uint256 tickData_\\n )\\n public\\n view\\n returns (\\n int256, // positionTick_\\n uint256, // positionRawDebt_\\n uint256 positionRawCol_,\\n uint256 branchId_,\\n uint256 branchData_\\n )\\n {\\n uint256 initialPositionRawDebt_ = positionRawDebt_;\\n uint256 connectionFactor_;\\n bool isFullyLiquidated_;\\n\\n // Checking if tick's total ID = user's tick ID\\n if (((tickData_ >> 1) & X24) == positionTickId_) {\\n // fetching from tick data itself\\n isFullyLiquidated_ = ((tickData_ >> 25) & 1) == 1;\\n branchId_ = (tickData_ >> 26) & X30;\\n connectionFactor_ = (tickData_ >> 56) & X50;\\n } else {\\n {\\n uint256 tickLiquidationData_;\\n unchecked {\\n // Fetching tick's liquidation data. One variable contains data of 3 IDs. Tick Id mapping is starting from 1.\\n tickLiquidationData_ =\\n tickId[positionTick_][(positionTickId_ + 2) / 3] >>\\n (((positionTickId_ + 2) % 3) * 85);\\n }\\n\\n isFullyLiquidated_ = (tickLiquidationData_ & 1) == 1;\\n branchId_ = (tickLiquidationData_ >> 1) & X30;\\n connectionFactor_ = (tickLiquidationData_ >> 31) & X50;\\n }\\n }\\n\\n // data of branch\\n branchData_ = branchData[branchId_];\\n\\n if (isFullyLiquidated_) {\\n positionTick_ = type(int).min;\\n positionRawDebt_ = 0;\\n } else {\\n // Below information about connection debt factor\\n // If branch is merged, Connection debt factor is used to multiply in order to get perfect liquidation of user\\n // For example: Considering user was at the top.\\n // In first branch, the user liquidated to debt factor 0.5 and then branch got merged (branching starting from 1)\\n // In second branch, it got liquidated to 0.4 but when the above branch merged the debt factor on this branch was 0.6\\n // Meaning on 1st branch, user got liquidated by 50% & on 2nd by 33.33%. So a total of 66.6%.\\n // What we will set a connection factor will be 0.6/0.5 = 1.2\\n // So now to get user's position, this is what we'll do:\\n // finalDebt = (0.4 / (1 * 1.2)) * debtBeforeLiquidation\\n // 0.4 is current active branch's minima debt factor\\n // 1 is debt factor from where user started\\n // 1.2 is connection factor which we found out through 0.6 / 0.5\\n while ((branchData_ & 3) == 2) {\\n // If true then the branch is merged\\n\\n // userTickDebtFactor * connectionDebtFactor *... connectionDebtFactor aka adjustmentDebtFactor\\n connectionFactor_ = connectionFactor_.mulBigNumber(((branchData_ >> 116) & X50));\\n if (connectionFactor_ == BigMathVault.MAX_MASK_DEBT_FACTOR) break; // user ~100% liquidated\\n // Note we don't need updated branch data in case of 100% liquidated so saving gas for fetching it\\n\\n // Fetching new branch data\\n branchId_ = (branchData_ >> 166) & X30; // Link to base branch of current branch\\n branchData_ = branchData[branchId_];\\n }\\n // When the while loop breaks meaning the branch now has minima Debt Factor or is a closed branch;\\n\\n if (((branchData_ & 3) == 3) || (connectionFactor_ == BigMathVault.MAX_MASK_DEBT_FACTOR)) {\\n // Branch got closed (or user liquidated ~100%). Hence make the user's position 0\\n // Rare cases to get into this situation\\n // Branch can get close often but once closed it's tricky that some user might come iterating through there\\n // If a user comes then that user will be very mini user like some cents probably\\n positionTick_ = type(int).min;\\n positionRawDebt_ = 0;\\n } else {\\n // If branch is not merged, the main branch it's connected to then it'll have minima debt factor\\n\\n // position debt = debt * base branch minimaDebtFactor / connectionFactor\\n positionRawDebt_ = positionRawDebt_.mulDivNormal(\\n (branchData_ >> 116) & X50, // minimaDebtFactor\\n connectionFactor_\\n );\\n\\n unchecked {\\n // Reducing user's liquidity by 0.01% if user got liquidated.\\n // As this will make sure that the branch always have some debt even if all liquidated user left\\n // This saves a lot more logics & consideration on Operate function\\n // if we don't do this then we have to add logics related to closing the branch and factor connections accordingly.\\n if (positionRawDebt_ > (initialPositionRawDebt_ / 100)) {\\n positionRawDebt_ = (positionRawDebt_ * 9999) / 10000;\\n } else {\\n // if user debt reduced by more than 99% in liquidation then making user as fully liquidated\\n positionRawDebt_ = 0;\\n }\\n }\\n\\n {\\n if (positionRawDebt_ > 0) {\\n // positionTick_ -> read minima tick of branch\\n unchecked {\\n positionTick_ = branchData_ & 4 == 4\\n ? int((branchData_ >> 3) & X19)\\n : -int((branchData_ >> 3) & X19);\\n }\\n // Calculating user's collateral\\n uint256 ratioAtTick_ = TickMath.getRatioAtTick(int24(positionTick_));\\n uint256 ratioOneLess_;\\n unchecked {\\n ratioOneLess_ = (ratioAtTick_ * 10000) / 10015;\\n }\\n // formula below for better readability:\\n // length = ratioAtTick_ - ratioOneLess_\\n // ratio = ratioOneLess_ + (length * positionPartials_) / X30\\n // positionRawCol_ = (positionRawDebt_ * (1 << 96)) / ratio_\\n positionRawCol_ =\\n (positionRawDebt_ * TickMath.ZERO_TICK_SCALED_RATIO) /\\n (ratioOneLess_ + ((ratioAtTick_ - ratioOneLess_) * ((branchData_ >> 22) & X30)) / X30);\\n } else {\\n positionTick_ = type(int).min;\\n }\\n }\\n }\\n }\\n return (positionTick_, positionRawDebt_, positionRawCol_, branchId_, branchData_);\\n }\\n\\n /// @dev sets `tick_` as having debt or no debt in storage `tickHasDebt` depending on `addOrRemove_`\\n /// @param tick_ tick to add or remove from tickHasDebt\\n /// @param addOrRemove_ if true then add else remove\\n function _updateTickHasDebt(int tick_, bool addOrRemove_) internal {\\n // Positive mapID_ starts from 0 & above and negative starts below 0.\\n // tick 0 to 255 will have mapId_ as 0 while tick -256 to -1 will have mapId_ as -1.\\n unchecked {\\n int mapId_ = tick_ < 0 ? ((tick_ + 1) / 256) - 1 : tick_ / 256;\\n\\n // in case of removing:\\n // (tick == 255) tickHasDebt[mapId_] - 1 << 255\\n // (tick == 0) tickHasDebt[mapId_] - 1 << 0\\n // (tick == -1) tickHasDebt[mapId_] - 1 << 255\\n // (tick == -256) tickHasDebt[mapId_] - 1 << 0\\n // in case of adding:\\n // (tick == 255) tickHasDebt[mapId_] - 1 << 255\\n // (tick == 0) tickHasDebt[mapId_] - 1 << 0\\n // (tick == -1) tickHasDebt[mapId_] - 1 << 255\\n // (tick == -256) tickHasDebt[mapId_] - 1 << 0\\n uint position_ = uint(tick_ - (mapId_ * 256));\\n\\n tickHasDebt[mapId_] = addOrRemove_\\n ? tickHasDebt[mapId_] | (1 << position_)\\n : tickHasDebt[mapId_] & ~(1 << position_);\\n }\\n }\\n\\n /// @dev gets next perfect top tick (tick which is not liquidated)\\n /// @param topTick_ current top tick which will no longer be top tick\\n /// @return nextTick_ next top tick which will become the new top tick\\n function _fetchNextTopTick(int topTick_) internal view returns (int nextTick_) {\\n int mapId_;\\n uint tickHasDebt_;\\n\\n unchecked {\\n mapId_ = topTick_ < 0 ? ((topTick_ + 1) / 256) - 1 : topTick_ / 256;\\n uint bitsToRemove_ = uint(-topTick_ + (mapId_ * 256 + 256));\\n // Removing current top tick from tickHasDebt\\n tickHasDebt_ = (tickHasDebt[mapId_] << bitsToRemove_) >> bitsToRemove_;\\n\\n // For last user remaining in vault there could be a lot of iterations in the while loop.\\n // Chances of this to happen is extremely low (like ~0%)\\n while (true) {\\n if (tickHasDebt_ > 0) {\\n nextTick_ = mapId_ * 256 + int(tickHasDebt_.mostSignificantBit()) - 1;\\n break;\\n }\\n\\n // Reducing mapId_ by 1 in every loop; if it reaches to -129 then no filled tick exist, meaning it's the last tick\\n if (--mapId_ == -129) {\\n nextTick_ = type(int).min;\\n break;\\n }\\n\\n tickHasDebt_ = tickHasDebt[mapId_];\\n }\\n }\\n }\\n\\n /// @dev adding debt to a particular tick\\n /// @param totalColRaw_ total raw collateral of position\\n /// @param netDebtRaw_ net raw debt (total debt - dust debt)\\n /// @return tick_ tick where the debt is being added\\n /// @return tickId_ tick current id\\n /// @return userRawDebt_ user's total raw debt\\n /// @return rawDust_ dust debt used for adjustment\\n function _addDebtToTickWrite(\\n uint256 totalColRaw_,\\n uint256 netDebtRaw_ // debtRaw - dust\\n ) internal returns (int256 tick_, uint256 tickId_, uint256 userRawDebt_, uint256 rawDust_) {\\n if (netDebtRaw_ < 10000) {\\n // thrown if user's debt is too low\\n revert FluidVaultError(ErrorTypes.VaultT1__UserDebtTooLow);\\n }\\n // tick_ & ratio_ returned from library is round down. Hence increasing it by 1 and increasing ratio by 1 tick.\\n uint ratio_ = (netDebtRaw_ * TickMath.ZERO_TICK_SCALED_RATIO) / totalColRaw_;\\n (tick_, ratio_) = TickMath.getTickAtRatio(ratio_);\\n unchecked {\\n ++tick_;\\n ratio_ = (ratio_ * 10015) / 10000;\\n }\\n userRawDebt_ = (ratio_ * totalColRaw_) >> 96;\\n rawDust_ = userRawDebt_ - netDebtRaw_;\\n\\n // Current state of tick\\n uint256 tickData_ = tickData[tick_];\\n tickId_ = (tickData_ >> 1) & X24;\\n\\n uint tickNewDebt_;\\n if (tickId_ > 0 && tickData_ & 1 == 0) {\\n // Current debt in the tick\\n uint256 tickExistingRawDebt_ = (tickData_ >> 25) & X64;\\n tickExistingRawDebt_ = (tickExistingRawDebt_ >> 8) << (tickExistingRawDebt_ & X8);\\n\\n // Tick's already initialized and not liquidated. Hence simply add the debt\\n tickNewDebt_ = tickExistingRawDebt_ + userRawDebt_;\\n if (tickExistingRawDebt_ == 0) {\\n // Adding tick into tickHasDebt\\n _updateTickHasDebt(tick_, true);\\n }\\n } else {\\n // Liquidation happened or tick getting initialized for the very first time.\\n if (tickId_ > 0) {\\n // Meaning a liquidation happened. Hence move the data to tickID\\n unchecked {\\n uint tickMap_ = (tickId_ + 2) / 3;\\n // Adding 2 in ID so we can get right mapping ID. For example for ID 1, 2 & 3 mapping should be 1 and so on..\\n // For example shift for id 1 should be 0, for id 2 should be 85, for id 3 it should be 170 and so on..\\n tickId[tick_][tickMap_] =\\n tickId[tick_][tickMap_] |\\n ((tickData_ >> 25) << (((tickId_ + 2) % 3) * 85));\\n }\\n }\\n // Increasing total ID by one\\n unchecked {\\n ++tickId_;\\n }\\n tickNewDebt_ = userRawDebt_;\\n\\n // Adding tick into tickHasDebt\\n _updateTickHasDebt(tick_, true);\\n }\\n if (tickNewDebt_ < 10000) {\\n // thrown if tick's debt/liquidity is too low\\n revert FluidVaultError(ErrorTypes.VaultT1__TickDebtTooLow);\\n }\\n tickData[tick_] = (tickId_ << 1) | (tickNewDebt_.toBigNumber(56, 8, BigMathMinified.ROUND_DOWN) << 25);\\n }\\n\\n /// @dev sets new top tick. If it comes to this function then that means current top tick is perfect tick.\\n /// if next top tick is liquidated then unitializes the current non liquidated branch and make the liquidated branch as current branch\\n /// @param topTick_ current top tick\\n /// @param vaultVariables_ vaultVariables of storage but with newer updates\\n /// @return newVaultVariables_ newVaultVariables_ updated vault variable internally to this function\\n /// @return newTopTick_ new top tick\\n function _setNewTopTick(\\n int topTick_,\\n uint vaultVariables_\\n ) internal returns (uint newVaultVariables_, int newTopTick_) {\\n // This function considers that the current top tick was not liquidated\\n // Overall flow of function:\\n // if new top tick liquidated (aka base branch's minima tick) -> Close the current branch and make base branch as current branch\\n // if new top tick not liquidated -> update things in current branch.\\n // if new top tick is not liquidated and same tick exist in base branch then tick is considered as not liquidated.\\n\\n uint branchId_ = (vaultVariables_ >> 22) & X30; // branch id of current branch\\n\\n uint256 branchData_ = branchData[branchId_];\\n int256 baseBranchMinimaTick_;\\n if ((branchData_ >> 196) & 1 == 1) {\\n baseBranchMinimaTick_ = int((branchData_ >> 197) & X19);\\n } else {\\n unchecked {\\n baseBranchMinimaTick_ = -int((branchData_ >> 197) & X19);\\n }\\n if (baseBranchMinimaTick_ == 0) {\\n // meaning the current branch is the master branch\\n baseBranchMinimaTick_ = type(int).min;\\n }\\n }\\n\\n // Returns type(int).min if no top tick exist\\n int nextTopTickNotLiquidated_ = _fetchNextTopTick(topTick_);\\n\\n newTopTick_ = baseBranchMinimaTick_ > nextTopTickNotLiquidated_\\n ? baseBranchMinimaTick_\\n : nextTopTickNotLiquidated_;\\n\\n if (newTopTick_ == type(int).min) {\\n // if this happens that means this was the last user of the vault :(\\n vaultVariables_ = vaultVariables_ & 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc00001;\\n } else if (newTopTick_ == nextTopTickNotLiquidated_) {\\n // New top tick exist in current non liquidated branch\\n if (newTopTick_ < 0) {\\n unchecked {\\n vaultVariables_ =\\n (vaultVariables_ & 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc00001) |\\n (uint(-newTopTick_) << 3);\\n }\\n } else {\\n vaultVariables_ =\\n (vaultVariables_ & 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc00001) |\\n 4 | // setting top tick as positive\\n (uint(newTopTick_) << 3);\\n }\\n } else {\\n // if this happens that means base branch exists & is the next top tick\\n // Remove current non liquidated branch as active.\\n // Not deleting here as it's going to get initialize again whenever a new top tick comes\\n branchData[branchId_] = 0;\\n // Inserting liquidated branch's minima tick\\n unchecked {\\n vaultVariables_ =\\n (vaultVariables_ & 0xfffffffffffffffffffffffffffffffffffffffffffc00000000000000000001) |\\n 2 | // Setting top tick as liquidated\\n (((branchData_ >> 196) & X20) << 2) | // new current top tick = base branch minima tick\\n (((branchData_ >> 166) & X30) << 22) | // new current branch id = base branch id\\n ((branchId_ - 1) << 52); // reduce total branch id by 1\\n }\\n }\\n\\n newVaultVariables_ = vaultVariables_;\\n }\\n\\n constructor(ConstantViews memory constants_) ConstantVariables(constants_) {}\\n}\\n\",\"keccak256\":\"0xbcbd186a0c739caf614f5a21e6e6171c2bd6d9048e66900d5a6347405e48b028\",\"license\":\"BUSL-1.1\"},\"contracts/protocols/vault/vaultT1/coreModule/main.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\npragma solidity 0.8.21;\\n\\n\\nimport { IFluidOracle } from \\\"../../../../oracle/fluidOracle.sol\\\";\\n\\nimport { TickMath } from \\\"../../../../libraries/tickMath.sol\\\";\\nimport { BigMathMinified } from \\\"../../../../libraries/bigMathMinified.sol\\\";\\nimport { BigMathVault } from \\\"../../../../libraries/bigMathVault.sol\\\";\\nimport { LiquidityCalcs } from \\\"../../../../libraries/liquidityCalcs.sol\\\";\\nimport { SafeTransfer } from \\\"../../../../libraries/safeTransfer.sol\\\";\\n\\nimport { Helpers } from \\\"./helpers.sol\\\";\\nimport { LiquiditySlotsLink } from \\\"../../../../libraries/liquiditySlotsLink.sol\\\";\\n\\nimport { ErrorTypes } from \\\"../../errorTypes.sol\\\";\\n\\n/// @notice Fluid \\\"VaultT1\\\" (Vault Type 1). Fluid vault protocol main contract.\\n/// Fluid Vault protocol is a borrow / lending protocol, allowing users to create collateral / borrow positions.\\n/// All funds are deposited into / borrowed from Fluid Liquidity layer.\\n/// Positions are represented through NFTs minted by the VaultFactory.\\n/// Deployed by \\\"VaultFactory\\\" and linked together with VaultT1 AdminModule `ADMIN_IMPLEMENTATION` and\\n/// FluidVaultT1Secondary (main2.sol) `SECONDARY_IMPLEMENTATION`.\\n/// AdminModule & FluidVaultT1Secondary methods are delegateCalled, if the msg.sender has the required authorization.\\n/// This contract links to an Oracle, which is used to assess collateral / debt value. Oracles implement the\\n/// \\\"FluidOracle\\\" base contract and return the price in 1e27 precision.\\n/// @dev For view methods / accessing data, use the \\\"VaultResolver\\\" periphery contract.\\n//\\n// vaults can only be deployed for tokens that are listed at Liquidity (constructor reverts otherwise\\n// if either the exchange price for the supply token or the borrow token is still not set at Liquidity).\\ncontract FluidVaultT1 is Helpers {\\n using BigMathMinified for uint256;\\n using BigMathVault for uint256;\\n\\n /// @dev Single function which handles supply, withdraw, borrow & payback\\n /// @param nftId_ NFT ID for interaction. If 0 then create new NFT/position.\\n /// @param newCol_ new collateral. If positive then deposit, if negative then withdraw, if 0 then do nohing\\n /// @param newDebt_ new debt. If positive then borrow, if negative then payback, if 0 then do nohing\\n /// @param to_ address where withdraw or borrow should go. If address(0) then msg.sender\\n /// @return nftId_ if 0 then this returns the newly created NFT Id else returns the same NFT ID\\n /// @return newCol_ final supply amount. Mainly if max withdraw using type(int).min then this is useful to get perfect amount else remain same as newCol_\\n /// @return newDebt_ final borrow amount. Mainly if max payback using type(int).min then this is useful to get perfect amount else remain same as newDebt_\\n function operate(\\n uint256 nftId_, // if 0 then new position\\n int256 newCol_, // if negative then withdraw\\n int256 newDebt_, // if negative then payback\\n address to_ // address at which the borrow & withdraw amount should go to. If address(0) then it'll go to msg.sender\\n )\\n public\\n payable\\n returns (\\n uint256, // nftId_\\n int256, // final supply amount. if - then withdraw\\n int256 // final borrow amount. if - then payback\\n )\\n {\\n uint256 vaultVariables_ = vaultVariables;\\n // re-entrancy check\\n if (vaultVariables_ & 1 == 0) {\\n // Updating on storage\\n vaultVariables = vaultVariables_ | 1;\\n } else {\\n revert FluidVaultError(ErrorTypes.VaultT1__AlreadyEntered);\\n }\\n\\n if (\\n (newCol_ == 0 && newDebt_ == 0) ||\\n // withdrawal or deposit cannot be too small\\n ((newCol_ != 0) && (newCol_ > -10000 && newCol_ < 10000)) ||\\n // borrow or payback cannot be too small\\n ((newDebt_ != 0) && (newDebt_ > -10000 && newDebt_ < 10000))\\n ) {\\n revert FluidVaultError(ErrorTypes.VaultT1__InvalidOperateAmount);\\n }\\n\\n // Check msg.value aligns with input amounts if supply or borrow token is native token.\\n // Note that it's not possible for a vault to have both supply token and borrow token as native token.\\n if (SUPPLY_TOKEN == NATIVE_TOKEN && newCol_ > 0) {\\n if (uint(newCol_) != msg.value) {\\n revert FluidVaultError(ErrorTypes.VaultT1__InvalidMsgValueOperate);\\n }\\n } else if (msg.value > 0) {\\n if (!(BORROW_TOKEN == NATIVE_TOKEN && newDebt_ < 0)) {\\n // msg.value sent along for withdraw, borrow, or non-native token operations\\n revert FluidVaultError(ErrorTypes.VaultT1__InvalidMsgValueOperate);\\n }\\n }\\n\\n OperateMemoryVars memory o_;\\n // Temporary variables used as helpers at many places\\n uint256 temp_;\\n uint256 temp2_;\\n int256 temp3_;\\n\\n o_.vaultVariables2 = vaultVariables2;\\n\\n temp_ = (vaultVariables_ >> 2) & X20;\\n unchecked {\\n o_.topTick = (temp_ == 0) ? type(int).min : ((temp_ & 1) == 1)\\n ? int((temp_ >> 1) & X19)\\n : -int((temp_ >> 1) & X19);\\n }\\n\\n {\\n // Fetching user's position\\n if (nftId_ == 0) {\\n // creating new position.\\n o_.tick = type(int).min;\\n // minting new NFT vault for user.\\n nftId_ = VAULT_FACTORY.mint(VAULT_ID, msg.sender);\\n // Adding 1 in total positions. Total positions cannot exceed 32bits as NFT minting checks for that\\n unchecked {\\n vaultVariables_ = vaultVariables_ + (1 << 210);\\n }\\n } else {\\n // Updating existing position\\n\\n // checking owner only in case of withdraw or borrow\\n if ((newCol_ < 0 || newDebt_ > 0) && (VAULT_FACTORY.ownerOf(nftId_) != msg.sender)) {\\n revert FluidVaultError(ErrorTypes.VaultT1__NotAnOwner);\\n }\\n\\n // temp_ => user's position data\\n temp_ = positionData[nftId_];\\n\\n if (temp_ == 0) {\\n revert FluidVaultError(ErrorTypes.VaultT1__NftNotOfThisVault);\\n }\\n // temp2_ => user's supply amount\\n temp2_ = (temp_ >> 45) & X64;\\n // Converting big number into normal number\\n o_.colRaw = (temp2_ >> 8) << (temp2_ & X8);\\n // temp2_ => user's dust debt amount\\n temp2_ = (temp_ >> 109) & X64;\\n // Converting big number into normal number\\n o_.dustDebtRaw = (temp2_ >> 8) << (temp2_ & X8);\\n\\n // 1 is supply & 0 is borrow\\n if (temp_ & 1 == 1) {\\n // only supply position (has no debt)\\n o_.tick = type(int).min;\\n } else {\\n // borrow position (has collateral & debt)\\n unchecked {\\n o_.tick = temp_ & 2 == 2 ? int((temp_ >> 2) & X19) : -int((temp_ >> 2) & X19);\\n }\\n o_.tickId = (temp_ >> 21) & X24;\\n }\\n }\\n }\\n\\n // Get latest updated Position's debt & supply (if position is with debt -> not new / supply position)\\n if (o_.tick > type(int).min) {\\n // if entering this if statement then temp_ here will always be user's position data\\n // extracting collateral exponent\\n temp_ = (temp_ >> 45) & X8;\\n // if exponent is > 0 then rounding up the collateral just for calculating debt\\n unchecked {\\n temp_ = temp_ == 0 ? (o_.colRaw + 1) : o_.colRaw + (1 << temp_);\\n }\\n // fetch current debt\\n o_.debtRaw = ((TickMath.getRatioAtTick(int24(o_.tick)) * temp_) >> 96) + 1;\\n\\n // Tick data from user's tick\\n temp_ = tickData[o_.tick];\\n\\n // Checking if tick is liquidated (first bit 1) OR if the total IDs of tick is greater than user's tick ID\\n if (((temp_ & 1) == 1) || (((temp_ >> 1) & X24) > o_.tickId)) {\\n // User got liquidated\\n (\\n // returns the position of the user if the user got liquidated.\\n o_.tick,\\n o_.debtRaw,\\n o_.colRaw,\\n temp2_, // final branchId from liquidation where position exist right now\\n o_.branchData\\n ) = fetchLatestPosition(o_.tick, o_.tickId, o_.debtRaw, temp_);\\n\\n if (o_.debtRaw > o_.dustDebtRaw) {\\n // temp_ => branch's Debt\\n temp_ = (o_.branchData >> 52) & X64;\\n temp_ = (temp_ >> 8) << (temp_ & X8);\\n\\n // o_.debtRaw should always be < branch's Debt (temp_).\\n // Taking margin (0.01%) in fetchLatestPosition to make sure it's always less\\n temp_ -= o_.debtRaw;\\n if (temp_ < 100) {\\n // explicitly making sure that branch debt/liquidity doesn't get super low.\\n temp_ = 100;\\n }\\n // Inserting updated branch's debt\\n branchData[temp2_] =\\n (o_.branchData & 0xfffffffffffffffffffffffffffffffffff0000000000000000fffffffffffff) |\\n (temp_.toBigNumber(56, 8, BigMathMinified.ROUND_UP) << 52);\\n\\n unchecked {\\n // Converted positionRawDebt_ in net position debt\\n o_.debtRaw -= o_.dustDebtRaw;\\n }\\n } else {\\n // Liquidated 100% or almost 100%\\n // absorbing dust debt\\n absorbedDustDebt = absorbedDustDebt + o_.dustDebtRaw - o_.debtRaw;\\n o_.debtRaw = 0;\\n o_.colRaw = 0;\\n }\\n } else {\\n // User didn't got liquidated\\n // Removing user's debt from tick data\\n // temp2_ => debt in tick\\n temp2_ = (temp_ >> 25) & X64;\\n // below require can fail when a user liquidity is extremely low (talking about way less than even $1)\\n // adding require meaning this vault user won't be able to interact unless someone makes the liquidity in tick as non 0.\\n // reason of adding is the tick has already removed from everywhere. Can removing it again break something? Better to simply remove that case entirely\\n if (temp2_ == 0) {\\n revert FluidVaultError(ErrorTypes.VaultT1__TickIsEmpty);\\n }\\n // Converting big number into normal number\\n temp2_ = (temp2_ >> 8) << (temp2_ & X8);\\n // debtInTick (temp2_) < debtToRemove (o_.debtRaw) that means minor precision error. Hence make the debtInTick as 0.\\n // The precision error can be caused with Bigmath library limiting the precision to 2**56.\\n unchecked {\\n temp2_ = o_.debtRaw < temp2_ ? temp2_ - o_.debtRaw : 0;\\n }\\n\\n if (temp2_ < 10000) {\\n temp2_ = 0;\\n // if debt becomes 0 then remove from tick has debt\\n\\n if (o_.tick == o_.topTick) {\\n // if tick is top tick then current top tick is perfect tick -> fetch & set new top tick\\n\\n // Updating new top tick in vaultVariables_ and topTick_\\n (vaultVariables_, o_.topTick) = _setNewTopTick(o_.topTick, vaultVariables_);\\n }\\n\\n // Removing from tickHasDebt\\n _updateTickHasDebt(o_.tick, false);\\n }\\n\\n tickData[o_.tick] = (temp_ & X25) | (temp2_.toBigNumber(56, 8, BigMathMinified.ROUND_DOWN) << 25);\\n\\n // Converted positionRawDebt_ in net position debt\\n o_.debtRaw -= o_.dustDebtRaw;\\n }\\n o_.dustDebtRaw = 0;\\n }\\n\\n // Setting the current tick into old tick as the position tick is going to change now.\\n o_.oldTick = o_.tick;\\n o_.oldColRaw = o_.colRaw;\\n o_.oldNetDebtRaw = o_.debtRaw;\\n\\n {\\n (o_.liquidityExPrice, , o_.supplyExPrice, o_.borrowExPrice) = updateExchangePrices(o_.vaultVariables2);\\n\\n {\\n // supply or withdraw\\n if (newCol_ > 0) {\\n // supply new col, rounding down\\n o_.colRaw += (uint256(newCol_) * EXCHANGE_PRICES_PRECISION) / o_.supplyExPrice;\\n // final user's collateral should not be above 2**128 bits\\n if (o_.colRaw > X128) {\\n revert FluidVaultError(ErrorTypes.VaultT1__UserCollateralDebtExceed);\\n }\\n } else if (newCol_ < 0) {\\n // if withdraw equals type(int).min then max withdraw\\n if (newCol_ > type(int128).min) {\\n // partial withdraw, rounding up removing extra wei from collateral\\n temp3_ = ((newCol_ * int(EXCHANGE_PRICES_PRECISION)) / int256(o_.supplyExPrice)) - 1;\\n unchecked {\\n if (uint256(-temp3_) > o_.colRaw) {\\n revert FluidVaultError(ErrorTypes.VaultT1__ExcessCollateralWithdrawal);\\n }\\n o_.colRaw -= uint256(-temp3_);\\n }\\n } else if (newCol_ == type(int).min) {\\n // max withdraw, rounding up:\\n // adding +1 to negative withdrawAmount newCol_ for safe rounding (reducing withdraw)\\n newCol_ = -(int256((o_.colRaw * o_.supplyExPrice) / EXCHANGE_PRICES_PRECISION)) + 1;\\n o_.colRaw = 0;\\n } else {\\n revert FluidVaultError(ErrorTypes.VaultT1__UserCollateralDebtExceed);\\n }\\n }\\n }\\n {\\n // borrow or payback\\n if (newDebt_ > 0) {\\n // borrow new debt, rounding up adding extra wei in debt\\n temp_ = ((uint(newDebt_) * EXCHANGE_PRICES_PRECISION) / o_.borrowExPrice) + 1;\\n // if borrow fee is 0 then it'll become temp_ + 0.\\n // Only adding fee in o_.debtRaw and not in newDebt_ as newDebt_ is debt that needs to be borrowed from Liquidity\\n // as we have added fee in debtRaw hence it will get added in user's position & vault's total borrow.\\n // It can be collected with rebalance function.\\n o_.debtRaw += temp_ + (temp_ * ((o_.vaultVariables2 >> 82) & X10)) / 10000;\\n // final user's debt should not be above 2**128 bits\\n if (o_.debtRaw > X128) {\\n revert FluidVaultError(ErrorTypes.VaultT1__UserCollateralDebtExceed);\\n }\\n } else if (newDebt_ < 0) {\\n // if payback equals type(int).min then max payback\\n if (newDebt_ > type(int128).min) {\\n // partial payback.\\n // temp3_ => newDebt_ in raw terms, safe rounding up negative amount to rounding reduce payback\\n temp3_ = (newDebt_ * int256(EXCHANGE_PRICES_PRECISION)) / int256(o_.borrowExPrice) + 1;\\n unchecked {\\n temp3_ = -temp3_;\\n if (uint256(temp3_) > o_.debtRaw) {\\n revert FluidVaultError(ErrorTypes.VaultT1__ExcessDebtPayback);\\n }\\n o_.debtRaw -= uint256(temp3_);\\n }\\n } else if (newDebt_ == type(int).min) {\\n // max payback, rounding up amount that will be transferred in to pay back full debt:\\n // subtracting -1 of negative debtAmount newDebt_ for safe rounding (increasing payback)\\n newDebt_ = -(int256((o_.debtRaw * o_.borrowExPrice) / EXCHANGE_PRICES_PRECISION)) - 1;\\n o_.debtRaw = 0;\\n } else {\\n revert FluidVaultError(ErrorTypes.VaultT1__UserCollateralDebtExceed);\\n }\\n }\\n }\\n }\\n\\n // if position has no collateral or debt and user sends type(int).min for withdraw and payback then this results in 0\\n // there's is no issue if it stays 0 but better to throw here to avoid checking for potential issues if there could be\\n if (newCol_ == 0 && newDebt_ == 0) {\\n revert FluidVaultError(ErrorTypes.VaultT1__InvalidOperateAmount);\\n }\\n\\n // Assign new tick\\n if (o_.debtRaw > 0) {\\n // updating tickHasDebt in the below function if required\\n // o_.debtRaw here is updated to new debt raw incl. dust debt (not net debt)\\n unchecked {\\n (o_.tick, o_.tickId, o_.debtRaw, o_.dustDebtRaw) = _addDebtToTickWrite(\\n o_.colRaw,\\n ((o_.debtRaw * 1000000001) / 1000000000) + 1\\n );\\n }\\n\\n if (newDebt_ < 0) {\\n // anyone can payback debt of any position\\n // hence, explicitly checking the debt should decrease\\n if ((o_.debtRaw - o_.dustDebtRaw) > o_.oldNetDebtRaw) {\\n revert FluidVaultError(ErrorTypes.VaultT1__InvalidPaybackOrDeposit);\\n }\\n }\\n if ((newCol_ > 0) && (newDebt_ == 0)) {\\n // anyone can deposit collateral in any position\\n // Hence, explicitly checking that new ratio should be less than old ratio\\n if (\\n (((o_.debtRaw - o_.dustDebtRaw) * TickMath.ZERO_TICK_SCALED_RATIO) / o_.colRaw) >\\n ((o_.oldNetDebtRaw * TickMath.ZERO_TICK_SCALED_RATIO) / o_.oldColRaw)\\n ) {\\n revert FluidVaultError(ErrorTypes.VaultT1__InvalidPaybackOrDeposit);\\n }\\n }\\n\\n if (o_.tick >= o_.topTick) {\\n // Updating topTick in storage\\n // temp_ => tick to insert in vault variables\\n unchecked {\\n temp_ = o_.tick < 0 ? uint(-o_.tick) << 1 : (uint(o_.tick) << 1) | 1;\\n }\\n if (vaultVariables_ & 2 == 0) {\\n // Current branch not liquidated. Hence, just update top tick\\n vaultVariables_ =\\n (vaultVariables_ & 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc00000) |\\n (temp_ << 2);\\n } else {\\n // Current branch liquidated\\n // Initialize a new branch\\n // temp2_ => totalBranchId_\\n unchecked {\\n temp2_ = ((vaultVariables_ >> 52) & X30) + 1; // would take 34 years to overflow if a new branch is created every second\\n }\\n // Connecting new active branch with current active branch which is now base branch\\n // Current top tick is now base branch's minima tick\\n branchData[temp2_] =\\n (((vaultVariables_ >> 22) & X30) << 166) | // current branch id set as base branch id\\n (((vaultVariables_ >> 2) & X20) << 196); // current top tick set as base branch minima tick\\n // Updating new vault variables in memory with new branch\\n vaultVariables_ =\\n (vaultVariables_ & 0xfffffffffffffffffffffffffffffffffffffffffffc00000000000000000000) |\\n (temp_ << 2) | // new top tick\\n (temp2_ << 22) | // new branch id\\n (temp2_ << 52); // total branch ids\\n }\\n }\\n } else {\\n // debtRaw_ remains 0 in this situation\\n // This kind of position will not have any tick. Meaning it'll be a supply position.\\n o_.tick = type(int).min;\\n }\\n\\n {\\n if (newCol_ < 0 || newDebt_ > 0) {\\n // withdraw or borrow\\n if (to_ == address(0)) {\\n to_ = msg.sender;\\n }\\n\\n unchecked {\\n // if debt is greater than 0 & transaction includes borrow or withdraw (incl. combinations such as deposit + borrow etc.)\\n // -> check collateral factor\\n // calc for net debt can be unchecked as o_.dustDebtRaw can not be > o_.debtRaw:\\n // o_.dustDebtRaw is the result of o_.debtRaw - x where x > 0 see _addDebtToTickWrite()\\n\\n // Only fetch oracle if position is getting riskier or if borrowing is involved\\n // if user is withdrawing and paying back in the same transaction such that the final ratio\\n // is lower than initial then as well no need to check oracle aka user is doing payback & withdraw or deleverage\\n if (o_.debtRaw > 0 && (\\n o_.oldTick <= o_.tick ||\\n (o_.debtRaw - o_.dustDebtRaw) > (((o_.oldNetDebtRaw * 1000000001) / 1000000000) + 1)\\n )\\n ) {\\n // Oracle returns price at 100% ratio.\\n // converting oracle 160 bits into oracle address\\n // temp_ => debt price w.r.t to col in 1e27\\n temp_ = IFluidOracle(address(uint160(o_.vaultVariables2 >> 96))).getExchangeRateOperate();\\n // Note if price would come back as 0 `getTickAtRatio` will fail\\n\\n // reverting if oracle price is too high or lower than 1e9 to avoid precision issues\\n if (temp_ > 1e54 || temp_ < 1e9) {\\n revert FluidVaultError(ErrorTypes.VaultT1__InvalidOraclePrice);\\n }\\n\\n // Converting price in terms of raw amounts\\n temp_ = (temp_ * o_.supplyExPrice) / o_.borrowExPrice;\\n\\n // capping oracle pricing to 1e45 (#487RGF783GF: id reference for other similar cases in codebase)\\n // This means we are restricting collateral price to never go above 1e45\\n // Above 1e45 precisions gets too low for calculations\\n // This can will never happen for all good token pairs (for example, WBTC/DAI pair when WBTC price is $1M, oracle price will come as 1e43)\\n // Restricting oracle price doesn't pose any risk to protocol as we are capping collateral price, meaning if price is above 1e45\\n // user is simply not able to borrow more\\n if (temp_ > 1e45) {\\n temp_ = 1e45;\\n }\\n\\n // temp2_ => ratio at CF. CF is in 3 decimals. 900 = 90%\\n temp2_ = ((temp_ * ((o_.vaultVariables2 >> 32) & X10)) / 1000);\\n\\n // Price from oracle is in 1e27 decimals. Converting it into (1 << 96) decimals\\n temp2_ = ((temp2_ * TickMath.ZERO_TICK_SCALED_RATIO) / 1e27);\\n\\n // temp3_ => tickAtCF_\\n (temp3_, ) = TickMath.getTickAtRatio(temp2_);\\n if (o_.tick > temp3_) {\\n // Above CF, user should only be allowed to reduce ratio either by paying debt or by depositing more collateral\\n // Not comparing collateral as user can potentially use safe/deleverage to reduce tick & debt.\\n // On use of safe/deleverage, collateral will decrease but debt will decrease as well making the overall position safer.\\n revert FluidVaultError(ErrorTypes.VaultT1__PositionAboveCF);\\n }\\n }\\n }\\n\\n }\\n }\\n\\n {\\n // Updating user's new position on storage\\n // temp_ => tick to insert as user position tick\\n if (o_.tick > type(int).min) {\\n unchecked {\\n temp_ = o_.tick < 0 ? (uint(-o_.tick) << 1) : ((uint(o_.tick) << 1) | 1);\\n }\\n } else {\\n // if positionTick_ = type(int).min OR positionRawDebt_ == 0 then that means it's only supply position\\n // (for case of positionRawDebt_ == 0, tick is set to type(int).min further up)\\n temp_ = 0;\\n }\\n\\n positionData[nftId_] =\\n ((temp_ == 0) ? 1 : 0) | // setting if supply only position (1) or not (first bit)\\n (temp_ << 1) |\\n (o_.tickId << 21) |\\n (o_.colRaw.toBigNumber(56, 8, BigMathMinified.ROUND_DOWN) << 45) |\\n // dust debt is rounded down because user debt = debt - dustDebt. rounding up would mean we reduce user debt\\n (o_.dustDebtRaw.toBigNumber(56, 8, BigMathMinified.ROUND_DOWN) << 109);\\n }\\n\\n // Withdrawal gap to make sure there's always liquidity for liquidation\\n // For example if withdrawal allowance is 15% on liquidity then we can limit operate's withdrawal allowance to 10%\\n // this will allow liquidate function to get extra 5% buffer for potential liquidations.\\n if (newCol_ < 0) {\\n // extracting withdrawal gap which is in 0.1% precision.\\n temp_ = (o_.vaultVariables2 >> 62) & X10;\\n if (temp_ > 0) {\\n // fetching user's supply slot data\\n o_.userSupplyLiquidityData = LIQUIDITY.readFromStorage(LIQUIDITY_USER_SUPPLY_SLOT);\\n\\n // converting current user's supply from big number to normal\\n temp2_ = (o_.userSupplyLiquidityData >> LiquiditySlotsLink.BITS_USER_SUPPLY_AMOUNT) & X64;\\n temp2_ = (temp2_ >> 8) << (temp2_ & X8);\\n\\n // fetching liquidity's withdrawal limit\\n temp3_ = int(LiquidityCalcs.calcWithdrawalLimitBeforeOperate(o_.userSupplyLiquidityData, temp2_));\\n\\n // max the number could go is vault's supply * 1000. Overflowing is almost impossible.\\n unchecked {\\n // (liquidityUserSupply - withdrawalGap - liquidityWithdrawaLimit) should be less than user's withdrawal\\n if (\\n (temp3_ > 0) &&\\n (((int(temp2_ * (1000 - temp_)) / 1000)) - temp3_) <\\n (((-newCol_) * int(EXCHANGE_PRICES_PRECISION)) / int(o_.liquidityExPrice))\\n ) {\\n revert FluidVaultError(ErrorTypes.VaultT1__WithdrawMoreThanOperateLimit);\\n }\\n }\\n }\\n }\\n\\n {\\n // execute actions at Liquidity: deposit & payback is first and then withdraw & borrow\\n if (newCol_ > 0) {\\n // deposit\\n LIQUIDITY.operate{ value: SUPPLY_TOKEN == NATIVE_TOKEN ? msg.value : 0 }(\\n SUPPLY_TOKEN,\\n newCol_,\\n 0,\\n address(0),\\n address(0),\\n abi.encode(msg.sender)\\n );\\n }\\n if (newDebt_ < 0) {\\n if (BORROW_TOKEN == NATIVE_TOKEN) {\\n unchecked {\\n temp_ = uint(-newDebt_);\\n if (msg.value > temp_) {\\n SafeTransfer.safeTransferNative(msg.sender, msg.value - temp_);\\n } else if (msg.value < temp_) {\\n revert FluidVaultError(ErrorTypes.VaultT1__InvalidMsgValueOperate);\\n }\\n }\\n } else {\\n temp_ = 0;\\n }\\n // payback\\n LIQUIDITY.operate{ value: temp_ }(\\n BORROW_TOKEN,\\n 0,\\n newDebt_,\\n address(0),\\n address(0),\\n abi.encode(msg.sender)\\n );\\n }\\n if (newCol_ < 0) {\\n // withdraw\\n LIQUIDITY.operate(SUPPLY_TOKEN, newCol_, 0, to_, address(0), new bytes(0));\\n }\\n if (newDebt_ > 0) {\\n // borrow\\n LIQUIDITY.operate(BORROW_TOKEN, 0, newDebt_, address(0), to_, new bytes(0));\\n }\\n }\\n\\n {\\n // Updating vault variables on storage\\n\\n // Calculating new total collateral & total debt.\\n temp_ = (vaultVariables_ >> 82) & X64;\\n temp_ = ((temp_ >> 8) << (temp_ & X8)) + o_.colRaw - o_.oldColRaw;\\n temp2_ = (vaultVariables_ >> 146) & X64;\\n temp2_ = ((temp2_ >> 8) << (temp2_ & X8)) + (o_.debtRaw - o_.dustDebtRaw) - o_.oldNetDebtRaw;\\n // Updating vault variables on storage. This will also reentrancy 0 back again\\n // Converting total supply & total borrow in 64 bits (56 | 8) bignumber\\n vaultVariables =\\n (vaultVariables_ & 0xfffffffffffc00000000000000000000000000000003ffffffffffffffffffff) |\\n (temp_.toBigNumber(56, 8, BigMathMinified.ROUND_DOWN) << 82) | // total supply\\n (temp2_.toBigNumber(56, 8, BigMathMinified.ROUND_UP) << 146); // total borrow\\n }\\n\\n emit LogOperate(msg.sender, nftId_, newCol_, newDebt_, to_);\\n\\n return (nftId_, newCol_, newDebt_);\\n }\\n\\n /// @dev allows to liquidate all bad debt of all users at once. Liquidator can also liquidate partially any amount they want.\\n /// @param debtAmt_ total debt to liquidate (aka debt token to swap into collateral token)\\n /// @param colPerUnitDebt_ minimum collateral token per unit of debt in 1e18 decimals\\n /// @param to_ address at which collateral token should go to.\\n /// If dead address (0x000000000000000000000000000000000000dEaD) then reverts with custom error \\\"FluidLiquidateResult\\\"\\n /// returning the actual collateral and actual debt liquidated. Useful to find max liquidatable amounts via try / catch.\\n /// @param absorb_ if true then liquidate from absorbed first\\n /// @return actualDebtAmt_ if liquidator sends debtAmt_ more than debt remaining to liquidate then actualDebtAmt_ changes from debtAmt_ else remains same\\n /// @return actualColAmt_ total liquidated collateral which liquidator will get\\n function liquidate(\\n uint256 debtAmt_,\\n uint256 colPerUnitDebt_, // min collateral needed per unit of debt in 1e18\\n address to_,\\n bool absorb_\\n ) public payable returns (uint actualDebtAmt_, uint actualColAmt_) {\\n LiquidateMemoryVars memory memoryVars_;\\n\\n uint vaultVariables_ = vaultVariables;\\n\\n // ############# turning re-entrancy bit on #############\\n if (vaultVariables_ & 1 == 0) {\\n // Updating on storage\\n vaultVariables = vaultVariables_ | 1;\\n } else {\\n revert FluidVaultError(ErrorTypes.VaultT1__AlreadyEntered);\\n }\\n\\n if (BORROW_TOKEN == NATIVE_TOKEN) {\\n if ((msg.value != debtAmt_) && (to_ != 0x000000000000000000000000000000000000dEaD)) {\\n revert FluidVaultError(ErrorTypes.VaultT1__InvalidMsgValueLiquidate);\\n }\\n } else if (msg.value > 0) {\\n revert FluidVaultError(ErrorTypes.VaultT1__InvalidMsgValueLiquidate);\\n }\\n\\n memoryVars_.vaultVariables2 = vaultVariables2;\\n\\n if (((vaultVariables_ >> 2) & X20) == 0) {\\n revert FluidVaultError(ErrorTypes.VaultT1__TopTickDoesNotExist);\\n }\\n\\n // Below are exchange prices of vaults\\n (, , memoryVars_.supplyExPrice, memoryVars_.borrowExPrice) = updateExchangePrices(memoryVars_.vaultVariables2);\\n\\n CurrentLiquidity memory currentData_;\\n BranchData memory branch_;\\n // Temporary holder variables, used many times for different small things\\n uint temp_;\\n uint temp2_;\\n\\n {\\n // ############# Oracle related stuff #############\\n // Col price w.r.t debt. For example: 1 ETH = 1000 DAI\\n // temp_ -> debtPerCol\\n temp_ = IFluidOracle(address(uint160(memoryVars_.vaultVariables2 >> 96))).getExchangeRateLiquidate(); // Price in 27 decimals\\n\\n // not reverting if oracle price is lower than 1e9 as it can pause potential liquidation in this edge case situations\\n if (temp_ > 1e54 || temp_ == 0) {\\n revert FluidVaultError(ErrorTypes.VaultT1__InvalidOraclePrice);\\n }\\n\\n unchecked {\\n // temp_ -> debtPerCol Converting in terms of raw amount\\n temp_ = (temp_ * memoryVars_.supplyExPrice) / memoryVars_.borrowExPrice;\\n\\n // capping oracle pricing to 1e45\\n // Reason mentioned at (search: #487RGF783GF)\\n if (temp_ > 1e45) {\\n temp_ = 1e45;\\n }\\n // temp2_ -> Raw colPerDebt_ in 27 decimals\\n temp2_ = 1e54 / temp_;\\n\\n // temp2_ can never be > 1e54\\n // Oracle price should never be > 1e54\\n // Liquidation penalty in 4 decimals (1e2 = 1%) (max: 10.23%) -> (vaultVariables2_ >> 72) & X10\\n currentData_.colPerDebt = (temp2_ * (10000 + ((memoryVars_.vaultVariables2 >> 72) & X10))) / 10000;\\n\\n // get liquidiation tick (tick at liquidation threshold ratio)\\n // Liquidation threshold in 3 decimals (900 = 90%) -> (vaultVariables2_ >> 42) & X10\\n // Dividing by 1e27 to convert temp_ into normal number\\n temp_ = ((temp_ * TickMath.ZERO_TICK_SCALED_RATIO) / 1e27);\\n // temp2_ -> liquidationRatio_\\n temp2_ = (temp_ * ((memoryVars_.vaultVariables2 >> 42) & X10)) / 1000;\\n }\\n (memoryVars_.liquidationTick, ) = TickMath.getTickAtRatio(temp2_);\\n\\n // get liquidiation max limit tick (tick at liquidation max limit ratio)\\n // Max limit in 3 decimals (900 = 90%) -> (vaultVariables2_ >> 52) & X10\\n // temp2_ -> maxRatio_\\n unchecked {\\n temp2_ = (temp_ * ((memoryVars_.vaultVariables2 >> 52) & X10)) / 1000;\\n }\\n (memoryVars_.maxTick, ) = TickMath.getTickAtRatio(temp2_);\\n }\\n\\n // extracting top tick as top tick will be the current tick\\n unchecked {\\n currentData_.tick = (vaultVariables_ & 4) == 4\\n ? int256((vaultVariables_ >> 3) & X19)\\n : -int256((vaultVariables_ >> 3) & X19);\\n }\\n\\n if (currentData_.tick > memoryVars_.maxTick) {\\n // absorbing all the debt above maxTick if available\\n vaultVariables_ = (abi.decode(_spell(SECONDARY_IMPLEMENTATION, abi.encodeWithSignature(\\\"absorb(uint256,int256)\\\", vaultVariables_, memoryVars_.maxTick)), (uint256)));\\n\\n // updating current tick to new topTick after absorb\\n unchecked {\\n currentData_.tick = (vaultVariables_ & 4) == 4\\n ? int256((vaultVariables_ >> 3) & X19)\\n : -int256((vaultVariables_ >> 3) & X19);\\n }\\n if (debtAmt_ == 0) {\\n // updating vault variables on storage as the transaction was for only absorb\\n vaultVariables = vaultVariables_;\\n return (0, 0);\\n }\\n }\\n\\n if (debtAmt_ < 10000 || debtAmt_ > X128) {\\n revert FluidVaultError(ErrorTypes.VaultT1__InvalidLiquidationAmt);\\n }\\n\\n // setting up status if top tick is liquidated or not\\n currentData_.tickStatus = vaultVariables_ & 2 == 0 ? 1 : 2;\\n // Tick info is mainly used as a place holder to store temporary tick related data\\n // (it can be current or ref using same memory variable)\\n TickData memory tickInfo_;\\n tickInfo_.tick = currentData_.tick;\\n\\n {\\n // ############# Setting current branch in memory #############\\n\\n // Updating branch related data\\n branch_.id = (vaultVariables_ >> 22) & X30;\\n branch_.data = branchData[branch_.id];\\n branch_.debtFactor = (branch_.data >> 116) & X50;\\n if (branch_.debtFactor == 0) {\\n // Initializing branch debt factor. 35 | 15 bit number. Where full 35 bits and 15th bit is occupied.\\n // Making the total number as (2**35 - 1) << 2**14.\\n // note: initial debt factor can be any number.\\n branch_.debtFactor = ((X35 << 15) | (1 << 14));\\n }\\n // fetching base branch's minima tick. if 0 that means it's a master branch\\n temp_ = (branch_.data >> 196) & X20;\\n if (temp_ > 0) {\\n unchecked {\\n branch_.minimaTick = (temp_ & 1) == 1 ? int256((temp_ >> 1) & X19) : -int256((temp_ >> 1) & X19);\\n }\\n } else {\\n branch_.minimaTick = type(int).min;\\n }\\n }\\n\\n // debtAmt_ should be less than 2**128 & EXCHANGE_PRICES_PRECISION is 1e12\\n unchecked {\\n currentData_.debtRemaining = (debtAmt_ * EXCHANGE_PRICES_PRECISION) / memoryVars_.borrowExPrice;\\n }\\n\\n // extracting total debt\\n temp2_ = (vaultVariables_ >> 146) & X64;\\n temp2_ = ((temp2_ >> 8) << (temp2_ & X8));\\n\\n if ((temp2_ / 1e9) > currentData_.debtRemaining) {\\n // if liquidation amount is less than 1e9 of total debt then revert\\n // so if total debt is $1B then minimum liquidation limit = $1\\n // so if total debt is $1T then minimum liquidation limit = $1000\\n // partials precision is slightlty above 1e9 so this will make sure that on every liquidation atleast 1 partial gets liquidated\\n // not sure if it can result in any issue but restricting amount further more to remove very low amount scenarios totally\\n revert FluidVaultError(ErrorTypes.VaultT1__InvalidLiquidationAmt);\\n }\\n\\n if (absorb_) {\\n temp_ = absorbedLiquidity;\\n // temp2_ -> absorbed col\\n temp2_ = (temp_ >> 128) & X128;\\n // temp_ -> absorbed debt\\n temp_ = temp_ & X128;\\n\\n if (temp_ > currentData_.debtRemaining) {\\n // Removing collateral in equal proportion as debt\\n currentData_.totalColLiq = ((temp2_ * currentData_.debtRemaining) / temp_);\\n temp2_ -= currentData_.totalColLiq;\\n // Removing debt\\n currentData_.totalDebtLiq = currentData_.debtRemaining;\\n unchecked {\\n temp_ -= currentData_.debtRemaining;\\n }\\n currentData_.debtRemaining = 0;\\n\\n // updating on storage\\n absorbedLiquidity = temp_ | (temp2_ << 128);\\n } else {\\n // updating on storage\\n absorbedLiquidity = 0;\\n unchecked {\\n currentData_.debtRemaining -= temp_;\\n }\\n currentData_.totalDebtLiq = temp_;\\n currentData_.totalColLiq = temp2_;\\n }\\n }\\n\\n // current tick should be greater than liquidationTick and it cannot be greater than maxTick as absorb will run\\n if (currentData_.tick > memoryVars_.liquidationTick) {\\n if (currentData_.debtRemaining > 0) {\\n // Stores liquidated debt & collateral in each loop\\n uint debtLiquidated_;\\n uint colLiquidated_;\\n uint debtFactor_ = BigMathVault.TWO_POWER_64;\\n\\n TickHasDebt memory tickHasDebt_;\\n unchecked {\\n tickHasDebt_.mapId = (currentData_.tick < 0)\\n ? (((currentData_.tick + 1) / 256) - 1)\\n : (currentData_.tick / 256);\\n }\\n\\n tickInfo_.ratio = TickMath.getRatioAtTick(tickInfo_.tick);\\n\\n if (currentData_.tickStatus == 1) {\\n // top tick is not liquidated. Hence it's a perfect tick.\\n currentData_.ratio = tickInfo_.ratio;\\n // if current tick in liquidation is a perfect tick then it is also the next tick that has debt.\\n tickHasDebt_.nextTick = currentData_.tick;\\n } else {\\n // top tick is liquidated. Hence it has partials.\\n // next tick that has debt liquidity will have to be fetched from tickHasDebt\\n unchecked {\\n tickInfo_.ratioOneLess = (tickInfo_.ratio * 10000) / 10015;\\n tickInfo_.length = tickInfo_.ratio - tickInfo_.ratioOneLess;\\n tickInfo_.partials = (branch_.data >> 22) & X30;\\n currentData_.ratio = tickInfo_.ratioOneLess + ((tickInfo_.length * tickInfo_.partials) / X30);\\n \\n if ((memoryVars_.liquidationTick + 1) == tickInfo_.tick && (tickInfo_.partials == 1)) {\\n if (to_ == 0x000000000000000000000000000000000000dEaD) {\\n // revert with liquidated amounts if to_ address is the dead address.\\n // this can be used in a resolver to find the max liquidatable amounts.\\n revert FluidLiquidateResult(0, 0);\\n }\\n revert FluidVaultError(ErrorTypes.VaultT1__InvalidLiquidation);\\n }\\n }\\n }\\n\\n while (true) {\\n if (currentData_.tickStatus == 1) {\\n // not liquidated -> Getting the debt from tick data itself\\n temp2_ = tickData[currentData_.tick];\\n // temp_ => tick debt\\n temp_ = (temp2_ >> 25) & X64;\\n // Converting big number into normal number\\n temp_ = (temp_ >> 8) << (temp_ & X8);\\n // Updating tickData on storage with removing debt & adding connection to branch\\n tickData[currentData_.tick] =\\n 1 | // set tick as liquidated\\n (temp2_ & 0x1fffffe) | // set same total tick ids\\n (branch_.id << 26) | // branch id where this tick got liquidated\\n (branch_.debtFactor << 56);\\n } else {\\n // already liquidated -> Get the debt from branch data in big number\\n // temp_ => tick debt\\n temp_ = (branch_.data >> 52) & X64;\\n // Converting big number into normal number\\n temp_ = (temp_ >> 8) << (temp_ & X8);\\n // Branch is getting updated over the end\\n }\\n\\n // Adding new debt into active debt for liquidation\\n currentData_.debt += temp_;\\n\\n // Adding new col into active col for liquidation\\n // Ratio is in 2**96 decimals hence multiplying debt with 2**96 to get proper collateral\\n currentData_.col += (temp_ * TickMath.ZERO_TICK_SCALED_RATIO) / currentData_.ratio;\\n\\n if (\\n (tickHasDebt_.nextTick == currentData_.tick && currentData_.tickStatus == 1) ||\\n tickHasDebt_.tickHasDebt == 0\\n ) {\\n // Fetching next perfect tick with liquidity\\n // tickHasDebt_.tickHasDebt == 0 will only happen in the first while loop\\n // in the very first perfect tick liquidation it'll be 0\\n if (tickHasDebt_.tickHasDebt == 0) {\\n tickHasDebt_.tickHasDebt = tickHasDebt[tickHasDebt_.mapId];\\n }\\n\\n // in 1st loop tickStatus can be 2. Meaning not a perfect current tick\\n if (currentData_.tickStatus == 1) {\\n unchecked {\\n tickHasDebt_.bitsToRemove = uint(-currentData_.tick + (tickHasDebt_.mapId * 256 + 256));\\n }\\n // Removing current top tick from tickHasDebt\\n tickHasDebt_.tickHasDebt =\\n (tickHasDebt_.tickHasDebt << tickHasDebt_.bitsToRemove) >>\\n tickHasDebt_.bitsToRemove;\\n // Updating in storage if tickHasDebt becomes 0.\\n if (tickHasDebt_.tickHasDebt == 0) {\\n tickHasDebt[tickHasDebt_.mapId] = 0;\\n }\\n }\\n\\n // For last user remaining in vault there could be a lot of while loop.\\n // Chances of this to happen is extremely low (like ~0%)\\n while (true) {\\n if (tickHasDebt_.tickHasDebt > 0) {\\n unchecked {\\n tickHasDebt_.nextTick =\\n tickHasDebt_.mapId *\\n 256 +\\n int(tickHasDebt_.tickHasDebt.mostSignificantBit()) -\\n 1;\\n }\\n break;\\n }\\n\\n // tickHasDebt_.tickHasDebt == 0. Checking if minimum tick of this mapID is less than liquidationTick_\\n // if true that means now the next tick is not needed as liquidation gets over minimum at liquidationTick_\\n unchecked {\\n if ((tickHasDebt_.mapId * 256) < memoryVars_.liquidationTick) {\\n tickHasDebt_.nextTick = type(int).min;\\n break;\\n }\\n\\n // Fetching next tick has debt by decreasing tickHasDebt_.mapId first\\n tickHasDebt_.tickHasDebt = tickHasDebt[--tickHasDebt_.mapId];\\n }\\n }\\n }\\n\\n // Fetching refTick. refTick is the biggest tick of these 3:\\n // 1. Next tick with liquidity (from tickHasDebt)\\n // 2. Minima tick of current branch\\n // 3. Liquidation threshold tick\\n {\\n // Setting currentData_.refTick & currentData_.refTickStatus\\n if (\\n branch_.minimaTick > tickHasDebt_.nextTick &&\\n branch_.minimaTick > memoryVars_.liquidationTick\\n ) {\\n // next tick will be of base branch (merge)\\n currentData_.refTick = branch_.minimaTick;\\n currentData_.refTickStatus = 2;\\n } else if (tickHasDebt_.nextTick > memoryVars_.liquidationTick) {\\n // next tick will be next tick from perfect tick\\n currentData_.refTick = tickHasDebt_.nextTick;\\n currentData_.refTickStatus = 1;\\n } else {\\n // next tick is threshold tick\\n currentData_.refTick = memoryVars_.liquidationTick;\\n currentData_.refTickStatus = 3; // leads to end of liquidation loop\\n }\\n }\\n\\n // using tickInfo variable again for ref tick as we don't have the need for it any more\\n tickInfo_.ratio = TickMath.getRatioAtTick(int24(currentData_.refTick));\\n if (currentData_.refTickStatus == 2) {\\n // merge current branch with base branch\\n unchecked {\\n tickInfo_.ratioOneLess = (tickInfo_.ratio * 10000) / 10015;\\n tickInfo_.length = tickInfo_.ratio - tickInfo_.ratioOneLess;\\n // Fetching base branch data to get the base branch's partial\\n branch_.baseBranchData = branchData[((branch_.data >> 166) & X30)];\\n tickInfo_.partials = (branch_.baseBranchData >> 22) & X30;\\n tickInfo_.currentRatio =\\n tickInfo_.ratioOneLess +\\n ((tickInfo_.length * tickInfo_.partials) / X30);\\n currentData_.refRatio = tickInfo_.currentRatio;\\n }\\n } else {\\n // refTickStatus can only be 1 (next tick from perfect tick) or 3 (liquidation threshold tick)\\n tickInfo_.currentRatio = tickInfo_.ratio;\\n currentData_.refRatio = tickInfo_.ratio;\\n tickInfo_.partials = X30;\\n }\\n\\n // Formula: (debt_ - x) / (col_ - (x * colPerDebt_)) = ratioEnd_\\n // x = ((ratioEnd_ * col) - debt_) / ((colPerDebt_ * ratioEnd_) - 1)\\n // x is debtToLiquidate_\\n // col_ = debt_ / ratioStart_ -> (currentData_.debt / currentData_.ratio)\\n // ratioEnd_ is currentData_.refRatio\\n //\\n // Calculation results of numerator & denominator is always negative\\n // which will cancel out to give positive output in the end so we can safely cast to uint.\\n // for nominator:\\n // ratioStart can only be >= ratioEnd so first part can only be reducing currentData_.debt leading to\\n // currentData_.debt reduced - currentData_.debt original * 1e27 -> can only be a negative number\\n // for denominator:\\n // currentData_.colPerDebt and currentData_.refRatio are inversely proportional to each other.\\n // the maximum value they can ever be is ~9.97e26 which is the 0.3% away from 100% because liquidation\\n // threshold + liquidation penalty can never be > 99.7%. This can also be verified by going back from\\n // min / max ratio values further up where we fetch oracle price etc.\\n // as optimization we can inverse nominator and denominator subtraction to directly get a positive number.\\n\\n debtLiquidated_ =\\n // nominator\\n ((currentData_.debt - (currentData_.refRatio * currentData_.debt) / currentData_.ratio) *\\n 1e27) /\\n // denominator\\n (1e27 - ((currentData_.colPerDebt * currentData_.refRatio) / TickMath.ZERO_TICK_SCALED_RATIO));\\n\\n colLiquidated_ = (debtLiquidated_ * currentData_.colPerDebt) / 1e27;\\n\\n if (currentData_.debt == debtLiquidated_) {\\n debtLiquidated_ -= 1;\\n }\\n\\n if (debtLiquidated_ >= currentData_.debtRemaining || currentData_.refTickStatus == 3) {\\n // End of liquidation as full amount to liquidate or liquidation threshold tick has been reached;\\n\\n // Updating tickHasDebt on storage.\\n tickHasDebt[tickHasDebt_.mapId] = tickHasDebt_.tickHasDebt;\\n\\n if (debtLiquidated_ >= currentData_.debtRemaining) {\\n // Liquidation ended between currentTick & refTick.\\n // Not all of liquidatable debt is actually liquidated -> recalculate\\n debtLiquidated_ = currentData_.debtRemaining;\\n colLiquidated_ = (debtLiquidated_ * currentData_.colPerDebt) / 1e27;\\n // Liquidating to debt. temp_ => final ratio after liquidation\\n // liquidatable debt - debtLiquidated / liquidatable col - colLiquidated\\n temp_ =\\n ((currentData_.debt - debtLiquidated_) * TickMath.ZERO_TICK_SCALED_RATIO) /\\n (currentData_.col - colLiquidated_);\\n // Fetching tick of where liquidation ended\\n (tickInfo_.tick, tickInfo_.ratioOneLess) = TickMath.getTickAtRatio(temp_);\\n if ((tickInfo_.tick < currentData_.refTick) && (tickInfo_.partials == X30)) {\\n // this situation might never happen\\n // if this happens then there might be some very edge case precision of few weis which is returning 1 tick less\\n // if the above were to ever happen then tickInfo_.tick only be currentData_.refTick - 1\\n // in this case the partial will be very very near to full (X30)\\n // increasing tick by 2 and making partial as 1 which is basically very very near to currentData_.refTick\\n unchecked {\\n tickInfo_.tick += 2;\\n }\\n tickInfo_.partials = 1;\\n } else {\\n unchecked {\\n // Increasing tick by 1 as final ratio will probably be a partial\\n ++tickInfo_.tick;\\n\\n // if ref tick is old liquidated tick then storing partials in temp2_\\n // tickInfo_.partials contains partial of branch which is the current ref tick\\n temp2_ = (currentData_.refTickStatus == 2 && tickInfo_.tick == currentData_.refTick) ? tickInfo_.partials : 0;\\n\\n tickInfo_.ratio = (tickInfo_.ratioOneLess * 10015) / 10000;\\n tickInfo_.length = tickInfo_.ratio - tickInfo_.ratioOneLess;\\n tickInfo_.partials = ((temp_ - tickInfo_.ratioOneLess) * X30) / tickInfo_.length;\\n\\n // Taking edge cases where partial comes as 0 or X30 meaning perfect tick.\\n // Hence, increasing or reducing it by 1 as liquidation tick cannot be perfect tick.\\n tickInfo_.partials = tickInfo_.partials == 0 ? 1 : tickInfo_.partials >= X30\\n ? X30 - 1\\n : tickInfo_.partials;\\n }\\n if (temp2_ > 0 && temp2_ >= tickInfo_.partials) {\\n // if refTick is liquidated tick and hence contains partials then checking that\\n // current liquidation tick's partial should not be less than last liquidation refTick\\n\\n // not sure if this is even possible to happen but adding checks to avoid it fully\\n // if it reverts here then next liquidation on next block should go through fine\\n revert FluidVaultError(ErrorTypes.VaultT1__LiquidationReverts);\\n }\\n }\\n } else {\\n // End in liquidation threshold.\\n // finalRatio_ = currentData_.refRatio;\\n // Increasing liquidation threshold tick by 1 partial. With 1 partial it'll reach to the next tick.\\n // Ratio change will be negligible. Doing this as liquidation threshold tick can also be a perfect non-liquidated tick.\\n unchecked {\\n tickInfo_.tick = currentData_.refTick + 1;\\n }\\n // Making partial as 1 so it doesn't stay perfect tick\\n tickInfo_.partials = 1;\\n // length is not needed as only partials are written to storage\\n }\\n\\n // debtFactor = debtFactor * (liquidatableDebt - debtLiquidated) / liquidatableDebt\\n // -> debtFactor * leftOverDebt / liquidatableDebt\\n debtFactor_ = (debtFactor_ * (currentData_.debt - debtLiquidated_)) / currentData_.debt;\\n currentData_.totalDebtLiq += debtLiquidated_;\\n currentData_.debt -= debtLiquidated_; // currentData_.debt => leftOverDebt after debtLiquidated_\\n currentData_.totalColLiq += colLiquidated_;\\n currentData_.col -= colLiquidated_; // currentData_.col => leftOverCol after colLiquidated_\\n\\n // Updating branch's debt factor & write to storage as liquidation is over\\n branch_.debtFactor = branch_.debtFactor.mulDivBigNumber(debtFactor_);\\n\\n if (currentData_.debt < 100) {\\n // this can happen when someone tries to create a dust tick\\n revert FluidVaultError(ErrorTypes.VaultT1__BranchDebtTooLow);\\n }\\n\\n unchecked {\\n // Tick to insert\\n temp2_ = tickInfo_.tick < 0\\n ? (uint(-tickInfo_.tick) << 1)\\n : ((uint(tickInfo_.tick) << 1) | 1);\\n }\\n\\n // Updating Branch data with debt factor, debt, partials, minima tick & assigning is liquidated\\n branchData[branch_.id] =\\n ((branch_.data >> 166) << 166) |\\n 1 | // set as liquidated\\n (temp2_ << 2) | // minima tick of branch\\n (tickInfo_.partials << 22) |\\n (currentData_.debt.toBigNumber(56, 8, BigMathMinified.ROUND_UP) << 52) | // branch debt\\n (branch_.debtFactor << 116);\\n\\n // Updating vault variables with current branch & tick\\n vaultVariables_ =\\n ((vaultVariables_ >> 52) << 52) |\\n 2 | // set as liquidated\\n (temp2_ << 2) | // top tick\\n (branch_.id << 22);\\n break;\\n }\\n\\n unchecked {\\n // debtLiquidated_ >= currentData_.debtRemaining leads to loop break in if statement above\\n // so this can be unchecked\\n currentData_.debtRemaining -= debtLiquidated_;\\n }\\n\\n // debtFactor = debtFactor * (liquidatableDebt - debtLiquidated) / liquidatableDebt\\n // -> debtFactor * leftOverDebt / liquidatableDebt\\n debtFactor_ = (debtFactor_ * (currentData_.debt - debtLiquidated_)) / currentData_.debt;\\n currentData_.totalDebtLiq += debtLiquidated_;\\n currentData_.debt -= debtLiquidated_;\\n currentData_.totalColLiq += colLiquidated_;\\n currentData_.col -= colLiquidated_;\\n\\n // updating branch's debt factor\\n branch_.debtFactor = branch_.debtFactor.mulDivBigNumber(debtFactor_);\\n // Setting debt factor as 1 << 64 again\\n debtFactor_ = BigMathVault.TWO_POWER_64;\\n\\n if (currentData_.refTickStatus == 2) {\\n // ref tick is base branch's minima hence merging current branch to base branch\\n // and making base branch as current branch.\\n\\n // read base branch related data\\n temp_ = (branch_.data >> 166) & X30; // temp_ -> base branch id\\n temp2_ = branch_.baseBranchData;\\n {\\n uint newBranchDebtFactor_ = (temp2_ >> 116) & X50;\\n\\n // connectionFactor_ = baseBranchDebtFactor / currentBranchDebtFactor\\n uint connectionFactor_ = newBranchDebtFactor_.divBigNumber(branch_.debtFactor);\\n // Updating current branch in storage\\n branchData[branch_.id] =\\n ((branch_.data >> 166) << 166) | // deleting debt / partials / minima tick\\n 2 | // setting as merged\\n (connectionFactor_ << 116); // set new connectionFactor\\n\\n // Storing base branch in memory\\n // Updating branch ID to base branch ID\\n branch_.id = temp_;\\n // Updating branch data with base branch data\\n branch_.data = temp2_;\\n // Remove next branch connection from base branch\\n branch_.debtFactor = newBranchDebtFactor_;\\n // temp_ => minima tick of base branch\\n temp_ = (temp2_ >> 196) & X20;\\n if (temp_ > 0) {\\n unchecked {\\n branch_.minimaTick = (temp_ & 1) == 1\\n ? int256((temp_ >> 1) & X19)\\n : -int256((temp_ >> 1) & X19);\\n }\\n } else {\\n branch_.minimaTick = type(int).min;\\n }\\n }\\n }\\n\\n // Making refTick as currentTick\\n currentData_.tick = currentData_.refTick;\\n currentData_.tickStatus = currentData_.refTickStatus;\\n currentData_.ratio = currentData_.refRatio;\\n }\\n }\\n }\\n\\n // calculating net token amounts using exchange price\\n actualDebtAmt_ = (currentData_.totalDebtLiq * memoryVars_.borrowExPrice) / EXCHANGE_PRICES_PRECISION;\\n actualColAmt_ = (currentData_.totalColLiq * memoryVars_.supplyExPrice) / EXCHANGE_PRICES_PRECISION;\\n\\n // Chances of this to happen are in few wei\\n if (actualDebtAmt_ > debtAmt_) {\\n // calc new actualColAmt_ via ratio.\\n actualColAmt_ = actualColAmt_ * (debtAmt_ / actualDebtAmt_);\\n actualDebtAmt_ = debtAmt_;\\n }\\n\\n if (actualDebtAmt_ == 0) {\\n revert FluidVaultError(ErrorTypes.VaultT1__InvalidLiquidation);\\n }\\n\\n if (((actualColAmt_ * 1e18) / actualDebtAmt_) < colPerUnitDebt_) {\\n revert FluidVaultError(ErrorTypes.VaultT1__ExcessSlippageLiquidation);\\n }\\n\\n if (to_ == 0x000000000000000000000000000000000000dEaD) {\\n // revert with liquidated amounts if to_ address is the dead address.\\n // this can be used in a resolver to find the max liquidatable amounts.\\n revert FluidLiquidateResult(actualColAmt_, actualDebtAmt_);\\n }\\n\\n // payback at Liquidity\\n if (BORROW_TOKEN == NATIVE_TOKEN) {\\n temp_ = actualDebtAmt_;\\n if (actualDebtAmt_ < msg.value) {\\n unchecked {\\n // subtraction can be unchecked because of if check above\\n SafeTransfer.safeTransferNative(msg.sender, msg.value - actualDebtAmt_);\\n }\\n }\\n // else if actualDebtAmt_ > msg.value not possible as actualDebtAmt_ can maximally be debtAmt_ and\\n // msg.value == debtAmt_ is checked in the beginning of function.\\n } else {\\n temp_ = 0;\\n }\\n unchecked {\\n // payback at liquidity\\n LIQUIDITY.operate{ value: temp_ }(\\n BORROW_TOKEN,\\n 0,\\n -int(actualDebtAmt_),\\n address(0),\\n address(0),\\n abi.encode(msg.sender)\\n );\\n // withdraw at liquidity\\n LIQUIDITY.operate(SUPPLY_TOKEN, -int(actualColAmt_), 0, to_, address(0), new bytes(0));\\n }\\n\\n // Calculating new total collateral & total debt.\\n // temp_ -> total supply\\n temp_ = (vaultVariables_ >> 82) & X64;\\n temp_ = ((temp_ >> 8) << (temp_ & X8)) - currentData_.totalColLiq;\\n // temp2_ -> total borrow\\n temp2_ = (vaultVariables_ >> 146) & X64;\\n temp2_ = ((temp2_ >> 8) << (temp2_ & X8)) - currentData_.totalDebtLiq;\\n // Updating vault variables on storage\\n // Converting total supply & total borrow in 64 bits (56 | 8) bignumber\\n vaultVariables =\\n (vaultVariables_ & 0xfffffffffffc00000000000000000000000000000003ffffffffffffffffffff) |\\n (temp_.toBigNumber(56, 8, BigMathMinified.ROUND_DOWN) << 82) | // total supply\\n (temp2_.toBigNumber(56, 8, BigMathMinified.ROUND_UP) << 146); // total borrow\\n\\n emit LogLiquidate(msg.sender, actualColAmt_, actualDebtAmt_, to_);\\n }\\n\\n /// @dev Checks total supply of vault's in Liquidity Layer & Vault contract and rebalance it accordingly\\n /// if vault supply is more than Liquidity Layer then deposit difference through reserve/rebalance contract\\n /// if vault supply is less than Liquidity Layer then withdraw difference to reserve/rebalance contract\\n /// if vault borrow is more than Liquidity Layer then borrow difference to reserve/rebalance contract\\n /// if vault borrow is less than Liquidity Layer then payback difference through reserve/rebalance contract\\n function rebalance() external payable returns (int supplyAmt_, int borrowAmt_) {\\n (supplyAmt_, borrowAmt_) = abi.decode(_spell(SECONDARY_IMPLEMENTATION, msg.data), (int, int));\\n }\\n\\n /// @dev liquidity callback for cheaper token transfers in case of deposit or payback.\\n /// only callable by Liquidity during an operation.\\n function liquidityCallback(address token_, uint amount_, bytes calldata data_) external {\\n if (msg.sender != address(LIQUIDITY))\\n revert FluidVaultError(ErrorTypes.VaultT1__InvalidLiquidityCallbackAddress);\\n if (vaultVariables & 1 == 0) revert FluidVaultError(ErrorTypes.VaultT1__NotEntered);\\n\\n SafeTransfer.safeTransferFrom(token_, abi.decode(data_, (address)), address(LIQUIDITY), amount_);\\n }\\n\\n constructor(ConstantViews memory constants_) Helpers(constants_) {\\n // Note that vaults are deployed by VaultFactory so we somewhat trust the values being passed in\\n\\n // Setting branch in vault.\\n vaultVariables = (vaultVariables) | (1 << 22) | (1 << 52);\\n\\n uint liqSupplyExchangePrice_ = (LIQUIDITY.readFromStorage(LIQUIDITY_SUPPLY_EXCHANGE_PRICE_SLOT) >>\\n LiquiditySlotsLink.BITS_EXCHANGE_PRICES_SUPPLY_EXCHANGE_PRICE) & X64;\\n uint liqBorrowExchangePrice_ = (LIQUIDITY.readFromStorage(LIQUIDITY_BORROW_EXCHANGE_PRICE_SLOT) >>\\n LiquiditySlotsLink.BITS_EXCHANGE_PRICES_BORROW_EXCHANGE_PRICE) & X64;\\n\\n if (\\n liqSupplyExchangePrice_ < EXCHANGE_PRICES_PRECISION || liqBorrowExchangePrice_ < EXCHANGE_PRICES_PRECISION\\n ) {\\n revert FluidVaultError(ErrorTypes.VaultT1__TokenNotInitialized);\\n }\\n // Updating initial rates in storage\\n rates =\\n liqSupplyExchangePrice_ |\\n (liqBorrowExchangePrice_ << 64) |\\n (EXCHANGE_PRICES_PRECISION << 128) |\\n (EXCHANGE_PRICES_PRECISION << 192);\\n }\\n\\n fallback() external {\\n if (!(VAULT_FACTORY.isGlobalAuth(msg.sender) || VAULT_FACTORY.isVaultAuth(address(this), msg.sender))) {\\n revert FluidVaultError(ErrorTypes.VaultT1__NotAnAuth);\\n }\\n\\n // Delegate the current call to `implementation`.\\n // This does not return to its internall call site, it will return directly to the external caller.\\n // solhint-disable-next-line no-inline-assembly\\n _spell(ADMIN_IMPLEMENTATION, msg.data);\\n }\\n\\n function _spell(address target_, bytes memory data_) private returns (bytes memory response_) {\\n assembly {\\n let succeeded := delegatecall(gas(), target_, add(data_, 0x20), mload(data_), 0, 0)\\n let size := returndatasize()\\n\\n response_ := mload(0x40)\\n mstore(0x40, add(response_, and(add(add(size, 0x20), 0x1f), not(0x1f))))\\n mstore(response_, size)\\n returndatacopy(add(response_, 0x20), 0, size)\\n\\n switch iszero(succeeded)\\n case 1 {\\n // throw if delegatecall failed\\n returndatacopy(0x00, 0x00, size)\\n revert(0x00, size)\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x608af9a03cb54f29c1d9d27a8249fbaf8f584e4b5869ec3d7eacacadd2f41753\",\"license\":\"BUSL-1.1\"},\"contracts/protocols/vault/vaultT1/coreModule/structs.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\npragma solidity 0.8.21;\\n\\ncontract Structs {\\n // structs are used to mitigate Stack too deep errors\\n\\n struct OperateMemoryVars {\\n // ## User's position before update ##\\n uint oldColRaw;\\n uint oldNetDebtRaw; // total debt - dust debt\\n int oldTick;\\n // ## User's position after update ##\\n uint colRaw;\\n uint debtRaw;\\n uint dustDebtRaw;\\n int tick;\\n uint tickId;\\n // others\\n uint256 vaultVariables2;\\n uint256 branchId;\\n int256 topTick;\\n uint liquidityExPrice;\\n uint supplyExPrice;\\n uint borrowExPrice;\\n uint branchData;\\n // user's supply slot data in liquidity\\n uint userSupplyLiquidityData;\\n }\\n\\n struct BranchData {\\n uint id;\\n uint data;\\n uint ratio;\\n uint debtFactor;\\n int minimaTick;\\n uint baseBranchData;\\n }\\n\\n struct TickData {\\n int tick;\\n uint data;\\n uint ratio;\\n uint ratioOneLess;\\n uint length;\\n uint currentRatio; // current tick is ratio with partials.\\n uint partials;\\n }\\n\\n // note: All the below token amounts are in raw form.\\n struct CurrentLiquidity {\\n uint256 debtRemaining; // Debt remaining to liquidate\\n uint256 debt; // Current liquidatable debt before reaching next check point\\n uint256 col; // Calculate using debt & ratioCurrent\\n uint256 colPerDebt; // How much collateral to liquidate per unit of Debt\\n uint256 totalDebtLiq; // Total debt liquidated till now\\n uint256 totalColLiq; // Total collateral liquidated till now\\n int tick; // Current tick to liquidate\\n uint ratio; // Current ratio to liquidate\\n uint tickStatus; // if 1 then it's a perfect tick, if 2 that means it's a liquidated tick\\n int refTick; // ref tick to liquidate\\n uint refRatio; // ratio at ref tick\\n uint refTickStatus; // if 1 then it's a perfect tick, if 2 that means it's a liquidated tick, if 3 that means it's a liquidation threshold\\n }\\n\\n struct TickHasDebt {\\n int tick; // current tick\\n int nextTick; // next tick with liquidity\\n int mapId; // mapping ID of tickHasDebt\\n uint bitsToRemove; // liquidity to remove till tick_ so we can search for next tick\\n uint tickHasDebt; // getting tickHasDebt_ from tickHasDebt[mapId_]\\n uint mostSigBit; // most significant bit in tickHasDebt_ to get the next tick\\n }\\n\\n struct LiquidateMemoryVars {\\n uint256 vaultVariables2;\\n int liquidationTick;\\n int maxTick;\\n uint256 supplyExPrice;\\n uint256 borrowExPrice;\\n }\\n\\n struct AbsorbMemoryVariables {\\n uint256 debtAbsorbed;\\n uint256 colAbsorbed;\\n int256 startingTick;\\n uint256 mostSigBit;\\n }\\n\\n struct ConstantViews {\\n address liquidity;\\n address factory;\\n address adminImplementation;\\n address secondaryImplementation;\\n address supplyToken;\\n address borrowToken;\\n uint8 supplyDecimals;\\n uint8 borrowDecimals;\\n uint vaultId;\\n bytes32 liquiditySupplyExchangePriceSlot;\\n bytes32 liquidityBorrowExchangePriceSlot;\\n bytes32 liquidityUserSupplySlot;\\n bytes32 liquidityUserBorrowSlot;\\n }\\n\\n struct RebalanceMemoryVariables {\\n uint256 liqSupplyExPrice;\\n uint256 liqBorrowExPrice;\\n uint256 vaultSupplyExPrice;\\n uint256 vaultBorrowExPrice;\\n }\\n}\\n\",\"keccak256\":\"0xcd3160a62445eaf106ad9f598fe6f5ef06621a5cd3e7d80b0f59ac4a396a6c7a\",\"license\":\"BUSL-1.1\"},\"solmate/src/utils/SSTORE2.sol\":{\"content\":\"// SPDX-License-Identifier: AGPL-3.0-only\\npragma solidity >=0.8.0;\\n\\n/// @notice Read and write to persistent storage at a fraction of the cost.\\n/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/SSTORE2.sol)\\n/// @author Modified from 0xSequence (https://github.com/0xSequence/sstore2/blob/master/contracts/SSTORE2.sol)\\nlibrary SSTORE2 {\\n uint256 internal constant DATA_OFFSET = 1; // We skip the first byte as it's a STOP opcode to ensure the contract can't be called.\\n\\n /*//////////////////////////////////////////////////////////////\\n WRITE LOGIC\\n //////////////////////////////////////////////////////////////*/\\n\\n function write(bytes memory data) internal returns (address pointer) {\\n // Prefix the bytecode with a STOP opcode to ensure it cannot be called.\\n bytes memory runtimeCode = abi.encodePacked(hex\\\"00\\\", data);\\n\\n bytes memory creationCode = abi.encodePacked(\\n //---------------------------------------------------------------------------------------------------------------//\\n // Opcode | Opcode + Arguments | Description | Stack View //\\n //---------------------------------------------------------------------------------------------------------------//\\n // 0x60 | 0x600B | PUSH1 11 | codeOffset //\\n // 0x59 | 0x59 | MSIZE | 0 codeOffset //\\n // 0x81 | 0x81 | DUP2 | codeOffset 0 codeOffset //\\n // 0x38 | 0x38 | CODESIZE | codeSize codeOffset 0 codeOffset //\\n // 0x03 | 0x03 | SUB | (codeSize - codeOffset) 0 codeOffset //\\n // 0x80 | 0x80 | DUP | (codeSize - codeOffset) (codeSize - codeOffset) 0 codeOffset //\\n // 0x92 | 0x92 | SWAP3 | codeOffset (codeSize - codeOffset) 0 (codeSize - codeOffset) //\\n // 0x59 | 0x59 | MSIZE | 0 codeOffset (codeSize - codeOffset) 0 (codeSize - codeOffset) //\\n // 0x39 | 0x39 | CODECOPY | 0 (codeSize - codeOffset) //\\n // 0xf3 | 0xf3 | RETURN | //\\n //---------------------------------------------------------------------------------------------------------------//\\n hex\\\"60_0B_59_81_38_03_80_92_59_39_F3\\\", // Returns all code in the contract except for the first 11 (0B in hex) bytes.\\n runtimeCode // The bytecode we want the contract to have after deployment. Capped at 1 byte less than the code size limit.\\n );\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n // Deploy a new contract with the generated creation code.\\n // We start 32 bytes into the code to avoid copying the byte length.\\n pointer := create(0, add(creationCode, 32), mload(creationCode))\\n }\\n\\n require(pointer != address(0), \\\"DEPLOYMENT_FAILED\\\");\\n }\\n\\n /*//////////////////////////////////////////////////////////////\\n READ LOGIC\\n //////////////////////////////////////////////////////////////*/\\n\\n function read(address pointer) internal view returns (bytes memory) {\\n return readBytecode(pointer, DATA_OFFSET, pointer.code.length - DATA_OFFSET);\\n }\\n\\n function read(address pointer, uint256 start) internal view returns (bytes memory) {\\n start += DATA_OFFSET;\\n\\n return readBytecode(pointer, start, pointer.code.length - start);\\n }\\n\\n function read(\\n address pointer,\\n uint256 start,\\n uint256 end\\n ) internal view returns (bytes memory) {\\n start += DATA_OFFSET;\\n end += DATA_OFFSET;\\n\\n require(pointer.code.length >= end, \\\"OUT_OF_BOUNDS\\\");\\n\\n return readBytecode(pointer, start, end - start);\\n }\\n\\n /*//////////////////////////////////////////////////////////////\\n INTERNAL HELPER LOGIC\\n //////////////////////////////////////////////////////////////*/\\n\\n function readBytecode(\\n address pointer,\\n uint256 start,\\n uint256 size\\n ) private view returns (bytes memory data) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n // Get a pointer to some free memory.\\n data := mload(0x40)\\n\\n // Update the free memory pointer to prevent overriding our data.\\n // We use and(x, not(31)) as a cheaper equivalent to sub(x, mod(x, 32)).\\n // Adding 31 to size and running the result through the logic above ensures\\n // the memory pointer remains word-aligned, following the Solidity convention.\\n mstore(0x40, add(data, and(add(add(size, 32), 31), not(31))))\\n\\n // Store the size of the data in the first 32 byte chunk of free memory.\\n mstore(data, size)\\n\\n // Copy the code into memory right after the 32 bytes we used to store the size.\\n extcodecopy(pointer, add(data, 32), start, size)\\n }\\n }\\n}\\n\",\"keccak256\":\"0xc5359c92365c550c418725fc534a538426ea8f6e7f6c06c0a9d66647d864469d\",\"license\":\"AGPL-3.0-only\"}},\"version\":1}", "bytecode": "0x6101406040523480156200001257600080fd5b50604051620073df380380620073df833981016040819052620000359162000331565b6001600160a01b0380841660c05282811660e052811661010052604051600090620000636020820162000306565b6020820181038252601f19601f82011660405250519050620000c2620000bc60405180602001620000949062000306565b601f1982820381018352601f909101166040526000620000b660028662000391565b6200013e565b6200025b565b6001600160a01b03166080526040516200012290620000bc90620000e96020820162000306565b601f1982820381018352601f909101166040526200010960028562000391565b6200011660028662000391565b620000b69086620003b4565b6001600160a01b031660a0525050306101205250620004569050565b6060816200014e81601f620003d0565b1015620001935760405162461bcd60e51b815260206004820152600e60248201526d736c6963655f6f766572666c6f7760901b60448201526064015b60405180910390fd5b6200019f8284620003d0565b84511015620001e55760405162461bcd60e51b8152602060048201526011602482015270736c6963655f6f75744f66426f756e647360781b60448201526064016200018a565b60608215801562000206576040519150600082526020820160405262000252565b6040519150601f8416801560200281840101858101878315602002848b0101015b818310156200024157805183526020928301920162000227565b5050858452601f01601f1916604052505b50949350505050565b6000808260405160200162000271919062000418565b604051602081830303815290604052905060008160405160200162000297919062000434565b60405160208183030381529060405290508051602082016000f092506001600160a01b038316620002ff5760405162461bcd60e51b81526020600482015260116024820152701111541313d65351539517d19052531151607a1b60448201526064016200018a565b5050919050565b61621f80620011c083390190565b80516001600160a01b03811681146200032c57600080fd5b919050565b6000806000606084860312156200034757600080fd5b620003528462000314565b9250620003626020850162000314565b9150620003726040850162000314565b90509250925092565b634e487b7160e01b600052601160045260246000fd5b600082620003af57634e487b7160e01b600052601260045260246000fd5b500490565b81810381811115620003ca57620003ca6200037b565b92915050565b80820180821115620003ca57620003ca6200037b565b6000815160005b81811015620004095760208185018101518683015201620003ed565b50600093019283525090919050565b6000815260006200042d6001830184620003e6565b9392505050565b6a600b5981380380925939f360a81b815260006200042d600b830184620003e6565b60805160a05160c05160e0516101005161012051610d00620004c06000396000818161010901526101df01526000818160e2015261035d0152600081816101300152610333015260008181607c0152610308015260006101980152600061016f0152610d006000f3fe608060405234801561001057600080fd5b50600436106100725760003560e01c8063cc025f7c11610050578063cc025f7c14610104578063cc2fe94b1461012b578063f9f872f51461015257600080fd5b80632861c7d11461007757806368f4787e146100c8578063a07ddc17146100dd575b600080fd5b61009e7f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b6100d0610165565b6040516100bf9190610a03565b61009e7f000000000000000000000000000000000000000000000000000000000000000081565b61009e7f000000000000000000000000000000000000000000000000000000000000000081565b61009e7f000000000000000000000000000000000000000000000000000000000000000081565b6100d0610160366004610a79565b6101c6565b60606101c16101937f00000000000000000000000000000000000000000000000000000000000000006108d5565b6101bc7f00000000000000000000000000000000000000000000000000000000000000006108d5565b610903565b905090565b606073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000163003610240576040517f60121cca00000000000000000000000000000000000000000000000000000000815261753760048201526024015b60405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036102a9576040517f60121cca0000000000000000000000000000000000000000000000000000000081526175336004820152602401610237565b604080516101a081018252600060a0820181905260c0820181905260e08201819052610100820181905261012082018190526101408201819052610160820181905261018082015273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000811682523060208301527f00000000000000000000000000000000000000000000000000000000000000008116928201929092527f000000000000000000000000000000000000000000000000000000000000000082166060820152908416608082018190527fffffffffffffffffffffffff1111111111111111111111111111111111111112016103ba576012610429565b8373ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015610405573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104299190610ab2565b60ff1660c082015273ffffffffffffffffffffffffffffffffffffffff831660a082018190527fffffffffffffffffffffffff11111111111111111111111111111111111111120161047c5760126104eb565b8273ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156104c7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104eb9190610ab2565b60ff1660e0820152604080517f8d65402300000000000000000000000000000000000000000000000000000000815290513091638d6540239160048083019260209291908290030181865afa158015610548573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061056c9190610adc565b61010082018190526040517fe6bd26a2000000000000000000000000000000000000000000000000000000008152600091309163e6bd26a2916105b59160040190815260200190565b602060405180830381865afa1580156105d2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105f69190610af5565b90506107e18282604080516101a081018252600080825260208083018290528284018290526060808401839052608080850184905260a0850184905260c0850184905260e08501849052610100850184905261012085018490526101408501849052610160850184905261018085019390935291860151845173ffffffffffffffffffffffffffffffffffffffff909116818301526005818601528451808203860181529201909352805192019190912061012084015260a08301516040805173ffffffffffffffffffffffffffffffffffffffff909216602080840191909152600583830152815180840383018152606090930190915281519101206101408401526080808401516040805173ffffffffffffffffffffffffffffffffffffffff808716602080840191909152600883850152835180840385018152606084018552805190820120919094169482019490945260a0808201949094528151808203909401845260c0019052815191012061016084015260a0808401516040805173ffffffffffffffffffffffffffffffffffffffff808716602080840191909152600983850152835180840385018152606084018552805190820120919094166080830152818501528151808203909401845260c001905281519101206101808401525090919050565b91506107eb610165565b826040516020016107fc9190610b12565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152908290526108389291602001610c61565b60405160208183030381529060405292508373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f4960ed60da9bf499a0841c5bb40e134da1b7a55ec0436c1ca8e19848e78031a38561010001516040516108c491815260200190565b60405180910390a450505b92915050565b60606108cf8260016108fe8173ffffffffffffffffffffffffffffffffffffffff84163b610c90565b61099e565b6060806040519050835180825260208201818101602087015b8183101561093457805183526020928301920161091c565b50855184518101855292509050808201602086015b81831015610961578051835260209283019201610949565b508651929092011591909101601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660405250905092915050565b60408051603f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168101909152818152818360208301863c9392505050565b60005b838110156109fa5781810151838201526020016109e2565b50506000910152565b6020815260008251806020840152610a228160408501602087016109df565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b73ffffffffffffffffffffffffffffffffffffffff81168114610a7657600080fd5b50565b60008060408385031215610a8c57600080fd5b8235610a9781610a54565b91506020830135610aa781610a54565b809150509250929050565b600060208284031215610ac457600080fd5b815160ff81168114610ad557600080fd5b9392505050565b600060208284031215610aee57600080fd5b5051919050565b600060208284031215610b0757600080fd5b8151610ad581610a54565b815173ffffffffffffffffffffffffffffffffffffffff1681526101a081016020830151610b58602084018273ffffffffffffffffffffffffffffffffffffffff169052565b506040830151610b80604084018273ffffffffffffffffffffffffffffffffffffffff169052565b506060830151610ba8606084018273ffffffffffffffffffffffffffffffffffffffff169052565b506080830151610bd0608084018273ffffffffffffffffffffffffffffffffffffffff169052565b5060a0830151610bf860a084018273ffffffffffffffffffffffffffffffffffffffff169052565b5060c0830151610c0d60c084018260ff169052565b5060e0830151610c2260e084018260ff169052565b50610100838101519083015261012080840151908301526101408084015190830152610160808401519083015261018092830151929091019190915290565b60008351610c738184602088016109df565b835190830190610c878183602088016109df565b01949350505050565b818103818111156108cf577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fdfea264697066735822122068f258e6cc2fc43fd52fb8d1eabc2215cbfc2cee76e1a0992458140cb0f37b9464736f6c634300081500336102206040523480156200001257600080fd5b506040516200621f3803806200621f8339810160408190526200003591620002a6565b80516001600160a01b0390811661014081815260208401518316610160908152610100808601516101809081526080808801518716905260a0808801518716905260c08088015160ff90811690915260e0808901519091169052610120808801516101a0819052948801516101c052928701516101e052860151610200526040808701518616909152606086015190941690526000805466100000004000001781559251632d71cdb960e21b815260048101919091526001600160401b0391605b9163b5c736e490602401602060405180830381865afa1580156200011e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000144919062000396565b901c16905060006001600160401b03609b610140516001600160a01b031663b5c736e46101c0516040518263ffffffff1660e01b81526004016200018a91815260200190565b602060405180830381865afa158015620001a8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001ce919062000396565b901c16905064e8d4a51000821080620001eb575064e8d4a5100081105b1562000212576040516330090e6560e11b8152617924600482015260240160405180910390fd5b60401b177ce8d4a51000000000e8d4a51000000000000000000000000000000000001760085550620003b0565b6040516101a081016001600160401b03811182821017156200027157634e487b7160e01b600052604160045260246000fd5b60405290565b80516001600160a01b03811681146200028f57600080fd5b919050565b805160ff811681146200028f57600080fd5b60006101a08284031215620002ba57600080fd5b620002c46200023f565b620002cf8362000277565b8152620002df6020840162000277565b6020820152620002f26040840162000277565b6040820152620003056060840162000277565b6060820152620003186080840162000277565b60808201526200032b60a0840162000277565b60a08201526200033e60c0840162000294565b60c08201526200035160e0840162000294565b60e08201526101008381015190820152610120808401519082015261014080840151908201526101608084015190820152610180928301519281019290925250919050565b600060208284031215620003a957600080fd5b5051919050565b60805160a05160c05160e05161010051610120516101405161016051610180516101a0516101c0516101e05161020051615ccf6200055060003960006106f30152600081816106cc0152611c2b0152600081816106a501526124dd01526000818161067e01526123fb01526000818161044d015281816106570152610bff015260008181610102015281816101bc015281816103780152818161054001528181610c2b0152610d1b0152600081816104190152818161051b01528181611c5101528181611d7b01528181611fb8015281816120d7015281816121bc015281816124430152818161250a01528181613f260152818161404301528181614250015261430001526000818161058f015281816129300152612e0d015260008181610280015261056801526000610630015260006106080152600081816105df01528181610a2701528181611f1a01528181611ff5015281816121fa01528181612a1601528181613ec90152613f630152600081816105b70152818161098101528181611de201528181611e2701528181612115015261406a0152615ccf6000f3fe6080604052600436106100c75760003560e01c8063540acabc11610074578063ad2075011161004e578063ad207501146104ad578063b5c736e4146104cd578063b7791bf2146104ec576100c7565b8063540acabc1461043b5780637d7c2a1c1461047d5780638433ea221461049a576100c7565b8063103f2907116100a5578063103f29071461036657806322348cc7146103bf5780632861c7d114610407576100c7565b806302161887146102de578063032d22761461031857806309f0d8cb14610346575b3480156100d357600080fd5b506040517f4502d0630000000000000000000000000000000000000000000000000000000081523360048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690634502d06390602401602060405180830381865afa15801561015e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061018291906156a1565b8061023c57506040517fe04c8e5d0000000000000000000000000000000000000000000000000000000081523060048201523360248201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063e04c8e5d90604401602060405180830381865afa158015610218573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061023c91906156a1565b61027b576040517f60121cca00000000000000000000000000000000000000000000000000000000815261792560048201526024015b60405180910390fd5b6102dc7f00000000000000000000000000000000000000000000000000000000000000006000368080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061072492505050565b005b3480156102ea57600080fd5b506102f3610770565b6040805194855260208501939093529183015260608201526080015b60405180910390f35b61032b6103263660046156e0565b610864565b6040805193845260208401929092529082015260600161030f565b34801561035257600080fd5b506102f3610361366004615721565b6123d0565b34801561037257600080fd5b5061039a7f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161030f565b3480156103cb57600080fd5b506103df6103da36600461573a565b612668565b604080519586526020860194909452928401919091526060830152608082015260a00161030f565b34801561041357600080fd5b5061039a7f000000000000000000000000000000000000000000000000000000000000000081565b34801561044757600080fd5b5061046f7f000000000000000000000000000000000000000000000000000000000000000081565b60405190815260200161030f565b610485612928565b6040805192835260208301919091520161030f565b6104856104a836600461576c565b6129a8565b3480156104b957600080fd5b506102dc6104c83660046157ab565b614238565b3480156104d957600080fd5b5061046f6104e8366004615721565b5490565b3480156104f857600080fd5b50604080516101a08101825273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000811682527f0000000000000000000000000000000000000000000000000000000000000000811660208301527f00000000000000000000000000000000000000000000000000000000000000008116828401527f0000000000000000000000000000000000000000000000000000000000000000811660608301527f0000000000000000000000000000000000000000000000000000000000000000811660808301527f00000000000000000000000000000000000000000000000000000000000000001660a082015260ff7f0000000000000000000000000000000000000000000000000000000000000000811660c08301527f00000000000000000000000000000000000000000000000000000000000000001660e08201527f00000000000000000000000000000000000000000000000000000000000000006101008201527f00000000000000000000000000000000000000000000000000000000000000006101208201527f00000000000000000000000000000000000000000000000000000000000000006101408201527f00000000000000000000000000000000000000000000000000000000000000006101608201527f0000000000000000000000000000000000000000000000000000000000000000610180820152905161030f9190615834565b6060600080835160208501865af43d6040519250601f19601f6020830101168301604052808352806000602085013e81156001810361076757816000803e816000fd5b50505092915050565b6000806000806107816001546123d0565b9296509094509250905067ffffffffffffffff8411806107a8575067ffffffffffffffff83115b806107ba575067ffffffffffffffff82115b806107cc575067ffffffffffffffff81115b15610807576040517f60121cca00000000000000000000000000000000000000000000000000000000815261792d6004820152602401610272565b604083811b8517608084901b1760c083901b17600855517fcde545703e0372175cadfff811d67c32910c3dcb33199679b3271c4106afdf9a906108569084908490918252602082015260400190565b60405180910390a190919293565b600080548190819060018116820361088257600181176000556108b8565b6040517f60121cca0000000000000000000000000000000000000000000000000000000081526179196004820152602401610272565b861580156108c4575085155b806109045750861580159061090457507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd8f087138015610904575061271087125b806109445750851580159061094457507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd8f086138015610944575061271086125b1561097f576040517f60121cca00000000000000000000000000000000000000000000000000000000815261791a6004820152602401610272565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee1480156109d85750600087135b15610a1f57348714610a1a576040517f60121cca00000000000000000000000000000000000000000000000000000000815261791b6004820152602401610272565b610ab8565b3415610ab8577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee148015610a7e5750600086125b610ab8576040517f60121cca00000000000000000000000000000000000000000000000000000000815261791b6004820152602401610272565b610b38604051806102000160405280600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b600154610100820152600282901c620fffff166000808215610b805782600116600114610b71576207ffff600184901c16600003610ba2565b6207ffff600184901c16610ba2565b7f80000000000000000000000000000000000000000000000000000000000000005b61014085015260008c9003610cd4577f800000000000000000000000000000000000000000000000000000000000000060c08501526040517f94bf804d0000000000000000000000000000000000000000000000000000000081527f000000000000000000000000000000000000000000000000000000000000000060048201523360248201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906394bf804d906044016020604051808303816000875af1158015610c89573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cad9190615983565b9b50847a040000000000000000000000000000000000000000000000000000019450610ef3565b60008b1280610ce3575060008a135b8015610db457506040517f6352211e000000000000000000000000000000000000000000000000000000008152600481018d905233907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690636352211e90602401602060405180830381865afa158015610d77573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d9b919061599c565b73ffffffffffffffffffffffffffffffffffffffff1614155b15610def576040517f60121cca00000000000000000000000000000000000000000000000000000000815261791c6004820152602401610272565b60008c8152600360205260408120549350839003610e3d576040517f60121cca0000000000000000000000000000000000000000000000000000000081526179236004820152602401610272565b66ffffffffffffff603584901c811660ff602d86901c81169190911b6060870152607585901c909116606d85901c9182161b60a086015267ffffffffffffffff16915060018084169003610eb6577f800000000000000000000000000000000000000000000000000000000000000060c0850152610ef3565b82600216600214610ed3576207ffff600284901c16600003610ede565b6207ffff600284901c165b60c0850152601583901c62ffffff1660e08501525b7f80000000000000000000000000000000000000000000000000000000000000008460c0015113156111e157602d9290921c60ff16918215610f3e5760608401516001841b01610f47565b83606001516001015b9250606083610f5c8660c0015160020b61432b565b610f6691906159e8565b610f72911c60016159ff565b608085015260c0840151600090815260056020526040902054925060018084161480610faa57508360e0015162ffffff600185901c16115b156110d257610fc78460c001518560e00151866080015186612668565b6101c089015260608801919091526080870182905260c087019290925260a0860151919350111561109b5767ffffffffffffffff6034856101c00151901c16925060ff8316600884901c901b92508360800151836110259190615a12565b9250606483101561103557606492505b60346110468460386008600161458d565b6101c086015160008581526007602052604090207ffffffffffffffffffffffffffffffffffff0000000000000000fffffffffffff9091169190921b17905560a08401516080850180519190910390526111d9565b83608001518460a00151600a546110b291906159ff565b6110bc9190615a12565b600a5560006080850181905260608501526111d9565b67ffffffffffffffff601984901c16915081600003611121576040517f60121cca00000000000000000000000000000000000000000000000000000000815261791d6004820152602401610272565b60ff8216600883901c901b915081846080015110611140576000611148565b836080015182035b915061271082101561118f57600091508361014001518460c001510361118057611177846101400151866146b6565b61014086015294505b61118f8460c001516000614898565b60196111a08360386008600061458d565b60c08601516000908152600560205260409020911b6301ffffff851617905560a08401516080850180516111d5908390615a12565b9052505b600060a08501525b60c08401516040850152606084015184526080840151602085015261010084015161120b906123d0565b6101a08801526101808701525061016085015260008b13156112b15761018084015161123c64e8d4a510008d6159e8565b6112469190615a54565b8460600181815161125791906159ff565b90525060608401516fffffffffffffffffffffffffffffffff10156112ac576040517f60121cca00000000000000000000000000000000000000000000000000000000815261792f6004820152602401610272565b611408565b60008b1215611408577fffffffffffffffffffffffffffffffff800000000000000000000000000000008b1315611364576101808401516001906112fa64e8d4a510008e615a68565b6113049190615ab4565b61130e9190615b1c565b90508360600151816000031115611355576040517f60121cca0000000000000000000000000000000000000000000000000000000081526179266004820152602401610272565b60608401805182019052611408565b7f80000000000000000000000000000000000000000000000000000000000000008b036113d25764e8d4a5100084610180015185606001516113a691906159e8565b6113b09190615a54565b6113b990615b43565b6113c4906001615b7b565b600060608601529a50611408565b6040517f60121cca00000000000000000000000000000000000000000000000000000000815261792f6004820152602401610272565b60008a13156114d8576101a084015161142664e8d4a510008c6159e8565b6114309190615a54565b61143b9060016159ff565b92506127106103ff6052866101000151901c168461145991906159e8565b6114639190615a54565b61146d90846159ff565b8460800181815161147e91906159ff565b90525060808401516fffffffffffffffffffffffffffffffff10156114d3576040517f60121cca00000000000000000000000000000000000000000000000000000000815261792f6004820152602401610272565b6115f8565b60008a12156115f8577fffffffffffffffffffffffffffffffff800000000000000000000000000000008a131561158d576101a084015161151e64e8d4a510008c615a68565b6115289190615ab4565b611533906001615b7b565b9050806000039050836080015181111561157d576040517f60121cca0000000000000000000000000000000000000000000000000000000081526179276004820152602401610272565b60808401805182900390526115f8565b7f80000000000000000000000000000000000000000000000000000000000000008a036113d257600164e8d4a51000856101a0015186608001516115d191906159e8565b6115db9190615a54565b6115e490615b43565b6115ee9190615b1c565b6000608086015299505b8a158015611604575089155b1561163f576040517f60121cca00000000000000000000000000000000000000000000000000000000815261791a6004820152602401610272565b6080840151156118b4576116778460600151633b9aca008660800151633b9aca01028161166e5761166e615a25565b0460010161490b565b60a0880152608087015260e086015260c085015260008a12156116e95783602001518460a0015185608001516116ad9190615a12565b11156116e9576040517f60121cca0000000000000000000000000000000000000000000000000000000081526179346004820152602401610272565b60008b1380156116f7575089155b1561179c578351602085015161171b906c01000000000000000000000000906159e8565b6117259190615a54565b84606001516c010000000000000000000000008660a00151876080015161174c9190615a12565b61175691906159e8565b6117609190615a54565b111561179c576040517f60121cca0000000000000000000000000000000000000000000000000000000081526179346004820152602401610272565b8361014001518460c00151126118af5760008460c00151126117c95760018460c00151901b6001176117d5565b60c084015160000360011b5b92508460021660000361181257600283901b857fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc00000161794506118db565b6001603486811c633fffffff16919091016000818152600760205260409020780fffffffc00000000000000000000000000000000000000000609089901b167afffff000000000000000000000000000000000000000000000000060c28a901b161790557ffffffffffffffffffffffffffffffffffffffffffffc00000000000000000000909616600285901b17601687901b179086901b179491505b6118db565b7f800000000000000000000000000000000000000000000000000000000000000060c08501525b60008b12806118ea575060008a135b15611b155773ffffffffffffffffffffffffffffffffffffffff891661190e573398505b6000846080015111801561195d57508360c00151846040015113158061195d5750633b9aca008460200151633b9aca01028161194c5761194c615a25565b046001018460a00151856080015103115b15611b15576060846101000151901c73ffffffffffffffffffffffffffffffffffffffff16638e7bfbc06040518163ffffffff1660e01b8152600401602060405180830381865afa1580156119b6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119da9190615983565b9250760a70c3c40a64e6c51999090b65f67d9240000000000000831180611a045750633b9aca0083105b15611a3f576040517f60121cca0000000000000000000000000000000000000000000000000000000081526179396004820152602401610272565b836101a00151846101800151840281611a5a57611a5a615a25565b049250722cd76fe086b93ce2f768a00b22a00000000000831115611a8f57722cd76fe086b93ce2f768a00b22a0000000000092505b6101008401516103e89060201c6103ff1684020491506b033b2e3c9fd0803ce80000006c010000000000000000000000008302049150611ace82614ae8565b5080915050808460c001511315611b15576040517f60121cca00000000000000000000000000000000000000000000000000000000815261791e6004820152602401610272565b7f80000000000000000000000000000000000000000000000000000000000000008460c001511315611b715760008460c0015112611b5e5760018460c00151901b600117611b6a565b60c084015160000360011b5b9250611b76565b600092505b60a0840151606d90611b8d9060386008600061458d565b6060860151911b90602d90611ba79060386008600061458d565b60e0870151911b9060151b600186901b8615611bc4576000611bc7565b60015b60ff1617171717600360008e81526020019081526020016000208190555060008b1215611d7057610100840151603e1c6103ff1692508215611d70576040517fb5c736e40000000000000000000000000000000000000000000000000000000081527f000000000000000000000000000000000000000000000000000000000000000060048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063b5c736e490602401602060405180830381865afa158015611cad573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611cd19190615983565b6101e0850181905266ffffffffffffff600982901c1660ff600183901c161b9250611cfc9083614efd565b9050600081138015611d35575083610160015164e8d4a510008c6000030281611d2757611d27615a25565b05816103e885810385020503125b15611d70576040517f60121cca0000000000000000000000000000000000000000000000000000000081526179286004820152602401610272565b60008b1315611eee577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663ad967e1573eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff167f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1614611e23576000611e25565b345b7f00000000000000000000000000000000000000000000000000000000000000008e600080600033604051602001611e79919073ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b6040516020818303038152906040526040518863ffffffff1660e01b8152600401611ea996959493929190615bff565b604080518083038185885af1158015611ec6573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190611eeb9190615c58565b50505b60008a12156120bc577fffffffffffffffffffffffff11111111111111111111111111111111111111127f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1601611fb15789600003925082341115611f7357611f6e33843403614f8f565b611fb6565b82341015611f6e576040517f60121cca00000000000000000000000000000000000000000000000000000000815261791b6004820152602401610272565b600092505b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663ad967e15847f000000000000000000000000000000000000000000000000000000000000000060008e60008033604051602001612047919073ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b6040516020818303038152906040526040518863ffffffff1660e01b815260040161207796959493929190615bff565b604080518083038185885af1158015612094573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906120b99190615c58565b50505b60008b12156121a157604080516000808252602082019092527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169163ad967e15917f0000000000000000000000000000000000000000000000000000000000000000918f918e9082906040518763ffffffff1660e01b815260040161215c96959493929190615bff565b60408051808303816000875af115801561217a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061219e9190615c58565b50505b60008a131561228757604080516000808252602082019092527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169163ad967e15917f000000000000000000000000000000000000000000000000000000000000000091908e9082908f906040518763ffffffff1660e01b815260040161224296959493929190615bff565b60408051808303816000875af1158015612260573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122849190615c58565b50505b67ffffffffffffffff605286901c1692508360000151846060015160ff8516600886901c901b6122b791906159ff565b6122c19190615a12565b925067ffffffffffffffff609286901c16915083602001518460a0015185608001516122ed9190615a12565b61230090600885901c60ff86161b6159ff565b61230a9190615a12565b9150609261231d8360386008600161458d565b901b60526123308560386008600061458d565b901b7ffffffffffffc00000000000000000000000000000003ffffffffffffffffffff8716171760005560408051338152602081018e90529081018c9052606081018b905273ffffffffffffffffffffffffffffffffffffffff8a1660808201527ffef64760e30a41b9d5ba7dd65ff7236a61d89ed8b44c67a29e84db1a67513a1c9060a00160405180910390a150999a98995096979650505050505050565b6008546040517fb5c736e40000000000000000000000000000000000000000000000000000000081527f000000000000000000000000000000000000000000000000000000000000000060048201526000918291829182916124b49073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169063b5c736e4906024015b602060405180830381865afa15801561248b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124af9190615983565b614fde565b506040517fb5c736e40000000000000000000000000000000000000000000000000000000081527f0000000000000000000000000000000000000000000000000000000000000000600482015290955061254e907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063b5c736e49060240161246e565b94505067ffffffffffffffff81811690604083901c168187108061257157508086105b156125ac576040517f60121cca0000000000000000000000000000000000000000000000000000000081526179326004820152602401610272565b61271061ffff8916670de0b6b3a7640000848a670de0b6b3a764000002816125d6576125d6615a25565b040302816125e6576125e6615a25565b04945061271061ffff60108a901c16670de0b6b3a76400008389670de0b6b3a7640000028161261757612617615a25565b0403028161262757612627615a25565b049350670de0b6b3a7640000608084901c67ffffffffffffffff1686820102049450670de0b6b3a764000060c084901c858201020493505050509193509193565b600080808080868180600189901c62ffffff168b90036126ae575050601a87901c633fffffff169250603887901c6603ffffffffffff166001601989901c811614612705565b60008c8152600660205260408120600360028e0181810660550292918491048152602081019190915260400160002054901c600181811c633fffffff169750601f82901c6603ffffffffffff169450908116149150505b60008581526007602052604090205493508015612748577f80000000000000000000000000000000000000000000000000000000000000009b5060009950612914565b836003166002036127b25761276a82607486901c6603ffffffffffff166151ec565b9150600161277a600f60236159ff565b6001901b6127889190615a12565b82146127b25760a69390931c633fffffff1660008181526007602052604090205490945092612748565b83600316600314806127de575060016127cd600f60236159ff565b6001901b6127db9190615a12565b82145b1561280f577f80000000000000000000000000000000000000000000000000000000000000009b5060009950612914565b6128278a607486901c6603ffffffffffff1684615284565b9950606483048a11156128445761271061270f8b02049950612849565b600099505b89156128f0578360041660041461286c576207ffff600385901c16600003612877565b6207ffff600385901c165b9b5060006128878d60020b61432b565b905061271f612710820204633fffffff601687901c81166128a88385615a12565b6128b291906159e8565b6128bc9190615a54565b6128c690826159ff565b6128dd6c010000000000000000000000008e6159e8565b6128e79190615a54565b97505050612914565b7f80000000000000000000000000000000000000000000000000000000000000009b505b8b8a97509750505050945094509450945094565b60008061298c7f00000000000000000000000000000000000000000000000000000000000000006000368080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061072492505050565b80602001905181019061299f9190615c58565b90939092509050565b6000806129dd6040518060a0016040528060008152602001600081526020016000815260200160008152602001600081525090565b600080549060018216900361088257600181176000557fffffffffffffffffffffffff11111111111111111111111111111111111111127f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1601612ab857873414158015612a78575061dead73ffffffffffffffffffffffffffffffffffffffff871614155b15612ab3576040517f60121cca0000000000000000000000000000000000000000000000000000000081526179206004820152602401610272565b612af4565b3415612af4576040517f60121cca0000000000000000000000000000000000000000000000000000000081526179206004820152602401610272565b6001548252600281901c620fffff16600003612b40576040517f60121cca00000000000000000000000000000000000000000000000000000000815261791f6004820152602401610272565b8151612b4b906123d0565b90919250909150836060018460800182815250828152505050612bc86040518061018001604052806000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b612c016040518060c001604052806000815260200160008152602001600081526020016000815260200160008152602001600081525090565b60008060608660000151901c73ffffffffffffffffffffffffffffffffffffffff1663f3190c896040518163ffffffff1660e01b8152600401602060405180830381865afa158015612c57573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c7b9190615983565b9150760a70c3c40a64e6c51999090b65f67d9240000000000000821180612ca0575081155b15612cdb576040517f60121cca0000000000000000000000000000000000000000000000000000000081526179396004820152602401610272565b85608001518660600151830281612cf457612cf4615a25565b049150722cd76fe086b93ce2f768a00b22a00000000000821115612d2957722cd76fe086b93ce2f768a00b22a0000000000091505b81760a70c3c40a64e6c51999090b65f67d924000000000000081612d4f57612d4f615a25565b875191900491506127109060481c6103ff16810182020460608501526b033b2e3c9fd0803ce80000006c010000000000000000000000008302875191900492506103e890602a1c6103ff168302049050612da881614ae8565b50602087015285516103e89060341c6103ff168302049050612dc981614ae8565b506040870152600480861614612deb576207ffff600386901c16600003612df6565b6207ffff600386901c165b60c0850181905260408701511215612f2757612ec77f0000000000000000000000000000000000000000000000000000000000000000868860400151604051602401612e4c929190918252602082015260400190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f9e3e482100000000000000000000000000000000000000000000000000000000179052610724565b806020019051810190612eda9190615983565b945084600416600414612ef9576207ffff600386901c16600003612f04565b6207ffff600386901c165b60c085015260008c9003612f2757505050600091825550925082915061422f9050565b6127108c1080612f4657506fffffffffffffffffffffffffffffffff8c115b15612f81576040517f60121cca00000000000000000000000000000000000000000000000000000000815261792e6004820152602401610272565b6002851615612f91576002612f94565b60015b60ff1684610100018181525050612fe16040518060e00160405280600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b60c08501518152601686901c633fffffff16808552600090815260076020908152604082205490860181905260741c6603ffffffffffff16606086018190529003613034576603ffffffffc00060608501525b602084015160c41c620fffff169250821561307b5782600116600114613066576207ffff600184901c16600003613071565b6207ffff600184901c165b60808501526130a2565b7f800000000000000000000000000000000000000000000000000000000000000060808501525b866080015164e8d4a510008e02816130bc576130bc615a25565b0480865266ffffffffffffff609a88901c1660ff609289901c161b92506130e7633b9aca0084615a54565b1115613123576040517f60121cca00000000000000000000000000000000000000000000000000000000815261792e6004820152602401610272565b89156131b65760025485516fffffffffffffffffffffffffffffffff8216945060809190911c925083111561319b578451839061316090846159e8565b61316a9190615a54565b60a0860181905261317b9083615a12565b855160808088018290526000885282901b940393841760025591506131b6565b6000600255845183900385526080850183905260a085018290525b86602001518560c001511315613d4557845115613d45576040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a081018290528190680100000000000000009060008960c0015112613232576101008960c001518161322c5761322c615a25565b0561324f565b60016101008a60c001516001018161324c5761324c615a25565b05035b6040820152845161325f9061432b565b604086015261010089015160010361328a57604085015160e08a015260c08901516020820152613391565b61271f856040015161271002816132a3576132a3615a25565b046060860181905260408601510360808601819052602089015160161c633fffffff90811660c0880181905290910260608701519190040160e08a0152845160208c01516001011480156132fb57508460c001516001145b156133915773ffffffffffffffffffffffffffffffffffffffff8f1661dead0361335b576040517fcc36aa440000000000000000000000000000000000000000000000000000000081526000600482018190526024820152604401610272565b6040517f60121cca0000000000000000000000000000000000000000000000000000000081526179356004820152602401610272565b8861010001516001036134015760c0890180516000908152600560205260408082205460608c01518c5194518452919092206301fffffe8316601a9490941b9390931760389190911b1760011790915566ffffffffffffff602182901c1660ff601983901c161b97509550613424565b67ffffffffffffffff60348960200151901c16965060ff8716600888901c901b96505b868960200181815161343691906159ff565b90525060e08901516134556c01000000000000000000000000896159e8565b61345f9190615a54565b8960400181815161347091906159ff565b90525060c0890151602082015114801561348f57508861010001516001145b8061349c57506080810151155b156135cc5780608001516000036134c55760408082015160009081526004602052205460808201525b88610100015160010361351c57604081015160c08a015160009081036101009283020190910160608301819052608083018051821b90911c90819052900361351c5760408082015160009081526004602052908120555b60808101511561354a57600161353582608001516152c9565b604083015161010002010360208201526135cc565b8a602001518160400151610100021215613589577f800000000000000000000000000000000000000000000000000000000000000060208201526135cc565b604080820180517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190819052600090815260046020522054608082015261351c565b806020015188608001511380156135ea57508a602001518860800151135b156136075760808801516101208a015260026101608a0152613643565b8a602001518160200151131561362f5760208101516101208a015260016101608a0152613643565b60208b01516101208a015260036101608a01525b61365489610120015160020b61432b565b60408601526101608901516002036136e85761271f8560400151612710028161367f5761367f615a25565b046060860181905260408087015191909103608087019081526020808b015160a61c633fffffff908116600090815260079092529290205460a08b0181905260161c821660c0880181905290510260608701519190040160a086018190526101408a0152613705565b604085015160a086018190526101408a0152633fffffff60c08601525b6c010000000000000000000000008961014001518a6060015161372891906159e8565b6137329190615a54565b613748906b033b2e3c9fd0803ce8000000615a12565b8960e001518a602001518b610140015161376291906159e8565b61376c9190615a54565b8a6020015161377b9190615a12565b613791906b033b2e3c9fd0803ce80000006159e8565b61379b9190615a54565b93506b033b2e3c9fd0803ce80000008960600151856137ba91906159e8565b6137c49190615a54565b9250838960200151036137df576137dc600185615a12565b93505b8851841015806137f457508861016001516003145b15613b5f576080810151604080830151600090815260046020522055885184106139d457885160608a01519094506b033b2e3c9fd0803ce80000009061383a90866159e8565b6138449190615a54565b92508289604001516138569190615a12565b6c01000000000000000000000000858b602001516138749190615a12565b61387e91906159e8565b6138889190615a54565b965061389387614ae8565b60608701528086526101208a01511380156138b55750633fffffff8560c00151145b156138cd5784516002018552600160c08601526139e7565b8451600101855261016089015160021480156138ee57506101208901518551145b6138f95760006138ff565b8460c001515b9550612710856060015161271f028161391a5761391a615a25565b046040860181905260608601519081900360808701819052908803633fffffff028161394857613948615a25565b0460c086018190521561397957633fffffff8560c00151101561396f578460c0015161397c565b633ffffffe61397c565b60015b60c0860152851580159061399457508460c001518610155b156139cf576040517f60121cca0000000000000000000000000000000000000000000000000000000081526179386004820152602401610272565b6139e7565b6101208901516001908101865260c08601525b60208901516139f68582615a12565b613a0090846159e8565b613a0a9190615a54565b91508389608001818151613a1e91906159ff565b905250602089018051859190613a35908390615a12565b90525060a089018051849190613a4c9083906159ff565b905250604089018051849190613a63908390615a12565b9052506060880151613a75908361537f565b6060890152602089015160641115613abd576040517f60121cca0000000000000000000000000000000000000000000000000000000081526179306004820152602401610272565b8451600013613ad3578451600190811b17613adc565b845160000360011b5b606089015160208b015191975060741b90603490613aff9060386008600161458d565b901b60168760c00151901b600289901b60a6808d60200151901c901b60011717171717600760008a6000015181526020019081526020016000208190555060168860000151901b600287901b6034808d901c901b60021717179950613d40565b885184900389526020890151613b758582615a12565b613b7f90846159e8565b613b899190615a54565b91508389608001818151613b9d91906159ff565b905250602089018051859190613bb4908390615a12565b90525060a089018051849190613bcb9083906159ff565b905250604089018051849190613be2908390615a12565b9052506060880151613bf4908361537f565b6060890152610160890151680100000000000000009250600203613d1957633fffffff60a68960200151901c1696508760a00151955060006603ffffffffffff607488901c1690506000613c558a606001518361542390919063ffffffff16565b6020808c0180518d516000908152600790935260409092207fffffffffffffffffffffffc00000000000000000000000000000000000000000909216607484901b17600217909155998b5298889052506060890181905260c487901c620fffff16978815613cef5788600116600114613cda576207ffff60018a901c16600003613ce5565b6207ffff60018a901c165b60808b0152613d16565b7f800000000000000000000000000000000000000000000000000000000000000060808b01525b50505b61012089015160c08a01526101608901516101008a015261014089015160e08a0152613391565b505050505b64e8d4a5100087608001518660800151613d5f91906159e8565b613d699190615a54565b985064e8d4a5100087606001518660a00151613d8591906159e8565b613d8f9190615a54565b97508c891115613db357613da3898e615a54565b613dad90896159e8565b97508c98505b88600003613df1576040517f60121cca0000000000000000000000000000000000000000000000000000000081526179356004820152602401610272565b8b89613e058a670de0b6b3a76400006159e8565b613e0f9190615a54565b1015613e4b576040517f60121cca0000000000000000000000000000000000000000000000000000000081526179216004820152602401610272565b73ffffffffffffffffffffffffffffffffffffffff8b1661dead03613ea6576040517fcc36aa4400000000000000000000000000000000000000000000000000000000815260048101899052602481018a9052604401610272565b7fffffffffffffffffffffffff11111111111111111111111111111111111111127f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1601613f1f5788925034891015613f1a57613f1a338a3403614f8f565b613f24565b600092505b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663ad967e15847f000000000000000000000000000000000000000000000000000000000000000060008d60000360008033604051602001613fb8919073ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b6040516020818303038152906040526040518863ffffffff1660e01b8152600401613fe896959493929190615bff565b604080518083038185885af1158015614005573d6000803e3d6000fd5b50505050506040513d601f19601f8201168201806040525081019061402a9190615c58565b505073ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001663ad967e157f000000000000000000000000000000000000000000000000000000000000000060008b8103908f81806040519080825280601f01601f1916602001820160405280156140bc576020820181803683370190505b506040518763ffffffff1660e01b81526004016140de96959493929190615bff565b60408051808303816000875af11580156140fc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906141209190615c58565b505067ffffffffffffffff605287901c1692508460a0015160ff8416600885901c901b61414d9190615a12565b925067ffffffffffffffff609287901c169150846080015160ff8316600884901c901b61417a9190615a12565b9150609261418d8360386008600161458d565b901b60526141a08560386008600061458d565b7ffffffffffffc00000000000000000000000000000003ffffffffffffffffffff8916911b171760005560408051338152602081018a90529081018a905273ffffffffffffffffffffffffffffffffffffffff8c1660608201527f80fd9cc6b1821f4a510e45ffce6852ea3404807b5d3d833ffa85664408afcb669060800160405180910390a1505050505050505b94509492505050565b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016146142ab576040517f60121cca0000000000000000000000000000000000000000000000000000000081526179296004820152602401610272565b6000546001166000036142ee576040517f60121cca00000000000000000000000000000000000000000000000000000000815261792a6004820152602401610272565b614325846142fe83850185615c7c565b7f0000000000000000000000000000000000000000000000000000000000000000866154ce565b50505050565b600060ff82901d80831803617fff81111561434557600080fd5b700100000000000000000000000000000000600182161561437357506fff9dd7de423466c20352b1246ce4856f5b6002821615614392576fff3bd55f4488ad277531fa1c725a66d00260801c5b60048216156143b1576ffe78410fd6498b73cb96a6917f8532590260801c5b60088216156143d0576ffcf2d9987c9be178ad5bfeffaa1232730260801c5b60108216156143ef576ff9ef02c4529258b057769680fc6601b30260801c5b602082161561440e576ff402d288133a85a17784a411f7aba0820260801c5b604082161561442d576fe895615b5beb6386553757b0352bda900260801c5b608082161561444c576fd34f17a00ffa00a8309940a15930391a0260801c5b61010082161561446c576fae6b7961714e20548d88ea5123f9a0ff0260801c5b61020082161561448c576f76d6461f27082d74e0feed3b388c0ca10260801c5b6104008216156144ac576f372a3bfe0745d8b6b19d985d9a8b85bb0260801c5b6108008216156144cc576f0be32cbee48979763cf7247dd7bb539d0260801c5b6110008216156144eb576e8d4f70c9ff4924dac37612d1e2921e0260801c5b612000821615614509576d4e009ae5519380809a02ca7aec770260801c5b614000821615614525576b17c45e641b6e95dee056ff100260801c5b600091507f80000000000000000000000000000000000000000000000000000000000000008416614583577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0463ffffffff81161561458357600191505b60201c0192915050565b600080856fffffffffffffffffffffffffffffffff8111156145b05760809150811c5b67ffffffffffffffff8111156145c8576040918201911c5b63ffffffff8111156145dc576020918201911c5b61ffff8111156145ee576010918201911c5b60ff8111156145ff576008918201911c5b600f811115614610576004918201911c5b6003811115614621576002918201911c5b6001811115614631576001820191505b801561463e576001820191505b508481101561464a5750835b848103905085811c6000821184161561469957600181019050806001871b0361469957506001908101907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff86011b5b6001851b82106146a857600080fd5b90931b909201949350505050565b601681901c633fffffff166000818152600760205260408120549091829182600160c483901c811690036146f4575060c581901c6207ffff1661472c565b5060c581901c6207ffff1660008190039061472c57507f80000000000000000000000000000000000000000000000000000000000000005b600061473788615595565b90508082136147465780614748565b815b94507f8000000000000000000000000000000000000000000000000000000000000000850361479b57867fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0000116965061488a565b8085036148115760008512156147de57600385600003901b877fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc000011617965061488a565b600385901b877fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc000011660041717965061488a565b6000848152600760205260408120557ffffffffffffffffffffffffffffffffffffffffffffc00000000000000000001909616623ffffc60c284901c1617660fffffffc00000609084901c16177fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff840160341b17600217955b869550505050509250929050565b60008083126148ab5761010083056148b6565b600161010084820105035b905061010081028303826148de576000828152600460205260409020546001821b19166148f3565b6000828152600460205260409020546001821b175b60009283526004602052604090922091909155505050565b600080600080612710851015614951576040517f60121cca0000000000000000000000000000000000000000000000000000000081526179336004820152602401610272565b60008661496b6c01000000000000000000000000886159e8565b6149759190615a54565b905061498081614ae8565b60019091019550905061271061271f820204905060606149a088836159e8565b901c92506149ae8684615a12565b600086815260056020526040812054600181901c62ffffff16965091935085158015906149dc575060018216155b15614a1d5766ffffffffffffff602183901c1660ff601984901c161b614a0286826159ff565b915080600003614a1757614a17886001614898565b50614a71565b8515614a5d576000878152600660209081526040808320600360028b0181810486529190935292208054601986901c929093066055029190911b90911790555b856001019550849050614a71876001614898565b612710811015614ab1576040517f60121cca0000000000000000000000000000000000000000000000000000000081526179316004820152602401610272565b6019614ac28260386008600061458d565b6000898152600560205260409020911b600188901b179055509497939650919450925050565b600080630235b88083107473d85bca016a2338b31715f8e13054c005f8b995d384111715614b1557600080fd5b6c010000000000000000000000008310600081614b4b57506c010000000000000000000000006a52b7d2dcc80cd2e40000008502045b8115614b6e57507652b7d2dcc80cd2e40000000000000000000000000000008490045b6f037af932b2affa9738cc6c38ca5278318110614baf57614000841793506f037af932b2affa9738cc6c38ca5278316a52b7d2dcc80cd2e400000082020490505b6d010f7a088a76f267264caa114f0a8110614bec57612000841793506d010f7a088a76f267264caa114f0a6a52b7d2dcc80cd2e400000082020490505b6b95da74f87f839fc2e0dc5bd98110614c2557611000841793506b95da74f87f839fc2e0dc5bd96a52b7d2dcc80cd2e400000082020490505b6b06f55dedafd8491caed5a1b88110614c5e57610800841793506b06f55dedafd8491caed5a1b86a52b7d2dcc80cd2e400000082020490505b6b017fdd10ee11e624491b4cc18110614c9757610400841793506b017fdd10ee11e624491b4cc16a52b7d2dcc80cd2e400000082020490505b6ab23131bf0c30217b0a2c698110614cce57610200841793506ab23131bf0c30217b0a2c696a52b7d2dcc80cd2e400000082020490505b6a79683edcb9280d797aded78110614d0557610100841793506a79683edcb9280d797aded76a52b7d2dcc80cd2e400000082020490505b6a64366e2f9919f0d9b0dc908110614d3b576080841793506a64366e2f9919f0d9b0dc906a52b7d2dcc80cd2e400000082020490505b6a5b0bcda5a78850646b0a818110614d71576040841793506a5b0bcda5a78850646b0a816a52b7d2dcc80cd2e400000082020490505b6a56c840f992c70f959ae8108110614da7576020841793506a56c840f992c70f959ae8106a52b7d2dcc80cd2e400000082020490505b6a54b9cd178695194f9be0a08110614ddd576010841793506a54b9cd178695194f9be0a06a52b7d2dcc80cd2e400000082020490505b6a53b7458aff204b5e65d6818110614e13576008841793506a53b7458aff204b5e65d6816a52b7d2dcc80cd2e400000082020490505b6a53372a2f38c240d689e4008110614e49576004841793506a53372a2f38c240d689e4006a52b7d2dcc80cd2e400000082020490505b6a52f76617a04499e66400008110614e7f576002841793506a52f76617a04499e66400006a52b7d2dcc80cd2e400000082020490505b6a52d79660f3dec355c000008110614eb5576001841793506a52d79660f3dec355c000006a52b7d2dcc80cd2e400000082020490505b81614ecd57806a52b7d2dcc80cd2e400000086020492505b8115614ee9579219926a52d79660f3dec355c000008582020492505b505082811115614ef857600080fd5b915091565b600066ffffffffffffff604984901c1660ff604185901c161b808203614f27576000915050614f89565b612710613fff60a286901c168402046401ffffffff608186901c16420362ffffff60b087901c16614f5882846159e8565b614f629190615a54565b9050808311614f72576000614f76565b8083035b9350508084038381111561076757925050505b92915050565b600080600080600085875af1905080614fd9576040517fdee51a8a0000000000000000000000000000000000000000000000000000000081526201155a6004820152602401610272565b505050565b67ffffffffffffffff605b82901c811690609b83901c16811580615000575080155b1561503c576040517fd50d7512000000000000000000000000000000000000000000000000000000008152620111716004820152602401610272565b61ffff8316603a84901c6401ffffffff16428181039160ea87901c617fff16911480615066575082155b806150715750806001145b1561507e57505050915091565b64496cebb80084840283020484019350617fff60db87901c169250826001036150a957505050915091565b826001166001036150fe5760019290921c91826c7e37be2022c0914b2680000000816150d7576150d7615a25565b049250612710601e87901c613fff166b033b2e3c9fd0803ce800000085010204925061512b565b60019290921c916305f5e100601e87901c613fff166127108501026b033b2e3c9fd0803ce8000000020492505b806001166001036151625760011c61271081016b033b2e3c9fd0803ce800000082028161515a5761515a615a25565b049050615198565b60011c61271081016b033b2e3c9fd0803ce800000082028161518657615186615a25565b046b033b2e3c9fd0803ce80000000390505b760a70c3c40a64e6c51999090b65f67d92400000000000008382026127100261ffff881691900402601087901c613fff16612710030292506801b5a660ea44b8000085840283020485019450505050915091565b6000600f83811c9083901c0281681fffffffffffffffff8211615210576022615213565b60235b91821c919050617fff85811690851601810161400081101561523457600080fd5b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc00001617fff81111561527357506603ffffffffffff9250614f89915050565b600f9290921b909117949350505050565b6000617fff8381169083160360818110156152bc57600f83811c821b9085901c8602816152b3576152b3615a25565b049150506152c2565b60009150505b9392505050565b6000816fffffffffffffffffffffffffffffffff8311156152eb5760809150811c5b67ffffffffffffffff811115615303576040918201911c5b63ffffffff811115615317576020918201911c5b61ffff811115615329576010918201911c5b60ff81111561533a576008918201911c5b600f81111561534b576004918201911c5b600381111561535c576002918201911c5b600181111561536c576001820191505b8015615379576001820191505b50919050565b6000600f83901c8202816c03ffffffffffffffffffffffff82116153c6576c01ffffffffffffffffffffffff82116153bf576153ba826152c9565b6153c9565b60626153c9565b60635b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdd617fff87168201810194500191821c919050604083111561541657604083600f84901b0103925061541b565b600080fd5b505092915050565b600080600f83901c7fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000603186901b168161545f5761545f615a25565b0490506000604082901c60011461547757604061547a565b60415b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdd81019290921c91617fff8581166040019250613fdd90871690910101818111156154165703600f9190911b179050614f89565b60006040517f23b872dd00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8516600482015273ffffffffffffffffffffffffffffffffffffffff841660248201528260448201526020600060648360008a5af13d15601f3d116001600051141617169150508061558e576040517fdee51a8a000000000000000000000000000000000000000000000000000000008152620115596004820152602401610272565b5050505050565b60008060008084126155ab5761010084056155b6565b600161010085820105035b600081815260046020526040812054919350859003610100808502919091010190811b811c91505b81156155fd5760016155ef836152c9565b846101000201039350615688565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8301927fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f03600101615672577f80000000000000000000000000000000000000000000000000000000000000009350615688565b60008381526004602052604090205491506155de565b505050919050565b801515811461569e57600080fd5b50565b6000602082840312156156b357600080fd5b81516152c281615690565b73ffffffffffffffffffffffffffffffffffffffff8116811461569e57600080fd5b600080600080608085870312156156f657600080fd5b8435935060208501359250604085013591506060850135615716816156be565b939692955090935050565b60006020828403121561573357600080fd5b5035919050565b6000806000806080858703121561575057600080fd5b5050823594602084013594506040840135936060013592509050565b6000806000806080858703121561578257600080fd5b8435935060208501359250604085013561579b816156be565b9150606085013561571681615690565b600080600080606085870312156157c157600080fd5b84356157cc816156be565b935060208501359250604085013567ffffffffffffffff808211156157f057600080fd5b818701915087601f83011261580457600080fd5b81358181111561581357600080fd5b88602082850101111561582557600080fd5b95989497505060200194505050565b815173ffffffffffffffffffffffffffffffffffffffff1681526101a08101602083015161587a602084018273ffffffffffffffffffffffffffffffffffffffff169052565b5060408301516158a2604084018273ffffffffffffffffffffffffffffffffffffffff169052565b5060608301516158ca606084018273ffffffffffffffffffffffffffffffffffffffff169052565b5060808301516158f2608084018273ffffffffffffffffffffffffffffffffffffffff169052565b5060a083015161591a60a084018273ffffffffffffffffffffffffffffffffffffffff169052565b5060c083015161592f60c084018260ff169052565b5060e083015161594460e084018260ff169052565b50610100838101519083015261012080840151908301526101408084015190830152610160808401519083015261018092830151929091019190915290565b60006020828403121561599557600080fd5b5051919050565b6000602082840312156159ae57600080fd5b81516152c2816156be565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8082028115828204841417614f8957614f896159b9565b80820180821115614f8957614f896159b9565b81810381811115614f8957614f896159b9565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082615a6357615a63615a25565b500490565b808202600082127f800000000000000000000000000000000000000000000000000000000000000084141615615aa057615aa06159b9565b8181058314821517614f8957614f896159b9565b600082615ac357615ac3615a25565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83147f800000000000000000000000000000000000000000000000000000000000000083141615615b1757615b176159b9565b500590565b8181036000831280158383131683831282161715615b3c57615b3c6159b9565b5092915050565b60007f80000000000000000000000000000000000000000000000000000000000000008203615b7457615b746159b9565b5060000390565b808201828112600083128015821682158216171561541b5761541b6159b9565b6000815180845260005b81811015615bc157602081850181015186830182015201615ba5565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b600073ffffffffffffffffffffffffffffffffffffffff8089168352876020840152866040840152808616606084015280851660808401525060c060a0830152615c4c60c0830184615b9b565b98975050505050505050565b60008060408385031215615c6b57600080fd5b505080516020909101519092909150565b600060208284031215615c8e57600080fd5b81356152c2816156be56fea2646970667358221220bd1cedb4ef1e580fa4bec1e12a6abad1d1668013e0141254313f07a6b3f9696464736f6c63430008150033", "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100725760003560e01c8063cc025f7c11610050578063cc025f7c14610104578063cc2fe94b1461012b578063f9f872f51461015257600080fd5b80632861c7d11461007757806368f4787e146100c8578063a07ddc17146100dd575b600080fd5b61009e7f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b6100d0610165565b6040516100bf9190610a03565b61009e7f000000000000000000000000000000000000000000000000000000000000000081565b61009e7f000000000000000000000000000000000000000000000000000000000000000081565b61009e7f000000000000000000000000000000000000000000000000000000000000000081565b6100d0610160366004610a79565b6101c6565b60606101c16101937f00000000000000000000000000000000000000000000000000000000000000006108d5565b6101bc7f00000000000000000000000000000000000000000000000000000000000000006108d5565b610903565b905090565b606073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000163003610240576040517f60121cca00000000000000000000000000000000000000000000000000000000815261753760048201526024015b60405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036102a9576040517f60121cca0000000000000000000000000000000000000000000000000000000081526175336004820152602401610237565b604080516101a081018252600060a0820181905260c0820181905260e08201819052610100820181905261012082018190526101408201819052610160820181905261018082015273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000811682523060208301527f00000000000000000000000000000000000000000000000000000000000000008116928201929092527f000000000000000000000000000000000000000000000000000000000000000082166060820152908416608082018190527fffffffffffffffffffffffff1111111111111111111111111111111111111112016103ba576012610429565b8373ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015610405573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104299190610ab2565b60ff1660c082015273ffffffffffffffffffffffffffffffffffffffff831660a082018190527fffffffffffffffffffffffff11111111111111111111111111111111111111120161047c5760126104eb565b8273ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156104c7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104eb9190610ab2565b60ff1660e0820152604080517f8d65402300000000000000000000000000000000000000000000000000000000815290513091638d6540239160048083019260209291908290030181865afa158015610548573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061056c9190610adc565b61010082018190526040517fe6bd26a2000000000000000000000000000000000000000000000000000000008152600091309163e6bd26a2916105b59160040190815260200190565b602060405180830381865afa1580156105d2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105f69190610af5565b90506107e18282604080516101a081018252600080825260208083018290528284018290526060808401839052608080850184905260a0850184905260c0850184905260e08501849052610100850184905261012085018490526101408501849052610160850184905261018085019390935291860151845173ffffffffffffffffffffffffffffffffffffffff909116818301526005818601528451808203860181529201909352805192019190912061012084015260a08301516040805173ffffffffffffffffffffffffffffffffffffffff909216602080840191909152600583830152815180840383018152606090930190915281519101206101408401526080808401516040805173ffffffffffffffffffffffffffffffffffffffff808716602080840191909152600883850152835180840385018152606084018552805190820120919094169482019490945260a0808201949094528151808203909401845260c0019052815191012061016084015260a0808401516040805173ffffffffffffffffffffffffffffffffffffffff808716602080840191909152600983850152835180840385018152606084018552805190820120919094166080830152818501528151808203909401845260c001905281519101206101808401525090919050565b91506107eb610165565b826040516020016107fc9190610b12565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152908290526108389291602001610c61565b60405160208183030381529060405292508373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f4960ed60da9bf499a0841c5bb40e134da1b7a55ec0436c1ca8e19848e78031a38561010001516040516108c491815260200190565b60405180910390a450505b92915050565b60606108cf8260016108fe8173ffffffffffffffffffffffffffffffffffffffff84163b610c90565b61099e565b6060806040519050835180825260208201818101602087015b8183101561093457805183526020928301920161091c565b50855184518101855292509050808201602086015b81831015610961578051835260209283019201610949565b508651929092011591909101601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660405250905092915050565b60408051603f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168101909152818152818360208301863c9392505050565b60005b838110156109fa5781810151838201526020016109e2565b50506000910152565b6020815260008251806020840152610a228160408501602087016109df565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b73ffffffffffffffffffffffffffffffffffffffff81168114610a7657600080fd5b50565b60008060408385031215610a8c57600080fd5b8235610a9781610a54565b91506020830135610aa781610a54565b809150509250929050565b600060208284031215610ac457600080fd5b815160ff81168114610ad557600080fd5b9392505050565b600060208284031215610aee57600080fd5b5051919050565b600060208284031215610b0757600080fd5b8151610ad581610a54565b815173ffffffffffffffffffffffffffffffffffffffff1681526101a081016020830151610b58602084018273ffffffffffffffffffffffffffffffffffffffff169052565b506040830151610b80604084018273ffffffffffffffffffffffffffffffffffffffff169052565b506060830151610ba8606084018273ffffffffffffffffffffffffffffffffffffffff169052565b506080830151610bd0608084018273ffffffffffffffffffffffffffffffffffffffff169052565b5060a0830151610bf860a084018273ffffffffffffffffffffffffffffffffffffffff169052565b5060c0830151610c0d60c084018260ff169052565b5060e0830151610c2260e084018260ff169052565b50610100838101519083015261012080840151908301526101408084015190830152610160808401519083015261018092830151929091019190915290565b60008351610c738184602088016109df565b835190830190610c878183602088016109df565b01949350505050565b818103818111156108cf577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fdfea264697066735822122068f258e6cc2fc43fd52fb8d1eabc2215cbfc2cee76e1a0992458140cb0f37b9464736f6c63430008150033", "devdoc": { "events": { "VaultT1Deployed(address,uint256,address,address)": { "params": { "borrowToken": "The address of the borrow token.", "supplyToken": "The address of the supply token.", "vault": "The address of the newly deployed vault.", "vaultId": "The id of the newly deployed vault." } } }, "kind": "dev", "methods": { "vaultT1(address,address)": { "params": { "borrowToken_": "The address of the borrow token.", "supplyToken_": "The address of the supply token." }, "returns": { "vaultCreationBytecode_": " Returns the bytecode of the new vault to deploy." } } }, "stateVariables": { "VAULT_T1_CREATIONCODE_ADDRESS_1": { "details": "SSTORE2 pointer for the VaultT1 creation code. Stored externally to reduce factory bytecode (in 2 parts)" } }, "version": 1 }, "userdoc": { "errors": { "FluidLiquidateResult(uint256,uint256)": [ { "notice": "used to simulate liquidation to find the maximum liquidatable amounts" } ] }, "events": { "VaultT1Deployed(address,uint256,address,address)": { "notice": "Emitted when a new vaultT1 is deployed." } }, "kind": "user", "methods": { "ADDRESS_THIS()": { "notice": "address of this contract" }, "ADMIN_IMPLEMENTATION()": { "notice": "address of Admin implementation" }, "LIQUIDITY()": { "notice": "address of liquidity contract" }, "SECONDARY_IMPLEMENTATION()": { "notice": "address of Secondary implementation" }, "vaultT1(address,address)": { "notice": "Computes vaultT1 bytecode for the given supply token (`supplyToken_`) and borrow token (`borrowToken_`). This will be called by the VaultFactory via .delegateCall" }, "vaultT1CreationBytecode()": { "notice": "returns the stored VaultT1 creation bytecode" } }, "version": 1 }, "storageLayout": { "storage": [], "types": null } }