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

967 lines
235 KiB
JSON

{
"address": "0xC215485C572365AE87f908ad35233EC2572A3BEC",
"abi": [
{
"inputs": [
{
"internalType": "contract IFluidLendingFactory",
"name": "lendingFactory_",
"type": "address"
},
{
"internalType": "contract IFluidLiquidityResolver",
"name": "liquidityResolver_",
"type": "address"
}
],
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"inputs": [],
"name": "FluidLendingResolver__AddressZero",
"type": "error"
},
{
"inputs": [],
"name": "LENDING_FACTORY",
"outputs": [
{
"internalType": "contract IFluidLendingFactory",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "LIQUIDITY_RESOLVER",
"outputs": [
{
"internalType": "contract IFluidLiquidityResolver",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "asset_",
"type": "address"
},
{
"internalType": "string",
"name": "fTokenType_",
"type": "string"
}
],
"name": "computeFToken",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "getAllFTokenTypes",
"outputs": [
{
"internalType": "string[]",
"name": "",
"type": "string[]"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "getAllFTokens",
"outputs": [
{
"internalType": "address[]",
"name": "",
"type": "address[]"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "contract IFToken",
"name": "fToken_",
"type": "address"
}
],
"name": "getFTokenDetails",
"outputs": [
{
"components": [
{
"internalType": "address",
"name": "tokenAddress",
"type": "address"
},
{
"internalType": "bool",
"name": "eip2612Deposits",
"type": "bool"
},
{
"internalType": "bool",
"name": "isNativeUnderlying",
"type": "bool"
},
{
"internalType": "string",
"name": "name",
"type": "string"
},
{
"internalType": "string",
"name": "symbol",
"type": "string"
},
{
"internalType": "uint256",
"name": "decimals",
"type": "uint256"
},
{
"internalType": "address",
"name": "asset",
"type": "address"
},
{
"internalType": "uint256",
"name": "totalAssets",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "totalSupply",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "convertToShares",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "convertToAssets",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "rewardsRate",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "supplyRate",
"type": "uint256"
},
{
"internalType": "int256",
"name": "rebalanceDifference",
"type": "int256"
},
{
"components": [
{
"internalType": "bool",
"name": "modeWithInterest",
"type": "bool"
},
{
"internalType": "uint256",
"name": "supply",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "withdrawalLimit",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "lastUpdateTimestamp",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "expandPercent",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "expandDuration",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "baseWithdrawalLimit",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "withdrawableUntilLimit",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "withdrawable",
"type": "uint256"
}
],
"internalType": "struct Structs.UserSupplyData",
"name": "liquidityUserSupplyData",
"type": "tuple"
}
],
"internalType": "struct Structs.FTokenDetails",
"name": "fTokenDetails_",
"type": "tuple"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "contract IFToken",
"name": "fToken_",
"type": "address"
}
],
"name": "getFTokenInternalData",
"outputs": [
{
"internalType": "contract IFluidLiquidity",
"name": "liquidity_",
"type": "address"
},
{
"internalType": "contract IFluidLendingFactory",
"name": "lendingFactory_",
"type": "address"
},
{
"internalType": "contract IFluidLendingRewardsRateModel",
"name": "lendingRewardsRateModel_",
"type": "address"
},
{
"internalType": "contract IAllowanceTransfer",
"name": "permit2_",
"type": "address"
},
{
"internalType": "address",
"name": "rebalancer_",
"type": "address"
},
{
"internalType": "bool",
"name": "rewardsActive_",
"type": "bool"
},
{
"internalType": "uint256",
"name": "liquidityBalance_",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "liquidityExchangePrice_",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "tokenExchangePrice_",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "contract IFToken",
"name": "fToken_",
"type": "address"
}
],
"name": "getFTokenRewards",
"outputs": [
{
"internalType": "contract IFluidLendingRewardsRateModel",
"name": "rewardsRateModel_",
"type": "address"
},
{
"internalType": "uint256",
"name": "rewardsRate_",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "contract IFToken",
"name": "fToken_",
"type": "address"
}
],
"name": "getFTokenRewardsRateModelConfig",
"outputs": [
{
"internalType": "uint256",
"name": "duration_",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "startTime_",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "endTime_",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "startTvl_",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "maxRate_",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "rewardAmount_",
"type": "uint256"
},
{
"internalType": "address",
"name": "initiator_",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "getFTokensEntireData",
"outputs": [
{
"components": [
{
"internalType": "address",
"name": "tokenAddress",
"type": "address"
},
{
"internalType": "bool",
"name": "eip2612Deposits",
"type": "bool"
},
{
"internalType": "bool",
"name": "isNativeUnderlying",
"type": "bool"
},
{
"internalType": "string",
"name": "name",
"type": "string"
},
{
"internalType": "string",
"name": "symbol",
"type": "string"
},
{
"internalType": "uint256",
"name": "decimals",
"type": "uint256"
},
{
"internalType": "address",
"name": "asset",
"type": "address"
},
{
"internalType": "uint256",
"name": "totalAssets",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "totalSupply",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "convertToShares",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "convertToAssets",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "rewardsRate",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "supplyRate",
"type": "uint256"
},
{
"internalType": "int256",
"name": "rebalanceDifference",
"type": "int256"
},
{
"components": [
{
"internalType": "bool",
"name": "modeWithInterest",
"type": "bool"
},
{
"internalType": "uint256",
"name": "supply",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "withdrawalLimit",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "lastUpdateTimestamp",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "expandPercent",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "expandDuration",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "baseWithdrawalLimit",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "withdrawableUntilLimit",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "withdrawable",
"type": "uint256"
}
],
"internalType": "struct Structs.UserSupplyData",
"name": "liquidityUserSupplyData",
"type": "tuple"
}
],
"internalType": "struct Structs.FTokenDetails[]",
"name": "",
"type": "tuple[]"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "contract IFToken",
"name": "fToken_",
"type": "address"
},
{
"internalType": "uint256",
"name": "assets_",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "shares_",
"type": "uint256"
}
],
"name": "getPreviews",
"outputs": [
{
"internalType": "uint256",
"name": "previewDeposit_",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "previewMint_",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "previewWithdraw_",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "previewRedeem_",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "contract IFToken",
"name": "fToken_",
"type": "address"
},
{
"internalType": "address",
"name": "user_",
"type": "address"
}
],
"name": "getUserPosition",
"outputs": [
{
"components": [
{
"internalType": "uint256",
"name": "fTokenShares",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "underlyingAssets",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "underlyingBalance",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "allowance",
"type": "uint256"
}
],
"internalType": "struct Structs.UserPosition",
"name": "userPosition",
"type": "tuple"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "user_",
"type": "address"
}
],
"name": "getUserPositions",
"outputs": [
{
"components": [
{
"components": [
{
"internalType": "address",
"name": "tokenAddress",
"type": "address"
},
{
"internalType": "bool",
"name": "eip2612Deposits",
"type": "bool"
},
{
"internalType": "bool",
"name": "isNativeUnderlying",
"type": "bool"
},
{
"internalType": "string",
"name": "name",
"type": "string"
},
{
"internalType": "string",
"name": "symbol",
"type": "string"
},
{
"internalType": "uint256",
"name": "decimals",
"type": "uint256"
},
{
"internalType": "address",
"name": "asset",
"type": "address"
},
{
"internalType": "uint256",
"name": "totalAssets",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "totalSupply",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "convertToShares",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "convertToAssets",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "rewardsRate",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "supplyRate",
"type": "uint256"
},
{
"internalType": "int256",
"name": "rebalanceDifference",
"type": "int256"
},
{
"components": [
{
"internalType": "bool",
"name": "modeWithInterest",
"type": "bool"
},
{
"internalType": "uint256",
"name": "supply",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "withdrawalLimit",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "lastUpdateTimestamp",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "expandPercent",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "expandDuration",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "baseWithdrawalLimit",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "withdrawableUntilLimit",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "withdrawable",
"type": "uint256"
}
],
"internalType": "struct Structs.UserSupplyData",
"name": "liquidityUserSupplyData",
"type": "tuple"
}
],
"internalType": "struct Structs.FTokenDetails",
"name": "fTokenDetails",
"type": "tuple"
},
{
"components": [
{
"internalType": "uint256",
"name": "fTokenShares",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "underlyingAssets",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "underlyingBalance",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "allowance",
"type": "uint256"
}
],
"internalType": "struct Structs.UserPosition",
"name": "userPosition",
"type": "tuple"
}
],
"internalType": "struct Structs.FTokenDetailsUserPosition[]",
"name": "",
"type": "tuple[]"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "auth_",
"type": "address"
}
],
"name": "isLendingFactoryAuth",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "deployer_",
"type": "address"
}
],
"name": "isLendingFactoryDeployer",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
}
],
"transactionHash": "0x4f9ba325a0d5ea7cd48ece14a4d0870606a492b9142f79d0e94a21f6d6073910",
"receipt": {
"to": "0x4e59b44847b379578588920cA78FbF26c0B4956C",
"from": "0x0Ed35B1609Ec45c7079E80d11149a52717e4859A",
"contractAddress": null,
"transactionIndex": 215,
"gasUsed": "2366859",
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"blockHash": "0xec0f4039878cb0ee6a6672d46e50806409795271cfabe586bf42c8626b0e5b08",
"transactionHash": "0x4f9ba325a0d5ea7cd48ece14a4d0870606a492b9142f79d0e94a21f6d6073910",
"logs": [],
"blockNumber": 19992071,
"cumulativeGasUsed": "23261908",
"status": 1,
"byzantium": true
},
"args": [
"0x54B91A0D94cb471F37f949c60F7Fa7935b551D03",
"0xD7588F6c99605Ab274C211a0AFeC60947668A8Cb"
],
"numDeployments": 3,
"solcInputHash": "033d84042c3fe6a1afa58a71e8e52d69",
"metadata": "{\"compiler\":{\"version\":\"0.8.21+commit.d9974bed\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"contract IFluidLendingFactory\",\"name\":\"lendingFactory_\",\"type\":\"address\"},{\"internalType\":\"contract IFluidLiquidityResolver\",\"name\":\"liquidityResolver_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"FluidLendingResolver__AddressZero\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LENDING_FACTORY\",\"outputs\":[{\"internalType\":\"contract IFluidLendingFactory\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"LIQUIDITY_RESOLVER\",\"outputs\":[{\"internalType\":\"contract IFluidLiquidityResolver\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"asset_\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"fTokenType_\",\"type\":\"string\"}],\"name\":\"computeFToken\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllFTokenTypes\",\"outputs\":[{\"internalType\":\"string[]\",\"name\":\"\",\"type\":\"string[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllFTokens\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IFToken\",\"name\":\"fToken_\",\"type\":\"address\"}],\"name\":\"getFTokenDetails\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"eip2612Deposits\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"isNativeUnderlying\",\"type\":\"bool\"},{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"symbol\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"decimals\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"totalAssets\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"totalSupply\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"convertToShares\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"convertToAssets\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"rewardsRate\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"supplyRate\",\"type\":\"uint256\"},{\"internalType\":\"int256\",\"name\":\"rebalanceDifference\",\"type\":\"int256\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"modeWithInterest\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"supply\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"withdrawalLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"lastUpdateTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"expandPercent\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"expandDuration\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"baseWithdrawalLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"withdrawableUntilLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"withdrawable\",\"type\":\"uint256\"}],\"internalType\":\"struct Structs.UserSupplyData\",\"name\":\"liquidityUserSupplyData\",\"type\":\"tuple\"}],\"internalType\":\"struct Structs.FTokenDetails\",\"name\":\"fTokenDetails_\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IFToken\",\"name\":\"fToken_\",\"type\":\"address\"}],\"name\":\"getFTokenInternalData\",\"outputs\":[{\"internalType\":\"contract IFluidLiquidity\",\"name\":\"liquidity_\",\"type\":\"address\"},{\"internalType\":\"contract IFluidLendingFactory\",\"name\":\"lendingFactory_\",\"type\":\"address\"},{\"internalType\":\"contract IFluidLendingRewardsRateModel\",\"name\":\"lendingRewardsRateModel_\",\"type\":\"address\"},{\"internalType\":\"contract IAllowanceTransfer\",\"name\":\"permit2_\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"rebalancer_\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"rewardsActive_\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"liquidityBalance_\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"liquidityExchangePrice_\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"tokenExchangePrice_\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IFToken\",\"name\":\"fToken_\",\"type\":\"address\"}],\"name\":\"getFTokenRewards\",\"outputs\":[{\"internalType\":\"contract IFluidLendingRewardsRateModel\",\"name\":\"rewardsRateModel_\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"rewardsRate_\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IFToken\",\"name\":\"fToken_\",\"type\":\"address\"}],\"name\":\"getFTokenRewardsRateModelConfig\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"duration_\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"startTime_\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"endTime_\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"startTvl_\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxRate_\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"rewardAmount_\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"initiator_\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getFTokensEntireData\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"eip2612Deposits\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"isNativeUnderlying\",\"type\":\"bool\"},{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"symbol\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"decimals\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"totalAssets\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"totalSupply\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"convertToShares\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"convertToAssets\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"rewardsRate\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"supplyRate\",\"type\":\"uint256\"},{\"internalType\":\"int256\",\"name\":\"rebalanceDifference\",\"type\":\"int256\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"modeWithInterest\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"supply\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"withdrawalLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"lastUpdateTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"expandPercent\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"expandDuration\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"baseWithdrawalLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"withdrawableUntilLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"withdrawable\",\"type\":\"uint256\"}],\"internalType\":\"struct Structs.UserSupplyData\",\"name\":\"liquidityUserSupplyData\",\"type\":\"tuple\"}],\"internalType\":\"struct Structs.FTokenDetails[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IFToken\",\"name\":\"fToken_\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"assets_\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"shares_\",\"type\":\"uint256\"}],\"name\":\"getPreviews\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"previewDeposit_\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"previewMint_\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"previewWithdraw_\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"previewRedeem_\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IFToken\",\"name\":\"fToken_\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"user_\",\"type\":\"address\"}],\"name\":\"getUserPosition\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"fTokenShares\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"underlyingAssets\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"underlyingBalance\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"allowance\",\"type\":\"uint256\"}],\"internalType\":\"struct Structs.UserPosition\",\"name\":\"userPosition\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"user_\",\"type\":\"address\"}],\"name\":\"getUserPositions\",\"outputs\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"eip2612Deposits\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"isNativeUnderlying\",\"type\":\"bool\"},{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"symbol\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"decimals\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"totalAssets\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"totalSupply\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"convertToShares\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"convertToAssets\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"rewardsRate\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"supplyRate\",\"type\":\"uint256\"},{\"internalType\":\"int256\",\"name\":\"rebalanceDifference\",\"type\":\"int256\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"modeWithInterest\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"supply\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"withdrawalLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"lastUpdateTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"expandPercent\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"expandDuration\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"baseWithdrawalLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"withdrawableUntilLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"withdrawable\",\"type\":\"uint256\"}],\"internalType\":\"struct Structs.UserSupplyData\",\"name\":\"liquidityUserSupplyData\",\"type\":\"tuple\"}],\"internalType\":\"struct Structs.FTokenDetails\",\"name\":\"fTokenDetails\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"fTokenShares\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"underlyingAssets\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"underlyingBalance\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"allowance\",\"type\":\"uint256\"}],\"internalType\":\"struct Structs.UserPosition\",\"name\":\"userPosition\",\"type\":\"tuple\"}],\"internalType\":\"struct Structs.FTokenDetailsUserPosition[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"auth_\",\"type\":\"address\"}],\"name\":\"isLendingFactoryAuth\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"deployer_\",\"type\":\"address\"}],\"name\":\"isLendingFactoryDeployer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"computeFToken(address,string)\":{\"params\":{\"asset_\":\"address of the asset\",\"fTokenType_\":\"type of fToken: - if underlying asset supports EIP-2612, the fToken should be type `EIP2612Deposits` - otherwise it should use `Permit2Deposits` - if it's the native token, it should use `NativeUnderlying` - could be more types available, check `fTokenTypes()`\"},\"returns\":{\"_0\":\"token_ detemrinistic address of the computed token\"}},\"getFTokenDetails(address)\":{\"params\":{\"fToken_\":\"the fToken to get the details for\"},\"returns\":{\"fTokenDetails_\":\" retrieved FTokenDetails struct\"}},\"getFTokenInternalData(address)\":{\"params\":{\"fToken_\":\"the fToken to get the data for\"},\"returns\":{\"lendingFactory_\":\"address of the Lending factory contract.\",\"lendingRewardsRateModel_\":\"address of the rewards rate model contract. changeable by LendingFactory auths.\",\"liquidityBalance_\":\"current Liquidity supply balance of `address(this)` for the underyling asset\",\"liquidityExchangePrice_\":\"(updated) exchange price for the underlying assset in the liquidity protocol (without rewards)\",\"liquidity_\":\"address of the Liquidity contract.\",\"permit2_\":\"address of the Permit2 contract used for deposits / mint with signature\",\"rebalancer_\":\"address of the rebalancer allowed to execute `rebalance()`\",\"rewardsActive_\":\"true if rewards are currently active\",\"tokenExchangePrice_\":\"(updated) exchange price between fToken and the underlying assset (with rewards)\"}},\"getPreviews(address,uint256,uint256)\":{\"returns\":{\"previewDeposit_\":\"preview for deposit of `assets_`\",\"previewMint_\":\"preview for mint of `shares_`\",\"previewRedeem_\":\"preview for redeem of `shares_`\",\"previewWithdraw_\":\"preview for withdraw of `assets_`\"}},\"getUserPosition(address,address)\":{\"returns\":{\"userPosition\":\"user position struct\"}}},\"stateVariables\":{\"_NATIVE_TOKEN_ADDRESS\":{\"details\":\"address that is mapped to the chain native token\"}},\"version\":1},\"userdoc\":{\"errors\":{\"FluidLendingResolver__AddressZero()\":[{\"notice\":\"thrown if an input param address is zero\"}]},\"kind\":\"user\",\"methods\":{\"LENDING_FACTORY()\":{\"notice\":\"returns the lending factory address\"},\"LIQUIDITY_RESOLVER()\":{\"notice\":\"returns the liquidity resolver address\"},\"computeFToken(address,string)\":{\"notice\":\"computes deterministic token address for `asset_` for a lending protocol\"},\"constructor\":{\"notice\":\"constructor sets the immutable `LENDING_FACTORY` and `LIQUIDITY_RESOLVER` address\"},\"getAllFTokenTypes()\":{\"notice\":\"returns all fToken types at the `LENDING_FACTORY`\"},\"getAllFTokens()\":{\"notice\":\"returns all created fTokens at the `LENDING_FACTORY`\"},\"getFTokenDetails(address)\":{\"notice\":\"gets all public details for a certain `fToken_`, such as fToken type, name, symbol, decimals, underlying asset, total amounts, convertTo values, rewards. Note it also returns whether the fToken supports deposits / mints via EIP-2612, but it is not a 100% guarantee! To make sure, check for the underlying if it supports EIP-2612 manually.\"},\"getFTokenInternalData(address)\":{\"notice\":\"returns config, rewards and exchange prices data of an fToken.\"},\"getFTokenRewards(address)\":{\"notice\":\"gets rewards related data: the `rewardsRateModel_` contract and the current `rewardsRate_` for the `fToken_`\"},\"getFTokenRewardsRateModelConfig(address)\":{\"notice\":\"gets rewards rate model config constants\"},\"getFTokensEntireData()\":{\"notice\":\"gets all public details for all itokens, such as fToken type, name, symbol, decimals, underlying asset, total amounts, convertTo values, rewards\"},\"getPreviews(address,uint256,uint256)\":{\"notice\":\"gets `fToken_` preview amounts for `assets_` or `shares_`.\"},\"getUserPosition(address,address)\":{\"notice\":\"gets a `user_` position for an `fToken_`.\"},\"getUserPositions(address)\":{\"notice\":\"gets all public details for all itokens, such as fToken type, name, symbol, decimals, underlying asset, total amounts, convertTo values, rewards and user position for each token\"},\"isLendingFactoryAuth(address)\":{\"notice\":\"reads if a certain `auth_` address is an allowed auth or not. Owner is auth by default.\"},\"isLendingFactoryDeployer(address)\":{\"notice\":\"reads if a certain `deployer_` address is an allowed deployer or not. Owner is deployer by default.\"}},\"notice\":\"Fluid Lending protocol (fTokens) resolver Implements various view-only methods to give easy access to Lending protocol data.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/periphery/resolvers/lending/main.sol\":\"FluidLendingResolver\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":10000000},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/interfaces/IERC4626.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (interfaces/IERC4626.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../token/ERC20/IERC20.sol\\\";\\nimport \\\"../token/ERC20/extensions/IERC20Metadata.sol\\\";\\n\\n/**\\n * @dev Interface of the ERC4626 \\\"Tokenized Vault Standard\\\", as defined in\\n * https://eips.ethereum.org/EIPS/eip-4626[ERC-4626].\\n *\\n * _Available since v4.7._\\n */\\ninterface IERC4626 is IERC20, IERC20Metadata {\\n event Deposit(address indexed sender, address indexed owner, uint256 assets, uint256 shares);\\n\\n event Withdraw(\\n address indexed sender,\\n address indexed receiver,\\n address indexed owner,\\n uint256 assets,\\n uint256 shares\\n );\\n\\n /**\\n * @dev Returns the address of the underlying token used for the Vault for accounting, depositing, and withdrawing.\\n *\\n * - MUST be an ERC-20 token contract.\\n * - MUST NOT revert.\\n */\\n function asset() external view returns (address assetTokenAddress);\\n\\n /**\\n * @dev Returns the total amount of the underlying asset that is \\u201cmanaged\\u201d by Vault.\\n *\\n * - SHOULD include any compounding that occurs from yield.\\n * - MUST be inclusive of any fees that are charged against assets in the Vault.\\n * - MUST NOT revert.\\n */\\n function totalAssets() external view returns (uint256 totalManagedAssets);\\n\\n /**\\n * @dev Returns the amount of shares that the Vault would exchange for the amount of assets provided, in an ideal\\n * scenario where all the conditions are met.\\n *\\n * - MUST NOT be inclusive of any fees that are charged against assets in the Vault.\\n * - MUST NOT show any variations depending on the caller.\\n * - MUST NOT reflect slippage or other on-chain conditions, when performing the actual exchange.\\n * - MUST NOT revert.\\n *\\n * NOTE: This calculation MAY NOT reflect the \\u201cper-user\\u201d price-per-share, and instead should reflect the\\n * \\u201caverage-user\\u2019s\\u201d price-per-share, meaning what the average user should expect to see when exchanging to and\\n * from.\\n */\\n function convertToShares(uint256 assets) external view returns (uint256 shares);\\n\\n /**\\n * @dev Returns the amount of assets that the Vault would exchange for the amount of shares provided, in an ideal\\n * scenario where all the conditions are met.\\n *\\n * - MUST NOT be inclusive of any fees that are charged against assets in the Vault.\\n * - MUST NOT show any variations depending on the caller.\\n * - MUST NOT reflect slippage or other on-chain conditions, when performing the actual exchange.\\n * - MUST NOT revert.\\n *\\n * NOTE: This calculation MAY NOT reflect the \\u201cper-user\\u201d price-per-share, and instead should reflect the\\n * \\u201caverage-user\\u2019s\\u201d price-per-share, meaning what the average user should expect to see when exchanging to and\\n * from.\\n */\\n function convertToAssets(uint256 shares) external view returns (uint256 assets);\\n\\n /**\\n * @dev Returns the maximum amount of the underlying asset that can be deposited into the Vault for the receiver,\\n * through a deposit call.\\n *\\n * - MUST return a limited value if receiver is subject to some deposit limit.\\n * - MUST return 2 ** 256 - 1 if there is no limit on the maximum amount of assets that may be deposited.\\n * - MUST NOT revert.\\n */\\n function maxDeposit(address receiver) external view returns (uint256 maxAssets);\\n\\n /**\\n * @dev Allows an on-chain or off-chain user to simulate the effects of their deposit at the current block, given\\n * current on-chain conditions.\\n *\\n * - MUST return as close to and no more than the exact amount of Vault shares that would be minted in a deposit\\n * call in the same transaction. I.e. deposit should return the same or more shares as previewDeposit if called\\n * in the same transaction.\\n * - MUST NOT account for deposit limits like those returned from maxDeposit and should always act as though the\\n * deposit would be accepted, regardless if the user has enough tokens approved, etc.\\n * - MUST be inclusive of deposit fees. Integrators should be aware of the existence of deposit fees.\\n * - MUST NOT revert.\\n *\\n * NOTE: any unfavorable discrepancy between convertToShares and previewDeposit SHOULD be considered slippage in\\n * share price or some other type of condition, meaning the depositor will lose assets by depositing.\\n */\\n function previewDeposit(uint256 assets) external view returns (uint256 shares);\\n\\n /**\\n * @dev Mints shares Vault shares to receiver by depositing exactly amount of underlying tokens.\\n *\\n * - MUST emit the Deposit event.\\n * - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the\\n * deposit execution, and are accounted for during deposit.\\n * - MUST revert if all of assets cannot be deposited (due to deposit limit being reached, slippage, the user not\\n * approving enough underlying tokens to the Vault contract, etc).\\n *\\n * NOTE: most implementations will require pre-approval of the Vault with the Vault\\u2019s underlying asset token.\\n */\\n function deposit(uint256 assets, address receiver) external returns (uint256 shares);\\n\\n /**\\n * @dev Returns the maximum amount of the Vault shares that can be minted for the receiver, through a mint call.\\n * - MUST return a limited value if receiver is subject to some mint limit.\\n * - MUST return 2 ** 256 - 1 if there is no limit on the maximum amount of shares that may be minted.\\n * - MUST NOT revert.\\n */\\n function maxMint(address receiver) external view returns (uint256 maxShares);\\n\\n /**\\n * @dev Allows an on-chain or off-chain user to simulate the effects of their mint at the current block, given\\n * current on-chain conditions.\\n *\\n * - MUST return as close to and no fewer than the exact amount of assets that would be deposited in a mint call\\n * in the same transaction. I.e. mint should return the same or fewer assets as previewMint if called in the\\n * same transaction.\\n * - MUST NOT account for mint limits like those returned from maxMint and should always act as though the mint\\n * would be accepted, regardless if the user has enough tokens approved, etc.\\n * - MUST be inclusive of deposit fees. Integrators should be aware of the existence of deposit fees.\\n * - MUST NOT revert.\\n *\\n * NOTE: any unfavorable discrepancy between convertToAssets and previewMint SHOULD be considered slippage in\\n * share price or some other type of condition, meaning the depositor will lose assets by minting.\\n */\\n function previewMint(uint256 shares) external view returns (uint256 assets);\\n\\n /**\\n * @dev Mints exactly shares Vault shares to receiver by depositing amount of underlying tokens.\\n *\\n * - MUST emit the Deposit event.\\n * - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the mint\\n * execution, and are accounted for during mint.\\n * - MUST revert if all of shares cannot be minted (due to deposit limit being reached, slippage, the user not\\n * approving enough underlying tokens to the Vault contract, etc).\\n *\\n * NOTE: most implementations will require pre-approval of the Vault with the Vault\\u2019s underlying asset token.\\n */\\n function mint(uint256 shares, address receiver) external returns (uint256 assets);\\n\\n /**\\n * @dev Returns the maximum amount of the underlying asset that can be withdrawn from the owner balance in the\\n * Vault, through a withdraw call.\\n *\\n * - MUST return a limited value if owner is subject to some withdrawal limit or timelock.\\n * - MUST NOT revert.\\n */\\n function maxWithdraw(address owner) external view returns (uint256 maxAssets);\\n\\n /**\\n * @dev Allows an on-chain or off-chain user to simulate the effects of their withdrawal at the current block,\\n * given current on-chain conditions.\\n *\\n * - MUST return as close to and no fewer than the exact amount of Vault shares that would be burned in a withdraw\\n * call in the same transaction. I.e. withdraw should return the same or fewer shares as previewWithdraw if\\n * called\\n * in the same transaction.\\n * - MUST NOT account for withdrawal limits like those returned from maxWithdraw and should always act as though\\n * the withdrawal would be accepted, regardless if the user has enough shares, etc.\\n * - MUST be inclusive of withdrawal fees. Integrators should be aware of the existence of withdrawal fees.\\n * - MUST NOT revert.\\n *\\n * NOTE: any unfavorable discrepancy between convertToShares and previewWithdraw SHOULD be considered slippage in\\n * share price or some other type of condition, meaning the depositor will lose assets by depositing.\\n */\\n function previewWithdraw(uint256 assets) external view returns (uint256 shares);\\n\\n /**\\n * @dev Burns shares from owner and sends exactly assets of underlying tokens to receiver.\\n *\\n * - MUST emit the Withdraw event.\\n * - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the\\n * withdraw execution, and are accounted for during withdraw.\\n * - MUST revert if all of assets cannot be withdrawn (due to withdrawal limit being reached, slippage, the owner\\n * not having enough shares, etc).\\n *\\n * Note that some implementations will require pre-requesting to the Vault before a withdrawal may be performed.\\n * Those methods should be performed separately.\\n */\\n function withdraw(\\n uint256 assets,\\n address receiver,\\n address owner\\n ) external returns (uint256 shares);\\n\\n /**\\n * @dev Returns the maximum amount of Vault shares that can be redeemed from the owner balance in the Vault,\\n * through a redeem call.\\n *\\n * - MUST return a limited value if owner is subject to some withdrawal limit or timelock.\\n * - MUST return balanceOf(owner) if owner is not subject to any withdrawal limit or timelock.\\n * - MUST NOT revert.\\n */\\n function maxRedeem(address owner) external view returns (uint256 maxShares);\\n\\n /**\\n * @dev Allows an on-chain or off-chain user to simulate the effects of their redeemption at the current block,\\n * given current on-chain conditions.\\n *\\n * - MUST return as close to and no more than the exact amount of assets that would be withdrawn in a redeem call\\n * in the same transaction. I.e. redeem should return the same or more assets as previewRedeem if called in the\\n * same transaction.\\n * - MUST NOT account for redemption limits like those returned from maxRedeem and should always act as though the\\n * redemption would be accepted, regardless if the user has enough shares, etc.\\n * - MUST be inclusive of withdrawal fees. Integrators should be aware of the existence of withdrawal fees.\\n * - MUST NOT revert.\\n *\\n * NOTE: any unfavorable discrepancy between convertToAssets and previewRedeem SHOULD be considered slippage in\\n * share price or some other type of condition, meaning the depositor will lose assets by redeeming.\\n */\\n function previewRedeem(uint256 shares) external view returns (uint256 assets);\\n\\n /**\\n * @dev Burns exactly shares from owner and sends assets of underlying tokens to receiver.\\n *\\n * - MUST emit the Withdraw event.\\n * - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the\\n * redeem execution, and are accounted for during redeem.\\n * - MUST revert if all of shares cannot be redeemed (due to withdrawal limit being reached, slippage, the owner\\n * not having enough shares, etc).\\n *\\n * NOTE: some implementations will require pre-requesting to the Vault before a withdrawal may be performed.\\n * Those methods should be performed separately.\\n */\\n function redeem(\\n uint256 shares,\\n address receiver,\\n address owner\\n ) external returns (uint256 assets);\\n}\\n\",\"keccak256\":\"0xd82776ed6975a5939668e068f995acb1394c2f60a12a9ef3f14cacb91b5a8fd4\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"keccak256\":\"0x9750c6b834f7b43000631af5cc30001c5f547b3ceb3635488f140f60e897ea6b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\n\\n/**\\n * @dev Interface for the optional metadata functions from the ERC20 standard.\\n *\\n * _Available since v4.1._\\n */\\ninterface IERC20Metadata is IERC20 {\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() external view returns (string memory);\\n\\n /**\\n * @dev Returns the symbol of the token.\\n */\\n function symbol() external view returns (string memory);\\n\\n /**\\n * @dev Returns the decimals places of the token.\\n */\\n function decimals() external view returns (uint8);\\n}\\n\",\"keccak256\":\"0x8de418a5503946cabe331f35fe242d3201a73f67f77aaeb7110acb1f30423aca\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n */\\ninterface IERC20Permit {\\n /**\\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\\n * given ``owner``'s signed approval.\\n *\\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\\n * ordering also apply here.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `deadline` must be a timestamp in the future.\\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\\n * over the EIP712-formatted function arguments.\\n * - the signature must use ``owner``'s current nonce (see {nonces}).\\n *\\n * For more information on the signature format, see the\\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\\n * section].\\n */\\n function permit(\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) external;\\n\\n /**\\n * @dev Returns the current nonce for `owner`. This value must be\\n * included whenever a signature is generated for {permit}.\\n *\\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\\n * prevents a signature from being used multiple times.\\n */\\n function nonces(address owner) external view returns (uint256);\\n\\n /**\\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xf41ca991f30855bf80ffd11e9347856a517b977f0a6c2d52e6421a99b7840329\",\"license\":\"MIT\"},\"contracts/infiniteProxy/interfaces/iProxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.21;\\n\\ninterface IProxy {\\n function setAdmin(address newAdmin_) external;\\n\\n function setDummyImplementation(address newDummyImplementation_) external;\\n\\n function addImplementation(address implementation_, bytes4[] calldata sigs_) external;\\n\\n function removeImplementation(address implementation_) external;\\n\\n function getAdmin() external view returns (address);\\n\\n function getDummyImplementation() external view returns (address);\\n\\n function getImplementationSigs(address impl_) external view returns (bytes4[] memory);\\n\\n function getSigsImplementation(bytes4 sig_) external view returns (address);\\n\\n function readFromStorage(bytes32 slot_) external view returns (uint256 result_);\\n}\\n\",\"keccak256\":\"0xbb605491d4bac08e816248feecae7dd17cfc1877c88b2e555abece2970f5ea00\",\"license\":\"MIT\"},\"contracts/libraries/bigMathMinified.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\npragma solidity 0.8.21;\\n\\n/// @title library that represents a number in BigNumber(coefficient and exponent) format to store in smaller bits.\\n/// @notice the number is divided into two parts: a coefficient and an exponent. This comes at a cost of losing some precision\\n/// at the end of the number because the exponent simply fills it with zeroes. This precision is oftentimes negligible and can\\n/// result in significant gas cost reduction due to storage space reduction.\\n/// Also note, a valid big number is as follows: if the exponent is > 0, then coefficient last bits should be occupied to have max precision.\\n/// @dev roundUp is more like a increase 1, which happens everytime for the same number.\\n/// roundDown simply sets trailing digits after coefficientSize to zero (floor), only once for the same number.\\nlibrary BigMathMinified {\\n /// @dev constants to use for `roundUp` input param to increase readability\\n bool internal constant ROUND_DOWN = false;\\n bool internal constant ROUND_UP = true;\\n\\n /// @dev converts `normal` number to BigNumber with `exponent` and `coefficient` (or precision).\\n /// e.g.:\\n /// 5035703444687813576399599 (normal) = (coefficient[32bits], exponent[8bits])[40bits]\\n /// 5035703444687813576399599 (decimal) => 10000101010010110100000011111011110010100110100000000011100101001101001101011101111 (binary)\\n /// => 10000101010010110100000011111011000000000000000000000000000000000000000000000000000\\n /// ^-------------------- 51(exponent) -------------- ^\\n /// coefficient = 1000,0101,0100,1011,0100,0000,1111,1011 (2236301563)\\n /// exponent = 0011,0011 (51)\\n /// bigNumber = 1000,0101,0100,1011,0100,0000,1111,1011,0011,0011 (572493200179)\\n ///\\n /// @param normal number which needs to be converted into Big Number\\n /// @param coefficientSize at max how many bits of precision there should be (64 = uint64 (64 bits precision))\\n /// @param exponentSize at max how many bits of exponent there should be (8 = uint8 (8 bits exponent))\\n /// @param roundUp signals if result should be rounded down or up\\n /// @return bigNumber converted bigNumber (coefficient << exponent)\\n function toBigNumber(\\n uint256 normal,\\n uint256 coefficientSize,\\n uint256 exponentSize,\\n bool roundUp\\n ) internal pure returns (uint256 bigNumber) {\\n assembly {\\n let lastBit_\\n let number_ := normal\\n if gt(number_, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) {\\n number_ := shr(0x80, number_)\\n lastBit_ := 0x80\\n }\\n if gt(number_, 0xFFFFFFFFFFFFFFFF) {\\n number_ := shr(0x40, number_)\\n lastBit_ := add(lastBit_, 0x40)\\n }\\n if gt(number_, 0xFFFFFFFF) {\\n number_ := shr(0x20, number_)\\n lastBit_ := add(lastBit_, 0x20)\\n }\\n if gt(number_, 0xFFFF) {\\n number_ := shr(0x10, number_)\\n lastBit_ := add(lastBit_, 0x10)\\n }\\n if gt(number_, 0xFF) {\\n number_ := shr(0x8, number_)\\n lastBit_ := add(lastBit_, 0x8)\\n }\\n if gt(number_, 0xF) {\\n number_ := shr(0x4, number_)\\n lastBit_ := add(lastBit_, 0x4)\\n }\\n if gt(number_, 0x3) {\\n number_ := shr(0x2, number_)\\n lastBit_ := add(lastBit_, 0x2)\\n }\\n if gt(number_, 0x1) {\\n lastBit_ := add(lastBit_, 1)\\n }\\n if gt(number_, 0) {\\n lastBit_ := add(lastBit_, 1)\\n }\\n if lt(lastBit_, coefficientSize) {\\n // for throw exception\\n lastBit_ := coefficientSize\\n }\\n let exponent := sub(lastBit_, coefficientSize)\\n let coefficient := shr(exponent, normal)\\n if and(roundUp, gt(exponent, 0)) {\\n // rounding up is only needed if exponent is > 0, as otherwise the coefficient fully holds the original number\\n coefficient := add(coefficient, 1)\\n if eq(shl(coefficientSize, 1), coefficient) {\\n // case were coefficient was e.g. 111, with adding 1 it became 1000 (in binary) and coefficientSize 3 bits\\n // final coefficient would exceed it's size. -> reduce coefficent to 100 and increase exponent by 1.\\n coefficient := shl(sub(coefficientSize, 1), 1)\\n exponent := add(exponent, 1)\\n }\\n }\\n if iszero(lt(exponent, shl(exponentSize, 1))) {\\n // if exponent is >= exponentSize, the normal number is too big to fit within\\n // BigNumber with too small sizes for coefficient and exponent\\n revert(0, 0)\\n }\\n bigNumber := shl(exponentSize, coefficient)\\n bigNumber := add(bigNumber, exponent)\\n }\\n }\\n\\n /// @dev get `normal` number from `bigNumber`, `exponentSize` and `exponentMask`\\n function fromBigNumber(\\n uint256 bigNumber,\\n uint256 exponentSize,\\n uint256 exponentMask\\n ) internal pure returns (uint256 normal) {\\n assembly {\\n let coefficient := shr(exponentSize, bigNumber)\\n let exponent := and(bigNumber, exponentMask)\\n normal := shl(exponent, coefficient)\\n }\\n }\\n\\n /// @dev gets the most significant bit `lastBit` of a `normal` number (length of given number of binary format).\\n /// e.g.\\n /// 5035703444687813576399599 = 10000101010010110100000011111011110010100110100000000011100101001101001101011101111\\n /// lastBit = ^--------------------------------- 83 ----------------------------------------^\\n function mostSignificantBit(uint256 normal) internal pure returns (uint lastBit) {\\n assembly {\\n let number_ := normal\\n if gt(normal, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) {\\n number_ := shr(0x80, number_)\\n lastBit := 0x80\\n }\\n if gt(number_, 0xFFFFFFFFFFFFFFFF) {\\n number_ := shr(0x40, number_)\\n lastBit := add(lastBit, 0x40)\\n }\\n if gt(number_, 0xFFFFFFFF) {\\n number_ := shr(0x20, number_)\\n lastBit := add(lastBit, 0x20)\\n }\\n if gt(number_, 0xFFFF) {\\n number_ := shr(0x10, number_)\\n lastBit := add(lastBit, 0x10)\\n }\\n if gt(number_, 0xFF) {\\n number_ := shr(0x8, number_)\\n lastBit := add(lastBit, 0x8)\\n }\\n if gt(number_, 0xF) {\\n number_ := shr(0x4, number_)\\n lastBit := add(lastBit, 0x4)\\n }\\n if gt(number_, 0x3) {\\n number_ := shr(0x2, number_)\\n lastBit := add(lastBit, 0x2)\\n }\\n if gt(number_, 0x1) {\\n lastBit := add(lastBit, 1)\\n }\\n if gt(number_, 0) {\\n lastBit := add(lastBit, 1)\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xf0be1002909edf30aec3dc6623c2bd2407ed94064b62674c01032b844dec206a\",\"license\":\"BUSL-1.1\"},\"contracts/libraries/errorTypes.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\npragma solidity 0.8.21;\\n\\nlibrary LibsErrorTypes {\\n /***********************************|\\n | LiquidityCalcs | \\n |__________________________________*/\\n\\n /// @notice thrown when supply or borrow exchange price is zero at calc token data (token not configured yet)\\n uint256 internal constant LiquidityCalcs__ExchangePriceZero = 70001;\\n\\n /// @notice thrown when rate data is set to a version that is not implemented\\n uint256 internal constant LiquidityCalcs__UnsupportedRateVersion = 70002;\\n\\n /// @notice thrown when the calculated borrow rate turns negative. This should never happen.\\n uint256 internal constant LiquidityCalcs__BorrowRateNegative = 70003;\\n\\n /***********************************|\\n | SafeTransfer | \\n |__________________________________*/\\n\\n /// @notice thrown when safe transfer from for an ERC20 fails\\n uint256 internal constant SafeTransfer__TransferFromFailed = 71001;\\n\\n /// @notice thrown when safe transfer for an ERC20 fails\\n uint256 internal constant SafeTransfer__TransferFailed = 71002;\\n}\\n\",\"keccak256\":\"0xaf7732f30d00dd38082d37aa37887be485fc94b0c76ff302aff615d03381674f\",\"license\":\"BUSL-1.1\"},\"contracts/libraries/liquidityCalcs.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\npragma solidity 0.8.21;\\n\\nimport { LibsErrorTypes as ErrorTypes } from \\\"./errorTypes.sol\\\";\\nimport { LiquiditySlotsLink } from \\\"./liquiditySlotsLink.sol\\\";\\nimport { BigMathMinified } from \\\"./bigMathMinified.sol\\\";\\n\\n/// @notice implements calculation methods used for Fluid liquidity such as updated exchange prices,\\n/// borrow rate, withdrawal / borrow limits, revenue amount.\\nlibrary LiquidityCalcs {\\n error FluidLiquidityCalcsError(uint256 errorId_);\\n\\n /// @notice emitted if the calculated borrow rate surpassed max borrow rate (16 bits) and was capped at maximum value 65535\\n event BorrowRateMaxCap();\\n\\n /// @dev constants as from Liquidity variables.sol\\n uint256 internal constant EXCHANGE_PRICES_PRECISION = 1e12;\\n\\n /// @dev Ignoring leap years\\n uint256 internal constant SECONDS_PER_YEAR = 365 days;\\n // constants used for BigMath conversion from and to storage\\n uint256 internal constant DEFAULT_EXPONENT_SIZE = 8;\\n uint256 internal constant DEFAULT_EXPONENT_MASK = 0xFF;\\n\\n uint256 internal constant FOUR_DECIMALS = 1e4;\\n uint256 internal constant TWELVE_DECIMALS = 1e12;\\n uint256 internal constant X14 = 0x3fff;\\n uint256 internal constant X15 = 0x7fff;\\n uint256 internal constant X16 = 0xffff;\\n uint256 internal constant X18 = 0x3ffff;\\n uint256 internal constant X24 = 0xffffff;\\n uint256 internal constant X33 = 0x1ffffffff;\\n uint256 internal constant X64 = 0xffffffffffffffff;\\n\\n ///////////////////////////////////////////////////////////////////////////\\n ////////// CALC EXCHANGE PRICES /////////\\n ///////////////////////////////////////////////////////////////////////////\\n\\n /// @dev calculates interest (exchange prices) for a token given its' exchangePricesAndConfig from storage.\\n /// @param exchangePricesAndConfig_ exchange prices and config packed uint256 read from storage\\n /// @return supplyExchangePrice_ updated supplyExchangePrice\\n /// @return borrowExchangePrice_ updated borrowExchangePrice\\n function calcExchangePrices(\\n uint256 exchangePricesAndConfig_\\n ) internal view returns (uint256 supplyExchangePrice_, uint256 borrowExchangePrice_) {\\n // Extracting exchange prices\\n supplyExchangePrice_ =\\n (exchangePricesAndConfig_ >> LiquiditySlotsLink.BITS_EXCHANGE_PRICES_SUPPLY_EXCHANGE_PRICE) &\\n X64;\\n borrowExchangePrice_ =\\n (exchangePricesAndConfig_ >> LiquiditySlotsLink.BITS_EXCHANGE_PRICES_BORROW_EXCHANGE_PRICE) &\\n X64;\\n\\n if (supplyExchangePrice_ == 0 || borrowExchangePrice_ == 0) {\\n revert FluidLiquidityCalcsError(ErrorTypes.LiquidityCalcs__ExchangePriceZero);\\n }\\n\\n uint256 temp_ = exchangePricesAndConfig_ & X16; // temp_ = borrowRate\\n\\n unchecked {\\n // last timestamp can not be > current timestamp\\n uint256 secondsSinceLastUpdate_ = block.timestamp -\\n ((exchangePricesAndConfig_ >> LiquiditySlotsLink.BITS_EXCHANGE_PRICES_LAST_TIMESTAMP) & X33);\\n\\n uint256 borrowRatio_ = (exchangePricesAndConfig_ >> LiquiditySlotsLink.BITS_EXCHANGE_PRICES_BORROW_RATIO) &\\n X15;\\n if (secondsSinceLastUpdate_ == 0 || temp_ == 0 || borrowRatio_ == 1) {\\n // if no time passed, borrow rate is 0, or no raw borrowings: no exchange price update needed\\n // (if borrowRatio_ == 1 means there is only borrowInterestFree, as first bit is 1 and rest is 0)\\n return (supplyExchangePrice_, borrowExchangePrice_);\\n }\\n\\n // calculate new borrow exchange price.\\n // formula borrowExchangePriceIncrease: previous price * borrow rate * secondsSinceLastUpdate_.\\n // nominator is max uint112 (uint64 * uint16 * uint32). Divisor can not be 0.\\n borrowExchangePrice_ +=\\n (borrowExchangePrice_ * temp_ * secondsSinceLastUpdate_) /\\n (SECONDS_PER_YEAR * FOUR_DECIMALS);\\n\\n // FOR SUPPLY EXCHANGE PRICE:\\n // all yield paid by borrowers (in mode with interest) goes to suppliers in mode with interest.\\n // formula: previous price * supply rate * secondsSinceLastUpdate_.\\n // where supply rate = (borrow rate - revenueFee%) * ratioSupplyYield. And\\n // ratioSupplyYield = utilization * supplyRatio * borrowRatio\\n //\\n // Example:\\n // supplyRawInterest is 80, supplyInterestFree is 20. totalSupply is 100. BorrowedRawInterest is 50.\\n // BorrowInterestFree is 10. TotalBorrow is 60. borrow rate 40%, revenueFee 10%.\\n // yield is 10 (so half a year must have passed).\\n // supplyRawInterest must become worth 89. totalSupply must become 109. BorrowedRawInterest must become 60.\\n // borrowInterestFree must still be 10. supplyInterestFree still 20. totalBorrow 70.\\n // supplyExchangePrice would have to go from 1 to 1,125 (+ 0.125). borrowExchangePrice from 1 to 1,2 (+0.2).\\n // utilization is 60%. supplyRatio = 20 / 80 = 25% (only 80% of lenders receiving yield).\\n // borrowRatio = 10 / 50 = 20% (only 83,333% of borrowers paying yield):\\n // x of borrowers paying yield = 100% - (20 / (100 + 20)) = 100% - 16.6666666% = 83,333%.\\n // ratioSupplyYield = 60% * 83,33333% * (100% + 20%) = 62,5%\\n // supplyRate = (40% * (100% - 10%)) * = 36% * 62,5% = 22.5%\\n // increase in supplyExchangePrice, assuming 100 as previous price.\\n // 100 * 22,5% * 1/2 (half a year) = 0,1125.\\n // cross-check supplyRawInterest worth = 80 * 1.1125 = 89. totalSupply worth = 89 + 20.\\n\\n // -------------- 1. calculate ratioSupplyYield --------------------------------\\n // step1: utilization * supplyRatio (or actually part of lenders receiving yield)\\n\\n // temp_ => supplyRatio (in 1e2: 100% = 10_000; 1% = 100 -> max value 16_383)\\n // if first bit 0 then ratio is supplyInterestFree / supplyWithInterest (supplyWithInterest is bigger)\\n // else ratio is supplyWithInterest / supplyInterestFree (supplyInterestFree is bigger)\\n temp_ = (exchangePricesAndConfig_ >> LiquiditySlotsLink.BITS_EXCHANGE_PRICES_SUPPLY_RATIO) & X15;\\n\\n if (temp_ == 1) {\\n // if no raw supply: no exchange price update needed\\n // (if supplyRatio_ == 1 means there is only supplyInterestFree, as first bit is 1 and rest is 0)\\n return (supplyExchangePrice_, borrowExchangePrice_);\\n }\\n\\n // ratioSupplyYield precision is 1e27 as 100% for increased precision when supplyInterestFree > supplyWithInterest\\n if (temp_ & 1 == 1) {\\n // ratio is supplyWithInterest / supplyInterestFree (supplyInterestFree is bigger)\\n temp_ = temp_ >> 1;\\n\\n // Note: case where temp_ == 0 (only supplyInterestFree, no yield) already covered by early return\\n // in the if statement a little above.\\n\\n // based on above example but supplyRawInterest is 20, supplyInterestFree is 80. no fee.\\n // supplyRawInterest must become worth 30. totalSupply must become 110.\\n // supplyExchangePrice would have to go from 1 to 1,5. borrowExchangePrice from 1 to 1,2.\\n // so ratioSupplyYield must come out as 2.5 (250%).\\n // supplyRatio would be (20 * 10_000 / 80) = 2500. but must be inverted.\\n temp_ = (1e27 * FOUR_DECIMALS) / temp_; // e.g. 1e31 / 2500 = 4e27. (* 1e27 for precision)\\n // e.g. 5_000 * (1e27 + 4e27) / 1e27 = 25_000 (=250%).\\n temp_ =\\n // utilization * (100% + 100% / supplyRatio)\\n (((exchangePricesAndConfig_ >> LiquiditySlotsLink.BITS_EXCHANGE_PRICES_UTILIZATION) & X14) *\\n (1e27 + temp_)) / // extract utilization (max 16_383 so there is no way this can overflow).\\n (FOUR_DECIMALS);\\n // max possible value of temp_ here is 16383 * (1e27 + 1e31) / 1e4 = ~1.64e31\\n } else {\\n // ratio is supplyInterestFree / supplyWithInterest (supplyWithInterest is bigger)\\n temp_ = temp_ >> 1;\\n // if temp_ == 0 then only supplyWithInterest => full yield. temp_ is already 0\\n\\n // e.g. 5_000 * 10_000 + (20 * 10_000 / 80) / 10_000 = 5000 * 12500 / 10000 = 6250 (=62.5%).\\n temp_ =\\n // 1e27 * utilization * (100% + supplyRatio) / 100%\\n (1e27 *\\n ((exchangePricesAndConfig_ >> LiquiditySlotsLink.BITS_EXCHANGE_PRICES_UTILIZATION) & X14) * // extract utilization (max 16_383 so there is no way this can overflow).\\n (FOUR_DECIMALS + temp_)) /\\n (FOUR_DECIMALS * FOUR_DECIMALS);\\n // max possible temp_ value: 1e27 * 16383 * 2e4 / 1e8 = 3.2766e27\\n }\\n // from here temp_ => ratioSupplyYield (utilization * supplyRatio part) scaled by 1e27. max possible value ~1.64e31\\n\\n // step2 of ratioSupplyYield: add borrowRatio (only x% of borrowers paying yield)\\n if (borrowRatio_ & 1 == 1) {\\n // ratio is borrowWithInterest / borrowInterestFree (borrowInterestFree is bigger)\\n borrowRatio_ = borrowRatio_ >> 1;\\n // borrowRatio_ => x of total bororwers paying yield. scale to 1e27.\\n\\n // Note: case where borrowRatio_ == 0 (only borrowInterestFree, no yield) already covered\\n // at the beginning of the method by early return if `borrowRatio_ == 1`.\\n\\n // based on above example but borrowRawInterest is 10, borrowInterestFree is 50. no fee. borrowRatio = 20%.\\n // so only 16.66% of borrowers are paying yield. so the 100% - part of the formula is not needed.\\n // x of borrowers paying yield = (borrowRatio / (100 + borrowRatio)) = 16.6666666%\\n // borrowRatio_ => x of total bororwers paying yield. scale to 1e27.\\n borrowRatio_ = (borrowRatio_ * 1e27) / (FOUR_DECIMALS + borrowRatio_);\\n // max value here for borrowRatio_ is (1e31 / (1e4 + 1e4))= 5e26 (= 50% of borrowers paying yield).\\n } else {\\n // ratio is borrowInterestFree / borrowWithInterest (borrowWithInterest is bigger)\\n borrowRatio_ = borrowRatio_ >> 1;\\n\\n // borrowRatio_ => x of total bororwers paying yield. scale to 1e27.\\n // x of borrowers paying yield = 100% - (borrowRatio / (100 + borrowRatio)) = 100% - 16.6666666% = 83,333%.\\n borrowRatio_ = (1e27 - ((borrowRatio_ * 1e27) / (FOUR_DECIMALS + borrowRatio_)));\\n // borrowRatio can never be > 100%. so max subtraction can be 100% - 100% / 200%.\\n // or if borrowRatio_ is 0 -> 100% - 0. or if borrowRatio_ is 1 -> 100% - 1 / 101.\\n // max value here for borrowRatio_ is 1e27 - 0 = 1e27 (= 100% of borrowers paying yield).\\n }\\n\\n // temp_ => ratioSupplyYield. scaled down from 1e25 = 1% each to normal percent precision 1e2 = 1%.\\n // max nominator value is ~1.64e31 * 1e27 = 1.64e58. max result = 1.64e8\\n temp_ = (FOUR_DECIMALS * temp_ * borrowRatio_) / 1e54;\\n\\n // 2. calculate supply rate\\n // temp_ => supply rate (borrow rate - revenueFee%) * ratioSupplyYield.\\n // division part is done in next step to increase precision. (divided by 2x FOUR_DECIMALS, fee + borrowRate)\\n // Note that all calculation divisions for supplyExchangePrice are rounded down.\\n // Note supply rate can be bigger than the borrowRate, e.g. if there are only few lenders with interest\\n // but more suppliers not earning interest.\\n temp_ = ((exchangePricesAndConfig_ & X16) * // borrow rate\\n temp_ * // ratioSupplyYield\\n (FOUR_DECIMALS - ((exchangePricesAndConfig_ >> LiquiditySlotsLink.BITS_EXCHANGE_PRICES_FEE) & X14))); // revenueFee\\n // fee can not be > 100%. max possible = 65535 * ~1.64e8 * 1e4 =~1.074774e17.\\n\\n // 3. calculate increase in supply exchange price\\n supplyExchangePrice_ += ((supplyExchangePrice_ * temp_ * secondsSinceLastUpdate_) /\\n (SECONDS_PER_YEAR * FOUR_DECIMALS * FOUR_DECIMALS * FOUR_DECIMALS));\\n // max possible nominator = max uint 64 * 1.074774e17 * max uint32 = ~8.52e45. Denominator can not be 0.\\n }\\n }\\n\\n ///////////////////////////////////////////////////////////////////////////\\n ////////// CALC REVENUE /////////\\n ///////////////////////////////////////////////////////////////////////////\\n\\n /// @dev gets the `revenueAmount_` for a token given its' totalAmounts and exchangePricesAndConfig from storage\\n /// and the current balance of the Fluid liquidity contract for the token.\\n /// @param totalAmounts_ total amounts packed uint256 read from storage\\n /// @param exchangePricesAndConfig_ exchange prices and config packed uint256 read from storage\\n /// @param liquidityTokenBalance_ current balance of Liquidity contract (IERC20(token_).balanceOf(address(this)))\\n /// @return revenueAmount_ collectable revenue amount\\n function calcRevenue(\\n uint256 totalAmounts_,\\n uint256 exchangePricesAndConfig_,\\n uint256 liquidityTokenBalance_\\n ) internal view returns (uint256 revenueAmount_) {\\n // @dev no need to super-optimize this method as it is only used by admin\\n\\n // calculate the new exchange prices based on earned interest\\n (uint256 supplyExchangePrice_, uint256 borrowExchangePrice_) = calcExchangePrices(exchangePricesAndConfig_);\\n\\n // total supply = interest free + with interest converted from raw\\n uint256 totalSupply_ = getTotalSupply(totalAmounts_, supplyExchangePrice_);\\n\\n if (totalSupply_ > 0) {\\n // available revenue: balanceOf(token) + totalBorrowings - totalLendings.\\n revenueAmount_ = liquidityTokenBalance_ + getTotalBorrow(totalAmounts_, borrowExchangePrice_);\\n // ensure there is no possible case because of rounding etc. where this would revert,\\n // explicitly check if >\\n revenueAmount_ = revenueAmount_ > totalSupply_ ? revenueAmount_ - totalSupply_ : 0;\\n // Note: if utilization > 100% (totalSupply < totalBorrow), then all the amount above 100% utilization\\n // can only be revenue.\\n } else {\\n // if supply is 0, then rest of balance can be withdrawn as revenue so that no amounts get stuck\\n revenueAmount_ = liquidityTokenBalance_;\\n }\\n }\\n\\n ///////////////////////////////////////////////////////////////////////////\\n ////////// CALC LIMITS /////////\\n ///////////////////////////////////////////////////////////////////////////\\n\\n /// @dev calculates withdrawal limit before an operate execution:\\n /// amount of user supply that must stay supplied (not amount that can be withdrawn).\\n /// i.e. if user has supplied 100m and can withdraw 5M, this method returns the 95M, not the withdrawable amount 5M\\n /// @param userSupplyData_ user supply data packed uint256 from storage\\n /// @param userSupply_ current user supply amount already extracted from `userSupplyData_` and converted from BigMath\\n /// @return currentWithdrawalLimit_ current withdrawal limit updated for expansion since last interaction.\\n /// returned value is in raw for with interest mode, normal amount for interest free mode!\\n function calcWithdrawalLimitBeforeOperate(\\n uint256 userSupplyData_,\\n uint256 userSupply_\\n ) internal view returns (uint256 currentWithdrawalLimit_) {\\n // @dev must support handling the case where timestamp is 0 (config is set but no interactions yet).\\n // first tx where timestamp is 0 will enter `if (lastWithdrawalLimit_ == 0)` because lastWithdrawalLimit_ is not set yet.\\n // returning max withdrawal allowed, which is not exactly right but doesn't matter because the first interaction must be\\n // a deposit anyway. Important is that it would not revert.\\n\\n // Note the first time a deposit brings the user supply amount to above the base withdrawal limit, the active limit\\n // is the fully expanded limit immediately.\\n\\n // extract last set withdrawal limit\\n uint256 lastWithdrawalLimit_ = (userSupplyData_ >>\\n LiquiditySlotsLink.BITS_USER_SUPPLY_PREVIOUS_WITHDRAWAL_LIMIT) & X64;\\n lastWithdrawalLimit_ =\\n (lastWithdrawalLimit_ >> DEFAULT_EXPONENT_SIZE) <<\\n (lastWithdrawalLimit_ & DEFAULT_EXPONENT_MASK);\\n if (lastWithdrawalLimit_ == 0) {\\n // withdrawal limit is not activated. Max withdrawal allowed\\n return 0;\\n }\\n\\n uint256 maxWithdrawableLimit_;\\n uint256 temp_;\\n unchecked {\\n // extract max withdrawable percent of user supply and\\n // calculate maximum withdrawable amount expandPercentage of user supply at full expansion duration elapsed\\n // e.g.: if 10% expandPercentage, meaning 10% is withdrawable after full expandDuration has elapsed.\\n\\n // userSupply_ needs to be atleast 1e73 to overflow max limit of ~1e77 in uint256 (no token in existence where this is possible).\\n maxWithdrawableLimit_ =\\n (((userSupplyData_ >> LiquiditySlotsLink.BITS_USER_SUPPLY_EXPAND_PERCENT) & X14) * userSupply_) /\\n FOUR_DECIMALS;\\n\\n // time elapsed since last withdrawal limit was set (in seconds)\\n // @dev last process timestamp is guaranteed to exist for withdrawal, as a supply must have happened before.\\n // last timestamp can not be > current timestamp\\n temp_ =\\n block.timestamp -\\n ((userSupplyData_ >> LiquiditySlotsLink.BITS_USER_SUPPLY_LAST_UPDATE_TIMESTAMP) & X33);\\n }\\n // calculate withdrawable amount of expandPercent that is elapsed of expandDuration.\\n // e.g. if 60% of expandDuration has elapsed, then user should be able to withdraw 6% of user supply, down to 94%.\\n // Note: no explicit check for this needed, it is covered by setting minWithdrawalLimit_ if needed.\\n temp_ =\\n (maxWithdrawableLimit_ * temp_) /\\n // extract expand duration: After this, decrement won't happen (user can withdraw 100% of withdraw limit)\\n ((userSupplyData_ >> LiquiditySlotsLink.BITS_USER_SUPPLY_EXPAND_DURATION) & X24); // expand duration can never be 0\\n // calculate expanded withdrawal limit: last withdrawal limit - withdrawable amount.\\n // Note: withdrawable amount here can grow bigger than userSupply if timeElapsed is a lot bigger than expandDuration,\\n // which would cause the subtraction `lastWithdrawalLimit_ - withdrawableAmount_` to revert. In that case, set 0\\n // which will cause minimum (fully expanded) withdrawal limit to be set in lines below.\\n unchecked {\\n // underflow explicitly checked & handled\\n currentWithdrawalLimit_ = lastWithdrawalLimit_ > temp_ ? lastWithdrawalLimit_ - temp_ : 0;\\n // calculate minimum withdrawal limit: minimum amount of user supply that must stay supplied at full expansion.\\n // subtraction can not underflow as maxWithdrawableLimit_ is a percentage amount (<=100%) of userSupply_\\n temp_ = userSupply_ - maxWithdrawableLimit_;\\n }\\n // if withdrawal limit is decreased below minimum then set minimum\\n // (e.g. when more than expandDuration time has elapsed)\\n if (temp_ > currentWithdrawalLimit_) {\\n currentWithdrawalLimit_ = temp_;\\n }\\n }\\n\\n /// @dev calculates withdrawal limit after an operate execution:\\n /// amount of user supply that must stay supplied (not amount that can be withdrawn).\\n /// i.e. if user has supplied 100m and can withdraw 5M, this method returns the 95M, not the withdrawable amount 5M\\n /// @param userSupplyData_ user supply data packed uint256 from storage\\n /// @param userSupply_ current user supply amount already extracted from `userSupplyData_` and added / subtracted with the executed operate amount\\n /// @param newWithdrawalLimit_ current withdrawal limit updated for expansion since last interaction, result from `calcWithdrawalLimitBeforeOperate`\\n /// @return withdrawalLimit_ updated withdrawal limit that should be written to storage. returned value is in\\n /// raw for with interest mode, normal amount for interest free mode!\\n function calcWithdrawalLimitAfterOperate(\\n uint256 userSupplyData_,\\n uint256 userSupply_,\\n uint256 newWithdrawalLimit_\\n ) internal pure returns (uint256) {\\n // temp_ => base withdrawal limit. below this, maximum withdrawals are allowed\\n uint256 temp_ = (userSupplyData_ >> LiquiditySlotsLink.BITS_USER_SUPPLY_BASE_WITHDRAWAL_LIMIT) & X18;\\n temp_ = (temp_ >> DEFAULT_EXPONENT_SIZE) << (temp_ & DEFAULT_EXPONENT_MASK);\\n\\n // if user supply is below base limit then max withdrawals are allowed\\n if (userSupply_ < temp_) {\\n return 0;\\n }\\n // temp_ => withdrawal limit expandPercent (is in 1e2 decimals)\\n temp_ = (userSupplyData_ >> LiquiditySlotsLink.BITS_USER_SUPPLY_EXPAND_PERCENT) & X14;\\n unchecked {\\n // temp_ => minimum withdrawal limit: userSupply - max withdrawable limit (userSupply * expandPercent))\\n // userSupply_ needs to be atleast 1e73 to overflow max limit of ~1e77 in uint256 (no token in existence where this is possible).\\n // subtraction can not underflow as maxWithdrawableLimit_ is a percentage amount (<=100%) of userSupply_\\n temp_ = userSupply_ - ((userSupply_ * temp_) / FOUR_DECIMALS);\\n }\\n // if new (before operation) withdrawal limit is less than minimum limit then set minimum limit.\\n // e.g. can happen on new deposits. withdrawal limit is instantly fully expanded in a scenario where\\n // increased deposit amount outpaces withrawals.\\n if (temp_ > newWithdrawalLimit_) {\\n return temp_;\\n }\\n return newWithdrawalLimit_;\\n }\\n\\n /// @dev calculates borrow limit before an operate execution:\\n /// total amount user borrow can reach (not borrowable amount in current operation).\\n /// i.e. if user has borrowed 50M and can still borrow 5M, this method returns the total 55M, not the borrowable amount 5M\\n /// @param userBorrowData_ user borrow data packed uint256 from storage\\n /// @param userBorrow_ current user borrow amount already extracted from `userBorrowData_`\\n /// @return currentBorrowLimit_ current borrow limit updated for expansion since last interaction. returned value is in\\n /// raw for with interest mode, normal amount for interest free mode!\\n function calcBorrowLimitBeforeOperate(\\n uint256 userBorrowData_,\\n uint256 userBorrow_\\n ) internal view returns (uint256 currentBorrowLimit_) {\\n // @dev must support handling the case where timestamp is 0 (config is set but no interactions yet) -> base limit.\\n // first tx where timestamp is 0 will enter `if (maxExpandedBorrowLimit_ < baseBorrowLimit_)` because `userBorrow_` and thus\\n // `maxExpansionLimit_` and thus `maxExpandedBorrowLimit_` is 0 and `baseBorrowLimit_` can not be 0.\\n\\n // temp_ = extract borrow expand percent (is in 1e2 decimals)\\n uint256 temp_ = (userBorrowData_ >> LiquiditySlotsLink.BITS_USER_BORROW_EXPAND_PERCENT) & X14;\\n\\n uint256 maxExpansionLimit_;\\n uint256 maxExpandedBorrowLimit_;\\n unchecked {\\n // calculate max expansion limit: Max amount limit can expand to since last interaction\\n // userBorrow_ needs to be atleast 1e73 to overflow max limit of ~1e77 in uint256 (no token in existence where this is possible).\\n maxExpansionLimit_ = ((userBorrow_ * temp_) / FOUR_DECIMALS);\\n\\n // calculate max borrow limit: Max point limit can increase to since last interaction\\n maxExpandedBorrowLimit_ = userBorrow_ + maxExpansionLimit_;\\n }\\n\\n // currentBorrowLimit_ = extract base borrow limit\\n currentBorrowLimit_ = (userBorrowData_ >> LiquiditySlotsLink.BITS_USER_BORROW_BASE_BORROW_LIMIT) & X18;\\n currentBorrowLimit_ =\\n (currentBorrowLimit_ >> DEFAULT_EXPONENT_SIZE) <<\\n (currentBorrowLimit_ & DEFAULT_EXPONENT_MASK);\\n\\n if (maxExpandedBorrowLimit_ < currentBorrowLimit_) {\\n return currentBorrowLimit_;\\n }\\n // time elapsed since last borrow limit was set (in seconds)\\n unchecked {\\n // temp_ = timeElapsed_ (last timestamp can not be > current timestamp)\\n temp_ =\\n block.timestamp -\\n ((userBorrowData_ >> LiquiditySlotsLink.BITS_USER_BORROW_LAST_UPDATE_TIMESTAMP) & X33); // extract last update timestamp\\n }\\n\\n // currentBorrowLimit_ = expandedBorrowableAmount + extract last set borrow limit\\n currentBorrowLimit_ =\\n // calculate borrow limit expansion since last interaction for `expandPercent` that is elapsed of `expandDuration`.\\n // divisor is extract expand duration (after this, full expansion to expandPercentage happened).\\n ((maxExpansionLimit_ * temp_) /\\n ((userBorrowData_ >> LiquiditySlotsLink.BITS_USER_BORROW_EXPAND_DURATION) & X24)) + // expand duration can never be 0\\n // extract last set borrow limit\\n BigMathMinified.fromBigNumber(\\n (userBorrowData_ >> LiquiditySlotsLink.BITS_USER_BORROW_PREVIOUS_BORROW_LIMIT) & X64,\\n DEFAULT_EXPONENT_SIZE,\\n DEFAULT_EXPONENT_MASK\\n );\\n\\n // if timeElapsed is bigger than expandDuration, new borrow limit would be > max expansion,\\n // so set to `maxExpandedBorrowLimit_` in that case.\\n // also covers the case where last process timestamp = 0 (timeElapsed would simply be very big)\\n if (currentBorrowLimit_ > maxExpandedBorrowLimit_) {\\n currentBorrowLimit_ = maxExpandedBorrowLimit_;\\n }\\n // temp_ = extract hard max borrow limit. Above this user can never borrow (not expandable above)\\n temp_ = (userBorrowData_ >> LiquiditySlotsLink.BITS_USER_BORROW_MAX_BORROW_LIMIT) & X18;\\n temp_ = (temp_ >> DEFAULT_EXPONENT_SIZE) << (temp_ & DEFAULT_EXPONENT_MASK);\\n\\n if (currentBorrowLimit_ > temp_) {\\n currentBorrowLimit_ = temp_;\\n }\\n }\\n\\n /// @dev calculates borrow limit after an operate execution:\\n /// total amount user borrow can reach (not borrowable amount in current operation).\\n /// i.e. if user has borrowed 50M and can still borrow 5M, this method returns the total 55M, not the borrowable amount 5M\\n /// @param userBorrowData_ user borrow data packed uint256 from storage\\n /// @param userBorrow_ current user borrow amount already extracted from `userBorrowData_` and added / subtracted with the executed operate amount\\n /// @param newBorrowLimit_ current borrow limit updated for expansion since last interaction, result from `calcBorrowLimitBeforeOperate`\\n /// @return borrowLimit_ updated borrow limit that should be written to storage.\\n /// returned value is in raw for with interest mode, normal amount for interest free mode!\\n function calcBorrowLimitAfterOperate(\\n uint256 userBorrowData_,\\n uint256 userBorrow_,\\n uint256 newBorrowLimit_\\n ) internal pure returns (uint256 borrowLimit_) {\\n // temp_ = extract borrow expand percent\\n uint256 temp_ = (userBorrowData_ >> LiquiditySlotsLink.BITS_USER_BORROW_EXPAND_PERCENT) & X14; // (is in 1e2 decimals)\\n\\n unchecked {\\n // borrowLimit_ = calculate maximum borrow limit at full expansion.\\n // userBorrow_ needs to be at least 1e73 to overflow max limit of ~1e77 in uint256 (no token in existence where this is possible).\\n borrowLimit_ = userBorrow_ + ((userBorrow_ * temp_) / FOUR_DECIMALS);\\n }\\n\\n // temp_ = extract base borrow limit\\n temp_ = (userBorrowData_ >> LiquiditySlotsLink.BITS_USER_BORROW_BASE_BORROW_LIMIT) & X18;\\n temp_ = (temp_ >> DEFAULT_EXPONENT_SIZE) << (temp_ & DEFAULT_EXPONENT_MASK);\\n\\n if (borrowLimit_ < temp_) {\\n // below base limit, borrow limit is always base limit\\n return temp_;\\n }\\n // temp_ = extract hard max borrow limit. Above this user can never borrow (not expandable above)\\n temp_ = (userBorrowData_ >> LiquiditySlotsLink.BITS_USER_BORROW_MAX_BORROW_LIMIT) & X18;\\n temp_ = (temp_ >> DEFAULT_EXPONENT_SIZE) << (temp_ & DEFAULT_EXPONENT_MASK);\\n\\n // make sure fully expanded borrow limit is not above hard max borrow limit\\n if (borrowLimit_ > temp_) {\\n borrowLimit_ = temp_;\\n }\\n // if new borrow limit (from before operate) is > max borrow limit, set max borrow limit.\\n // (e.g. on a repay shrinking instantly to fully expanded borrow limit from new borrow amount. shrinking is instant)\\n if (newBorrowLimit_ > borrowLimit_) {\\n return borrowLimit_;\\n }\\n return newBorrowLimit_;\\n }\\n\\n ///////////////////////////////////////////////////////////////////////////\\n ////////// CALC RATES /////////\\n ///////////////////////////////////////////////////////////////////////////\\n\\n /// @dev Calculates new borrow rate from utilization for a token\\n /// @param rateData_ rate data packed uint256 from storage for the token\\n /// @param utilization_ totalBorrow / totalSupply. 1e4 = 100% utilization\\n /// @return rate_ rate for that particular token in 1e2 precision (e.g. 5% rate = 500)\\n function calcBorrowRateFromUtilization(uint256 rateData_, uint256 utilization_) internal returns (uint256 rate_) {\\n // extract rate version: 4 bits (0xF) starting from bit 0\\n uint256 rateVersion_ = (rateData_ & 0xF);\\n\\n if (rateVersion_ == 1) {\\n rate_ = calcRateV1(rateData_, utilization_);\\n } else if (rateVersion_ == 2) {\\n rate_ = calcRateV2(rateData_, utilization_);\\n } else {\\n revert FluidLiquidityCalcsError(ErrorTypes.LiquidityCalcs__UnsupportedRateVersion);\\n }\\n\\n if (rate_ > X16) {\\n // hard cap for borrow rate at maximum value 16 bits (65535) to make sure it does not overflow storage space.\\n // this is unlikely to ever happen if configs stay within expected levels.\\n rate_ = X16;\\n // emit event to more easily become aware\\n emit BorrowRateMaxCap();\\n }\\n }\\n\\n /// @dev calculates the borrow rate based on utilization for rate data version 1 (with one kink) in 1e2 precision\\n /// @param rateData_ rate data packed uint256 from storage for the token\\n /// @param utilization_ in 1e2 (100% = 1e4)\\n /// @return rate_ rate in 1e2 precision\\n function calcRateV1(uint256 rateData_, uint256 utilization_) internal pure returns (uint256 rate_) {\\n /// For rate v1 (one kink) ------------------------------------------------------\\n /// Next 16 bits => 4 - 19 => Rate at utilization 0% (in 1e2: 100% = 10_000; 1% = 100 -> max value 65535)\\n /// Next 16 bits => 20- 35 => Utilization at kink1 (in 1e2: 100% = 10_000; 1% = 100 -> max value 65535)\\n /// Next 16 bits => 36- 51 => Rate at utilization kink1 (in 1e2: 100% = 10_000; 1% = 100 -> max value 65535)\\n /// Next 16 bits => 52- 67 => Rate at utilization 100% (in 1e2: 100% = 10_000; 1% = 100 -> max value 65535)\\n /// Last 188 bits => 68-255 => blank, might come in use in future\\n\\n // y = mx + c.\\n // y is borrow rate\\n // x is utilization\\n // m = slope (m can also be negative for declining rates)\\n // c is constant (c can be negative)\\n\\n uint256 y1_;\\n uint256 y2_;\\n uint256 x1_;\\n uint256 x2_;\\n\\n // extract kink1: 16 bits (0xFFFF) starting from bit 20\\n // kink is in 1e2, same as utilization, so no conversion needed for direct comparison of the two\\n uint256 kink1_ = (rateData_ >> LiquiditySlotsLink.BITS_RATE_DATA_V1_UTILIZATION_AT_KINK) & X16;\\n if (utilization_ < kink1_) {\\n // if utilization is less than kink\\n y1_ = (rateData_ >> LiquiditySlotsLink.BITS_RATE_DATA_V1_RATE_AT_UTILIZATION_ZERO) & X16;\\n y2_ = (rateData_ >> LiquiditySlotsLink.BITS_RATE_DATA_V1_RATE_AT_UTILIZATION_KINK) & X16;\\n x1_ = 0; // 0%\\n x2_ = kink1_;\\n } else {\\n // else utilization is greater than kink\\n y1_ = (rateData_ >> LiquiditySlotsLink.BITS_RATE_DATA_V1_RATE_AT_UTILIZATION_KINK) & X16;\\n y2_ = (rateData_ >> LiquiditySlotsLink.BITS_RATE_DATA_V1_RATE_AT_UTILIZATION_MAX) & X16;\\n x1_ = kink1_;\\n x2_ = FOUR_DECIMALS; // 100%\\n }\\n\\n int256 constant_;\\n int256 slope_;\\n unchecked {\\n // calculating slope with twelve decimal precision. m = (y2 - y1) / (x2 - x1).\\n // utilization of x2 can not be <= utilization of x1 (so no underflow or 0 divisor)\\n // y is in 1e2 so can not overflow when multiplied with TWELVE_DECIMALS\\n slope_ = (int256(y2_ - y1_) * int256(TWELVE_DECIMALS)) / int256((x2_ - x1_));\\n\\n // calculating constant at 12 decimal precision. slope is already in 12 decimal hence only multiple with y1. c = y - mx.\\n // maximum y1_ value is 65535. 65535 * 1e12 can not overflow int256\\n // maximum slope is 65535 - 0 * TWELVE_DECIMALS / 1 = 65535 * 1e12;\\n // maximum x1_ is 100% (9_999 actually) => slope_ * x1_ can not overflow int256\\n // subtraction most extreme case would be 0 - max value slope_ * x1_ => can not underflow int256\\n constant_ = int256(y1_ * TWELVE_DECIMALS) - (slope_ * int256(x1_));\\n\\n // calculating new borrow rate\\n // - slope_ max value is 65535 * 1e12,\\n // - utilization max value is let's say 500% (extreme case where borrow rate increases borrow amount without new supply)\\n // - constant max value is 65535 * 1e12\\n // so max values are 65535 * 1e12 * 50_000 + 65535 * 1e12 -> 3.2768*10^21, which easily fits int256\\n // divisor TWELVE_DECIMALS can not be 0\\n slope_ = (slope_ * int256(utilization_)) + constant_; // reusing `slope_` as variable for gas savings\\n if (slope_ < 0) {\\n revert FluidLiquidityCalcsError(ErrorTypes.LiquidityCalcs__BorrowRateNegative);\\n }\\n rate_ = uint256(slope_) / TWELVE_DECIMALS;\\n }\\n }\\n\\n /// @dev calculates the borrow rate based on utilization for rate data version 2 (with two kinks) in 1e4 precision\\n /// @param rateData_ rate data packed uint256 from storage for the token\\n /// @param utilization_ in 1e2 (100% = 1e4)\\n /// @return rate_ rate in 1e4 precision\\n function calcRateV2(uint256 rateData_, uint256 utilization_) internal pure returns (uint256 rate_) {\\n /// For rate v2 (two kinks) -----------------------------------------------------\\n /// Next 16 bits => 4 - 19 => Rate at utilization 0% (in 1e2: 100% = 10_000; 1% = 100 -> max value 65535)\\n /// Next 16 bits => 20- 35 => Utilization at kink1 (in 1e2: 100% = 10_000; 1% = 100 -> max value 65535)\\n /// Next 16 bits => 36- 51 => Rate at utilization kink1 (in 1e2: 100% = 10_000; 1% = 100 -> max value 65535)\\n /// Next 16 bits => 52- 67 => Utilization at kink2 (in 1e2: 100% = 10_000; 1% = 100 -> max value 65535)\\n /// Next 16 bits => 68- 83 => Rate at utilization kink2 (in 1e2: 100% = 10_000; 1% = 100 -> max value 65535)\\n /// Next 16 bits => 84- 99 => Rate at utilization 100% (in 1e2: 100% = 10_000; 1% = 100 -> max value 65535)\\n /// Last 156 bits => 100-255 => blank, might come in use in future\\n\\n // y = mx + c.\\n // y is borrow rate\\n // x is utilization\\n // m = slope (m can also be negative for declining rates)\\n // c is constant (c can be negative)\\n\\n uint256 y1_;\\n uint256 y2_;\\n uint256 x1_;\\n uint256 x2_;\\n\\n // extract kink1: 16 bits (0xFFFF) starting from bit 20\\n // kink is in 1e2, same as utilization, so no conversion needed for direct comparison of the two\\n uint256 kink1_ = (rateData_ >> LiquiditySlotsLink.BITS_RATE_DATA_V2_UTILIZATION_AT_KINK1) & X16;\\n if (utilization_ < kink1_) {\\n // if utilization is less than kink1\\n y1_ = (rateData_ >> LiquiditySlotsLink.BITS_RATE_DATA_V2_RATE_AT_UTILIZATION_ZERO) & X16;\\n y2_ = (rateData_ >> LiquiditySlotsLink.BITS_RATE_DATA_V2_RATE_AT_UTILIZATION_KINK1) & X16;\\n x1_ = 0; // 0%\\n x2_ = kink1_;\\n } else {\\n // extract kink2: 16 bits (0xFFFF) starting from bit 52\\n uint256 kink2_ = (rateData_ >> LiquiditySlotsLink.BITS_RATE_DATA_V2_UTILIZATION_AT_KINK2) & X16;\\n if (utilization_ < kink2_) {\\n // if utilization is less than kink2\\n y1_ = (rateData_ >> LiquiditySlotsLink.BITS_RATE_DATA_V2_RATE_AT_UTILIZATION_KINK1) & X16;\\n y2_ = (rateData_ >> LiquiditySlotsLink.BITS_RATE_DATA_V2_RATE_AT_UTILIZATION_KINK2) & X16;\\n x1_ = kink1_;\\n x2_ = kink2_;\\n } else {\\n // else utilization is greater than kink2\\n y1_ = (rateData_ >> LiquiditySlotsLink.BITS_RATE_DATA_V2_RATE_AT_UTILIZATION_KINK2) & X16;\\n y2_ = (rateData_ >> LiquiditySlotsLink.BITS_RATE_DATA_V2_RATE_AT_UTILIZATION_MAX) & X16;\\n x1_ = kink2_;\\n x2_ = FOUR_DECIMALS;\\n }\\n }\\n\\n int256 constant_;\\n int256 slope_;\\n unchecked {\\n // calculating slope with twelve decimal precision. m = (y2 - y1) / (x2 - x1).\\n // utilization of x2 can not be <= utilization of x1 (so no underflow or 0 divisor)\\n // y is in 1e2 so can not overflow when multiplied with TWELVE_DECIMALS\\n slope_ = (int256(y2_ - y1_) * int256(TWELVE_DECIMALS)) / int256((x2_ - x1_));\\n\\n // calculating constant at 12 decimal precision. slope is already in 12 decimal hence only multiple with y1. c = y - mx.\\n // maximum y1_ value is 65535. 65535 * 1e12 can not overflow int256\\n // maximum slope is 65535 - 0 * TWELVE_DECIMALS / 1 = 65535 * 1e12;\\n // maximum x1_ is 100% (9_999 actually) => slope_ * x1_ can not overflow int256\\n // subtraction most extreme case would be 0 - max value slope_ * x1_ => can not underflow int256\\n constant_ = int256(y1_ * TWELVE_DECIMALS) - (slope_ * int256(x1_));\\n\\n // calculating new borrow rate\\n // - slope_ max value is 65535 * 1e12,\\n // - utilization max value is let's say 500% (extreme case where borrow rate increases borrow amount without new supply)\\n // - constant max value is 65535 * 1e12\\n // so max values are 65535 * 1e12 * 50_000 + 65535 * 1e12 -> 3.2768*10^21, which easily fits int256\\n // divisor TWELVE_DECIMALS can not be 0\\n slope_ = (slope_ * int256(utilization_)) + constant_; // reusing `slope_` as variable for gas savings\\n if (slope_ < 0) {\\n revert FluidLiquidityCalcsError(ErrorTypes.LiquidityCalcs__BorrowRateNegative);\\n }\\n rate_ = uint256(slope_) / TWELVE_DECIMALS;\\n }\\n }\\n\\n /// @dev reads the total supply out of Liquidity packed storage `totalAmounts_` for `supplyExchangePrice_`\\n function getTotalSupply(\\n uint256 totalAmounts_,\\n uint256 supplyExchangePrice_\\n ) internal pure returns (uint256 totalSupply_) {\\n // totalSupply_ => supplyInterestFree\\n totalSupply_ = (totalAmounts_ >> LiquiditySlotsLink.BITS_TOTAL_AMOUNTS_SUPPLY_INTEREST_FREE) & X64;\\n totalSupply_ = (totalSupply_ >> DEFAULT_EXPONENT_SIZE) << (totalSupply_ & DEFAULT_EXPONENT_MASK);\\n\\n uint256 totalSupplyRaw_ = totalAmounts_ & X64; // no shifting as supplyRaw is first 64 bits\\n totalSupplyRaw_ = (totalSupplyRaw_ >> DEFAULT_EXPONENT_SIZE) << (totalSupplyRaw_ & DEFAULT_EXPONENT_MASK);\\n\\n // totalSupply = supplyInterestFree + supplyRawInterest normalized from raw\\n totalSupply_ += ((totalSupplyRaw_ * supplyExchangePrice_) / EXCHANGE_PRICES_PRECISION);\\n }\\n\\n /// @dev reads the total borrow out of Liquidity packed storage `totalAmounts_` for `borrowExchangePrice_`\\n function getTotalBorrow(\\n uint256 totalAmounts_,\\n uint256 borrowExchangePrice_\\n ) internal pure returns (uint256 totalBorrow_) {\\n // totalBorrow_ => borrowInterestFree\\n // no & mask needed for borrow interest free as it occupies the last bits in the storage slot\\n totalBorrow_ = (totalAmounts_ >> LiquiditySlotsLink.BITS_TOTAL_AMOUNTS_BORROW_INTEREST_FREE);\\n totalBorrow_ = (totalBorrow_ >> DEFAULT_EXPONENT_SIZE) << (totalBorrow_ & DEFAULT_EXPONENT_MASK);\\n\\n uint256 totalBorrowRaw_ = (totalAmounts_ >> LiquiditySlotsLink.BITS_TOTAL_AMOUNTS_BORROW_WITH_INTEREST) & X64;\\n totalBorrowRaw_ = (totalBorrowRaw_ >> DEFAULT_EXPONENT_SIZE) << (totalBorrowRaw_ & DEFAULT_EXPONENT_MASK);\\n\\n // totalBorrow = borrowInterestFree + borrowRawInterest normalized from raw\\n totalBorrow_ += ((totalBorrowRaw_ * borrowExchangePrice_) / EXCHANGE_PRICES_PRECISION);\\n }\\n}\\n\",\"keccak256\":\"0xa65e2f84b2c33769ceb6b28fbd3221be29da2f8ac96e4d8b8cea91948d81a707\",\"license\":\"BUSL-1.1\"},\"contracts/libraries/liquiditySlotsLink.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\npragma solidity 0.8.21;\\n\\n/// @notice library that helps in reading / working with storage slot data of Fluid Liquidity.\\n/// @dev as all data for Fluid Liquidity is internal, any data must be fetched directly through manual\\n/// slot reading through this library or, if gas usage is less important, through the FluidLiquidityResolver.\\nlibrary LiquiditySlotsLink {\\n /// @dev storage slot for status at Liquidity\\n uint256 internal constant LIQUIDITY_STATUS_SLOT = 1;\\n /// @dev storage slot for auths mapping at Liquidity\\n uint256 internal constant LIQUIDITY_AUTHS_MAPPING_SLOT = 2;\\n /// @dev storage slot for guardians mapping at Liquidity\\n uint256 internal constant LIQUIDITY_GUARDIANS_MAPPING_SLOT = 3;\\n /// @dev storage slot for user class mapping at Liquidity\\n uint256 internal constant LIQUIDITY_USER_CLASS_MAPPING_SLOT = 4;\\n /// @dev storage slot for exchangePricesAndConfig mapping at Liquidity\\n uint256 internal constant LIQUIDITY_EXCHANGE_PRICES_MAPPING_SLOT = 5;\\n /// @dev storage slot for rateData mapping at Liquidity\\n uint256 internal constant LIQUIDITY_RATE_DATA_MAPPING_SLOT = 6;\\n /// @dev storage slot for totalAmounts mapping at Liquidity\\n uint256 internal constant LIQUIDITY_TOTAL_AMOUNTS_MAPPING_SLOT = 7;\\n /// @dev storage slot for user supply double mapping at Liquidity\\n uint256 internal constant LIQUIDITY_USER_SUPPLY_DOUBLE_MAPPING_SLOT = 8;\\n /// @dev storage slot for user borrow double mapping at Liquidity\\n uint256 internal constant LIQUIDITY_USER_BORROW_DOUBLE_MAPPING_SLOT = 9;\\n /// @dev storage slot for listed tokens array at Liquidity\\n uint256 internal constant LIQUIDITY_LISTED_TOKENS_ARRAY_SLOT = 10;\\n /// @dev storage slot for listed tokens array at Liquidity\\n uint256 internal constant LIQUIDITY_CONFIGS2_MAPPING_SLOT = 11;\\n\\n // --------------------------------\\n // @dev stacked uint256 storage slots bits position data for each:\\n\\n // ExchangePricesAndConfig\\n uint256 internal constant BITS_EXCHANGE_PRICES_BORROW_RATE = 0;\\n uint256 internal constant BITS_EXCHANGE_PRICES_FEE = 16;\\n uint256 internal constant BITS_EXCHANGE_PRICES_UTILIZATION = 30;\\n uint256 internal constant BITS_EXCHANGE_PRICES_UPDATE_THRESHOLD = 44;\\n uint256 internal constant BITS_EXCHANGE_PRICES_LAST_TIMESTAMP = 58;\\n uint256 internal constant BITS_EXCHANGE_PRICES_SUPPLY_EXCHANGE_PRICE = 91;\\n uint256 internal constant BITS_EXCHANGE_PRICES_BORROW_EXCHANGE_PRICE = 155;\\n uint256 internal constant BITS_EXCHANGE_PRICES_SUPPLY_RATIO = 219;\\n uint256 internal constant BITS_EXCHANGE_PRICES_BORROW_RATIO = 234;\\n uint256 internal constant BITS_EXCHANGE_PRICES_USES_CONFIGS2 = 249;\\n\\n // RateData:\\n uint256 internal constant BITS_RATE_DATA_VERSION = 0;\\n // RateData: V1\\n uint256 internal constant BITS_RATE_DATA_V1_RATE_AT_UTILIZATION_ZERO = 4;\\n uint256 internal constant BITS_RATE_DATA_V1_UTILIZATION_AT_KINK = 20;\\n uint256 internal constant BITS_RATE_DATA_V1_RATE_AT_UTILIZATION_KINK = 36;\\n uint256 internal constant BITS_RATE_DATA_V1_RATE_AT_UTILIZATION_MAX = 52;\\n // RateData: V2\\n uint256 internal constant BITS_RATE_DATA_V2_RATE_AT_UTILIZATION_ZERO = 4;\\n uint256 internal constant BITS_RATE_DATA_V2_UTILIZATION_AT_KINK1 = 20;\\n uint256 internal constant BITS_RATE_DATA_V2_RATE_AT_UTILIZATION_KINK1 = 36;\\n uint256 internal constant BITS_RATE_DATA_V2_UTILIZATION_AT_KINK2 = 52;\\n uint256 internal constant BITS_RATE_DATA_V2_RATE_AT_UTILIZATION_KINK2 = 68;\\n uint256 internal constant BITS_RATE_DATA_V2_RATE_AT_UTILIZATION_MAX = 84;\\n\\n // TotalAmounts\\n uint256 internal constant BITS_TOTAL_AMOUNTS_SUPPLY_WITH_INTEREST = 0;\\n uint256 internal constant BITS_TOTAL_AMOUNTS_SUPPLY_INTEREST_FREE = 64;\\n uint256 internal constant BITS_TOTAL_AMOUNTS_BORROW_WITH_INTEREST = 128;\\n uint256 internal constant BITS_TOTAL_AMOUNTS_BORROW_INTEREST_FREE = 192;\\n\\n // UserSupplyData\\n uint256 internal constant BITS_USER_SUPPLY_MODE = 0;\\n uint256 internal constant BITS_USER_SUPPLY_AMOUNT = 1;\\n uint256 internal constant BITS_USER_SUPPLY_PREVIOUS_WITHDRAWAL_LIMIT = 65;\\n uint256 internal constant BITS_USER_SUPPLY_LAST_UPDATE_TIMESTAMP = 129;\\n uint256 internal constant BITS_USER_SUPPLY_EXPAND_PERCENT = 162;\\n uint256 internal constant BITS_USER_SUPPLY_EXPAND_DURATION = 176;\\n uint256 internal constant BITS_USER_SUPPLY_BASE_WITHDRAWAL_LIMIT = 200;\\n uint256 internal constant BITS_USER_SUPPLY_IS_PAUSED = 255;\\n\\n // UserBorrowData\\n uint256 internal constant BITS_USER_BORROW_MODE = 0;\\n uint256 internal constant BITS_USER_BORROW_AMOUNT = 1;\\n uint256 internal constant BITS_USER_BORROW_PREVIOUS_BORROW_LIMIT = 65;\\n uint256 internal constant BITS_USER_BORROW_LAST_UPDATE_TIMESTAMP = 129;\\n uint256 internal constant BITS_USER_BORROW_EXPAND_PERCENT = 162;\\n uint256 internal constant BITS_USER_BORROW_EXPAND_DURATION = 176;\\n uint256 internal constant BITS_USER_BORROW_BASE_BORROW_LIMIT = 200;\\n uint256 internal constant BITS_USER_BORROW_MAX_BORROW_LIMIT = 218;\\n uint256 internal constant BITS_USER_BORROW_IS_PAUSED = 255;\\n\\n // Configs2\\n uint256 internal constant BITS_CONFIGS2_MAX_UTILIZATION = 0;\\n\\n // --------------------------------\\n\\n /// @notice Calculating the slot ID for Liquidity contract for single mapping at `slot_` for `key_`\\n function calculateMappingStorageSlot(uint256 slot_, address key_) internal pure returns (bytes32) {\\n return keccak256(abi.encode(key_, slot_));\\n }\\n\\n /// @notice Calculating the slot ID for Liquidity contract for double mapping at `slot_` for `key1_` and `key2_`\\n function calculateDoubleMappingStorageSlot(\\n uint256 slot_,\\n address key1_,\\n address key2_\\n ) internal pure returns (bytes32) {\\n bytes32 intermediateSlot_ = keccak256(abi.encode(key1_, slot_));\\n return keccak256(abi.encode(key2_, intermediateSlot_));\\n }\\n}\\n\",\"keccak256\":\"0x0ae3e1d231bb6c14b54fc1f5ffa306edc0ac827a6a92279c77c0c09627fe08ae\",\"license\":\"BUSL-1.1\"},\"contracts/liquidity/adminModule/structs.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\npragma solidity 0.8.21;\\n\\nabstract contract Structs {\\n struct AddressBool {\\n address addr;\\n bool value;\\n }\\n\\n struct AddressUint256 {\\n address addr;\\n uint256 value;\\n }\\n\\n /// @notice struct to set borrow rate data for version 1\\n struct RateDataV1Params {\\n ///\\n /// @param token for rate data\\n address token;\\n ///\\n /// @param kink in borrow rate. in 1e2: 100% = 10_000; 1% = 100\\n /// utilization below kink usually means slow increase in rate, once utilization is above kink borrow rate increases fast\\n uint256 kink;\\n ///\\n /// @param rateAtUtilizationZero desired borrow rate when utilization is zero. in 1e2: 100% = 10_000; 1% = 100\\n /// i.e. constant minimum borrow rate\\n /// e.g. at utilization = 0.01% rate could still be at least 4% (rateAtUtilizationZero would be 400 then)\\n uint256 rateAtUtilizationZero;\\n ///\\n /// @param rateAtUtilizationKink borrow rate when utilization is at kink. in 1e2: 100% = 10_000; 1% = 100\\n /// e.g. when rate should be 7% at kink then rateAtUtilizationKink would be 700\\n uint256 rateAtUtilizationKink;\\n ///\\n /// @param rateAtUtilizationMax borrow rate when utilization is maximum at 100%. in 1e2: 100% = 10_000; 1% = 100\\n /// e.g. when rate should be 125% at 100% then rateAtUtilizationMax would be 12_500\\n uint256 rateAtUtilizationMax;\\n }\\n\\n /// @notice struct to set borrow rate data for version 2\\n struct RateDataV2Params {\\n ///\\n /// @param token for rate data\\n address token;\\n ///\\n /// @param kink1 first kink in borrow rate. in 1e2: 100% = 10_000; 1% = 100\\n /// utilization below kink 1 usually means slow increase in rate, once utilization is above kink 1 borrow rate increases faster\\n uint256 kink1;\\n ///\\n /// @param kink2 second kink in borrow rate. in 1e2: 100% = 10_000; 1% = 100\\n /// utilization below kink 2 usually means slow / medium increase in rate, once utilization is above kink 2 borrow rate increases fast\\n uint256 kink2;\\n ///\\n /// @param rateAtUtilizationZero desired borrow rate when utilization is zero. in 1e2: 100% = 10_000; 1% = 100\\n /// i.e. constant minimum borrow rate\\n /// e.g. at utilization = 0.01% rate could still be at least 4% (rateAtUtilizationZero would be 400 then)\\n uint256 rateAtUtilizationZero;\\n ///\\n /// @param rateAtUtilizationKink1 desired borrow rate when utilization is at first kink. in 1e2: 100% = 10_000; 1% = 100\\n /// e.g. when rate should be 7% at first kink then rateAtUtilizationKink would be 700\\n uint256 rateAtUtilizationKink1;\\n ///\\n /// @param rateAtUtilizationKink2 desired borrow rate when utilization is at second kink. in 1e2: 100% = 10_000; 1% = 100\\n /// e.g. when rate should be 7% at second kink then rateAtUtilizationKink would be 1_200\\n uint256 rateAtUtilizationKink2;\\n ///\\n /// @param rateAtUtilizationMax desired borrow rate when utilization is maximum at 100%. in 1e2: 100% = 10_000; 1% = 100\\n /// e.g. when rate should be 125% at 100% then rateAtUtilizationMax would be 12_500\\n uint256 rateAtUtilizationMax;\\n }\\n\\n /// @notice struct to set token config\\n struct TokenConfig {\\n ///\\n /// @param token address\\n address token;\\n ///\\n /// @param fee charges on borrower's interest. in 1e2: 100% = 10_000; 1% = 100\\n uint256 fee;\\n ///\\n /// @param threshold on when to update the storage slot. in 1e2: 100% = 10_000; 1% = 100\\n uint256 threshold;\\n ///\\n /// @param maxUtilization maximum allowed utilization. in 1e2: 100% = 10_000; 1% = 100\\n /// set to 100% to disable and have default limit of 100% (avoiding SLOAD).\\n uint256 maxUtilization;\\n }\\n\\n /// @notice struct to set user supply & withdrawal config\\n struct UserSupplyConfig {\\n ///\\n /// @param user address\\n address user;\\n ///\\n /// @param token address\\n address token;\\n ///\\n /// @param mode: 0 = without interest. 1 = with interest\\n uint8 mode;\\n ///\\n /// @param expandPercent withdrawal limit expand percent. in 1e2: 100% = 10_000; 1% = 100\\n /// Also used to calculate rate at which withdrawal limit should decrease (instant).\\n uint256 expandPercent;\\n ///\\n /// @param expandDuration withdrawal limit expand duration in seconds.\\n /// used to calculate rate together with expandPercent\\n uint256 expandDuration;\\n ///\\n /// @param baseWithdrawalLimit base limit, below this, user can withdraw the entire amount.\\n /// amount in raw (to be multiplied with exchange price) or normal depends on configured mode in user config for the token:\\n /// with interest -> raw, without interest -> normal\\n uint256 baseWithdrawalLimit;\\n }\\n\\n /// @notice struct to set user borrow & payback config\\n struct UserBorrowConfig {\\n ///\\n /// @param user address\\n address user;\\n ///\\n /// @param token address\\n address token;\\n ///\\n /// @param mode: 0 = without interest. 1 = with interest\\n uint8 mode;\\n ///\\n /// @param expandPercent debt limit expand percent. in 1e2: 100% = 10_000; 1% = 100\\n /// Also used to calculate rate at which debt limit should decrease (instant).\\n uint256 expandPercent;\\n ///\\n /// @param expandDuration debt limit expand duration in seconds.\\n /// used to calculate rate together with expandPercent\\n uint256 expandDuration;\\n ///\\n /// @param baseDebtCeiling base borrow limit. until here, borrow limit remains as baseDebtCeiling\\n /// (user can borrow until this point at once without stepped expansion). Above this, automated limit comes in place.\\n /// amount in raw (to be multiplied with exchange price) or normal depends on configured mode in user config for the token:\\n /// with interest -> raw, without interest -> normal\\n uint256 baseDebtCeiling;\\n ///\\n /// @param maxDebtCeiling max borrow ceiling, maximum amount the user can borrow.\\n /// amount in raw (to be multiplied with exchange price) or normal depends on configured mode in user config for the token:\\n /// with interest -> raw, without interest -> normal\\n uint256 maxDebtCeiling;\\n }\\n}\\n\",\"keccak256\":\"0x10353c70015f27b880125cefab806dbed24a4458f187da66964f3ef60488f757\",\"license\":\"BUSL-1.1\"},\"contracts/liquidity/interfaces/iLiquidity.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\npragma solidity 0.8.21;\\n\\nimport { IProxy } from \\\"../../infiniteProxy/interfaces/iProxy.sol\\\";\\nimport { Structs as AdminModuleStructs } from \\\"../adminModule/structs.sol\\\";\\n\\ninterface IFluidLiquidityAdmin {\\n /// @notice adds/removes auths. Auths generally could be contracts which can have restricted actions defined on contract.\\n /// auths can be helpful in reducing governance overhead where it's not needed.\\n /// @param authsStatus_ array of structs setting allowed status for an address.\\n /// status true => add auth, false => remove auth\\n function updateAuths(AdminModuleStructs.AddressBool[] calldata authsStatus_) external;\\n\\n /// @notice adds/removes guardians. Only callable by Governance.\\n /// @param guardiansStatus_ array of structs setting allowed status for an address.\\n /// status true => add guardian, false => remove guardian\\n function updateGuardians(AdminModuleStructs.AddressBool[] calldata guardiansStatus_) external;\\n\\n /// @notice changes the revenue collector address (contract that is sent revenue). Only callable by Governance.\\n /// @param revenueCollector_ new revenue collector address\\n function updateRevenueCollector(address revenueCollector_) external;\\n\\n /// @notice changes current status, e.g. for pausing or unpausing all user operations. Only callable by Auths.\\n /// @param newStatus_ new status\\n /// status = 2 -> pause, status = 1 -> resume.\\n function changeStatus(uint256 newStatus_) external;\\n\\n /// @notice update tokens rate data version 1. Only callable by Auths.\\n /// @param tokensRateData_ array of RateDataV1Params with rate data to set for each token\\n function updateRateDataV1s(AdminModuleStructs.RateDataV1Params[] calldata tokensRateData_) external;\\n\\n /// @notice update tokens rate data version 2. Only callable by Auths.\\n /// @param tokensRateData_ array of RateDataV2Params with rate data to set for each token\\n function updateRateDataV2s(AdminModuleStructs.RateDataV2Params[] calldata tokensRateData_) external;\\n\\n /// @notice updates token configs: fee charge on borrowers interest & storage update utilization threshold.\\n /// Only callable by Auths.\\n /// @param tokenConfigs_ contains token address, fee & utilization threshold\\n function updateTokenConfigs(AdminModuleStructs.TokenConfig[] calldata tokenConfigs_) external;\\n\\n /// @notice updates user classes: 0 is for new protocols, 1 is for established protocols.\\n /// Only callable by Auths.\\n /// @param userClasses_ struct array of uint256 value to assign for each user address\\n function updateUserClasses(AdminModuleStructs.AddressUint256[] calldata userClasses_) external;\\n\\n /// @notice sets user supply configs per token basis. Eg: with interest or interest-free and automated limits.\\n /// Only callable by Auths.\\n /// @param userSupplyConfigs_ struct array containing user supply config, see `UserSupplyConfig` struct for more info\\n function updateUserSupplyConfigs(AdminModuleStructs.UserSupplyConfig[] memory userSupplyConfigs_) external;\\n\\n /// @notice setting user borrow configs per token basis. Eg: with interest or interest-free and automated limits.\\n /// Only callable by Auths.\\n /// @param userBorrowConfigs_ struct array containing user borrow config, see `UserBorrowConfig` struct for more info\\n function updateUserBorrowConfigs(AdminModuleStructs.UserBorrowConfig[] memory userBorrowConfigs_) external;\\n\\n /// @notice pause operations for a particular user in class 0 (class 1 users can't be paused by guardians).\\n /// Only callable by Guardians.\\n /// @param user_ address of user to pause operations for\\n /// @param supplyTokens_ token addresses to pause withdrawals for\\n /// @param borrowTokens_ token addresses to pause borrowings for\\n function pauseUser(address user_, address[] calldata supplyTokens_, address[] calldata borrowTokens_) external;\\n\\n /// @notice unpause operations for a particular user in class 0 (class 1 users can't be paused by guardians).\\n /// Only callable by Guardians.\\n /// @param user_ address of user to unpause operations for\\n /// @param supplyTokens_ token addresses to unpause withdrawals for\\n /// @param borrowTokens_ token addresses to unpause borrowings for\\n function unpauseUser(address user_, address[] calldata supplyTokens_, address[] calldata borrowTokens_) external;\\n\\n /// @notice collects revenue for tokens to configured revenueCollector address.\\n /// @param tokens_ array of tokens to collect revenue for\\n /// @dev Note that this can revert if token balance is < revenueAmount (utilization > 100%)\\n function collectRevenue(address[] calldata tokens_) external;\\n\\n /// @notice gets the current updated exchange prices for n tokens and updates all prices, rates related data in storage.\\n /// @param tokens_ tokens to update exchange prices for\\n /// @return supplyExchangePrices_ new supply rates of overall system for each token\\n /// @return borrowExchangePrices_ new borrow rates of overall system for each token\\n function updateExchangePrices(\\n address[] calldata tokens_\\n ) external returns (uint256[] memory supplyExchangePrices_, uint256[] memory borrowExchangePrices_);\\n}\\n\\ninterface IFluidLiquidityLogic is IFluidLiquidityAdmin {\\n /// @notice Single function which handles supply, withdraw, borrow & payback\\n /// @param token_ address of token (0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE for native)\\n /// @param supplyAmount_ if +ve then supply, if -ve then withdraw, if 0 then nothing\\n /// @param borrowAmount_ if +ve then borrow, if -ve then payback, if 0 then nothing\\n /// @param withdrawTo_ if withdrawal then to which address\\n /// @param borrowTo_ if borrow then to which address\\n /// @param callbackData_ callback data passed to `liquidityCallback` method of protocol\\n /// @return memVar3_ updated supplyExchangePrice\\n /// @return memVar4_ updated borrowExchangePrice\\n /// @dev to trigger skipping in / out transfers when in&out amounts balance themselves out (gas optimization):\\n /// - supply(+) == borrow(+), withdraw(-) == payback(-).\\n /// - `withdrawTo_` / `borrowTo_` must be msg.sender (protocol)\\n /// - `callbackData_` MUST be encoded so that \\\"from\\\" address is at last 20 bytes (if this optimization is desired),\\n /// also for native token operations where liquidityCallback is not triggered!\\n /// from address must come at last position if there is more data. I.e. encode like:\\n /// abi.encode(otherVar1, otherVar2, FROM_ADDRESS). Note dynamic types used with abi.encode come at the end\\n /// so if dynamic types are needed, you must use abi.encodePacked to ensure the from address is at the end.\\n function operate(\\n address token_,\\n int256 supplyAmount_,\\n int256 borrowAmount_,\\n address withdrawTo_,\\n address borrowTo_,\\n bytes calldata callbackData_\\n ) external payable returns (uint256 memVar3_, uint256 memVar4_);\\n}\\n\\ninterface IFluidLiquidity is IProxy, IFluidLiquidityLogic {}\\n\",\"keccak256\":\"0xc81ac0cfc8183ec57ec4e488b07a4f6d1ecd79787e0aaf0dcfdd0b9b7ac0fc84\",\"license\":\"MIT\"},\"contracts/periphery/resolvers/lending/iLendingResolver.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\npragma solidity 0.8.21;\\n\\nimport { IFluidLiquidity } from \\\"../../../liquidity/interfaces/iLiquidity.sol\\\";\\nimport { IAllowanceTransfer } from \\\"../../../protocols/lending/interfaces/permit2/iAllowanceTransfer.sol\\\";\\nimport { IFluidLendingFactory } from \\\"../../../protocols/lending/interfaces/iLendingFactory.sol\\\";\\nimport { IFluidLendingRewardsRateModel } from \\\"../../../protocols/lending/interfaces/iLendingRewardsRateModel.sol\\\";\\nimport { IFToken } from \\\"../../../protocols/lending/interfaces/iFToken.sol\\\";\\nimport { Structs } from \\\"./structs.sol\\\";\\nimport { IFluidLiquidityResolver } from \\\"../../../periphery/resolvers/liquidity/iLiquidityResolver.sol\\\";\\n\\ninterface IFluidLendingResolver {\\n /// @notice returns the lending factory address\\n function LENDING_FACTORY() external view returns (IFluidLendingFactory);\\n\\n /// @notice returns the liquidity resolver address\\n function LIQUIDITY_RESOLVER() external view returns (IFluidLiquidityResolver);\\n\\n /// @notice returns all fToken types at the `LENDING_FACTORY`\\n function getAllFTokenTypes() external view returns (string[] memory);\\n\\n /// @notice returns all created fTokens at the `LENDING_FACTORY`\\n function getAllFTokens() external view returns (address[] memory);\\n\\n /// @notice reads if a certain `auth_` address is an allowed auth or not. Owner is auth by default.\\n function isLendingFactoryAuth(address auth_) external view returns (bool);\\n\\n /// @notice reads if a certain `deployer_` address is an allowed deployer or not. Owner is deployer by default.\\n function isLendingFactoryDeployer(address deployer_) external view returns (bool);\\n\\n /// @notice computes deterministic token address for `asset_` for a lending protocol\\n /// @param asset_ address of the asset\\n /// @param fTokenType_ type of fToken:\\n /// - if underlying asset supports EIP-2612, the fToken should be type `EIP2612Deposits`\\n /// - otherwise it should use `Permit2Deposits`\\n /// - if it's the native token, it should use `NativeUnderlying`\\n /// - could be more types available, check `fTokenTypes()`\\n /// @return token_ detemrinistic address of the computed token\\n function computeFToken(address asset_, string calldata fTokenType_) external view returns (address);\\n\\n /// @notice gets all public details for a certain `fToken_`, such as\\n /// fToken type, name, symbol, decimals, underlying asset, total amounts, convertTo values, rewards.\\n /// Note it also returns whether the fToken supports deposits / mints via EIP-2612, but it is not a 100% guarantee!\\n /// To make sure, check for the underlying if it supports EIP-2612 manually.\\n /// @param fToken_ the fToken to get the details for\\n /// @return fTokenDetails_ retrieved FTokenDetails struct\\n function getFTokenDetails(IFToken fToken_) external view returns (Structs.FTokenDetails memory fTokenDetails_);\\n\\n /// @notice returns config, rewards and exchange prices data of an fToken.\\n /// @param fToken_ the fToken to get the data for\\n /// @return liquidity_ address of the Liquidity contract.\\n /// @return lendingFactory_ address of the Lending factory contract.\\n /// @return lendingRewardsRateModel_ address of the rewards rate model contract. changeable by LendingFactory auths.\\n /// @return permit2_ address of the Permit2 contract used for deposits / mint with signature\\n /// @return rebalancer_ address of the rebalancer allowed to execute `rebalance()`\\n /// @return rewardsActive_ true if rewards are currently active\\n /// @return liquidityBalance_ current Liquidity supply balance of `address(this)` for the underyling asset\\n /// @return liquidityExchangePrice_ (updated) exchange price for the underlying assset in the liquidity protocol (without rewards)\\n /// @return tokenExchangePrice_ (updated) exchange price between fToken and the underlying assset (with rewards)\\n function getFTokenInternalData(\\n IFToken fToken_\\n )\\n external\\n view\\n returns (\\n IFluidLiquidity liquidity_,\\n IFluidLendingFactory lendingFactory_,\\n IFluidLendingRewardsRateModel lendingRewardsRateModel_,\\n IAllowanceTransfer permit2_,\\n address rebalancer_,\\n bool rewardsActive_,\\n uint256 liquidityBalance_,\\n uint256 liquidityExchangePrice_,\\n uint256 tokenExchangePrice_\\n );\\n\\n /// @notice gets all public details for all itokens, such as\\n /// fToken type, name, symbol, decimals, underlying asset, total amounts, convertTo values, rewards\\n function getFTokensEntireData() external view returns (Structs.FTokenDetails[] memory);\\n\\n /// @notice gets all public details for all itokens, such as\\n /// fToken type, name, symbol, decimals, underlying asset, total amounts, convertTo values, rewards\\n /// and user position for each token\\n function getUserPositions(address user_) external view returns (Structs.FTokenDetailsUserPosition[] memory);\\n\\n /// @notice gets rewards related data: the `rewardsRateModel_` contract and the current `rewardsRate_` for the `fToken_`\\n function getFTokenRewards(\\n IFToken fToken_\\n ) external view returns (IFluidLendingRewardsRateModel rewardsRateModel_, uint256 rewardsRate_);\\n\\n /// @notice gets rewards rate model config constants\\n function getFTokenRewardsRateModelConfig(\\n IFToken fToken_\\n )\\n external\\n view\\n returns (\\n uint256 duration_,\\n uint256 startTime_,\\n uint256 endTime_,\\n uint256 startTvl_,\\n uint256 maxRate_,\\n uint256 rewardAmount_,\\n address initiator_\\n );\\n\\n /// @notice gets a `user_` position for an `fToken_`.\\n /// @return userPosition user position struct\\n function getUserPosition(\\n IFToken fToken_,\\n address user_\\n ) external view returns (Structs.UserPosition memory userPosition);\\n\\n /// @notice gets `fToken_` preview amounts for `assets_` or `shares_`.\\n /// @return previewDeposit_ preview for deposit of `assets_`\\n /// @return previewMint_ preview for mint of `shares_`\\n /// @return previewWithdraw_ preview for withdraw of `assets_`\\n /// @return previewRedeem_ preview for redeem of `shares_`\\n function getPreviews(\\n IFToken fToken_,\\n uint256 assets_,\\n uint256 shares_\\n )\\n external\\n view\\n returns (uint256 previewDeposit_, uint256 previewMint_, uint256 previewWithdraw_, uint256 previewRedeem_);\\n}\\n\",\"keccak256\":\"0xcc8dc67c18ab1c79c03e5ed71fbff23f9588b4e496ed09c10dd88d346a8e9174\",\"license\":\"MIT\"},\"contracts/periphery/resolvers/lending/main.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\npragma solidity 0.8.21;\\n\\nimport { IERC20Permit } from \\\"@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol\\\";\\nimport { IERC20 } from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\nimport { LiquidityCalcs } from \\\"../../../libraries/liquidityCalcs.sol\\\";\\nimport { IFluidLendingFactory } from \\\"../../../protocols/lending/interfaces/iLendingFactory.sol\\\";\\nimport { IFluidLendingRewardsRateModel } from \\\"../../../protocols/lending/interfaces/iLendingRewardsRateModel.sol\\\";\\nimport { IFluidLiquidity } from \\\"../../../liquidity/interfaces/iLiquidity.sol\\\";\\nimport { IAllowanceTransfer } from \\\"../../../protocols/lending/interfaces/permit2/iAllowanceTransfer.sol\\\";\\nimport { IFToken, IFTokenNativeUnderlying } from \\\"../../../protocols/lending/interfaces/iFToken.sol\\\";\\nimport { IFluidLiquidityResolver } from \\\"../../../periphery/resolvers/liquidity/iLiquidityResolver.sol\\\";\\nimport { Structs as LiquidityStructs } from \\\"../../../periphery/resolvers/liquidity/structs.sol\\\";\\nimport { IFluidLendingResolver } from \\\"./iLendingResolver.sol\\\";\\nimport { Structs } from \\\"./structs.sol\\\";\\n\\n/// @notice Fluid Lending protocol (fTokens) resolver\\n/// Implements various view-only methods to give easy access to Lending protocol data.\\ncontract FluidLendingResolver is IFluidLendingResolver, Structs {\\n /// @dev address that is mapped to the chain native token\\n address internal constant _NATIVE_TOKEN_ADDRESS = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;\\n\\n /// @inheritdoc IFluidLendingResolver\\n IFluidLendingFactory public immutable LENDING_FACTORY;\\n\\n /// @inheritdoc IFluidLendingResolver\\n IFluidLiquidityResolver public immutable LIQUIDITY_RESOLVER;\\n\\n /// @notice thrown if an input param address is zero\\n error FluidLendingResolver__AddressZero();\\n\\n /// @notice constructor sets the immutable `LENDING_FACTORY` and `LIQUIDITY_RESOLVER` address\\n constructor(IFluidLendingFactory lendingFactory_, IFluidLiquidityResolver liquidityResolver_) {\\n if (address(lendingFactory_) == address(0) || address(liquidityResolver_) == address(0)) {\\n revert FluidLendingResolver__AddressZero();\\n }\\n LENDING_FACTORY = lendingFactory_;\\n LIQUIDITY_RESOLVER = liquidityResolver_;\\n }\\n\\n /// @inheritdoc IFluidLendingResolver\\n function isLendingFactoryAuth(address auth_) external view returns (bool) {\\n return LENDING_FACTORY.isAuth(auth_);\\n }\\n\\n /// @inheritdoc IFluidLendingResolver\\n function isLendingFactoryDeployer(address deployer_) external view returns (bool) {\\n return LENDING_FACTORY.isDeployer(deployer_);\\n }\\n\\n /// @inheritdoc IFluidLendingResolver\\n function getAllFTokenTypes() public view returns (string[] memory) {\\n return LENDING_FACTORY.fTokenTypes();\\n }\\n\\n /// @inheritdoc IFluidLendingResolver\\n function getAllFTokens() public view returns (address[] memory) {\\n return LENDING_FACTORY.allTokens();\\n }\\n\\n /// @inheritdoc IFluidLendingResolver\\n function computeFToken(address asset_, string calldata fTokenType_) external view returns (address) {\\n return LENDING_FACTORY.computeToken(asset_, fTokenType_);\\n }\\n\\n /// @inheritdoc IFluidLendingResolver\\n function getFTokenDetails(IFToken fToken_) public view returns (FTokenDetails memory fTokenDetails_) {\\n address underlying_ = fToken_.asset();\\n\\n bool isNativeUnderlying_ = false;\\n try IFTokenNativeUnderlying(address(fToken_)).NATIVE_TOKEN_ADDRESS() {\\n // if NATIVE_TOKEN_ADDRESS is defined, fTokenType must be NativeUnderlying.\\n isNativeUnderlying_ = true;\\n } catch {}\\n\\n bool supportsEIP2612Deposits_ = false;\\n try IERC20Permit(underlying_).DOMAIN_SEPARATOR() {\\n // if DOMAIN_SEPARATOR is defined, we assume underlying supports EIP2612. Not a 100% guarantee\\n supportsEIP2612Deposits_ = true;\\n } catch {}\\n\\n (, uint256 rewardsRate_) = getFTokenRewards(fToken_);\\n (\\n LiquidityStructs.UserSupplyData memory userSupplyData_,\\n LiquidityStructs.OverallTokenData memory overallTokenData_\\n ) = LIQUIDITY_RESOLVER.getUserSupplyData(\\n address(fToken_),\\n isNativeUnderlying_ ? _NATIVE_TOKEN_ADDRESS : underlying_\\n );\\n\\n uint256 totalAssets_ = fToken_.totalAssets();\\n\\n fTokenDetails_ = FTokenDetails(\\n address(fToken_),\\n supportsEIP2612Deposits_,\\n isNativeUnderlying_,\\n fToken_.name(),\\n fToken_.symbol(),\\n fToken_.decimals(),\\n underlying_,\\n totalAssets_,\\n fToken_.totalSupply(),\\n fToken_.convertToShares(10 ** fToken_.decimals()), // example convertToShares for 10 ** decimals\\n fToken_.convertToAssets(10 ** fToken_.decimals()), // example convertToAssets for 10 ** decimals\\n rewardsRate_,\\n overallTokenData_.supplyRate,\\n int256(userSupplyData_.supply) - int256(totalAssets_), // rebalanceDifference\\n userSupplyData_\\n );\\n\\n return fTokenDetails_;\\n }\\n\\n /// @inheritdoc IFluidLendingResolver\\n function getFTokenInternalData(\\n IFToken fToken_\\n )\\n public\\n view\\n returns (\\n IFluidLiquidity liquidity_,\\n IFluidLendingFactory lendingFactory_,\\n IFluidLendingRewardsRateModel lendingRewardsRateModel_,\\n IAllowanceTransfer permit2_,\\n address rebalancer_,\\n bool rewardsActive_,\\n uint256 liquidityBalance_,\\n uint256 liquidityExchangePrice_,\\n uint256 tokenExchangePrice_\\n )\\n {\\n return fToken_.getData();\\n }\\n\\n /// @inheritdoc IFluidLendingResolver\\n function getFTokensEntireData() public view returns (FTokenDetails[] memory) {\\n address[] memory allTokens = getAllFTokens();\\n FTokenDetails[] memory fTokenDetailsArr_ = new FTokenDetails[](allTokens.length);\\n for (uint256 i = 0; i < allTokens.length; ) {\\n fTokenDetailsArr_[i] = getFTokenDetails(IFToken(allTokens[i]));\\n unchecked {\\n i++;\\n }\\n }\\n return fTokenDetailsArr_;\\n }\\n\\n /// @inheritdoc IFluidLendingResolver\\n function getUserPositions(address user_) external view returns (FTokenDetailsUserPosition[] memory) {\\n FTokenDetails[] memory fTokensEntireData_ = getFTokensEntireData();\\n FTokenDetailsUserPosition[] memory userPositionArr_ = new FTokenDetailsUserPosition[](\\n fTokensEntireData_.length\\n );\\n for (uint256 i = 0; i < fTokensEntireData_.length; ) {\\n userPositionArr_[i].fTokenDetails = fTokensEntireData_[i];\\n userPositionArr_[i].userPosition = getUserPosition(IFToken(fTokensEntireData_[i].tokenAddress), user_);\\n unchecked {\\n i++;\\n }\\n }\\n return userPositionArr_;\\n }\\n\\n /// @inheritdoc IFluidLendingResolver\\n function getFTokenRewards(\\n IFToken fToken_\\n ) public view returns (IFluidLendingRewardsRateModel rewardsRateModel_, uint256 rewardsRate_) {\\n bool rewardsActive_;\\n (, , rewardsRateModel_, , , rewardsActive_, , , ) = fToken_.getData();\\n\\n if (rewardsActive_ && address(rewardsRateModel_) != address(0)) {\\n (rewardsRate_, , ) = rewardsRateModel_.getRate(fToken_.totalAssets());\\n }\\n }\\n\\n /// @inheritdoc IFluidLendingResolver\\n function getFTokenRewardsRateModelConfig(\\n IFToken fToken_\\n )\\n public\\n view\\n returns (\\n uint256 duration_,\\n uint256 startTime_,\\n uint256 endTime_,\\n uint256 startTvl_,\\n uint256 maxRate_,\\n uint256 rewardAmount_,\\n address initiator_\\n )\\n {\\n IFluidLendingRewardsRateModel rewardsRateModel_;\\n (, , rewardsRateModel_, , , , , , ) = fToken_.getData();\\n\\n if (address(rewardsRateModel_) != address(0)) {\\n (duration_, startTime_, endTime_, startTvl_, maxRate_, rewardAmount_, initiator_) = rewardsRateModel_\\n .getConfig();\\n }\\n }\\n\\n /// @inheritdoc IFluidLendingResolver\\n function getUserPosition(IFToken fToken_, address user_) public view returns (UserPosition memory userPosition) {\\n IERC20 underlying_ = IERC20(fToken_.asset());\\n\\n userPosition.fTokenShares = fToken_.balanceOf(user_);\\n userPosition.underlyingAssets = fToken_.convertToAssets(userPosition.fTokenShares);\\n userPosition.underlyingBalance = underlying_.balanceOf(user_);\\n userPosition.allowance = underlying_.allowance(user_, address(fToken_));\\n }\\n\\n /// @inheritdoc IFluidLendingResolver\\n function getPreviews(\\n IFToken fToken_,\\n uint256 assets_,\\n uint256 shares_\\n )\\n public\\n view\\n returns (uint256 previewDeposit_, uint256 previewMint_, uint256 previewWithdraw_, uint256 previewRedeem_)\\n {\\n previewDeposit_ = fToken_.previewDeposit(assets_);\\n previewMint_ = fToken_.previewMint(shares_);\\n previewWithdraw_ = fToken_.previewWithdraw(assets_);\\n previewRedeem_ = fToken_.previewRedeem(shares_);\\n }\\n}\\n\",\"keccak256\":\"0xb8435cab88287fc9ee60c53d59324e51d50ab4973b6034a5a5172a283799ef2f\",\"license\":\"BUSL-1.1\"},\"contracts/periphery/resolvers/lending/structs.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\npragma solidity 0.8.21;\\n\\nimport { IFluidLendingFactory } from \\\"../../../protocols/lending/interfaces/iLendingFactory.sol\\\";\\nimport { Structs as FluidLiquidityResolverStructs } from \\\"../liquidity/structs.sol\\\";\\n\\nabstract contract Structs {\\n struct FTokenDetails {\\n address tokenAddress;\\n bool eip2612Deposits;\\n bool isNativeUnderlying;\\n string name;\\n string symbol;\\n uint256 decimals;\\n address asset;\\n uint256 totalAssets;\\n uint256 totalSupply;\\n uint256 convertToShares;\\n uint256 convertToAssets;\\n // additional yield from rewards, if active\\n uint256 rewardsRate;\\n // yield at Liquidity\\n uint256 supplyRate;\\n // difference between fToken assets & actual deposit at Liquidity. (supplyAtLiquidity - totalAssets).\\n // if negative, rewards must be funded to guarantee withdrawal is possible for all users. This happens\\n // by executing rebalance().\\n int256 rebalanceDifference;\\n // liquidity related data such as supply amount, limits, expansion etc.\\n FluidLiquidityResolverStructs.UserSupplyData liquidityUserSupplyData;\\n }\\n\\n struct UserPosition {\\n uint256 fTokenShares;\\n uint256 underlyingAssets;\\n uint256 underlyingBalance;\\n uint256 allowance;\\n }\\n\\n struct FTokenDetailsUserPosition {\\n FTokenDetails fTokenDetails;\\n UserPosition userPosition;\\n }\\n}\\n\",\"keccak256\":\"0x99e73e307429f60030c7aeef2ef737ba86c67fd46cb233cbae3dcc7eb53f17bb\",\"license\":\"BUSL-1.1\"},\"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 configs2 packed uint256 storage slot for `token_`.\\n function getConfigs2(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 general data for all `listedTokens()` such as rates, exchange prices, utilization, fee, total amounts etc.\\n function getAllOverallTokensData()\\n external\\n view\\n 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\":\"0x241d94b63793c9fb2111bb4ec04035e1fa14ee7e0551683ea05460baa6000189\",\"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 uint256 maxUtilization; // maximum allowed utilization\\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; // borrowable amount until any borrow limit (incl. max utilization limit)\\n uint256 borrowable; // actual currently borrowable amount (borrow limit - already borrowed) & considering balance, max utilization\\n uint256 borrowLimitUtilization; // borrow limit for `maxUtilization`\\n }\\n}\\n\",\"keccak256\":\"0xf8a59b6c7963d0bd43be07db0c594e278f97e6dfa498dee8436e3707dd9f574e\",\"license\":\"BUSL-1.1\"},\"contracts/protocols/lending/interfaces/iFToken.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\npragma solidity 0.8.21;\\n\\nimport { IERC4626 } from \\\"@openzeppelin/contracts/interfaces/IERC4626.sol\\\";\\n\\nimport { IAllowanceTransfer } from \\\"./permit2/iAllowanceTransfer.sol\\\";\\nimport { IFluidLendingRewardsRateModel } from \\\"./iLendingRewardsRateModel.sol\\\";\\nimport { IFluidLendingFactory } from \\\"./iLendingFactory.sol\\\";\\nimport { IFluidLiquidity } from \\\"../../../liquidity/interfaces/iLiquidity.sol\\\";\\n\\ninterface IFTokenAdmin {\\n /// @notice updates the rewards rate model contract.\\n /// Only callable by LendingFactory auths.\\n /// @param rewardsRateModel_ the new rewards rate model contract address.\\n /// can be set to address(0) to set no rewards (to save gas)\\n function updateRewards(IFluidLendingRewardsRateModel rewardsRateModel_) external;\\n\\n /// @notice Balances out the difference between fToken supply at Liquidity vs totalAssets().\\n /// Deposits underlying from rebalancer address into Liquidity but doesn't mint any shares\\n /// -> thus making deposit available as rewards.\\n /// Only callable by rebalancer.\\n /// @return assets_ amount deposited to Liquidity\\n function rebalance() external payable returns (uint256 assets_);\\n\\n /// @notice gets the liquidity exchange price of the underlying asset, calculates the updated exchange price (with reward rates)\\n /// and writes those values to storage.\\n /// Callable by anyone.\\n /// @return tokenExchangePrice_ exchange price of fToken share to underlying asset\\n /// @return liquidityExchangePrice_ exchange price at Liquidity for the underlying asset\\n function updateRates() external returns (uint256 tokenExchangePrice_, uint256 liquidityExchangePrice_);\\n\\n /// @notice sends any potentially stuck funds to Liquidity contract. Only callable by LendingFactory auths.\\n function rescueFunds(address token_) external;\\n\\n /// @notice Updates the rebalancer address (ReserveContract). Only callable by LendingFactory auths.\\n function updateRebalancer(address rebalancer_) external;\\n}\\n\\ninterface IFToken is IERC4626, IFTokenAdmin {\\n /// @notice returns minimum amount required for deposit (rounded up)\\n function minDeposit() external view returns (uint256);\\n\\n /// @notice returns config, rewards and exchange prices data in a single view method.\\n /// @return liquidity_ address of the Liquidity contract.\\n /// @return lendingFactory_ address of the Lending factory contract.\\n /// @return lendingRewardsRateModel_ address of the rewards rate model contract. changeable by LendingFactory auths.\\n /// @return permit2_ address of the Permit2 contract used for deposits / mint with signature\\n /// @return rebalancer_ address of the rebalancer allowed to execute `rebalance()`\\n /// @return rewardsActive_ true if rewards are currently active\\n /// @return liquidityBalance_ current Liquidity supply balance of `address(this)` for the underyling asset\\n /// @return liquidityExchangePrice_ (updated) exchange price for the underlying assset in the liquidity protocol (without rewards)\\n /// @return tokenExchangePrice_ (updated) exchange price between fToken and the underlying assset (with rewards)\\n function getData()\\n external\\n view\\n returns (\\n IFluidLiquidity liquidity_,\\n IFluidLendingFactory lendingFactory_,\\n IFluidLendingRewardsRateModel lendingRewardsRateModel_,\\n IAllowanceTransfer permit2_,\\n address rebalancer_,\\n bool rewardsActive_,\\n uint256 liquidityBalance_,\\n uint256 liquidityExchangePrice_,\\n uint256 tokenExchangePrice_\\n );\\n\\n /// @notice transfers `amount_` of `token_` to liquidity. Only callable by liquidity contract.\\n /// @dev this callback is used to optimize gas consumption (reducing necessary token transfers).\\n function liquidityCallback(address token_, uint256 amount_, bytes calldata data_) external;\\n\\n /// @notice deposit `assets_` amount with Permit2 signature for underlying asset approval.\\n /// reverts with `fToken__MinAmountOut()` if `minAmountOut_` of shares is not reached.\\n /// `assets_` must at least be `minDeposit()` amount; reverts otherwise.\\n /// @param assets_ amount of assets to deposit\\n /// @param receiver_ receiver of minted fToken shares\\n /// @param minAmountOut_ minimum accepted amount of shares minted\\n /// @param permit_ Permit2 permit message\\n /// @param signature_ packed signature of signing the EIP712 hash of `permit_`\\n /// @return shares_ amount of minted shares\\n function depositWithSignature(\\n uint256 assets_,\\n address receiver_,\\n uint256 minAmountOut_,\\n IAllowanceTransfer.PermitSingle calldata permit_,\\n bytes calldata signature_\\n ) external returns (uint256 shares_);\\n\\n /// @notice mint amount of `shares_` with Permit2 signature for underlying asset approval.\\n /// Signature should approve a little bit more than expected assets amount (`previewMint()`) to avoid reverts.\\n /// `shares_` must at least be `minMint()` amount; reverts otherwise.\\n /// Note there might be tiny inaccuracies between requested `shares_` and actually received shares amount.\\n /// Recommended to use `deposit()` over mint because it is more gas efficient and less likely to revert.\\n /// @param shares_ amount of shares to mint\\n /// @param receiver_ receiver of minted fToken shares\\n /// @param maxAssets_ maximum accepted amount of assets used as input to mint `shares_`\\n /// @param permit_ Permit2 permit message\\n /// @param signature_ packed signature of signing the EIP712 hash of `permit_`\\n /// @return assets_ deposited assets amount\\n function mintWithSignature(\\n uint256 shares_,\\n address receiver_,\\n uint256 maxAssets_,\\n IAllowanceTransfer.PermitSingle calldata permit_,\\n bytes calldata signature_\\n ) external returns (uint256 assets_);\\n}\\n\\ninterface IFTokenNativeUnderlying is IFToken {\\n /// @notice address that is mapped to the chain native token at Liquidity\\n function NATIVE_TOKEN_ADDRESS() external view returns (address);\\n\\n /// @notice deposits `msg.value` amount of native token for `receiver_`.\\n /// `msg.value` must be at least `minDeposit()` amount; reverts otherwise.\\n /// Recommended to use `depositNative()` with a `minAmountOut_` param instead to set acceptable limit.\\n /// @return shares_ actually minted shares\\n function depositNative(address receiver_) external payable returns (uint256 shares_);\\n\\n /// @notice same as {depositNative} but with an additional setting for minimum output amount.\\n /// reverts with `fToken__MinAmountOut()` if `minAmountOut_` of shares is not reached\\n function depositNative(address receiver_, uint256 minAmountOut_) external payable returns (uint256 shares_);\\n\\n /// @notice mints `shares_` for `receiver_`, paying with underlying native token.\\n /// `shares_` must at least be `minMint()` amount; reverts otherwise.\\n /// `shares_` set to type(uint256).max not supported.\\n /// Note there might be tiny inaccuracies between requested `shares_` and actually received shares amount.\\n /// Recommended to use `depositNative()` over mint because it is more gas efficient and less likely to revert.\\n /// Recommended to use `mintNative()` with a `minAmountOut_` param instead to set acceptable limit.\\n /// @return assets_ deposited assets amount\\n function mintNative(uint256 shares_, address receiver_) external payable returns (uint256 assets_);\\n\\n /// @notice same as {mintNative} but with an additional setting for minimum output amount.\\n /// reverts with `fToken__MaxAmount()` if `maxAssets_` of assets is surpassed to mint `shares_`.\\n function mintNative(\\n uint256 shares_,\\n address receiver_,\\n uint256 maxAssets_\\n ) external payable returns (uint256 assets_);\\n\\n /// @notice withdraws `assets_` amount in native underlying to `receiver_`, burning shares of `owner_`.\\n /// If `assets_` equals uint256.max then the whole fToken balance of `owner_` is withdrawn.This does not\\n /// consider withdrawal limit at liquidity so best to check with `maxWithdraw()` before.\\n /// Note there might be tiny inaccuracies between requested `assets_` and actually received assets amount.\\n /// Recommended to use `withdrawNative()` with a `maxSharesBurn_` param instead to set acceptable limit.\\n /// @return shares_ burned shares\\n function withdrawNative(uint256 assets_, address receiver_, address owner_) external returns (uint256 shares_);\\n\\n /// @notice same as {withdrawNative} but with an additional setting for minimum output amount.\\n /// reverts with `fToken__MaxAmount()` if `maxSharesBurn_` of shares burned is surpassed.\\n function withdrawNative(\\n uint256 assets_,\\n address receiver_,\\n address owner_,\\n uint256 maxSharesBurn_\\n ) external returns (uint256 shares_);\\n\\n /// @notice redeems `shares_` to native underlying to `receiver_`, burning shares of `owner_`.\\n /// If `shares_` equals uint256.max then the whole balance of `owner_` is withdrawn.This does not\\n /// consider withdrawal limit at liquidity so best to check with `maxRedeem()` before.\\n /// Recommended to use `withdrawNative()` over redeem because it is more gas efficient and can set specific amount.\\n /// Recommended to use `redeemNative()` with a `minAmountOut_` param instead to set acceptable limit.\\n /// @return assets_ withdrawn assets amount\\n function redeemNative(uint256 shares_, address receiver_, address owner_) external returns (uint256 assets_);\\n\\n /// @notice same as {redeemNative} but with an additional setting for minimum output amount.\\n /// reverts with `fToken__MinAmountOut()` if `minAmountOut_` of assets is not reached.\\n function redeemNative(\\n uint256 shares_,\\n address receiver_,\\n address owner_,\\n uint256 minAmountOut_\\n ) external returns (uint256 assets_);\\n\\n /// @notice withdraw amount of `assets_` in native token with ERC-2612 permit signature for fToken approval.\\n /// `owner_` signs ERC-2612 permit `signature_` to give allowance of fTokens to `msg.sender`.\\n /// Note there might be tiny inaccuracies between requested `assets_` and actually received assets amount.\\n /// allowance via signature should cover `previewWithdraw(assets_)` plus a little buffer to avoid revert.\\n /// Inherent trust assumption that `msg.sender` will set `receiver_` and `minAmountOut_` as `owner_` intends\\n /// (which is always the case when giving allowance to some spender).\\n /// @param sharesToPermit_ shares amount to use for EIP2612 permit(). Should cover `previewWithdraw(assets_)` + small buffer.\\n /// @param assets_ amount of assets to withdraw\\n /// @param receiver_ receiver of withdrawn assets\\n /// @param owner_ owner to withdraw from (must be signature signer)\\n /// @param maxSharesBurn_ maximum accepted amount of shares burned\\n /// @param deadline_ deadline for signature validity\\n /// @param signature_ packed signature of signing the EIP712 hash for ERC-2612 permit\\n /// @return shares_ burned shares amount\\n function withdrawWithSignatureNative(\\n uint256 sharesToPermit_,\\n uint256 assets_,\\n address receiver_,\\n address owner_,\\n uint256 maxSharesBurn_,\\n uint256 deadline_,\\n bytes calldata signature_\\n ) external returns (uint256 shares_);\\n\\n /// @notice redeem amount of `shares_` as native token with ERC-2612 permit signature for fToken approval.\\n /// `owner_` signs ERC-2612 permit `signature_` to give allowance of fTokens to `msg.sender`.\\n /// Note there might be tiny inaccuracies between requested `shares_` to redeem and actually burned shares.\\n /// allowance via signature must cover `shares_` plus a tiny buffer.\\n /// Inherent trust assumption that `msg.sender` will set `receiver_` and `minAmountOut_` as `owner_` intends\\n /// (which is always the case when giving allowance to some spender).\\n /// Recommended to use `withdrawNative()` over redeem because it is more gas efficient and can set specific amount.\\n /// @param shares_ amount of shares to redeem\\n /// @param receiver_ receiver of withdrawn assets\\n /// @param owner_ owner to withdraw from (must be signature signer)\\n /// @param minAmountOut_ minimum accepted amount of assets withdrawn\\n /// @param deadline_ deadline for signature validity\\n /// @param signature_ packed signature of signing the EIP712 hash for ERC-2612 permit\\n /// @return assets_ withdrawn assets amount\\n function redeemWithSignatureNative(\\n uint256 shares_,\\n address receiver_,\\n address owner_,\\n uint256 minAmountOut_,\\n uint256 deadline_,\\n bytes calldata signature_\\n ) external returns (uint256 assets_);\\n}\\n\",\"keccak256\":\"0xe3e26f6aa9bba6b8fd2d4f299e03843b237ab7a47e1a00249a1214abda02d064\",\"license\":\"MIT\"},\"contracts/protocols/lending/interfaces/iLendingFactory.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\npragma solidity 0.8.21;\\n\\nimport { IFluidLiquidity } from \\\"../../../liquidity/interfaces/iLiquidity.sol\\\";\\n\\ninterface IFluidLendingFactoryAdmin {\\n /// @notice reads if a certain `auth_` address is an allowed auth or not. Owner is auth by default.\\n function isAuth(address auth_) external view returns (bool);\\n\\n /// @notice Sets an address as allowed auth or not. Only callable by owner.\\n /// @param auth_ address to set auth value for\\n /// @param allowed_ bool flag for whether address is allowed as auth or not\\n function setAuth(address auth_, bool allowed_) external;\\n\\n /// @notice reads if a certain `deployer_` address is an allowed deployer or not. Owner is deployer by default.\\n function isDeployer(address deployer_) external view returns (bool);\\n\\n /// @notice Sets an address as allowed deployer or not. Only callable by owner.\\n /// @param deployer_ address to set deployer value for\\n /// @param allowed_ bool flag for whether address is allowed as deployer or not\\n function setDeployer(address deployer_, bool allowed_) external;\\n\\n /// @notice Sets the `creationCode_` bytecode for a certain `fTokenType_`. Only callable by auths.\\n /// @param fTokenType_ the fToken Type used to refer the creation code\\n /// @param creationCode_ contract creation code. can be set to bytes(0) to remove a previously available `fTokenType_`\\n function setFTokenCreationCode(string memory fTokenType_, bytes calldata creationCode_) external;\\n\\n /// @notice creates token for `asset_` for a lending protocol with interest. Only callable by deployers.\\n /// @param asset_ address of the asset\\n /// @param fTokenType_ type of fToken:\\n /// - if it's the native token, it should use `NativeUnderlying`\\n /// - otherwise it should use `fToken`\\n /// - could be more types available, check `fTokenTypes()`\\n /// @param isNativeUnderlying_ flag to signal fToken type that uses native underlying at Liquidity\\n /// @return token_ address of the created token\\n function createToken(\\n address asset_,\\n string calldata fTokenType_,\\n bool isNativeUnderlying_\\n ) external returns (address token_);\\n}\\n\\ninterface IFluidLendingFactory is IFluidLendingFactoryAdmin {\\n /// @notice list of all created tokens\\n function allTokens() external view returns (address[] memory);\\n\\n /// @notice list of all fToken types that can be deployed\\n function fTokenTypes() external view returns (string[] memory);\\n\\n /// @notice returns the creation code for a certain `fTokenType_`\\n function fTokenCreationCode(string memory fTokenType_) external view returns (bytes memory);\\n\\n /// @notice address of the Liquidity contract.\\n function LIQUIDITY() external view returns (IFluidLiquidity);\\n\\n /// @notice computes deterministic token address for `asset_` for a lending protocol\\n /// @param asset_ address of the asset\\n /// @param fTokenType_ type of fToken:\\n /// - if it's the native token, it should use `NativeUnderlying`\\n /// - otherwise it should use `fToken`\\n /// - could be more types available, check `fTokenTypes()`\\n /// @return token_ detemrinistic address of the computed token\\n function computeToken(address asset_, string calldata fTokenType_) external view returns (address token_);\\n}\\n\",\"keccak256\":\"0x90cc641714853b9ad77c2bf0653d8e558b670cbcc646dbce96d26f92842dbc66\",\"license\":\"MIT\"},\"contracts/protocols/lending/interfaces/iLendingRewardsRateModel.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\npragma solidity 0.8.21;\\n\\ninterface IFluidLendingRewardsRateModel {\\n /// @notice Calculates the current rewards rate (APR)\\n /// @param totalAssets_ amount of assets in the lending\\n /// @return rate_ rewards rate percentage per year with 1e12 RATE_PRECISION, e.g. 1e12 = 1%, 1e14 = 100%\\n /// @return ended_ flag to signal that rewards have ended (always 0 going forward)\\n /// @return startTime_ start time of rewards to compare against last update timestamp\\n function getRate(uint256 totalAssets_) external view returns (uint256 rate_, bool ended_, uint256 startTime_);\\n\\n /// @notice Returns config constants for rewards rate model\\n function getConfig()\\n external\\n view\\n returns (\\n uint256 duration_,\\n uint256 startTime_,\\n uint256 endTime_,\\n uint256 startTvl_,\\n uint256 maxRate_,\\n uint256 rewardAmount_,\\n address initiator_\\n );\\n}\\n\",\"keccak256\":\"0x04a6f1df74f55ba643f27ff08cd5bb9722c31d16b4782d1b090335845359196d\",\"license\":\"MIT\"},\"contracts/protocols/lending/interfaces/permit2/iAllowanceTransfer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.21;\\n\\n/// @title AllowanceTransfer\\n/// @notice Handles ERC20 token permissions through signature based allowance setting and ERC20 token transfers by checking allowed amounts\\n/// @dev Requires user's token approval on the Permit2 contract\\n/// from https://github.com/Uniswap/permit2/blob/main/src/interfaces/ISignatureTransfer.sol.\\n/// Copyright (c) 2022 Uniswap Labs\\ninterface IAllowanceTransfer {\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n\\n /// @notice Thrown when an allowance on a token has expired.\\n /// @param deadline The timestamp at which the allowed amount is no longer valid\\n error AllowanceExpired(uint256 deadline);\\n\\n /// @notice Thrown when an allowance on a token has been depleted.\\n /// @param amount The maximum amount allowed\\n error InsufficientAllowance(uint256 amount);\\n\\n /// @notice Thrown when too many nonces are invalidated.\\n error ExcessiveInvalidation();\\n\\n /// @notice Emits an event when the owner successfully invalidates an ordered nonce.\\n event NonceInvalidation(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint48 newNonce,\\n uint48 oldNonce\\n );\\n\\n /// @notice Emits an event when the owner successfully sets permissions on a token for the spender.\\n event Approval(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint160 amount,\\n uint48 expiration\\n );\\n\\n /// @notice Emits an event when the owner successfully sets permissions using a permit signature on a token for the spender.\\n event Permit(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint160 amount,\\n uint48 expiration,\\n uint48 nonce\\n );\\n\\n /// @notice Emits an event when the owner sets the allowance back to 0 with the lockdown function.\\n event Lockdown(address indexed owner, address token, address spender);\\n\\n /// @notice The permit data for a token\\n struct PermitDetails {\\n // ERC20 token address\\n address token;\\n // the maximum amount allowed to spend\\n uint160 amount;\\n // timestamp at which a spender's token allowances become invalid\\n uint48 expiration;\\n // an incrementing value indexed per owner,token,and spender for each signature\\n uint48 nonce;\\n }\\n\\n /// @notice The permit message signed for a single token allownce\\n struct PermitSingle {\\n // the permit data for a single token alownce\\n PermitDetails details;\\n // address permissioned on the allowed tokens\\n address spender;\\n // deadline on the permit signature\\n uint256 sigDeadline;\\n }\\n\\n /// @notice The permit message signed for multiple token allowances\\n struct PermitBatch {\\n // the permit data for multiple token allowances\\n PermitDetails[] details;\\n // address permissioned on the allowed tokens\\n address spender;\\n // deadline on the permit signature\\n uint256 sigDeadline;\\n }\\n\\n /// @notice The saved permissions\\n /// @dev This info is saved per owner, per token, per spender and all signed over in the permit message\\n /// @dev Setting amount to type(uint160).max sets an unlimited approval\\n struct PackedAllowance {\\n // amount allowed\\n uint160 amount;\\n // permission expiry\\n uint48 expiration;\\n // an incrementing value indexed per owner,token,and spender for each signature\\n uint48 nonce;\\n }\\n\\n /// @notice A token spender pair.\\n struct TokenSpenderPair {\\n // the token the spender is approved\\n address token;\\n // the spender address\\n address spender;\\n }\\n\\n /// @notice Details for a token transfer.\\n struct AllowanceTransferDetails {\\n // the owner of the token\\n address from;\\n // the recipient of the token\\n address to;\\n // the amount of the token\\n uint160 amount;\\n // the token to be transferred\\n address token;\\n }\\n\\n /// @notice A mapping from owner address to token address to spender address to PackedAllowance struct, which contains details and conditions of the approval.\\n /// @notice The mapping is indexed in the above order see: allowance[ownerAddress][tokenAddress][spenderAddress]\\n /// @dev The packed slot holds the allowed amount, expiration at which the allowed amount is no longer valid, and current nonce thats updated on any signature based approvals.\\n function allowance(\\n address user,\\n address token,\\n address spender\\n ) external view returns (uint160 amount, uint48 expiration, uint48 nonce);\\n\\n /// @notice Approves the spender to use up to amount of the specified token up until the expiration\\n /// @param token The token to approve\\n /// @param spender The spender address to approve\\n /// @param amount The approved amount of the token\\n /// @param expiration The timestamp at which the approval is no longer valid\\n /// @dev The packed allowance also holds a nonce, which will stay unchanged in approve\\n /// @dev Setting amount to type(uint160).max sets an unlimited approval\\n function approve(address token, address spender, uint160 amount, uint48 expiration) external;\\n\\n /// @notice Permit a spender to a given amount of the owners token via the owner's EIP-712 signature\\n /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce\\n /// @param owner The owner of the tokens being approved\\n /// @param permitSingle Data signed over by the owner specifying the terms of approval\\n /// @param signature The owner's signature over the permit data\\n function permit(address owner, PermitSingle memory permitSingle, bytes calldata signature) external;\\n\\n /// @notice Permit a spender to the signed amounts of the owners tokens via the owner's EIP-712 signature\\n /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce\\n /// @param owner The owner of the tokens being approved\\n /// @param permitBatch Data signed over by the owner specifying the terms of approval\\n /// @param signature The owner's signature over the permit data\\n function permit(address owner, PermitBatch memory permitBatch, bytes calldata signature) external;\\n\\n /// @notice Transfer approved tokens from one address to another\\n /// @param from The address to transfer from\\n /// @param to The address of the recipient\\n /// @param amount The amount of the token to transfer\\n /// @param token The token address to transfer\\n /// @dev Requires the from address to have approved at least the desired amount\\n /// of tokens to msg.sender.\\n function transferFrom(address from, address to, uint160 amount, address token) external;\\n\\n /// @notice Transfer approved tokens in a batch\\n /// @param transferDetails Array of owners, recipients, amounts, and tokens for the transfers\\n /// @dev Requires the from addresses to have approved at least the desired amount\\n /// of tokens to msg.sender.\\n function transferFrom(AllowanceTransferDetails[] calldata transferDetails) external;\\n\\n /// @notice Enables performing a \\\"lockdown\\\" of the sender's Permit2 identity\\n /// by batch revoking approvals\\n /// @param approvals Array of approvals to revoke.\\n function lockdown(TokenSpenderPair[] calldata approvals) external;\\n\\n /// @notice Invalidate nonces for a given (token, spender) pair\\n /// @param token The token to invalidate nonces for\\n /// @param spender The spender to invalidate nonces for\\n /// @param newNonce The new nonce to set. Invalidates all nonces less than it.\\n /// @dev Can't invalidate more than 2**16 nonces per transaction.\\n function invalidateNonces(address token, address spender, uint48 newNonce) external;\\n}\\n\",\"keccak256\":\"0x7153c4959bea79f52322c8d0a934614b11a56b65c85701f7f6656284afbd85b2\",\"license\":\"MIT\"}},\"version\":1}",
"bytecode": "0x60c06040523480156200001157600080fd5b5060405162002afd38038062002afd8339810160408190526200003491620000a2565b6001600160a01b03821615806200005257506001600160a01b038116155b1562000071576040516314a3366960e11b815260040160405180910390fd5b6001600160a01b039182166080521660a052620000e1565b6001600160a01b03811681146200009f57600080fd5b50565b60008060408385031215620000b657600080fd5b8251620000c38162000089565b6020840151909250620000d68162000089565b809150509250929050565b60805160a0516129cc62000131600039600081816101c001526112760152600081816102f2015281816108940152818161094c01528181610a4301528181610aff0152610b7001526129cc6000f3fe608060405234801561001057600080fd5b50600436106100f55760003560e01c80637a923a4d1161009757806396bac9311161006657806396bac931146102ed578063c4877f3a14610314578063d7a6fdb014610372578063e26533a31461039257600080fd5b80637a923a4d1461022a5780638ac9aad91461023d5780638c0293321461025057806392a576e6146102cd57600080fd5b80634af955c8116100d35780634af955c8146101915780634ec1e916146101a65780636902f79f146101bb57806370f53bc01461020757600080fd5b806314a287ab146100fa5780632a6bc2dd1461013e5780633caa319f1461015e575b600080fd5b61010d610108366004611a95565b6103a7565b6040805173ffffffffffffffffffffffffffffffffffffffff90931683526020830191909152015b60405180910390f35b61015161014c366004611a95565b610549565b6040516101359190611c90565b61017161016c366004611d51565b61064d565b604080519485526020850193909352918301526060820152608001610135565b610199610890565b6040516101359190611d86565b6101ae610948565b6040516101359190611de0565b6101e27f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610135565b61021a610215366004611a95565b6109fb565b6040519015158152602001610135565b61021a610238366004611a95565b610ab7565b6101e261024b366004611e53565b610b30565b61026361025e366004611a95565b610bf2565b6040805173ffffffffffffffffffffffffffffffffffffffff9a8b168152988a1660208a0152968916968801969096529387166060870152959091166080850152151560a084015260c083019390935260e082019290925261010081019190915261012001610135565b6102e06102db366004611ed8565b610c8f565b6040516101359190611f11565b6101e27f000000000000000000000000000000000000000000000000000000000000000081565b610327610322366004611a95565b610f92565b604080519788526020880196909652948601939093526060850191909152608084015260a083015273ffffffffffffffffffffffffffffffffffffffff1660c082015260e001610135565b610385610380366004611a95565b6110c4565b6040516101359190611f3c565b61039a611879565b6040516101359190611f4f565b60008060008373ffffffffffffffffffffffffffffffffffffffff16633bc5de306040518163ffffffff1660e01b815260040161012060405180830381865afa1580156103f8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061041c9190611fd7565b50949950909650869550508415935061044e92505050575073ffffffffffffffffffffffffffffffffffffffff831615155b15610543578273ffffffffffffffffffffffffffffffffffffffff1663577640948573ffffffffffffffffffffffffffffffffffffffff166301e1d1146040518163ffffffff1660e01b8152600401602060405180830381865afa1580156104ba573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104de9190612078565b6040518263ffffffff1660e01b81526004016104fc91815260200190565b606060405180830381865afa158015610519573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061053d9190612091565b50909250505b50915091565b60606000610555611879565b90506000815167ffffffffffffffff811115610573576105736120c6565b6040519080825280602002602001820160405280156105ac57816020015b610599611939565b8152602001906001900390816105915790505b50905060005b8251811015610645578281815181106105cd576105cd6120f5565b60200260200101518282815181106105e7576105e76120f5565b60200260200101516000018190525061061d83828151811061060b5761060b6120f5565b60200260200101516000015186610c8f565b82828151811061062f5761062f6120f5565b60209081029190910181015101526001016105b2565b509392505050565b6000806000808673ffffffffffffffffffffffffffffffffffffffff1663ef8b30f7876040518263ffffffff1660e01b815260040161068e91815260200190565b602060405180830381865afa1580156106ab573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106cf9190612078565b6040517fb3d7f6b90000000000000000000000000000000000000000000000000000000081526004810187905290945073ffffffffffffffffffffffffffffffffffffffff88169063b3d7f6b990602401602060405180830381865afa15801561073d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107619190612078565b6040517f0a28a4770000000000000000000000000000000000000000000000000000000081526004810188905290935073ffffffffffffffffffffffffffffffffffffffff881690630a28a47790602401602060405180830381865afa1580156107cf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107f39190612078565b6040517f4cdad5060000000000000000000000000000000000000000000000000000000081526004810187905290925073ffffffffffffffffffffffffffffffffffffffff881690634cdad50690602401602060405180830381865afa158015610861573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108859190612078565b905093509350935093565b60607f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16636ff97f1d6040518163ffffffff1660e01b8152600401600060405180830381865afa1580156108fd573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052610943919081019061222b565b905090565b60607f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663dd179e3b6040518163ffffffff1660e01b8152600401600060405180830381865afa1580156109b5573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052610943919081019061234c565b6040517f2520e7ff00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82811660048301526000917f000000000000000000000000000000000000000000000000000000000000000090911690632520e7ff906024015b602060405180830381865afa158015610a8d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ab191906123fd565b92915050565b6040517f50c358a400000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82811660048301526000917f0000000000000000000000000000000000000000000000000000000000000000909116906350c358a490602401610a70565b6040517fbb4a64d300000000000000000000000000000000000000000000000000000000815260009073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169063bb4a64d390610ba990879087908790600401612418565b602060405180830381865afa158015610bc6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bea9190612482565b949350505050565b60008060008060008060008060008973ffffffffffffffffffffffffffffffffffffffff16633bc5de306040518163ffffffff1660e01b815260040161012060405180830381865afa158015610c4c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c709190611fd7565b9850985098509850985098509850985098509193959799909294969850565b610cba6040518060800160405280600081526020016000815260200160008152602001600081525090565b60008373ffffffffffffffffffffffffffffffffffffffff166338d52e0f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610d07573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d2b9190612482565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8581166004830152919250908516906370a0823190602401602060405180830381865afa158015610d9b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dbf9190612078565b8083526040517f07a2d13a000000000000000000000000000000000000000000000000000000008152600481019190915273ffffffffffffffffffffffffffffffffffffffff8516906307a2d13a90602401602060405180830381865afa158015610e2e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e529190612078565b60208301526040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff84811660048301528216906370a0823190602401602060405180830381865afa158015610ec3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ee79190612078565b604083810191909152517fdd62ed3e00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8481166004830152858116602483015282169063dd62ed3e90604401602060405180830381865afa158015610f62573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f869190612078565b60608301525092915050565b6000806000806000806000808873ffffffffffffffffffffffffffffffffffffffff16633bc5de306040518163ffffffff1660e01b815260040161012060405180830381865afa158015610fea573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061100e9190611fd7565b50949750505073ffffffffffffffffffffffffffffffffffffffff86161594506110b89350505050578073ffffffffffffffffffffffffffffffffffffffff1663c3f909d46040518163ffffffff1660e01b815260040160e060405180830381865afa158015611082573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110a6919061249f565b959d50939b5091995097509550935091505b50919395979092949650565b6110cc611981565b60008273ffffffffffffffffffffffffffffffffffffffff166338d52e0f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611119573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061113d9190612482565b905060008373ffffffffffffffffffffffffffffffffffffffff1663df2ebdbb6040518163ffffffff1660e01b8152600401602060405180830381865afa9250505080156111c6575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682019092526111c391810190612482565b60015b156111d15750600190505b60008273ffffffffffffffffffffffffffffffffffffffff16633644e5156040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015611258575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820190925261125591810190612078565b60015b156112635750600190505b600061126e866103a7565b9150506000807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663e72ef91b89876112bc57886112d2565b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee5b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815273ffffffffffffffffffffffffffffffffffffffff9283166004820152911660248201526044016104c060405180830381865afa158015611343573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611367919061271a565b9150915060008873ffffffffffffffffffffffffffffffffffffffff166301e1d1146040518163ffffffff1660e01b8152600401602060405180830381865afa1580156113b8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113dc9190612078565b9050604051806101e001604052808a73ffffffffffffffffffffffffffffffffffffffff168152602001861515815260200187151581526020018a73ffffffffffffffffffffffffffffffffffffffff166306fdde036040518163ffffffff1660e01b8152600401600060405180830381865afa158015611461573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526114a791908101906127c0565b81526020018a73ffffffffffffffffffffffffffffffffffffffff166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa1580156114f7573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405261153d91908101906127c0565b81526020018a73ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa15801561158d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115b191906127f5565b60ff1681526020018873ffffffffffffffffffffffffffffffffffffffff1681526020018281526020018a73ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611626573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061164a9190612078565b81526020018a73ffffffffffffffffffffffffffffffffffffffff1663c6e6f5928c73ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156116b6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116da91906127f5565b6116e590600a612967565b6040518263ffffffff1660e01b815260040161170391815260200190565b602060405180830381865afa158015611720573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117449190612078565b81526020018a73ffffffffffffffffffffffffffffffffffffffff166307a2d13a8c73ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156117b0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117d491906127f5565b6117df90600a612967565b6040518263ffffffff1660e01b81526004016117fd91815260200190565b602060405180830381865afa15801561181a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061183e9190612078565b8152602001858152602001836020015181526020018285602001516118639190612976565b8152602001939093525090979650505050505050565b60606000611885610890565b90506000815167ffffffffffffffff8111156118a3576118a36120c6565b6040519080825280602002602001820160405280156118dc57816020015b6118c9611981565b8152602001906001900390816118c15790505b50905060005b82518110156119325761190d838281518110611900576119006120f5565b60200260200101516110c4565b82828151811061191f5761191f6120f5565b60209081029190910101526001016118e2565b5092915050565b604051806040016040528061194c611981565b815260200161197c6040518060800160405280600081526020016000815260200160008152602001600081525090565b905290565b604051806101e00160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001600015158152602001600015158152602001606081526020016060815260200160008152602001600073ffffffffffffffffffffffffffffffffffffffff1681526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200161197c60405180610120016040528060001515815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b73ffffffffffffffffffffffffffffffffffffffff81168114611a9257600080fd5b50565b600060208284031215611aa757600080fd5b8135611ab281611a70565b9392505050565b60005b83811015611ad4578181015183820152602001611abc565b50506000910152565b60008151808452611af5816020860160208601611ab9565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b805173ffffffffffffffffffffffffffffffffffffffff16825260006102e06020830151611b59602086018215159052565b506040830151611b6d604086018215159052565b506060830151816060860152611b8582860182611add565b91505060808301518482036080860152611b9f8282611add565b91505060a083015160a085015260c0830151611bd360c086018273ffffffffffffffffffffffffffffffffffffffff169052565b5060e08381015185820152610100808501518187015261012080860151908701526101408086015190870152610160808601519087015261018080860151908701526101a080860151908701526101c080860151805115158289015260208101516101e089015260408101516102008901526060810151610220890152608081015161024089015260a081015161026089015260c0810151610280890152928301516102a0880152908201516102c0870152905090949350505050565b6000602080830181845280855180835260408601915060408160051b870101925083870160005b82811015611d44577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0888603018452815160a08151818852611cfb82890182611b27565b915050878201519150611d3188880183805182526020810151602083015260408101516040830152606081015160608301525050565b9550509285019290850190600101611cb7565b5092979650505050505050565b600080600060608486031215611d6657600080fd5b8335611d7181611a70565b95602085013595506040909401359392505050565b6020808252825182820181905260009190848201906040850190845b81811015611dd457835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101611da2565b50909695505050505050565b6000602080830181845280855180835260408601915060408160051b870101925083870160005b82811015611d44577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0888603018452611e41858351611add565b94509285019290850190600101611e07565b600080600060408486031215611e6857600080fd5b8335611e7381611a70565b9250602084013567ffffffffffffffff80821115611e9057600080fd5b818601915086601f830112611ea457600080fd5b813581811115611eb357600080fd5b876020828501011115611ec557600080fd5b6020830194508093505050509250925092565b60008060408385031215611eeb57600080fd5b8235611ef681611a70565b91506020830135611f0681611a70565b809150509250929050565b8151815260208083015190820152604080830151908201526060808301519082015260808101610ab1565b602081526000611ab26020830184611b27565b6000602080830181845280855180835260408601915060408160051b870101925083870160005b82811015611d44577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0888603018452611fb0858351611b27565b94509285019290850190600101611f76565b80518015158114611fd257600080fd5b919050565b60008060008060008060008060006101208a8c031215611ff657600080fd5b895161200181611a70565b60208b015190995061201281611a70565b60408b015190985061202381611a70565b60608b015190975061203481611a70565b60808b015190965061204581611a70565b945061205360a08b01611fc2565b935060c08a0151925060e08a015191506101008a015190509295985092959850929598565b60006020828403121561208a57600080fd5b5051919050565b6000806000606084860312156120a657600080fd5b835192506120b660208501611fc2565b9150604084015190509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6040516060810167ffffffffffffffff81118282101715612147576121476120c6565b60405290565b60405160a0810167ffffffffffffffff81118282101715612147576121476120c6565b604051610220810167ffffffffffffffff81118282101715612147576121476120c6565b604051610120810167ffffffffffffffff81118282101715612147576121476120c6565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156121ff576121ff6120c6565b604052919050565b600067ffffffffffffffff821115612221576122216120c6565b5060051b60200190565b6000602080838503121561223e57600080fd5b825167ffffffffffffffff81111561225557600080fd5b8301601f8101851361226657600080fd5b805161227961227482612207565b6121b8565b81815260059190911b8201830190838101908783111561229857600080fd5b928401925b828410156122bf5783516122b081611a70565b8252928401929084019061229d565b979650505050505050565b600082601f8301126122db57600080fd5b815167ffffffffffffffff8111156122f5576122f56120c6565b61232660207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116016121b8565b81815284602083860101111561233b57600080fd5b610bea826020830160208701611ab9565b6000602080838503121561235f57600080fd5b825167ffffffffffffffff8082111561237757600080fd5b818501915085601f83011261238b57600080fd5b815161239961227482612207565b81815260059190911b830184019084810190888311156123b857600080fd5b8585015b838110156123f0578051858111156123d45760008081fd5b6123e28b89838a01016122ca565b8452509186019186016123bc565b5098975050505050505050565b60006020828403121561240f57600080fd5b611ab282611fc2565b73ffffffffffffffffffffffffffffffffffffffff8416815260406020820152816040820152818360608301376000818301606090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016010192915050565b60006020828403121561249457600080fd5b8151611ab281611a70565b600080600080600080600060e0888a0312156124ba57600080fd5b875196506020880151955060408801519450606088015193506080880151925060a0880151915060c08801516124ef81611a70565b8091505092959891949750929550565b600060e0828403121561251157600080fd5b60405160e0810181811067ffffffffffffffff82111715612534576125346120c6565b8060405250809150825161254781611a70565b808252506020830151602082015260408301516040820152606083015160608201526080830151608082015260a083015160a082015260c083015160c08201525092915050565b60008183036101a08112156125a257600080fd5b6125aa612124565b91508251825260a07fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0820112156125e057600080fd5b506125e961214d565b60208301516125f781611a70565b8082525060408301516020820152606083015160408201526080830151606082015260a08301516080820152806020830152506126378360c084016124ff565b604082015292915050565b60006103a0828403121561265557600080fd5b61265d612170565b825181526020808401519082015260408084015190820152606080840151908201526080808401519082015260a0808401519082015260c0808401519082015260e08084015190820152610100808401519082015261012080840151908201526101408084015190820152610160808401519082015261018080840151908201526101a080840151908201526101c080840151908201526101e0808401519082015290506102006127108482850161258e565b9082015292915050565b6000808284036104c081121561272f57600080fd5b6101208082121561273f57600080fd5b612747612194565b915061275285611fc2565b82526020850151602083015260408501516040830152606085015160608301526080850151608083015260a085015160a083015260c085015160c083015260e085015160e08301526101008086015181840152508193506127b586828701612642565b925050509250929050565b6000602082840312156127d257600080fd5b815167ffffffffffffffff8111156127e957600080fd5b610bea848285016122ca565b60006020828403121561280757600080fd5b815160ff81168114611ab257600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600181815b808511156128a057817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482111561288657612886612818565b8085161561289357918102915b93841c939080029061284c565b509250929050565b6000826128b757506001610ab1565b816128c457506000610ab1565b81600181146128da57600281146128e457612900565b6001915050610ab1565b60ff8411156128f5576128f5612818565b50506001821b610ab1565b5060208310610133831016604e8410600b8410161715612923575081810a610ab1565b61292d8383612847565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482111561295f5761295f612818565b029392505050565b6000611ab260ff8416836128a8565b81810360008312801583831316838312821617156119325761193261281856fea26469706673582212203ae3733737f743fee31440a0dede3cb5c3f9169534053e32e77ada3ad229eb3864736f6c63430008150033",
"deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100f55760003560e01c80637a923a4d1161009757806396bac9311161006657806396bac931146102ed578063c4877f3a14610314578063d7a6fdb014610372578063e26533a31461039257600080fd5b80637a923a4d1461022a5780638ac9aad91461023d5780638c0293321461025057806392a576e6146102cd57600080fd5b80634af955c8116100d35780634af955c8146101915780634ec1e916146101a65780636902f79f146101bb57806370f53bc01461020757600080fd5b806314a287ab146100fa5780632a6bc2dd1461013e5780633caa319f1461015e575b600080fd5b61010d610108366004611a95565b6103a7565b6040805173ffffffffffffffffffffffffffffffffffffffff90931683526020830191909152015b60405180910390f35b61015161014c366004611a95565b610549565b6040516101359190611c90565b61017161016c366004611d51565b61064d565b604080519485526020850193909352918301526060820152608001610135565b610199610890565b6040516101359190611d86565b6101ae610948565b6040516101359190611de0565b6101e27f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610135565b61021a610215366004611a95565b6109fb565b6040519015158152602001610135565b61021a610238366004611a95565b610ab7565b6101e261024b366004611e53565b610b30565b61026361025e366004611a95565b610bf2565b6040805173ffffffffffffffffffffffffffffffffffffffff9a8b168152988a1660208a0152968916968801969096529387166060870152959091166080850152151560a084015260c083019390935260e082019290925261010081019190915261012001610135565b6102e06102db366004611ed8565b610c8f565b6040516101359190611f11565b6101e27f000000000000000000000000000000000000000000000000000000000000000081565b610327610322366004611a95565b610f92565b604080519788526020880196909652948601939093526060850191909152608084015260a083015273ffffffffffffffffffffffffffffffffffffffff1660c082015260e001610135565b610385610380366004611a95565b6110c4565b6040516101359190611f3c565b61039a611879565b6040516101359190611f4f565b60008060008373ffffffffffffffffffffffffffffffffffffffff16633bc5de306040518163ffffffff1660e01b815260040161012060405180830381865afa1580156103f8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061041c9190611fd7565b50949950909650869550508415935061044e92505050575073ffffffffffffffffffffffffffffffffffffffff831615155b15610543578273ffffffffffffffffffffffffffffffffffffffff1663577640948573ffffffffffffffffffffffffffffffffffffffff166301e1d1146040518163ffffffff1660e01b8152600401602060405180830381865afa1580156104ba573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104de9190612078565b6040518263ffffffff1660e01b81526004016104fc91815260200190565b606060405180830381865afa158015610519573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061053d9190612091565b50909250505b50915091565b60606000610555611879565b90506000815167ffffffffffffffff811115610573576105736120c6565b6040519080825280602002602001820160405280156105ac57816020015b610599611939565b8152602001906001900390816105915790505b50905060005b8251811015610645578281815181106105cd576105cd6120f5565b60200260200101518282815181106105e7576105e76120f5565b60200260200101516000018190525061061d83828151811061060b5761060b6120f5565b60200260200101516000015186610c8f565b82828151811061062f5761062f6120f5565b60209081029190910181015101526001016105b2565b509392505050565b6000806000808673ffffffffffffffffffffffffffffffffffffffff1663ef8b30f7876040518263ffffffff1660e01b815260040161068e91815260200190565b602060405180830381865afa1580156106ab573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106cf9190612078565b6040517fb3d7f6b90000000000000000000000000000000000000000000000000000000081526004810187905290945073ffffffffffffffffffffffffffffffffffffffff88169063b3d7f6b990602401602060405180830381865afa15801561073d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107619190612078565b6040517f0a28a4770000000000000000000000000000000000000000000000000000000081526004810188905290935073ffffffffffffffffffffffffffffffffffffffff881690630a28a47790602401602060405180830381865afa1580156107cf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107f39190612078565b6040517f4cdad5060000000000000000000000000000000000000000000000000000000081526004810187905290925073ffffffffffffffffffffffffffffffffffffffff881690634cdad50690602401602060405180830381865afa158015610861573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108859190612078565b905093509350935093565b60607f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16636ff97f1d6040518163ffffffff1660e01b8152600401600060405180830381865afa1580156108fd573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052610943919081019061222b565b905090565b60607f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663dd179e3b6040518163ffffffff1660e01b8152600401600060405180830381865afa1580156109b5573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052610943919081019061234c565b6040517f2520e7ff00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82811660048301526000917f000000000000000000000000000000000000000000000000000000000000000090911690632520e7ff906024015b602060405180830381865afa158015610a8d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ab191906123fd565b92915050565b6040517f50c358a400000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82811660048301526000917f0000000000000000000000000000000000000000000000000000000000000000909116906350c358a490602401610a70565b6040517fbb4a64d300000000000000000000000000000000000000000000000000000000815260009073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169063bb4a64d390610ba990879087908790600401612418565b602060405180830381865afa158015610bc6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bea9190612482565b949350505050565b60008060008060008060008060008973ffffffffffffffffffffffffffffffffffffffff16633bc5de306040518163ffffffff1660e01b815260040161012060405180830381865afa158015610c4c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c709190611fd7565b9850985098509850985098509850985098509193959799909294969850565b610cba6040518060800160405280600081526020016000815260200160008152602001600081525090565b60008373ffffffffffffffffffffffffffffffffffffffff166338d52e0f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610d07573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d2b9190612482565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8581166004830152919250908516906370a0823190602401602060405180830381865afa158015610d9b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dbf9190612078565b8083526040517f07a2d13a000000000000000000000000000000000000000000000000000000008152600481019190915273ffffffffffffffffffffffffffffffffffffffff8516906307a2d13a90602401602060405180830381865afa158015610e2e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e529190612078565b60208301526040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff84811660048301528216906370a0823190602401602060405180830381865afa158015610ec3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ee79190612078565b604083810191909152517fdd62ed3e00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8481166004830152858116602483015282169063dd62ed3e90604401602060405180830381865afa158015610f62573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f869190612078565b60608301525092915050565b6000806000806000806000808873ffffffffffffffffffffffffffffffffffffffff16633bc5de306040518163ffffffff1660e01b815260040161012060405180830381865afa158015610fea573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061100e9190611fd7565b50949750505073ffffffffffffffffffffffffffffffffffffffff86161594506110b89350505050578073ffffffffffffffffffffffffffffffffffffffff1663c3f909d46040518163ffffffff1660e01b815260040160e060405180830381865afa158015611082573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110a6919061249f565b959d50939b5091995097509550935091505b50919395979092949650565b6110cc611981565b60008273ffffffffffffffffffffffffffffffffffffffff166338d52e0f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611119573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061113d9190612482565b905060008373ffffffffffffffffffffffffffffffffffffffff1663df2ebdbb6040518163ffffffff1660e01b8152600401602060405180830381865afa9250505080156111c6575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682019092526111c391810190612482565b60015b156111d15750600190505b60008273ffffffffffffffffffffffffffffffffffffffff16633644e5156040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015611258575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820190925261125591810190612078565b60015b156112635750600190505b600061126e866103a7565b9150506000807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663e72ef91b89876112bc57886112d2565b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee5b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815273ffffffffffffffffffffffffffffffffffffffff9283166004820152911660248201526044016104c060405180830381865afa158015611343573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611367919061271a565b9150915060008873ffffffffffffffffffffffffffffffffffffffff166301e1d1146040518163ffffffff1660e01b8152600401602060405180830381865afa1580156113b8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113dc9190612078565b9050604051806101e001604052808a73ffffffffffffffffffffffffffffffffffffffff168152602001861515815260200187151581526020018a73ffffffffffffffffffffffffffffffffffffffff166306fdde036040518163ffffffff1660e01b8152600401600060405180830381865afa158015611461573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526114a791908101906127c0565b81526020018a73ffffffffffffffffffffffffffffffffffffffff166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa1580156114f7573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405261153d91908101906127c0565b81526020018a73ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa15801561158d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115b191906127f5565b60ff1681526020018873ffffffffffffffffffffffffffffffffffffffff1681526020018281526020018a73ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611626573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061164a9190612078565b81526020018a73ffffffffffffffffffffffffffffffffffffffff1663c6e6f5928c73ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156116b6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116da91906127f5565b6116e590600a612967565b6040518263ffffffff1660e01b815260040161170391815260200190565b602060405180830381865afa158015611720573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117449190612078565b81526020018a73ffffffffffffffffffffffffffffffffffffffff166307a2d13a8c73ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156117b0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117d491906127f5565b6117df90600a612967565b6040518263ffffffff1660e01b81526004016117fd91815260200190565b602060405180830381865afa15801561181a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061183e9190612078565b8152602001858152602001836020015181526020018285602001516118639190612976565b8152602001939093525090979650505050505050565b60606000611885610890565b90506000815167ffffffffffffffff8111156118a3576118a36120c6565b6040519080825280602002602001820160405280156118dc57816020015b6118c9611981565b8152602001906001900390816118c15790505b50905060005b82518110156119325761190d838281518110611900576119006120f5565b60200260200101516110c4565b82828151811061191f5761191f6120f5565b60209081029190910101526001016118e2565b5092915050565b604051806040016040528061194c611981565b815260200161197c6040518060800160405280600081526020016000815260200160008152602001600081525090565b905290565b604051806101e00160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001600015158152602001600015158152602001606081526020016060815260200160008152602001600073ffffffffffffffffffffffffffffffffffffffff1681526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200161197c60405180610120016040528060001515815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b73ffffffffffffffffffffffffffffffffffffffff81168114611a9257600080fd5b50565b600060208284031215611aa757600080fd5b8135611ab281611a70565b9392505050565b60005b83811015611ad4578181015183820152602001611abc565b50506000910152565b60008151808452611af5816020860160208601611ab9565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b805173ffffffffffffffffffffffffffffffffffffffff16825260006102e06020830151611b59602086018215159052565b506040830151611b6d604086018215159052565b506060830151816060860152611b8582860182611add565b91505060808301518482036080860152611b9f8282611add565b91505060a083015160a085015260c0830151611bd360c086018273ffffffffffffffffffffffffffffffffffffffff169052565b5060e08381015185820152610100808501518187015261012080860151908701526101408086015190870152610160808601519087015261018080860151908701526101a080860151908701526101c080860151805115158289015260208101516101e089015260408101516102008901526060810151610220890152608081015161024089015260a081015161026089015260c0810151610280890152928301516102a0880152908201516102c0870152905090949350505050565b6000602080830181845280855180835260408601915060408160051b870101925083870160005b82811015611d44577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0888603018452815160a08151818852611cfb82890182611b27565b915050878201519150611d3188880183805182526020810151602083015260408101516040830152606081015160608301525050565b9550509285019290850190600101611cb7565b5092979650505050505050565b600080600060608486031215611d6657600080fd5b8335611d7181611a70565b95602085013595506040909401359392505050565b6020808252825182820181905260009190848201906040850190845b81811015611dd457835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101611da2565b50909695505050505050565b6000602080830181845280855180835260408601915060408160051b870101925083870160005b82811015611d44577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0888603018452611e41858351611add565b94509285019290850190600101611e07565b600080600060408486031215611e6857600080fd5b8335611e7381611a70565b9250602084013567ffffffffffffffff80821115611e9057600080fd5b818601915086601f830112611ea457600080fd5b813581811115611eb357600080fd5b876020828501011115611ec557600080fd5b6020830194508093505050509250925092565b60008060408385031215611eeb57600080fd5b8235611ef681611a70565b91506020830135611f0681611a70565b809150509250929050565b8151815260208083015190820152604080830151908201526060808301519082015260808101610ab1565b602081526000611ab26020830184611b27565b6000602080830181845280855180835260408601915060408160051b870101925083870160005b82811015611d44577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0888603018452611fb0858351611b27565b94509285019290850190600101611f76565b80518015158114611fd257600080fd5b919050565b60008060008060008060008060006101208a8c031215611ff657600080fd5b895161200181611a70565b60208b015190995061201281611a70565b60408b015190985061202381611a70565b60608b015190975061203481611a70565b60808b015190965061204581611a70565b945061205360a08b01611fc2565b935060c08a0151925060e08a015191506101008a015190509295985092959850929598565b60006020828403121561208a57600080fd5b5051919050565b6000806000606084860312156120a657600080fd5b835192506120b660208501611fc2565b9150604084015190509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6040516060810167ffffffffffffffff81118282101715612147576121476120c6565b60405290565b60405160a0810167ffffffffffffffff81118282101715612147576121476120c6565b604051610220810167ffffffffffffffff81118282101715612147576121476120c6565b604051610120810167ffffffffffffffff81118282101715612147576121476120c6565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156121ff576121ff6120c6565b604052919050565b600067ffffffffffffffff821115612221576122216120c6565b5060051b60200190565b6000602080838503121561223e57600080fd5b825167ffffffffffffffff81111561225557600080fd5b8301601f8101851361226657600080fd5b805161227961227482612207565b6121b8565b81815260059190911b8201830190838101908783111561229857600080fd5b928401925b828410156122bf5783516122b081611a70565b8252928401929084019061229d565b979650505050505050565b600082601f8301126122db57600080fd5b815167ffffffffffffffff8111156122f5576122f56120c6565b61232660207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116016121b8565b81815284602083860101111561233b57600080fd5b610bea826020830160208701611ab9565b6000602080838503121561235f57600080fd5b825167ffffffffffffffff8082111561237757600080fd5b818501915085601f83011261238b57600080fd5b815161239961227482612207565b81815260059190911b830184019084810190888311156123b857600080fd5b8585015b838110156123f0578051858111156123d45760008081fd5b6123e28b89838a01016122ca565b8452509186019186016123bc565b5098975050505050505050565b60006020828403121561240f57600080fd5b611ab282611fc2565b73ffffffffffffffffffffffffffffffffffffffff8416815260406020820152816040820152818360608301376000818301606090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016010192915050565b60006020828403121561249457600080fd5b8151611ab281611a70565b600080600080600080600060e0888a0312156124ba57600080fd5b875196506020880151955060408801519450606088015193506080880151925060a0880151915060c08801516124ef81611a70565b8091505092959891949750929550565b600060e0828403121561251157600080fd5b60405160e0810181811067ffffffffffffffff82111715612534576125346120c6565b8060405250809150825161254781611a70565b808252506020830151602082015260408301516040820152606083015160608201526080830151608082015260a083015160a082015260c083015160c08201525092915050565b60008183036101a08112156125a257600080fd5b6125aa612124565b91508251825260a07fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0820112156125e057600080fd5b506125e961214d565b60208301516125f781611a70565b8082525060408301516020820152606083015160408201526080830151606082015260a08301516080820152806020830152506126378360c084016124ff565b604082015292915050565b60006103a0828403121561265557600080fd5b61265d612170565b825181526020808401519082015260408084015190820152606080840151908201526080808401519082015260a0808401519082015260c0808401519082015260e08084015190820152610100808401519082015261012080840151908201526101408084015190820152610160808401519082015261018080840151908201526101a080840151908201526101c080840151908201526101e0808401519082015290506102006127108482850161258e565b9082015292915050565b6000808284036104c081121561272f57600080fd5b6101208082121561273f57600080fd5b612747612194565b915061275285611fc2565b82526020850151602083015260408501516040830152606085015160608301526080850151608083015260a085015160a083015260c085015160c083015260e085015160e08301526101008086015181840152508193506127b586828701612642565b925050509250929050565b6000602082840312156127d257600080fd5b815167ffffffffffffffff8111156127e957600080fd5b610bea848285016122ca565b60006020828403121561280757600080fd5b815160ff81168114611ab257600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600181815b808511156128a057817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482111561288657612886612818565b8085161561289357918102915b93841c939080029061284c565b509250929050565b6000826128b757506001610ab1565b816128c457506000610ab1565b81600181146128da57600281146128e457612900565b6001915050610ab1565b60ff8411156128f5576128f5612818565b50506001821b610ab1565b5060208310610133831016604e8410600b8410161715612923575081810a610ab1565b61292d8383612847565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482111561295f5761295f612818565b029392505050565b6000611ab260ff8416836128a8565b81810360008312801583831316838312821617156119325761193261281856fea26469706673582212203ae3733737f743fee31440a0dede3cb5c3f9169534053e32e77ada3ad229eb3864736f6c63430008150033",
"devdoc": {
"kind": "dev",
"methods": {
"computeFToken(address,string)": {
"params": {
"asset_": "address of the asset",
"fTokenType_": "type of fToken: - if underlying asset supports EIP-2612, the fToken should be type `EIP2612Deposits` - otherwise it should use `Permit2Deposits` - if it's the native token, it should use `NativeUnderlying` - could be more types available, check `fTokenTypes()`"
},
"returns": {
"_0": "token_ detemrinistic address of the computed token"
}
},
"getFTokenDetails(address)": {
"params": {
"fToken_": "the fToken to get the details for"
},
"returns": {
"fTokenDetails_": " retrieved FTokenDetails struct"
}
},
"getFTokenInternalData(address)": {
"params": {
"fToken_": "the fToken to get the data for"
},
"returns": {
"lendingFactory_": "address of the Lending factory contract.",
"lendingRewardsRateModel_": "address of the rewards rate model contract. changeable by LendingFactory auths.",
"liquidityBalance_": "current Liquidity supply balance of `address(this)` for the underyling asset",
"liquidityExchangePrice_": "(updated) exchange price for the underlying assset in the liquidity protocol (without rewards)",
"liquidity_": "address of the Liquidity contract.",
"permit2_": "address of the Permit2 contract used for deposits / mint with signature",
"rebalancer_": "address of the rebalancer allowed to execute `rebalance()`",
"rewardsActive_": "true if rewards are currently active",
"tokenExchangePrice_": "(updated) exchange price between fToken and the underlying assset (with rewards)"
}
},
"getPreviews(address,uint256,uint256)": {
"returns": {
"previewDeposit_": "preview for deposit of `assets_`",
"previewMint_": "preview for mint of `shares_`",
"previewRedeem_": "preview for redeem of `shares_`",
"previewWithdraw_": "preview for withdraw of `assets_`"
}
},
"getUserPosition(address,address)": {
"returns": {
"userPosition": "user position struct"
}
}
},
"stateVariables": {
"_NATIVE_TOKEN_ADDRESS": {
"details": "address that is mapped to the chain native token"
}
},
"version": 1
},
"userdoc": {
"errors": {
"FluidLendingResolver__AddressZero()": [
{
"notice": "thrown if an input param address is zero"
}
]
},
"kind": "user",
"methods": {
"LENDING_FACTORY()": {
"notice": "returns the lending factory address"
},
"LIQUIDITY_RESOLVER()": {
"notice": "returns the liquidity resolver address"
},
"computeFToken(address,string)": {
"notice": "computes deterministic token address for `asset_` for a lending protocol"
},
"constructor": {
"notice": "constructor sets the immutable `LENDING_FACTORY` and `LIQUIDITY_RESOLVER` address"
},
"getAllFTokenTypes()": {
"notice": "returns all fToken types at the `LENDING_FACTORY`"
},
"getAllFTokens()": {
"notice": "returns all created fTokens at the `LENDING_FACTORY`"
},
"getFTokenDetails(address)": {
"notice": "gets all public details for a certain `fToken_`, such as fToken type, name, symbol, decimals, underlying asset, total amounts, convertTo values, rewards. Note it also returns whether the fToken supports deposits / mints via EIP-2612, but it is not a 100% guarantee! To make sure, check for the underlying if it supports EIP-2612 manually."
},
"getFTokenInternalData(address)": {
"notice": "returns config, rewards and exchange prices data of an fToken."
},
"getFTokenRewards(address)": {
"notice": "gets rewards related data: the `rewardsRateModel_` contract and the current `rewardsRate_` for the `fToken_`"
},
"getFTokenRewardsRateModelConfig(address)": {
"notice": "gets rewards rate model config constants"
},
"getFTokensEntireData()": {
"notice": "gets all public details for all itokens, such as fToken type, name, symbol, decimals, underlying asset, total amounts, convertTo values, rewards"
},
"getPreviews(address,uint256,uint256)": {
"notice": "gets `fToken_` preview amounts for `assets_` or `shares_`."
},
"getUserPosition(address,address)": {
"notice": "gets a `user_` position for an `fToken_`."
},
"getUserPositions(address)": {
"notice": "gets all public details for all itokens, such as fToken type, name, symbol, decimals, underlying asset, total amounts, convertTo values, rewards and user position for each token"
},
"isLendingFactoryAuth(address)": {
"notice": "reads if a certain `auth_` address is an allowed auth or not. Owner is auth by default."
},
"isLendingFactoryDeployer(address)": {
"notice": "reads if a certain `deployer_` address is an allowed deployer or not. Owner is deployer by default."
}
},
"notice": "Fluid Lending protocol (fTokens) resolver Implements various view-only methods to give easy access to Lending protocol data.",
"version": 1
},
"storageLayout": {
"storage": [],
"types": null
}
}