fluid-contracts-public/deployments/mainnet/Vault_weETH_wstETH_MaxBorrowHandler.json
2024-07-11 13:05:09 +00:00

349 lines
129 KiB
JSON

{
"address": "0x383683D4414Fc27CC9669b7Cc6c7067716814b6a",
"abi": [
{
"inputs": [
{
"internalType": "contract IFluidReserveContract",
"name": "reserveContract_",
"type": "address"
},
{
"internalType": "contract IFluidLiquidity",
"name": "liquidity_",
"type": "address"
},
{
"internalType": "contract IFluidLiquidityResolver",
"name": "liquidityResolver_",
"type": "address"
},
{
"internalType": "address",
"name": "protocol_",
"type": "address"
},
{
"internalType": "address",
"name": "borrowToken_",
"type": "address"
},
{
"internalType": "uint256",
"name": "maxUtilization_",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "minUpdateDiff_",
"type": "uint256"
}
],
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "errorId_",
"type": "uint256"
}
],
"name": "FluidConfigError",
"type": "error"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "errorId_",
"type": "uint256"
}
],
"name": "FluidLiquidityCalcsError",
"type": "error"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "uint256",
"name": "totalSupplyNormal",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "oldMaxDebtCeilingRaw",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "maxDebtCeilingRaw",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "borrowExchangePrice",
"type": "uint256"
}
],
"name": "LogUpdateBorrowMaxDebtCeiling",
"type": "event"
},
{
"inputs": [],
"name": "BORROW_TOKEN",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "LIQUIDITY",
"outputs": [
{
"internalType": "contract IFluidLiquidity",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "LIQUIDITY_RESOLVER",
"outputs": [
{
"internalType": "contract IFluidLiquidityResolver",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "MAX_UTILIZATION",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "MIN_UPDATE_DIFF",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "PROTOCOL",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "RESERVE_CONTRACT",
"outputs": [
{
"internalType": "contract IFluidReserveContract",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "_getTotalSupply",
"outputs": [
{
"internalType": "uint256",
"name": "totalSupplyNormal_",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "borrowExchangePrice_",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "calcMaxDebtCeiling",
"outputs": [
{
"internalType": "uint256",
"name": "maxDebtCeiling_",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "calcMaxDebtCeilingNormal",
"outputs": [
{
"internalType": "uint256",
"name": "maxDebtCeilingNormal_",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "configPercentDiff",
"outputs": [
{
"internalType": "uint256",
"name": "configPercentDiff_",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "currentMaxDebtCeiling",
"outputs": [
{
"internalType": "uint256",
"name": "maxDebtCeiling_",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "getTotalSupply",
"outputs": [
{
"internalType": "uint256",
"name": "totalSupplyNormal_",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "rebalance",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
}
],
"transactionHash": "0x98e0cba2294bfa468a51f1373b2826ae7c66a3c91603bbb27594bc18a1f01e1d",
"receipt": {
"to": "0x4e59b44847b379578588920cA78FbF26c0B4956C",
"from": "0x0Ed35B1609Ec45c7079E80d11149a52717e4859A",
"contractAddress": null,
"transactionIndex": 210,
"gasUsed": "945146",
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"blockHash": "0x2c36ff0013759ee158a4ea6681e3ab766186a72ccc2a99be75c71d31a43bba41",
"transactionHash": "0x98e0cba2294bfa468a51f1373b2826ae7c66a3c91603bbb27594bc18a1f01e1d",
"logs": [],
"blockNumber": 19631308,
"cumulativeGasUsed": "17178801",
"status": 1,
"byzantium": true
},
"args": [
"0x264786EF916af64a1DB19F513F24a3681734ce92",
"0x52Aa899454998Be5b000Ad077a46Bbe360F4e497",
"0x741c2Cd25f053a55fd94afF1afAEf146523E1249",
"0x40D9b8417E6E1DcD358f04E3328bCEd061018A82",
"0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0",
8500,
100
],
"numDeployments": 2,
"solcInputHash": "fff19fac118acb472b89fa10e41facd7",
"metadata": "{\"compiler\":{\"version\":\"0.8.21+commit.d9974bed\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"contract IFluidReserveContract\",\"name\":\"reserveContract_\",\"type\":\"address\"},{\"internalType\":\"contract IFluidLiquidity\",\"name\":\"liquidity_\",\"type\":\"address\"},{\"internalType\":\"contract IFluidLiquidityResolver\",\"name\":\"liquidityResolver_\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"protocol_\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"borrowToken_\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"maxUtilization_\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"minUpdateDiff_\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"errorId_\",\"type\":\"uint256\"}],\"name\":\"FluidConfigError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"errorId_\",\"type\":\"uint256\"}],\"name\":\"FluidLiquidityCalcsError\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"totalSupplyNormal\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"oldMaxDebtCeilingRaw\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"maxDebtCeilingRaw\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"borrowExchangePrice\",\"type\":\"uint256\"}],\"name\":\"LogUpdateBorrowMaxDebtCeiling\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"BORROW_TOKEN\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"LIQUIDITY\",\"outputs\":[{\"internalType\":\"contract IFluidLiquidity\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"LIQUIDITY_RESOLVER\",\"outputs\":[{\"internalType\":\"contract IFluidLiquidityResolver\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MAX_UTILIZATION\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MIN_UPDATE_DIFF\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"PROTOCOL\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"RESERVE_CONTRACT\",\"outputs\":[{\"internalType\":\"contract IFluidReserveContract\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"_getTotalSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"totalSupplyNormal_\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"borrowExchangePrice_\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"calcMaxDebtCeiling\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"maxDebtCeiling_\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"calcMaxDebtCeilingNormal\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"maxDebtCeilingNormal_\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"configPercentDiff\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"configPercentDiff_\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"currentMaxDebtCeiling\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"maxDebtCeiling_\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTotalSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"totalSupplyNormal_\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"rebalance\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"events\":{\"LogUpdateBorrowMaxDebtCeiling(uint256,uint256,uint256,uint256)\":{\"notice\":\"emitted when borrow max limit is updated\"}},\"kind\":\"user\",\"methods\":{\"calcMaxDebtCeiling()\":{\"notice\":\"returns the max debt ceiling that should be set according to current state (in raw for mode with interest!).\"},\"calcMaxDebtCeilingNormal()\":{\"notice\":\"returns the max debt ceiling that should be set according to current state (in normal).\"},\"configPercentDiff()\":{\"notice\":\"returns how much new config would be different from current config in percent (100 = 1%, 1 = 0.01%).\"},\"currentMaxDebtCeiling()\":{\"notice\":\"returns the currently set max debt ceiling (in raw for mode with interest!).\"},\"getTotalSupply()\":{\"notice\":\"returns `BORROW_TOKEN` total supply at Liquidity (in normal).\"},\"rebalance()\":{\"notice\":\"Rebalances the configs for `PROTOCOL` at Fluid Liquidity based on protocol total supply & total borrow. Emits `LogUpdateBorrowMaxDebtCeiling` if update is executed. Reverts if no update is needed. Can only be called by an authorized rebalancer.\"}},\"notice\":\"Sets max borrow limit for a protocol on Liquidity based on utilization of total supply of the same borrow token\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/config/maxBorrowHandler/main.sol\":\"FluidMaxBorrowConfigHandler\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":10000000},\"remappings\":[]},\"sources\":{\"contracts/config/error.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\npragma solidity 0.8.21;\\n\\ncontract Error {\\n error FluidConfigError(uint256 errorId_);\\n}\\n\",\"keccak256\":\"0x7fac063d4cfeb626e3a2720595a2db1d7352353ed6c7df61e95a6c164450c9e6\",\"license\":\"BUSL-1.1\"},\"contracts/config/errorTypes.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\npragma solidity 0.8.21;\\n\\nlibrary ErrorTypes {\\n /***********************************|\\n | ExpandPercentConfigHandler | \\n |__________________________________*/\\n\\n /// @notice thrown when an input address is zero\\n uint256 internal constant ExpandPercentConfigHandler__AddressZero = 100001;\\n\\n /// @notice thrown when an unauthorized `msg.sender` calls a protected method\\n uint256 internal constant ExpandPercentConfigHandler__Unauthorized = 100002;\\n\\n /// @notice thrown when invalid params are passed into a method\\n uint256 internal constant ExpandPercentConfigHandler__InvalidParams = 100003;\\n\\n /// @notice thrown when no update is currently needed\\n uint256 internal constant ExpandPercentConfigHandler__NoUpdate = 100004;\\n\\n /// @notice thrown when slot is not used, e.g. when borrow token is 0 there is no borrow data\\n uint256 internal constant ExpandPercentConfigHandler__SlotDoesNotExist = 100005;\\n\\n /***********************************|\\n | EthenaRateConfigHandler | \\n |__________________________________*/\\n\\n /// @notice thrown when an input address is zero\\n uint256 internal constant EthenaRateConfigHandler__AddressZero = 100011;\\n\\n /// @notice thrown when an unauthorized `msg.sender` calls a protected method\\n uint256 internal constant EthenaRateConfigHandler__Unauthorized = 100012;\\n\\n /// @notice thrown when invalid params are passed into a method\\n uint256 internal constant EthenaRateConfigHandler__InvalidParams = 100013;\\n\\n /// @notice thrown when no update is currently needed\\n uint256 internal constant EthenaRateConfigHandler__NoUpdate = 100014;\\n\\n /***********************************|\\n | MaxBorrowConfigHandler | \\n |__________________________________*/\\n\\n /// @notice thrown when an input address is zero\\n uint256 internal constant MaxBorrowConfigHandler__AddressZero = 100021;\\n\\n /// @notice thrown when an unauthorized `msg.sender` calls a protected method\\n uint256 internal constant MaxBorrowConfigHandler__Unauthorized = 100022;\\n\\n /// @notice thrown when invalid params are passed into a method\\n uint256 internal constant MaxBorrowConfigHandler__InvalidParams = 100023;\\n\\n /// @notice thrown when no update is currently needed\\n uint256 internal constant MaxBorrowConfigHandler__NoUpdate = 100024;\\n}\\n\",\"keccak256\":\"0x4aea79efe1450f792bad6bd795b420a91e4e16da4860d3aa5322e30f5afce2f1\",\"license\":\"BUSL-1.1\"},\"contracts/config/maxBorrowHandler/main.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\npragma solidity 0.8.21;\\n\\nimport { IFluidLiquidity } from \\\"../../liquidity/interfaces/iLiquidity.sol\\\";\\nimport { IFluidLiquidityResolver } from \\\"../../periphery/resolvers/liquidity/iLiquidityResolver.sol\\\";\\nimport { LiquiditySlotsLink } from \\\"../../libraries/liquiditySlotsLink.sol\\\";\\nimport { BigMathMinified } from \\\"../../libraries/bigMathMinified.sol\\\";\\nimport { LiquidityCalcs } from \\\"../../libraries/liquidityCalcs.sol\\\";\\nimport { IFluidReserveContract } from \\\"../../reserve/interfaces/iReserveContract.sol\\\";\\nimport { Structs as AdminModuleStructs } from \\\"../../liquidity/adminModule/structs.sol\\\";\\nimport { Error } from \\\"../error.sol\\\";\\nimport { ErrorTypes } from \\\"../errorTypes.sol\\\";\\n\\nabstract contract Constants {\\n IFluidReserveContract public immutable RESERVE_CONTRACT;\\n IFluidLiquidity public immutable LIQUIDITY;\\n IFluidLiquidityResolver public immutable LIQUIDITY_RESOLVER;\\n address public immutable PROTOCOL;\\n address public immutable BORROW_TOKEN;\\n\\n /// @dev max utilization of total supply that will be set as max borrow limit. In percent (100 = 1%, 1 = 0.01%)\\n uint256 public immutable MAX_UTILIZATION;\\n\\n /// @dev minimum percent difference to trigger an update. In percent (100 = 1%, 1 = 0.01%)\\n uint256 public immutable MIN_UPDATE_DIFF;\\n\\n bytes32 internal immutable _LIQUDITY_PROTOCOL_BORROW_SLOT;\\n\\n uint256 internal constant MAX_UTILIZATION_PRECISION = 1e4;\\n uint256 internal constant DEFAULT_EXPONENT_SIZE = 8;\\n uint256 internal constant DEFAULT_EXPONENT_MASK = 0xff;\\n\\n uint256 internal constant EXCHANGE_PRICES_PRECISION = 1e12;\\n\\n uint256 internal constant X14 = 0x3fff;\\n uint256 internal constant X18 = 0x3ffff;\\n uint256 internal constant X24 = 0xffffff;\\n}\\n\\nabstract contract Events {\\n /// @notice emitted when borrow max limit is updated\\n event LogUpdateBorrowMaxDebtCeiling(\\n uint256 totalSupplyNormal,\\n uint256 oldMaxDebtCeilingRaw,\\n uint256 maxDebtCeilingRaw,\\n uint256 borrowExchangePrice\\n );\\n}\\n\\n/// @notice Sets max borrow limit for a protocol on Liquidity based on utilization of total supply of the same borrow token\\ncontract FluidMaxBorrowConfigHandler is Constants, Error, Events {\\n /// @dev Validates that an address is not the zero address\\n modifier validAddress(address value_) {\\n if (value_ == address(0)) {\\n revert FluidConfigError(ErrorTypes.MaxBorrowConfigHandler__AddressZero);\\n }\\n _;\\n }\\n\\n /// @dev Validates that an address is a rebalancer (taken from reserve contract)\\n modifier onlyRebalancer() {\\n if (!RESERVE_CONTRACT.isRebalancer(msg.sender)) {\\n revert FluidConfigError(ErrorTypes.MaxBorrowConfigHandler__Unauthorized);\\n }\\n _;\\n }\\n\\n constructor(\\n IFluidReserveContract reserveContract_,\\n IFluidLiquidity liquidity_,\\n IFluidLiquidityResolver liquidityResolver_,\\n address protocol_,\\n address borrowToken_,\\n uint256 maxUtilization_,\\n uint256 minUpdateDiff_\\n )\\n validAddress(address(reserveContract_))\\n validAddress(address(liquidity_))\\n validAddress(address(liquidityResolver_))\\n validAddress(protocol_)\\n validAddress(borrowToken_)\\n {\\n RESERVE_CONTRACT = reserveContract_;\\n LIQUIDITY = liquidity_;\\n LIQUIDITY_RESOLVER = liquidityResolver_;\\n PROTOCOL = protocol_;\\n BORROW_TOKEN = borrowToken_;\\n\\n if (maxUtilization_ > MAX_UTILIZATION_PRECISION || minUpdateDiff_ == 0) {\\n revert FluidConfigError(ErrorTypes.MaxBorrowConfigHandler__InvalidParams);\\n }\\n\\n _LIQUDITY_PROTOCOL_BORROW_SLOT = LiquiditySlotsLink.calculateDoubleMappingStorageSlot(\\n LiquiditySlotsLink.LIQUIDITY_USER_BORROW_DOUBLE_MAPPING_SLOT,\\n protocol_,\\n borrowToken_\\n );\\n\\n MAX_UTILIZATION = maxUtilization_;\\n MIN_UPDATE_DIFF = minUpdateDiff_;\\n }\\n\\n /// @notice returns `BORROW_TOKEN` total supply at Liquidity (in normal).\\n function getTotalSupply() public view returns (uint256 totalSupplyNormal_) {\\n (totalSupplyNormal_, ) = _getTotalSupply();\\n }\\n\\n /// @notice returns the currently set max debt ceiling (in raw for mode with interest!).\\n function currentMaxDebtCeiling() public view returns (uint256 maxDebtCeiling_) {\\n return\\n BigMathMinified.fromBigNumber(\\n (LIQUIDITY.readFromStorage(_LIQUDITY_PROTOCOL_BORROW_SLOT) >>\\n LiquiditySlotsLink.BITS_USER_BORROW_MAX_BORROW_LIMIT) & X18,\\n DEFAULT_EXPONENT_SIZE,\\n DEFAULT_EXPONENT_MASK\\n );\\n }\\n\\n /// @notice returns the max debt ceiling that should be set according to current state (in normal).\\n function calcMaxDebtCeilingNormal() public view returns (uint256 maxDebtCeilingNormal_) {\\n (uint256 maxDebtCeilingRaw_, , uint256 borrowExchangePrice_, , ) = _calcMaxDebtCeiling();\\n // convert to normal\\n maxDebtCeilingNormal_ = (maxDebtCeilingRaw_ * borrowExchangePrice_) / EXCHANGE_PRICES_PRECISION;\\n }\\n\\n /// @notice returns the max debt ceiling that should be set according to current state (in raw for mode with interest!).\\n function calcMaxDebtCeiling() public view returns (uint256 maxDebtCeiling_) {\\n (maxDebtCeiling_, , , , ) = _calcMaxDebtCeiling();\\n }\\n\\n /// @notice returns how much new config would be different from current config in percent (100 = 1%, 1 = 0.01%).\\n function configPercentDiff() public view returns (uint256 configPercentDiff_) {\\n (uint256 maxDebtCeilingRaw_, , , uint256 userBorrowData_, ) = _calcMaxDebtCeiling();\\n\\n (configPercentDiff_, ) = _configPercentDiff(userBorrowData_, maxDebtCeilingRaw_);\\n }\\n\\n /// @notice Rebalances the configs for `PROTOCOL` at Fluid Liquidity based on protocol total supply & total borrow.\\n /// Emits `LogUpdateBorrowMaxDebtCeiling` if update is executed.\\n /// Reverts if no update is needed.\\n /// Can only be called by an authorized rebalancer.\\n function rebalance() external onlyRebalancer {\\n if (!_updateBorrowLimits()) {\\n revert FluidConfigError(ErrorTypes.MaxBorrowConfigHandler__NoUpdate);\\n }\\n }\\n\\n /***********************************|\\n | INTERNALS | \\n |__________________________________*/\\n\\n function _getTotalSupply() public view returns (uint256 totalSupplyNormal_, uint256 borrowExchangePrice_) {\\n uint256 supplyExchangePrice_;\\n\\n (supplyExchangePrice_, borrowExchangePrice_) = LiquidityCalcs.calcExchangePrices(\\n LIQUIDITY_RESOLVER.getExchangePricesAndConfig(BORROW_TOKEN)\\n );\\n\\n totalSupplyNormal_ = LiquidityCalcs.getTotalSupply(\\n LIQUIDITY_RESOLVER.getTotalAmounts(BORROW_TOKEN),\\n supplyExchangePrice_\\n );\\n }\\n\\n function _calcMaxDebtCeiling()\\n internal\\n view\\n returns (\\n uint256 maxDebtCeilingRaw_,\\n uint256 totalSupplyNormal_,\\n uint256 borrowExchangePrice_,\\n uint256 userBorrowData_,\\n uint256 baseDebtCeilingRaw_\\n )\\n {\\n (totalSupplyNormal_, borrowExchangePrice_) = _getTotalSupply();\\n\\n uint256 maxDebtCeilingNormal_ = (MAX_UTILIZATION * totalSupplyNormal_) / MAX_UTILIZATION_PRECISION;\\n\\n // turn into maxDebtCeiling Raw\\n maxDebtCeilingRaw_ = (maxDebtCeilingNormal_ * EXCHANGE_PRICES_PRECISION) / borrowExchangePrice_;\\n\\n userBorrowData_ = LIQUIDITY.readFromStorage(_LIQUDITY_PROTOCOL_BORROW_SLOT); // total storage slot\\n\\n baseDebtCeilingRaw_ = BigMathMinified.fromBigNumber(\\n (userBorrowData_ >> LiquiditySlotsLink.BITS_USER_BORROW_BASE_BORROW_LIMIT) & X18,\\n DEFAULT_EXPONENT_SIZE,\\n DEFAULT_EXPONENT_MASK\\n );\\n\\n if (baseDebtCeilingRaw_ > maxDebtCeilingRaw_) {\\n // max debt ceiling can never be < base debt ceiling\\n maxDebtCeilingRaw_ = baseDebtCeilingRaw_;\\n }\\n }\\n\\n function _configPercentDiff(\\n uint256 userBorrowData_,\\n uint256 maxDebtCeilingRaw_\\n ) internal pure returns (uint256 configPercentDiff_, uint256 oldMaxDebtCeilingRaw_) {\\n oldMaxDebtCeilingRaw_ = BigMathMinified.fromBigNumber(\\n (userBorrowData_ >> LiquiditySlotsLink.BITS_USER_BORROW_MAX_BORROW_LIMIT) & X18,\\n DEFAULT_EXPONENT_SIZE,\\n DEFAULT_EXPONENT_MASK\\n );\\n\\n if (oldMaxDebtCeilingRaw_ == maxDebtCeilingRaw_) {\\n return (0, oldMaxDebtCeilingRaw_);\\n }\\n\\n if (oldMaxDebtCeilingRaw_ > maxDebtCeilingRaw_) {\\n // % of how much new max debt ceiling would be smaller\\n configPercentDiff_ = oldMaxDebtCeilingRaw_ - maxDebtCeilingRaw_;\\n // e.g. 10 - 8 = 2. 2 * 10000 / 10 -> 2000 (20%)\\n } else {\\n // % of how much new max debt ceiling would be bigger\\n configPercentDiff_ = maxDebtCeilingRaw_ - oldMaxDebtCeilingRaw_;\\n // e.g. 10 - 8 = 2. 2 * 10000 / 8 -> 2500 (25%)\\n }\\n\\n configPercentDiff_ = (configPercentDiff_ * 1e4) / oldMaxDebtCeilingRaw_;\\n }\\n\\n function _updateBorrowLimits() internal returns (bool updated_) {\\n (\\n uint256 maxDebtCeilingRaw_,\\n uint256 totalSupplyNormal_,\\n uint256 borrowExchangePrice_,\\n uint256 userBorrowData_,\\n uint256 baseDebtCeilingRaw_\\n ) = _calcMaxDebtCeiling();\\n\\n (uint256 configPercentDiff_, uint256 oldMaxDebtCeilingRaw_) = _configPercentDiff(\\n userBorrowData_,\\n maxDebtCeilingRaw_\\n );\\n\\n // check if min config deviation is reached\\n if (configPercentDiff_ < MIN_UPDATE_DIFF) {\\n return false;\\n }\\n\\n // execute update at Liquidity\\n AdminModuleStructs.UserBorrowConfig[] memory userBorrowConfigs_ = new AdminModuleStructs.UserBorrowConfig[](1);\\n userBorrowConfigs_[0] = AdminModuleStructs.UserBorrowConfig({\\n user: PROTOCOL,\\n token: BORROW_TOKEN,\\n mode: uint8(userBorrowData_ & 1), // first bit\\n expandPercent: (userBorrowData_ >> LiquiditySlotsLink.BITS_USER_BORROW_EXPAND_PERCENT) & X14, // set same as old\\n expandDuration: (userBorrowData_ >> LiquiditySlotsLink.BITS_USER_BORROW_EXPAND_DURATION) & X24, // set same as old\\n baseDebtCeiling: baseDebtCeilingRaw_, // set same as old\\n maxDebtCeiling: maxDebtCeilingRaw_\\n });\\n LIQUIDITY.updateUserBorrowConfigs(userBorrowConfigs_);\\n\\n emit LogUpdateBorrowMaxDebtCeiling(\\n totalSupplyNormal_,\\n oldMaxDebtCeilingRaw_,\\n maxDebtCeilingRaw_,\\n borrowExchangePrice_\\n );\\n\\n return true;\\n }\\n}\\n\",\"keccak256\":\"0x8192d05e2c03622ee3cd5f6d4de0cae3fb332f47b5cb702ce5e3f6122d14f742\",\"license\":\"BUSL-1.1\"},\"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/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 /***********************************|\\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\":\"0xfcd8d3b052c8e023b0db72cb9afe55c552d5a1ef4741dbcd1a494145f2d5ff62\",\"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 udpate 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 be 0 but never negative)\\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 uint256 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) and rate at y2 can not be < rate at y1\\n // y is in 1e2 so can not overflow when multiplied with TWELVE_DECIMALS\\n slope_ = ((y2_ - y1_) * TWELVE_DECIMALS) / (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) - int256(slope_ * 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 rate_ = (uint256(int256(slope_ * utilization_) + constant_)) / 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 be 0 but never negative)\\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 uint256 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) and rate at y2 can not be < rate at y1\\n // y is in 1e2 so can not overflow when multiplied with TWELVE_DECIMALS\\n slope_ = ((y2_ - y1_) * TWELVE_DECIMALS) / (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) - int256(slope_ * 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 rate_ = (uint256(int256(slope_ * utilization_) + constant_)) / 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\":\"0x1abba442b74ee50d039a5491aae9e7a156a62f783363ce545e44ee82cc699f27\",\"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\\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\\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 // --------------------------------\\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\":\"0x85725ce90bbeb00541715fe58fb213b96706515e9eafdae357657995e9ac147d\",\"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\\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\":\"0xcacc14afd7880d3179d0089d65dad6714c377df4801a9ad79a499d0d079124c0\",\"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/periphery/resolvers/liquidity/iLiquidityResolver.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\npragma solidity 0.8.21;\\n\\nimport { Structs as LiquidityStructs } from \\\"../../../periphery/resolvers/liquidity/structs.sol\\\";\\n\\ninterface IFluidLiquidityResolver {\\n /// @notice gets the `revenueAmount_` for a `token_`.\\n function getRevenue(address token_) external view returns (uint256 revenueAmount_);\\n\\n /// @notice address of contract that gets sent the revenue. Configurable by governance\\n function getRevenueCollector() external view returns (address);\\n\\n /// @notice Liquidity contract paused status: status = 1 -> normal. status = 2 -> paused.\\n function getStatus() external view returns (uint256);\\n\\n /// @notice checks if `auth_` is an allowed auth on Liquidity.\\n /// Auths can set most config values. E.g. contracts that automate certain flows like e.g. adding a new fToken.\\n /// Governance can add/remove auths. Governance is auth by default.\\n function isAuth(address auth_) external view returns (uint256);\\n\\n /// @notice checks if `guardian_` is an allowed Guardian on Liquidity.\\n /// Guardians can pause lower class users.\\n /// Governance can add/remove guardians. Governance is guardian by default.\\n function isGuardian(address guardian_) external view returns (uint256);\\n\\n /// @notice gets user class for `user_`. Class defines which protocols can be paused by guardians.\\n /// Currently there are 2 classes: 0 can be paused by guardians. 1 cannot be paused by guardians.\\n /// New protocols are added as class 0 and will be upgraded to 1 over time.\\n function getUserClass(address user_) external view returns (uint256);\\n\\n /// @notice gets exchangePricesAndConfig packed uint256 storage slot for `token_`.\\n function getExchangePricesAndConfig(address token_) external view returns (uint256);\\n\\n /// @notice gets rateConfig packed uint256 storage slot for `token_`.\\n function getRateConfig(address token_) external view returns (uint256);\\n\\n /// @notice gets totalAmounts packed uint256 storage slot for `token_`.\\n function getTotalAmounts(address token_) external view returns (uint256);\\n\\n /// @notice gets userSupply data packed uint256 storage slot for `user_` and `token_`.\\n function getUserSupply(address user_, address token_) external view returns (uint256);\\n\\n /// @notice gets userBorrow data packed uint256 storage slot for `user_` and `token_`.\\n function getUserBorrow(address user_, address token_) external view returns (uint256);\\n\\n /// @notice returns all `listedTokens_` at the Liquidity contract. Once configured, a token can never be removed.\\n function listedTokens() external view returns (address[] memory listedTokens_);\\n\\n /// @notice get the Rate config data `rateData_` for a `token_` compiled from the packed uint256 rateConfig storage slot\\n function getTokenRateData(address token_) external view returns (LiquidityStructs.RateData memory rateData_);\\n\\n /// @notice get the Rate config datas `rateDatas_` for multiple `tokens_` compiled from the packed uint256 rateConfig storage slot\\n function getTokensRateData(\\n address[] calldata tokens_\\n ) external view returns (LiquidityStructs.RateData[] memory rateDatas_);\\n\\n /// @notice returns general data for `token_` such as rates, exchange prices, utilization, fee, total amounts etc.\\n function getOverallTokenData(\\n address token_\\n ) external view returns (LiquidityStructs.OverallTokenData memory overallTokenData_);\\n\\n /// @notice returns general data for multiple `tokens_` such as rates, exchange prices, utilization, fee, total amounts etc.\\n function getOverallTokensData(\\n address[] calldata tokens_\\n ) external view returns (LiquidityStructs.OverallTokenData[] memory overallTokensData_);\\n\\n /// @notice returns `user_` supply data and general data (such as rates, exchange prices, utilization, fee, total amounts etc.) for `token_`\\n function getUserSupplyData(\\n address user_,\\n address token_\\n )\\n external\\n view\\n returns (\\n LiquidityStructs.UserSupplyData memory userSupplyData_,\\n LiquidityStructs.OverallTokenData memory overallTokenData_\\n );\\n\\n /// @notice returns `user_` supply data and general data (such as rates, exchange prices, utilization, fee, total amounts etc.) for multiple `tokens_`\\n function getUserMultipleSupplyData(\\n address user_,\\n address[] calldata tokens_\\n )\\n external\\n view\\n returns (\\n LiquidityStructs.UserSupplyData[] memory userSuppliesData_,\\n LiquidityStructs.OverallTokenData[] memory overallTokensData_\\n );\\n\\n /// @notice returns `user_` borrow data and general data (such as rates, exchange prices, utilization, fee, total amounts etc.) for `token_`\\n function getUserBorrowData(\\n address user_,\\n address token_\\n )\\n external\\n view\\n returns (\\n LiquidityStructs.UserBorrowData memory userBorrowData_,\\n LiquidityStructs.OverallTokenData memory overallTokenData_\\n );\\n\\n /// @notice returns `user_` borrow data and general data (such as rates, exchange prices, utilization, fee, total amounts etc.) for multiple `tokens_`\\n function getUserMultipleBorrowData(\\n address user_,\\n address[] calldata tokens_\\n )\\n external\\n view\\n returns (\\n LiquidityStructs.UserBorrowData[] memory userBorrowingsData_,\\n LiquidityStructs.OverallTokenData[] memory overallTokensData_\\n );\\n\\n /// @notice returns `user_` supply data and general data (such as rates, exchange prices, utilization, fee, total amounts etc.) for multiple `supplyTokens_`\\n /// and returns `user_` borrow data and general data (such as rates, exchange prices, utilization, fee, total amounts etc.) for multiple `borrowTokens_`\\n function getUserMultipleBorrowSupplyData(\\n address user_,\\n address[] calldata supplyTokens_,\\n address[] calldata borrowTokens_\\n )\\n external\\n view\\n returns (\\n LiquidityStructs.UserSupplyData[] memory userSuppliesData_,\\n LiquidityStructs.OverallTokenData[] memory overallSupplyTokensData_,\\n LiquidityStructs.UserBorrowData[] memory userBorrowingsData_,\\n LiquidityStructs.OverallTokenData[] memory overallBorrowTokensData_\\n );\\n}\\n\",\"keccak256\":\"0xb446bc409296f5e761f9d2038ce93511c13745683191caa1d9781d58e68ba3eb\",\"license\":\"MIT\"},\"contracts/periphery/resolvers/liquidity/structs.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\npragma solidity 0.8.21;\\n\\nimport { Structs as AdminModuleStructs } from \\\"../../../liquidity/adminModule/structs.sol\\\";\\n\\nabstract contract Structs {\\n struct RateData {\\n uint256 version;\\n AdminModuleStructs.RateDataV1Params rateDataV1;\\n AdminModuleStructs.RateDataV2Params rateDataV2;\\n }\\n\\n struct OverallTokenData {\\n uint256 borrowRate;\\n uint256 supplyRate;\\n uint256 fee; // revenue fee\\n uint256 lastStoredUtilization;\\n uint256 storageUpdateThreshold;\\n uint256 lastUpdateTimestamp;\\n uint256 supplyExchangePrice;\\n uint256 borrowExchangePrice;\\n uint256 supplyRawInterest;\\n uint256 supplyInterestFree;\\n uint256 borrowRawInterest;\\n uint256 borrowInterestFree;\\n uint256 totalSupply;\\n uint256 totalBorrow;\\n uint256 revenue;\\n RateData rateData;\\n }\\n\\n // amounts are always in normal (for withInterest already multiplied with exchange price)\\n struct UserSupplyData {\\n bool modeWithInterest; // true if mode = with interest, false = without interest\\n uint256 supply; // user supply amount\\n // the withdrawal limit (e.g. if 10% is the limit, and 100M is supplied, it would be 90M)\\n uint256 withdrawalLimit;\\n uint256 lastUpdateTimestamp;\\n uint256 expandPercent; // withdrawal limit expand percent in 1e2\\n uint256 expandDuration; // withdrawal limit expand duration in seconds\\n uint256 baseWithdrawalLimit;\\n // the current actual max withdrawable amount (e.g. if 10% is the limit, and 100M is supplied, it would be 10M)\\n uint256 withdrawableUntilLimit;\\n uint256 withdrawable; // actual currently withdrawable amount (supply - withdrawal Limit) & considering balance\\n }\\n\\n // amounts are always in normal (for withInterest already multiplied with exchange price)\\n struct UserBorrowData {\\n bool modeWithInterest; // true if mode = with interest, false = without interest\\n uint256 borrow; // user borrow amount\\n uint256 borrowLimit;\\n uint256 lastUpdateTimestamp;\\n uint256 expandPercent;\\n uint256 expandDuration;\\n uint256 baseBorrowLimit;\\n uint256 maxBorrowLimit;\\n uint256 borrowableUntilLimit;\\n uint256 borrowable; // actual currently borrowable amount (borrow limit - already borrowed) & considering balance\\n }\\n}\\n\",\"keccak256\":\"0x4a935db0fd6fee3a9a9456b0655953ee03158a975ef77faa5d390e4066f1ee89\",\"license\":\"BUSL-1.1\"},\"contracts/reserve/interfaces/iReserveContract.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\npragma solidity 0.8.21;\\n\\nimport { IFluidLiquidity } from \\\"../../liquidity/interfaces/iLiquidity.sol\\\";\\n\\ninterface IFluidReserveContract {\\n function isRebalancer(address user) external returns (bool);\\n\\n function initialize(\\n address[] memory _auths,\\n address[] memory _rebalancers,\\n IFluidLiquidity liquidity_,\\n address owner_\\n ) external;\\n\\n function rebalanceFToken(address protocol_) external;\\n\\n function rebalanceVault(address protocol_) external;\\n\\n function transferFunds(address token_) external;\\n\\n function getProtocolTokens(address protocol_) external;\\n\\n function updateAuth(address auth_, bool isAuth_) external;\\n\\n function updateRebalancer(address rebalancer_, bool isRebalancer_) external;\\n\\n function approve(address[] memory protocols_, address[] memory tokens_, uint256[] memory amounts_) external;\\n\\n function revoke(address[] memory protocols_, address[] memory tokens_) external;\\n}\\n\",\"keccak256\":\"0x36f69b8e3cf8479e5a2ab0390c6ac32e5ea4af5e7ecb91fc954c36503624eec8\",\"license\":\"BUSL-1.1\"}},\"version\":1}",
"bytecode": "0x6101806040523480156200001257600080fd5b506040516200136538038062001365833981016040819052620000359162000210565b866001600160a01b0381166200006857604051636801712d60e11b8152620186b560048201526024015b60405180910390fd5b866001600160a01b0381166200009757604051636801712d60e11b8152620186b560048201526024016200005f565b866001600160a01b038116620000c657604051636801712d60e11b8152620186b560048201526024016200005f565b866001600160a01b038116620000f557604051636801712d60e11b8152620186b560048201526024016200005f565b866001600160a01b0381166200012457604051636801712d60e11b8152620186b560048201526024016200005f565b6001600160a01b03808d166080528b811660a0528a811660c05289811660e05288166101005261271087118062000159575085155b156200017e57604051636801712d60e11b8152620186b760048201526024016200005f565b5050604080516001600160a01b0398891660208083019190915260098284015282518083038401815260608301845280519082012098909916608082015260a0808201989098528151808203909801885260c001905250508351939094019290922061016052610120526101405250620002a392505050565b6001600160a01b03811681146200020d57600080fd5b50565b600080600080600080600060e0888a0312156200022c57600080fd5b87516200023981620001f7565b60208901519097506200024c81620001f7565b60408901519096506200025f81620001f7565b60608901519095506200027281620001f7565b60808901519094506200028581620001f7565b8093505060a0880151915060c0880151905092959891949750929550565b60805160a05160c05160e0516101005161012051610140516101605161100262000363600039600081816102d001526107750152600081816101a9015261087601526000818160f401526107030152600081816101820152818161050d015281816105ed015261098e01526000818161024d01526109520152600081816101ff01528181610540015261061f01526000818161012e015281816102940152818161079e0152610a560152600081816101d801526103c901526110026000f3fe608060405234801561001057600080fd5b50600436106100ea5760003560e01c80636902f79f1161008c57806391b9b8271161006657806391b9b827146102485780639dc105661461026f578063abe3177914610277578063c4e41b221461027f57600080fd5b80636902f79f146101fa5780637d7c2a1c1461022157806382e1350a1461022b57600080fd5b80634c90f25c116100c85780634c90f25c1461017d578063535af56d146101a4578063591e3d44146101cb5780636449b8d7146101d357600080fd5b8063124fea4f146100ef5780632861c7d1146101295780634a46d11614610175575b600080fd5b6101167f000000000000000000000000000000000000000000000000000000000000000081565b6040519081526020015b60405180910390f35b6101507f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610120565b610116610287565b6101507f000000000000000000000000000000000000000000000000000000000000000081565b6101167f000000000000000000000000000000000000000000000000000000000000000081565b610116610364565b6101507f000000000000000000000000000000000000000000000000000000000000000081565b6101507f000000000000000000000000000000000000000000000000000000000000000081565b61022961039b565b005b6102336104d0565b60408051928352602083019190915201610120565b6101507f000000000000000000000000000000000000000000000000000000000000000081565b610116610699565b6101166106bf565b6101166106d3565b600061035f6203ffff60da7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663b5c736e47f00000000000000000000000000000000000000000000000000000000000000006040518263ffffffff1660e01b815260040161030d91815260200190565b602060405180830381865afa15801561032a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061034e9190610de1565b901c16600860ff9082901c91161b90565b905090565b60008060006103716106e3565b5050925050915064e8d4a51000818361038a9190610e29565b6103949190610e75565b9250505090565b6040517f467c9eff0000000000000000000000000000000000000000000000000000000081523360048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063467c9eff906024016020604051808303816000875af1158015610427573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061044b9190610eb0565b61048b576040517fd002e25a000000000000000000000000000000000000000000000000000000008152620186b660048201526024015b60405180910390fd5b610493610848565b6104ce576040517fd002e25a000000000000000000000000000000000000000000000000000000008152620186b86004820152602401610482565b565b6040517f2b00183300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000081166004830152600091829182916105b0917f00000000000000000000000000000000000000000000000000000000000000001690632b00183390602401602060405180830381865afa158015610587573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105ab9190610de1565b610b15565b6040517f6e93840600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000081166004830152919450919250610692917f000000000000000000000000000000000000000000000000000000000000000090911690636e93840690602401602060405180830381865afa158015610668573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061068c9190610de1565b82610d23565b9250509091565b60008060006106a66106e3565b509350505091506106b78183610d76565b509392505050565b60006106c96106e3565b5092949350505050565b60006106dd6104d0565b50919050565b60008060008060006106f36104d0565b90945092506000612710610727867f0000000000000000000000000000000000000000000000000000000000000000610e29565b6107319190610e75565b90508361074364e8d4a5100083610e29565b61074d9190610e75565b6040517fb5c736e40000000000000000000000000000000000000000000000000000000081527f000000000000000000000000000000000000000000000000000000000000000060048201529096507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063b5c736e490602401602060405180830381865afa1580156107fa573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061081e9190610de1565b92506103ff60d084901c1660ff60c885901c161b915085821115610840578195505b509091929394565b6000806000806000806108596106e3565b945094509450945094506000806108708488610d76565b915091507f00000000000000000000000000000000000000000000000000000000000000008210156108aa57600097505050505050505090565b604080516001808252818301909252600091816020015b6109306040518060e00160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff168152602001600060ff168152602001600081526020016000815260200160008152602001600081525090565b8152602001906001900390816108c15790505090506040518060e001604052807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1681526020018660011660ff168152602001613fff60a288901c16815260200162ffffff60b088901c1681526020018581526020018981525081600081518110610a0e57610a0e610ed9565b60209081029190910101526040517f01b88f8600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016906301b88f8690610a8b908490600401610f08565b600060405180830381600087803b158015610aa557600080fd5b505af1158015610ab9573d6000803e3d6000fd5b5050604080518a8152602081018690529081018b9052606081018990527ffb7b079eab340b206c50f95512290669e9100b85144e8f86783f2255e8da42ac9250608001905060405180910390a160019850505050505050505090565b67ffffffffffffffff605b82901c811690609b83901c16811580610b37575080155b15610b73576040517fd50d7512000000000000000000000000000000000000000000000000000000008152620111716004820152602401610482565b61ffff8316603a84901c6401ffffffff16428181039160ea87901c617fff16911480610b9d575082155b80610ba85750806001145b15610bb557505050915091565b64496cebb80084840283020484019350617fff60db87901c16925082600103610be057505050915091565b82600116600103610c355760019290921c91826c7e37be2022c0914b268000000081610c0e57610c0e610e46565b049250612710601e87901c613fff166b033b2e3c9fd0803ce8000000850102049250610c62565b60019290921c916305f5e100601e87901c613fff166127108501026b033b2e3c9fd0803ce8000000020492505b80600116600103610c995760011c61271081016b033b2e3c9fd0803ce8000000820281610c9157610c91610e46565b049050610ccf565b60011c61271081016b033b2e3c9fd0803ce8000000820281610cbd57610cbd610e46565b046b033b2e3c9fd0803ce80000000390505b760a70c3c40a64e6c51999090b65f67d92400000000000008382026127100261ffff881691900402601087901c613fff16612710030292506801b5a660ea44b8000085840283020485019450505050915091565b66ffffffffffffff604883901c811660ff604085901c81169190911b91600885901c169084161b64e8d4a51000610d5a8483610e29565b610d649190610e75565b610d6e9083610fa6565b949350505050565b600060e283901c6103ff1660da84901c60ff161b828103610d9a5760009150610dda565b82811115610db357610dac8382610fb9565b9150610dc0565b610dbd8184610fb9565b91505b80610dcd83612710610e29565b610dd79190610e75565b91505b9250929050565b600060208284031215610df357600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8082028115828204841417610e4057610e40610dfa565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082610eab577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b600060208284031215610ec257600080fd5b81518015158114610ed257600080fd5b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b602080825282518282018190526000919060409081850190868401855b82811015610f99578151805173ffffffffffffffffffffffffffffffffffffffff90811686528782015116878601528581015160ff1686860152606080820151908601526080808201519086015260a0808201519086015260c0908101519085015260e09093019290850190600101610f25565b5091979650505050505050565b80820180821115610e4057610e40610dfa565b81810381811115610e4057610e40610dfa56fea2646970667358221220eadbb16217247875f1ce003047ef717dc931cb11dcd2d9cbdc60d8f9d7ba58d264736f6c63430008150033",
"deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100ea5760003560e01c80636902f79f1161008c57806391b9b8271161006657806391b9b827146102485780639dc105661461026f578063abe3177914610277578063c4e41b221461027f57600080fd5b80636902f79f146101fa5780637d7c2a1c1461022157806382e1350a1461022b57600080fd5b80634c90f25c116100c85780634c90f25c1461017d578063535af56d146101a4578063591e3d44146101cb5780636449b8d7146101d357600080fd5b8063124fea4f146100ef5780632861c7d1146101295780634a46d11614610175575b600080fd5b6101167f000000000000000000000000000000000000000000000000000000000000000081565b6040519081526020015b60405180910390f35b6101507f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610120565b610116610287565b6101507f000000000000000000000000000000000000000000000000000000000000000081565b6101167f000000000000000000000000000000000000000000000000000000000000000081565b610116610364565b6101507f000000000000000000000000000000000000000000000000000000000000000081565b6101507f000000000000000000000000000000000000000000000000000000000000000081565b61022961039b565b005b6102336104d0565b60408051928352602083019190915201610120565b6101507f000000000000000000000000000000000000000000000000000000000000000081565b610116610699565b6101166106bf565b6101166106d3565b600061035f6203ffff60da7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663b5c736e47f00000000000000000000000000000000000000000000000000000000000000006040518263ffffffff1660e01b815260040161030d91815260200190565b602060405180830381865afa15801561032a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061034e9190610de1565b901c16600860ff9082901c91161b90565b905090565b60008060006103716106e3565b5050925050915064e8d4a51000818361038a9190610e29565b6103949190610e75565b9250505090565b6040517f467c9eff0000000000000000000000000000000000000000000000000000000081523360048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063467c9eff906024016020604051808303816000875af1158015610427573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061044b9190610eb0565b61048b576040517fd002e25a000000000000000000000000000000000000000000000000000000008152620186b660048201526024015b60405180910390fd5b610493610848565b6104ce576040517fd002e25a000000000000000000000000000000000000000000000000000000008152620186b86004820152602401610482565b565b6040517f2b00183300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000081166004830152600091829182916105b0917f00000000000000000000000000000000000000000000000000000000000000001690632b00183390602401602060405180830381865afa158015610587573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105ab9190610de1565b610b15565b6040517f6e93840600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000081166004830152919450919250610692917f000000000000000000000000000000000000000000000000000000000000000090911690636e93840690602401602060405180830381865afa158015610668573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061068c9190610de1565b82610d23565b9250509091565b60008060006106a66106e3565b509350505091506106b78183610d76565b509392505050565b60006106c96106e3565b5092949350505050565b60006106dd6104d0565b50919050565b60008060008060006106f36104d0565b90945092506000612710610727867f0000000000000000000000000000000000000000000000000000000000000000610e29565b6107319190610e75565b90508361074364e8d4a5100083610e29565b61074d9190610e75565b6040517fb5c736e40000000000000000000000000000000000000000000000000000000081527f000000000000000000000000000000000000000000000000000000000000000060048201529096507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063b5c736e490602401602060405180830381865afa1580156107fa573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061081e9190610de1565b92506103ff60d084901c1660ff60c885901c161b915085821115610840578195505b509091929394565b6000806000806000806108596106e3565b945094509450945094506000806108708488610d76565b915091507f00000000000000000000000000000000000000000000000000000000000000008210156108aa57600097505050505050505090565b604080516001808252818301909252600091816020015b6109306040518060e00160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff168152602001600060ff168152602001600081526020016000815260200160008152602001600081525090565b8152602001906001900390816108c15790505090506040518060e001604052807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1681526020018660011660ff168152602001613fff60a288901c16815260200162ffffff60b088901c1681526020018581526020018981525081600081518110610a0e57610a0e610ed9565b60209081029190910101526040517f01b88f8600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016906301b88f8690610a8b908490600401610f08565b600060405180830381600087803b158015610aa557600080fd5b505af1158015610ab9573d6000803e3d6000fd5b5050604080518a8152602081018690529081018b9052606081018990527ffb7b079eab340b206c50f95512290669e9100b85144e8f86783f2255e8da42ac9250608001905060405180910390a160019850505050505050505090565b67ffffffffffffffff605b82901c811690609b83901c16811580610b37575080155b15610b73576040517fd50d7512000000000000000000000000000000000000000000000000000000008152620111716004820152602401610482565b61ffff8316603a84901c6401ffffffff16428181039160ea87901c617fff16911480610b9d575082155b80610ba85750806001145b15610bb557505050915091565b64496cebb80084840283020484019350617fff60db87901c16925082600103610be057505050915091565b82600116600103610c355760019290921c91826c7e37be2022c0914b268000000081610c0e57610c0e610e46565b049250612710601e87901c613fff166b033b2e3c9fd0803ce8000000850102049250610c62565b60019290921c916305f5e100601e87901c613fff166127108501026b033b2e3c9fd0803ce8000000020492505b80600116600103610c995760011c61271081016b033b2e3c9fd0803ce8000000820281610c9157610c91610e46565b049050610ccf565b60011c61271081016b033b2e3c9fd0803ce8000000820281610cbd57610cbd610e46565b046b033b2e3c9fd0803ce80000000390505b760a70c3c40a64e6c51999090b65f67d92400000000000008382026127100261ffff881691900402601087901c613fff16612710030292506801b5a660ea44b8000085840283020485019450505050915091565b66ffffffffffffff604883901c811660ff604085901c81169190911b91600885901c169084161b64e8d4a51000610d5a8483610e29565b610d649190610e75565b610d6e9083610fa6565b949350505050565b600060e283901c6103ff1660da84901c60ff161b828103610d9a5760009150610dda565b82811115610db357610dac8382610fb9565b9150610dc0565b610dbd8184610fb9565b91505b80610dcd83612710610e29565b610dd79190610e75565b91505b9250929050565b600060208284031215610df357600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8082028115828204841417610e4057610e40610dfa565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082610eab577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b600060208284031215610ec257600080fd5b81518015158114610ed257600080fd5b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b602080825282518282018190526000919060409081850190868401855b82811015610f99578151805173ffffffffffffffffffffffffffffffffffffffff90811686528782015116878601528581015160ff1686860152606080820151908601526080808201519086015260a0808201519086015260c0908101519085015260e09093019290850190600101610f25565b5091979650505050505050565b80820180821115610e4057610e40610dfa565b81810381811115610e4057610e40610dfa56fea2646970667358221220eadbb16217247875f1ce003047ef717dc931cb11dcd2d9cbdc60d8f9d7ba58d264736f6c63430008150033",
"devdoc": {
"kind": "dev",
"methods": {},
"version": 1
},
"userdoc": {
"events": {
"LogUpdateBorrowMaxDebtCeiling(uint256,uint256,uint256,uint256)": {
"notice": "emitted when borrow max limit is updated"
}
},
"kind": "user",
"methods": {
"calcMaxDebtCeiling()": {
"notice": "returns the max debt ceiling that should be set according to current state (in raw for mode with interest!)."
},
"calcMaxDebtCeilingNormal()": {
"notice": "returns the max debt ceiling that should be set according to current state (in normal)."
},
"configPercentDiff()": {
"notice": "returns how much new config would be different from current config in percent (100 = 1%, 1 = 0.01%)."
},
"currentMaxDebtCeiling()": {
"notice": "returns the currently set max debt ceiling (in raw for mode with interest!)."
},
"getTotalSupply()": {
"notice": "returns `BORROW_TOKEN` total supply at Liquidity (in normal)."
},
"rebalance()": {
"notice": "Rebalances the configs for `PROTOCOL` at Fluid Liquidity based on protocol total supply & total borrow. Emits `LogUpdateBorrowMaxDebtCeiling` if update is executed. Reverts if no update is needed. Can only be called by an authorized rebalancer."
}
},
"notice": "Sets max borrow limit for a protocol on Liquidity based on utilization of total supply of the same borrow token",
"version": 1
},
"storageLayout": {
"storage": [],
"types": null
}
}